Add Push notification token and account creation endpoints

Complete documentation
Complete tests
Update the dependencies
Bump the package number
This commit is contained in:
Timothée Jaussoin 2021-02-23 17:45:33 +01:00
parent e2aeab285a
commit cd32657d21
16 changed files with 430 additions and 70 deletions

View file

@ -5,6 +5,7 @@ APP_DEBUG=false
APP_URL=http://localhost
APP_SIP_DOMAIN=sip.example.com
APP_FLEXISIP_PROXY_PID=/var/run/flexisip-proxy.pid
APP_FLEXISIP_PUSHER_PATH=
APP_EVERYONE_IS_ADMIN=false
# SIP server parameters

View file

@ -59,7 +59,7 @@ class AuthenticateController extends Controller
foreach ($account->passwords as $password) {
if (hash_equals(
$password->password,
Utils::bchash($request->get('username'), $account->domain, $request->get('password'), $password->algorithm)
Utils::bchash($request->get('username'), $account->resolvedRealm, $request->get('password'), $password->algorithm)
)) {
Auth::login($account);
return redirect()->route('account.panel');

View file

@ -20,9 +20,14 @@
namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Illuminate\Support\Str;
use App\Http\Controllers\Controller;
use App\Account;
use App\Rules\WithoutSpaces;
use Carbon\Carbon;
use App\Account;
use App\Token;
use App\Http\Controllers\Account\AuthenticateController as WebAuthenticateController;
class AccountController extends Controller
@ -40,6 +45,52 @@ class AccountController extends Controller
]);
}
public function store(Request $request)
{
$request->validate([
'username' => [
'required',
Rule::unique('external.accounts', 'username')->where(function ($query) use ($request) {
$query->where('domain', config('app.sip_domain'));
}),
'filled',
new WithoutSpaces
],
'algorithm' => 'required|in:SHA-256,MD5',
'password' => 'required|filled',
'domain' => 'min:3',
'token' => [
'required',
Rule::exists('tokens', 'token')->where(function ($query) {
$query->where('used', false);
}),
'size:'.WebAuthenticateController::$emailCodeSize
]
]);
$token = Token::where('token', $request->get('token'))->first();
$token->used = true;
$token->save();
$account = new Account;
$account->username = $request->get('username');
$account->email = $request->get('email');
$account->activated = false;
$account->domain = $request->has('domain')
? $request->get('domain')
: config('app.sip_domain');
$account->ip_address = $request->ip();
$account->creation_time = Carbon::now();
$account->user_agent = config('app.name');
$account->confirmation_key = Str::random(WebAuthenticateController::$emailCodeSize);
$account->save();
$account->updatePassword($request->get('password'), $request->get('algorithm'));
// Full reload
return Account::withoutGlobalScopes()->find($account->id);
}
public function activateEmail(Request $request, string $sip)
{
$request->validate([

View file

@ -105,11 +105,7 @@ class AccountController extends Controller
$account->save();
$password = new Password;
$password->account_id = $account->id;
$password->password = Utils::bchash($account->username, $account->resolvedRealm, $request->get('password'), $request->get('algorithm'));
$password->algorithm = $request->get('algorithm');
$password->save();
$account->updatePassword($request->get('password'), $request->get('algorithm'));
if ($request->has('admin') && (bool)$request->get('admin')) {
$admin = new Admin;

View file

@ -0,0 +1,52 @@
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use App\Token;
use App\Libraries\FlexisipPusherConnector;
use App\Http\Controllers\Account\AuthenticateController as WebAuthenticateController;
class TokenController extends Controller
{
public function create(Request $request)
{
$request->validate([
'pn_provider' => 'required',
'pn_param' => 'required',
'pn_prid' => 'required',
]);
if (Token::where('pn_provider', $request->get('pn_provider'))
->where('pn_param', $request->get('pn_param'))
->where('pn_prid', $request->get('pn_prid'))
->where('used', false)
->count() > 0) {
abort(403, 'A similar token was already used');
}
if (Token::where('pn_provider', $request->get('pn_provider'))
->where('pn_param', $request->get('pn_param'))
->where('pn_prid', $request->get('pn_prid'))
->count() > 3) {
abort(403, 'The limit of tokens generated for this device has been reached');
}
$token = new Token;
$token->token = Str::random(WebAuthenticateController::$emailCodeSize);
$token->pn_provider = $request->get('pn_provider');
$token->pn_param = $request->get('pn_param');
$token->pn_prid = $request->get('pn_prid');
// Send the token to the device via Push Notification
$fp = new FlexisipPusherConnector($token->pn_provider, $token->pn_param, $token->pn_prid);
if ($fp->sendToken($token->token)) {
$token->save();
} else {
abort(503, "Token not sent");
}
}
}

View file

@ -56,7 +56,7 @@ class FlexisipConnector
public function deleteDevice(string $from, string $uuid)
{
$content = $this->request('REGISTRAR_DELETE', [
$this->request('REGISTRAR_DELETE', [
'sip:'.$from,
'"<'.$uuid.'>"',
]);

View file

@ -0,0 +1,52 @@
<?php
/*
Flexisip Account Manager is a set of tools to manage SIP accounts.
Copyright (C) 2020 Belledonne Communications SARL, All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App\Libraries;
class FlexisipPusherConnector
{
private $pusherPath;
private $pnProvider;
private $pnParam;
private $pnPrid;
public function __construct(string $pnProvider, string $pnParam, string $pnPrid)
{
$this->pusherPath = config('app.flexisip_pusher_path');
$this->pnProvider = $pnProvider;
$this->pnParam = $pnParam;
$this->pnPrid = $pnPrid;
}
public function sendToken(string $token)
{
$payload = json_encode(['token' => $token]);
$command = $this->pusherPath
. " --pn-provider " . $this->pnProvider
. " --pn-param " . $this->pnParam
. " --pn-prid " . $this->pnPrid
. " --apple-push-type Background --customPayload " . $payload;
$output = null;
$retval = null;
return exec($command, $output, $retval);
}
}

11
flexiapi/app/Token.php Normal file
View file

@ -0,0 +1,11 @@
<?php
namespace App;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Token extends Model
{
use HasFactory;
}

122
flexiapi/composer.lock generated
View file

@ -970,16 +970,16 @@
},
{
"name": "laravel/framework",
"version": "v8.27.0",
"version": "v8.29.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/framework.git",
"reference": "a6680d98f9dadaa363aa7d5218517a08706cee64"
"reference": "d2eba352b3b3a3c515b18c5726b373fe5026733e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/framework/zipball/a6680d98f9dadaa363aa7d5218517a08706cee64",
"reference": "a6680d98f9dadaa363aa7d5218517a08706cee64",
"url": "https://api.github.com/repos/laravel/framework/zipball/d2eba352b3b3a3c515b18c5726b373fe5026733e",
"reference": "d2eba352b3b3a3c515b18c5726b373fe5026733e",
"shasum": ""
},
"require": {
@ -1087,7 +1087,7 @@
"phpunit/phpunit": "Required to use assertions and run tests (^8.5.8|^9.3.3).",
"predis/predis": "Required to use the predis connector (^1.1.2).",
"psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).",
"pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^4.0).",
"pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^4.0|^5.0).",
"symfony/cache": "Required to PSR-6 cache bridge (^5.1.4).",
"symfony/filesystem": "Required to enable support for relative symbolic links (^5.1.4).",
"symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^2.0).",
@ -1134,7 +1134,7 @@
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
},
"time": "2021-02-09T15:14:54+00:00"
"time": "2021-02-23T14:27:41+00:00"
},
{
"name": "laravel/tinker",
@ -3623,7 +3623,7 @@
},
{
"name": "symfony/polyfill-ctype",
"version": "v1.22.0",
"version": "v1.22.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
@ -3682,7 +3682,7 @@
"portable"
],
"support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.0"
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.1"
},
"funding": [
{
@ -3702,16 +3702,16 @@
},
{
"name": "symfony/polyfill-iconv",
"version": "v1.22.0",
"version": "v1.22.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-iconv.git",
"reference": "b34bfb8c4c22650ac080d2662ae3502e5f2f4ae6"
"reference": "06fb361659649bcfd6a208a0f1fcaf4e827ad342"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/b34bfb8c4c22650ac080d2662ae3502e5f2f4ae6",
"reference": "b34bfb8c4c22650ac080d2662ae3502e5f2f4ae6",
"url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/06fb361659649bcfd6a208a0f1fcaf4e827ad342",
"reference": "06fb361659649bcfd6a208a0f1fcaf4e827ad342",
"shasum": ""
},
"require": {
@ -3762,7 +3762,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-iconv/tree/v1.22.0"
"source": "https://github.com/symfony/polyfill-iconv/tree/v1.22.1"
},
"funding": [
{
@ -3778,20 +3778,20 @@
"type": "tidelift"
}
],
"time": "2021-01-07T16:49:33+00:00"
"time": "2021-01-22T09:19:47+00:00"
},
{
"name": "symfony/polyfill-intl-grapheme",
"version": "v1.22.0",
"version": "v1.22.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-grapheme.git",
"reference": "267a9adeb8ecb8071040a740930e077cdfb987af"
"reference": "5601e09b69f26c1828b13b6bb87cb07cddba3170"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/267a9adeb8ecb8071040a740930e077cdfb987af",
"reference": "267a9adeb8ecb8071040a740930e077cdfb987af",
"url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/5601e09b69f26c1828b13b6bb87cb07cddba3170",
"reference": "5601e09b69f26c1828b13b6bb87cb07cddba3170",
"shasum": ""
},
"require": {
@ -3843,7 +3843,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.22.0"
"source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.22.1"
},
"funding": [
{
@ -3859,20 +3859,20 @@
"type": "tidelift"
}
],
"time": "2021-01-07T16:49:33+00:00"
"time": "2021-01-22T09:19:47+00:00"
},
{
"name": "symfony/polyfill-intl-idn",
"version": "v1.22.0",
"version": "v1.22.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-idn.git",
"reference": "0eb8293dbbcd6ef6bf81404c9ce7d95bcdf34f44"
"reference": "2d63434d922daf7da8dd863e7907e67ee3031483"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/0eb8293dbbcd6ef6bf81404c9ce7d95bcdf34f44",
"reference": "0eb8293dbbcd6ef6bf81404c9ce7d95bcdf34f44",
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/2d63434d922daf7da8dd863e7907e67ee3031483",
"reference": "2d63434d922daf7da8dd863e7907e67ee3031483",
"shasum": ""
},
"require": {
@ -3930,7 +3930,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.22.0"
"source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.22.1"
},
"funding": [
{
@ -3946,20 +3946,20 @@
"type": "tidelift"
}
],
"time": "2021-01-07T16:49:33+00:00"
"time": "2021-01-22T09:19:47+00:00"
},
{
"name": "symfony/polyfill-intl-normalizer",
"version": "v1.22.0",
"version": "v1.22.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
"reference": "6e971c891537eb617a00bb07a43d182a6915faba"
"reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/6e971c891537eb617a00bb07a43d182a6915faba",
"reference": "6e971c891537eb617a00bb07a43d182a6915faba",
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/43a0283138253ed1d48d352ab6d0bdb3f809f248",
"reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248",
"shasum": ""
},
"require": {
@ -4014,7 +4014,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.22.0"
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.22.1"
},
"funding": [
{
@ -4030,20 +4030,20 @@
"type": "tidelift"
}
],
"time": "2021-01-07T17:09:11+00:00"
"time": "2021-01-22T09:19:47+00:00"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.22.0",
"version": "v1.22.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "f377a3dd1fde44d37b9831d68dc8dea3ffd28e13"
"reference": "5232de97ee3b75b0360528dae24e73db49566ab1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/f377a3dd1fde44d37b9831d68dc8dea3ffd28e13",
"reference": "f377a3dd1fde44d37b9831d68dc8dea3ffd28e13",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/5232de97ee3b75b0360528dae24e73db49566ab1",
"reference": "5232de97ee3b75b0360528dae24e73db49566ab1",
"shasum": ""
},
"require": {
@ -4094,7 +4094,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.22.0"
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.22.1"
},
"funding": [
{
@ -4110,11 +4110,11 @@
"type": "tidelift"
}
],
"time": "2021-01-07T16:49:33+00:00"
"time": "2021-01-22T09:19:47+00:00"
},
{
"name": "symfony/polyfill-php72",
"version": "v1.22.0",
"version": "v1.22.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php72.git",
@ -4170,7 +4170,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php72/tree/v1.22.0"
"source": "https://github.com/symfony/polyfill-php72/tree/v1.22.1"
},
"funding": [
{
@ -4190,7 +4190,7 @@
},
{
"name": "symfony/polyfill-php73",
"version": "v1.22.0",
"version": "v1.22.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php73.git",
@ -4249,7 +4249,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php73/tree/v1.22.0"
"source": "https://github.com/symfony/polyfill-php73/tree/v1.22.1"
},
"funding": [
{
@ -4269,7 +4269,7 @@
},
{
"name": "symfony/polyfill-php80",
"version": "v1.22.0",
"version": "v1.22.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php80.git",
@ -4332,7 +4332,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php80/tree/v1.22.0"
"source": "https://github.com/symfony/polyfill-php80/tree/v1.22.1"
},
"funding": [
{
@ -5256,16 +5256,16 @@
},
{
"name": "facade/flare-client-php",
"version": "1.3.7",
"version": "1.4.0",
"source": {
"type": "git",
"url": "https://github.com/facade/flare-client-php.git",
"reference": "fd688d3c06658f2b3b5f7bb19f051ee4ddf02492"
"reference": "ef0f5bce23b30b32d98fd9bb49c6fa37b40eb546"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/facade/flare-client-php/zipball/fd688d3c06658f2b3b5f7bb19f051ee4ddf02492",
"reference": "fd688d3c06658f2b3b5f7bb19f051ee4ddf02492",
"url": "https://api.github.com/repos/facade/flare-client-php/zipball/ef0f5bce23b30b32d98fd9bb49c6fa37b40eb546",
"reference": "ef0f5bce23b30b32d98fd9bb49c6fa37b40eb546",
"shasum": ""
},
"require": {
@ -5309,7 +5309,7 @@
],
"support": {
"issues": "https://github.com/facade/flare-client-php/issues",
"source": "https://github.com/facade/flare-client-php/tree/1.3.7"
"source": "https://github.com/facade/flare-client-php/tree/1.4.0"
},
"funding": [
{
@ -5317,20 +5317,20 @@
"type": "github"
}
],
"time": "2020-10-21T16:02:39+00:00"
"time": "2021-02-16T12:42:06+00:00"
},
{
"name": "facade/ignition",
"version": "2.5.12",
"version": "2.5.13",
"source": {
"type": "git",
"url": "https://github.com/facade/ignition.git",
"reference": "be73521836f978106b3c3cf57de7eaeb261af520"
"reference": "5e9ef386aaad9985cee2ac23281a27568d083b7e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/facade/ignition/zipball/be73521836f978106b3c3cf57de7eaeb261af520",
"reference": "be73521836f978106b3c3cf57de7eaeb261af520",
"url": "https://api.github.com/repos/facade/ignition/zipball/5e9ef386aaad9985cee2ac23281a27568d083b7e",
"reference": "5e9ef386aaad9985cee2ac23281a27568d083b7e",
"shasum": ""
},
"require": {
@ -5394,7 +5394,7 @@
"issues": "https://github.com/facade/ignition/issues",
"source": "https://github.com/facade/ignition"
},
"time": "2021-02-15T07:55:43+00:00"
"time": "2021-02-16T12:46:19+00:00"
},
{
"name": "facade/ignition-contracts",
@ -5906,16 +5906,16 @@
},
{
"name": "phar-io/version",
"version": "3.0.4",
"version": "3.1.0",
"source": {
"type": "git",
"url": "https://github.com/phar-io/version.git",
"reference": "e4782611070e50613683d2b9a57730e9a3ba5451"
"reference": "bae7c545bef187884426f042434e561ab1ddb182"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phar-io/version/zipball/e4782611070e50613683d2b9a57730e9a3ba5451",
"reference": "e4782611070e50613683d2b9a57730e9a3ba5451",
"url": "https://api.github.com/repos/phar-io/version/zipball/bae7c545bef187884426f042434e561ab1ddb182",
"reference": "bae7c545bef187884426f042434e561ab1ddb182",
"shasum": ""
},
"require": {
@ -5951,9 +5951,9 @@
"description": "Library for handling version information and constraints",
"support": {
"issues": "https://github.com/phar-io/version/issues",
"source": "https://github.com/phar-io/version/tree/3.0.4"
"source": "https://github.com/phar-io/version/tree/3.1.0"
},
"time": "2020-12-13T23:18:30+00:00"
"time": "2021-02-23T14:00:09+00:00"
},
{
"name": "phpdocumentor/reflection-common",

View file

@ -16,6 +16,7 @@ return [
'name' => env('APP_NAME', 'Laravel'),
'sip_domain' => env('APP_SIP_DOMAIN', 'sip.domain.com'),
'flexisip_proxy_pid' => env('APP_FLEXISIP_PROXY_PID', '/var/run/flexisip-proxy.pid'),
'flexisip_pusher_path' => env('APP_FLEXISIP_PUSHER_PATH', ''),
'terms_of_use_url' => env('TERMS_OF_USE_URL', ''),
'privacy_policy_url' => env('PRIVACY_POLICY_URL', ''),

View file

@ -0,0 +1,42 @@
<?php
/*
Flexisip Account Manager is a set of tools to manage SIP accounts.
Copyright (C) 2021 Belledonne Communications SARL, All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
use App\Token;
use App\Http\Controllers\Account\AuthenticateController as WebAuthenticateController;
class TokenFactory extends Factory
{
protected $model = Token::class;
public function definition()
{
return [
'pn_provider' => $this->faker->uuid,
'pn_param' => $this->faker->uuid,
'pn_prid' => $this->faker->uuid,
'token' => Str::random(WebAuthenticateController::$emailCodeSize),
'used' => false
];
}
}

View file

@ -0,0 +1,29 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateTokensTable extends Migration
{
public function up()
{
Schema::connection('local')->create('tokens', function (Blueprint $table) {
$table->id();
$table->string('token');
$table->string('pn_provider');
$table->string('pn_param');
$table->string('pn_prid');
$table->boolean('used')->default(false);
$table->timestamps();
$table->index('token');
$table->index(['pn_provider', 'pn_param', 'pn_prid']);
});
}
public function down()
{
Schema::connection('local')->dropIfExists('tokens');
}
}

View file

@ -55,6 +55,31 @@ For the moment only DIGEST-MD5 and DIGEST-SHA-256 are supported through the auth
<h4>Accounts</h4>
<h4><code>POST /tokens</code></h4>
<p>Send a token using a push notification to the device.</p>
<p>Return <code>403</code> if a token was already sent, or if the tokens limit is reached for this device.</p>
<p>Return <code>503</code> if the token was not successfully sent.</p>
<p>JSON parameters:</p>
<ul>
<li><code>pn_provider</code> the push notification provider</li>
<li><code>pn_param</code> the push notification parameter</li>
<li><code>pn_prid</code> the push notification unique id</li>
</ul>
<h4><code>POST /accounts/with-token</code></h4>
<p>Create an account using a token.</p>
<p>Return <code>422</code> if the parapeters are invalid or if the token is expired.</p>
<p>JSON parameters:</p>
<ul>
<li><code>username</code> unique username, minimum 6 characters</li>
<li><code>password</code> required minimum 6 characters</li>
<li><code>algorithm</code> required, values can be <code>SHA-256</code> or <code>MD5</code></li>
<li><code>domain</code> optional, the value is set to the default registration domain if not set</li>
<li><code>token</code> the unique token</li>
</ul>
<h4><code>GET /accounts/{sip}/info</code></h4>
<p>Retrieve public information about the account.</p>
<p>Return <code>404</code> if the account doesn't exists.</p>

View file

@ -26,7 +26,9 @@ Route::middleware('auth:api')->get('/user', function (Request $request) {
});
Route::get('ping', 'Api\PingController@ping');
Route::post('tokens', 'Api\TokenController@create');
Route::get('accounts/{sip}/info', 'Api\AccountController@info');
Route::post('accounts/with-token', 'Api\AccountController@store');
Route::post('accounts/{sip}/activate/email', 'Api\AccountController@activateEmail');
Route::post('accounts/{sip}/activate/phone', 'Api\AccountController@activatePhone');

View file

@ -0,0 +1,98 @@
<?php
/*
Flexisip Account Manager is a set of tools to manage SIP accounts.
Copyright (C) 2020 Belledonne Communications SARL, All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Tests\Feature;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
use App\Token;
class AccountTokenTest extends TestCase
{
use RefreshDatabase;
protected $tokenRoute = '/api/tokens';
protected $accountRoute = '/api/accounts/with-token';
protected $method = 'POST';
protected $pnProvider = 'provider';
protected $pnParam = 'param';
protected $pnPrid = 'id';
public function testMandatoryParameters()
{
$response = $this->json($this->method, $this->tokenRoute);
$response->assertStatus(422);
}
public function testCorrectParameters()
{
$response = $this->json($this->method, $this->tokenRoute, [
'pn_provider' => $this->pnProvider,
'pn_param' => $this->pnParam,
'pn_prid' => $this->pnPrid,
]);
$response->assertStatus(503);
}
public function testLimit()
{
$token = Token::factory()->create();
$response = $this->json($this->method, $this->tokenRoute, [
'pn_provider' => $token->pn_provider,
'pn_param' => $token->pn_param,
'pn_prid' => $token->pn_prid,
]);
$response->assertStatus(403);
}
public function testInvalidToken()
{
$token = Token::factory()->create();
// Invalid token
$response = $this->json($this->method, $this->accountRoute, [
'username' => 'username',
'algorithm' => 'SHA-256',
'password' => '2',
'token' => '0123456789abc'
]);
$response->assertStatus(422);
// Valid token
$response = $this->json($this->method, $this->accountRoute, [
'username' => 'username',
'algorithm' => 'SHA-256',
'password' => '2',
'token' => $token->token
]);
$response->assertStatus(200);
// Expired token
$response = $this->json($this->method, $this->accountRoute, [
'username' => 'username2',
'algorithm' => 'SHA-256',
'password' => '2',
'token' => $token->token
]);
$response->assertStatus(422);
}
}

View file

@ -8,7 +8,7 @@
#%define _datadir %{_datarootdir}
#%define _docdir %{_datadir}/doc
%define build_number 51
%define build_number 52
%define var_dir /var/opt/belledonne-communications
%define opt_dir /opt/belledonne-communications/share/flexisip-account-manager
%define env_file "$RPM_BUILD_ROOT/etc/flexisip-account-manager/flexiapi.env"