mirror of
https://gitlab.linphone.org/BC/public/flexisip-account-manager.git
synced 2026-01-17 10:08:05 +00:00
Add a send message endpoint, passing by the linphone-daemon unix pipe
Import ReactPHP Socket and required dependencies Add a new configuration variable to define the unix pipe path Generalize the API Key to all the users, add a new endpoint to retrieve it, update the documentation Update the dependencies Update the documentation Complete the tests
This commit is contained in:
parent
a1780254d7
commit
20f8fb4c45
30 changed files with 954 additions and 53 deletions
|
|
@ -1,6 +1,7 @@
|
|||
#!/bin/sh
|
||||
|
||||
cd /opt/belledonne-communications/share/flexisip-account-manager/flexiapi/
|
||||
sudo -su www-data && php artisan digest:expired-nonces-clear 60
|
||||
sudo -su www-data && php artisan digest:clear-nonces 60
|
||||
sudo -su www-data && php artisan accounts:clear-api-keys 60
|
||||
sudo -su www-data && php artisan accounts:clear-accounts-tombstones 7 --apply
|
||||
sudo -su www-data && php artisan accounts:clear-unconfirmed 30 --apply
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
#!/bin/sh
|
||||
|
||||
cd /opt/belledonne-communications/share/flexisip-account-manager/flexiapi/
|
||||
scl enable rh-php73 "php artisan digest:expired-nonces-clear 60"
|
||||
scl enable rh-php73 "php artisan digest:clear-nonces 60"
|
||||
scl enable rh-php73 "php artisan accounts:clear-api-keys 60"
|
||||
scl enable rh-php73 "php artisan accounts:clear-accounts-tombstones 7 --apply"
|
||||
scl enable rh-php73 "php artisan accounts:clear-unconfirmed 30 --apply"
|
||||
|
|
@ -4,9 +4,13 @@ APP_KEY=
|
|||
APP_DEBUG=false
|
||||
APP_URL=http://localhost
|
||||
APP_SIP_DOMAIN=sip.example.com
|
||||
|
||||
APP_FLEXISIP_PROXY_PID=/var/run/flexisip-proxy.pid
|
||||
APP_LINPHONE_DAEMON_UNIX_PATH=
|
||||
APP_FLEXISIP_PUSHER_PATH=
|
||||
|
||||
APP_API_KEY_EXPIRATION_MINUTES=60 # Number of minutes the generated API Keys are valid
|
||||
|
||||
# Risky toggles
|
||||
APP_EVERYONE_IS_ADMIN=false # Allow any accounts to request the API as an administrator
|
||||
APP_ADMINS_MANAGE_MULTI_DOMAINS=false # Allow admins to handle all the accounts in the database
|
||||
|
|
|
|||
|
|
@ -143,11 +143,17 @@ Several other parameters are also available to customize the migration process,
|
|||
|
||||
php artisan -h db:import
|
||||
|
||||
### Clear the expired API Keys
|
||||
|
||||
This will remove the API Keys that were not used after `x minutes`.
|
||||
|
||||
php artisan digest:clear-api-keys {minutes}
|
||||
|
||||
### Clear Expired Nonces for DIGEST authentication
|
||||
|
||||
This will remove the nonces stored that were not updated after `x minutes`.
|
||||
|
||||
php artisan digest:expired-nonces-clear {minutes}
|
||||
php artisan digest:clear-nonces {minutes}
|
||||
|
||||
### Remove the unconfirmed accounts
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ use App\Password;
|
|||
use App\EmailChanged;
|
||||
use App\Helpers\Utils;
|
||||
use App\Mail\ChangingEmail;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class Account extends Authenticatable
|
||||
{
|
||||
|
|
@ -223,6 +224,7 @@ class Account extends Authenticatable
|
|||
|
||||
$apiKey = new ApiKey;
|
||||
$apiKey->account_id = $this->id;
|
||||
$apiKey->last_used_at = Carbon::now();
|
||||
$apiKey->key = Str::random(40);
|
||||
$apiKey->save();
|
||||
}
|
||||
|
|
|
|||
49
flexiapi/app/Console/Commands/ClearApiKeys.php
Normal file
49
flexiapi/app/Console/Commands/ClearApiKeys.php
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
<?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\Console\Commands;
|
||||
|
||||
use App\ApiKey;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
use Carbon\Carbon;
|
||||
|
||||
class ClearApiKeys extends Command
|
||||
{
|
||||
protected $signature = 'accounts:clear-api-keys {minutes?}';
|
||||
protected $description = 'Clear the expired API Keys after n minutes';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$minutes = $this->argument('minutes') ?? config('app.api_key_expiration_minutes');
|
||||
|
||||
$this->info('Deleting api keys unused after ' . $minutes . ' minutes');
|
||||
|
||||
$count = ApiKey::where('last_used_at', '<',
|
||||
Carbon::now()->subMinutes($minutes)->toDateTimeString()
|
||||
)->delete();
|
||||
|
||||
$this->info($count . ' api keys deleted');
|
||||
}
|
||||
}
|
||||
|
|
@ -24,10 +24,10 @@ use Illuminate\Console\Command;
|
|||
use Carbon\Carbon;
|
||||
use App\DigestNonce;
|
||||
|
||||
class ClearExpiredNonces extends Command
|
||||
class ClearNonces extends Command
|
||||
{
|
||||
protected $signature = 'digest:expired-nonces-clear {minutes}';
|
||||
protected $description = 'Clear the expired DIGEST nonces';
|
||||
protected $signature = 'digest:clear-nonces {minutes}';
|
||||
protected $description = 'Clear the expired DIGEST nonces after n minutes';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
|
@ -54,6 +54,14 @@ class AccountController extends Controller
|
|||
]);
|
||||
}
|
||||
|
||||
public function generateApiKey(Request $request)
|
||||
{
|
||||
$account = $request->user();
|
||||
$account->generateApiKey();
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
public function delete(Request $request)
|
||||
{
|
||||
return view('account.delete', [
|
||||
|
|
|
|||
|
|
@ -197,14 +197,6 @@ class AccountController extends Controller
|
|||
return redirect()->route('admin.account.index');
|
||||
}
|
||||
|
||||
public function generateApiKey(Request $request)
|
||||
{
|
||||
$account = $request->user();
|
||||
$account->generateApiKey();
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
private function fillPassword(Request $request, Account $account)
|
||||
{
|
||||
if ($request->filled('password')) {
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ use Illuminate\Http\Request;
|
|||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Cookie;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Carbon\Carbon;
|
||||
|
||||
|
|
@ -165,4 +166,15 @@ class AccountController extends Controller
|
|||
return Account::where('id', $request->user()->id)
|
||||
->delete();
|
||||
}
|
||||
|
||||
public function generateApiKey(Request $request)
|
||||
{
|
||||
$account = $request->user();
|
||||
$account->generateApiKey();
|
||||
|
||||
$account->refresh();
|
||||
Cookie::queue('x-api-key', $account->apiKey->key, config('app.api_key_expiration_minutes'));
|
||||
|
||||
return $account->apiKey->key;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
50
flexiapi/app/Http/Controllers/Api/MessageController.php
Normal file
50
flexiapi/app/Http/Controllers/Api/MessageController.php
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class MessageController extends Controller
|
||||
{
|
||||
public function send(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'to' => 'required',
|
||||
'body' => 'required'
|
||||
]);
|
||||
|
||||
$returnedLines = [];
|
||||
|
||||
$loop = \React\EventLoop\Loop::get();
|
||||
$connector = new \React\Socket\UnixConnector($loop);
|
||||
|
||||
$connector->connect('unix://'.config('app.linphone_daemon_unix_pipe'))
|
||||
->then(function (\React\Socket\Connection $connection) use ($request, &$returnedLines) {
|
||||
|
||||
$connection->on('data', function ($message) use ($connection, &$returnedLines) {
|
||||
foreach (preg_split("/\r\n|\n|\r/", $message) as $line) {
|
||||
if(!empty($line) && false !== ($matches = explode(':', $line, 2))) {
|
||||
$returnedLines["{$matches[0]}"] = trim($matches[1]);
|
||||
}
|
||||
}
|
||||
|
||||
$connection->close();
|
||||
});
|
||||
|
||||
$connection->write("message sip:".$request->get('to')." ".$request->get('body')."\n");
|
||||
});
|
||||
|
||||
$loop->run();
|
||||
|
||||
if ($returnedLines['Status'] == 'Error') {
|
||||
throw ValidationException::withMessages([$returnedLines['Reason']]);
|
||||
}
|
||||
|
||||
if ($returnedLines['Status'] == 'Ok') {
|
||||
return response()->json(['id' => $returnedLines['Id']]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -55,7 +55,7 @@ class Kernel extends HttpKernel
|
|||
],
|
||||
|
||||
'api' => [
|
||||
'throttle:600,1', // move to 600 instead of 60
|
||||
'throttle:600,1', // move to 600 instead of 60
|
||||
'bindings',
|
||||
],
|
||||
];
|
||||
|
|
@ -75,6 +75,8 @@ class Kernel extends HttpKernel
|
|||
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
|
||||
'can' => \Illuminate\Auth\Middleware\Authorize::class,
|
||||
'cookie' => \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
|
||||
'cookie.encrypt' => \App\Http\Middleware\EncryptCookies::class,
|
||||
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
|
||||
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
|
||||
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ namespace App\Http\Middleware;
|
|||
|
||||
use App\Account;
|
||||
use App\Helpers\Utils;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Http\Response;
|
||||
|
|
@ -64,9 +64,16 @@ class AuthenticateDigestOrKey
|
|||
}
|
||||
|
||||
// Key authentication
|
||||
if ($request->header('x-api-key')) {
|
||||
|
||||
if ($request->header('x-api-key') || $request->cookie('x-api-key')) {
|
||||
if ($account->apiKey
|
||||
&& $account->apiKey->key == $request->header('x-api-key')) {
|
||||
&& ($account->apiKey->key == $request->header('x-api-key')
|
||||
|| $account->apiKey->key == $request->cookie('x-api-key')
|
||||
)) {
|
||||
// Refresh the API Key
|
||||
$account->apiKey->last_used_at = Carbon::now();
|
||||
$account->apiKey->save();
|
||||
|
||||
Auth::login($account);
|
||||
$response = $next($request);
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@
|
|||
"laravel/tinker": "^2.4",
|
||||
"laravelcollective/html": "^6.2",
|
||||
"ovh/ovh": "^2.0",
|
||||
"parsedown/laravel": "^1.2"
|
||||
"parsedown/laravel": "^1.2",
|
||||
"react/socket": "^1.10"
|
||||
},
|
||||
"require-dev": {
|
||||
"barryvdh/laravel-debugbar": "^3.6",
|
||||
|
|
@ -33,7 +34,10 @@
|
|||
},
|
||||
"optimize-autoloader": true,
|
||||
"preferred-install": "dist",
|
||||
"sort-packages": true
|
||||
"sort-packages": true,
|
||||
"allow-plugins": {
|
||||
"composer/package-versions-deprecated": true
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"laravel": {
|
||||
|
|
|
|||
582
flexiapi/composer.lock
generated
582
flexiapi/composer.lock
generated
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "e89db40702fce75cb782f0c1a761aee4",
|
||||
"content-hash": "9112b0a4903727d599efd72b01596cc4",
|
||||
"packages": [
|
||||
{
|
||||
"name": "anhskohbo/no-captcha",
|
||||
|
|
@ -996,6 +996,53 @@
|
|||
},
|
||||
"time": "2019-12-30T22:54:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "evenement/evenement",
|
||||
"version": "v3.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/igorw/evenement.git",
|
||||
"reference": "531bfb9d15f8aa57454f5f0285b18bec903b8fb7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/igorw/evenement/zipball/531bfb9d15f8aa57454f5f0285b18bec903b8fb7",
|
||||
"reference": "531bfb9d15f8aa57454f5f0285b18bec903b8fb7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^6.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Evenement": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Igor Wiedler",
|
||||
"email": "igor@wiedler.ch"
|
||||
}
|
||||
],
|
||||
"description": "Événement is a very simple event dispatching library for PHP",
|
||||
"keywords": [
|
||||
"event-dispatcher",
|
||||
"event-emitter"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/igorw/evenement/issues",
|
||||
"source": "https://github.com/igorw/evenement/tree/master"
|
||||
},
|
||||
"time": "2017-07-23T21:35:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "fideloper/proxy",
|
||||
"version": "4.4.1",
|
||||
|
|
@ -3081,6 +3128,539 @@
|
|||
],
|
||||
"time": "2021-09-25T23:10:38+00:00"
|
||||
},
|
||||
{
|
||||
"name": "react/cache",
|
||||
"version": "v1.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/reactphp/cache.git",
|
||||
"reference": "4bf736a2cccec7298bdf745db77585966fc2ca7e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/reactphp/cache/zipball/4bf736a2cccec7298bdf745db77585966fc2ca7e",
|
||||
"reference": "4bf736a2cccec7298bdf745db77585966fc2ca7e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0",
|
||||
"react/promise": "^3.0 || ^2.0 || ^1.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"React\\Cache\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Christian Lück",
|
||||
"email": "christian@clue.engineering",
|
||||
"homepage": "https://clue.engineering/"
|
||||
},
|
||||
{
|
||||
"name": "Cees-Jan Kiewiet",
|
||||
"email": "reactphp@ceesjankiewiet.nl",
|
||||
"homepage": "https://wyrihaximus.net/"
|
||||
},
|
||||
{
|
||||
"name": "Jan Sorgalla",
|
||||
"email": "jsorgalla@gmail.com",
|
||||
"homepage": "https://sorgalla.com/"
|
||||
},
|
||||
{
|
||||
"name": "Chris Boden",
|
||||
"email": "cboden@gmail.com",
|
||||
"homepage": "https://cboden.dev/"
|
||||
}
|
||||
],
|
||||
"description": "Async, Promise-based cache interface for ReactPHP",
|
||||
"keywords": [
|
||||
"cache",
|
||||
"caching",
|
||||
"promise",
|
||||
"reactphp"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/reactphp/cache/issues",
|
||||
"source": "https://github.com/reactphp/cache/tree/v1.1.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/WyriHaximus",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/clue",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-02-02T06:47:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "react/dns",
|
||||
"version": "v1.9.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/reactphp/dns.git",
|
||||
"reference": "6d38296756fa644e6cb1bfe95eff0f9a4ed6edcb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/reactphp/dns/zipball/6d38296756fa644e6cb1bfe95eff0f9a4ed6edcb",
|
||||
"reference": "6d38296756fa644e6cb1bfe95eff0f9a4ed6edcb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0",
|
||||
"react/cache": "^1.0 || ^0.6 || ^0.5",
|
||||
"react/event-loop": "^1.2",
|
||||
"react/promise": "^3.0 || ^2.7 || ^1.2.1",
|
||||
"react/promise-timer": "^1.8"
|
||||
},
|
||||
"require-dev": {
|
||||
"clue/block-react": "^1.2",
|
||||
"phpunit/phpunit": "^9.3 || ^4.8.35"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"React\\Dns\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Christian Lück",
|
||||
"email": "christian@clue.engineering",
|
||||
"homepage": "https://clue.engineering/"
|
||||
},
|
||||
{
|
||||
"name": "Cees-Jan Kiewiet",
|
||||
"email": "reactphp@ceesjankiewiet.nl",
|
||||
"homepage": "https://wyrihaximus.net/"
|
||||
},
|
||||
{
|
||||
"name": "Jan Sorgalla",
|
||||
"email": "jsorgalla@gmail.com",
|
||||
"homepage": "https://sorgalla.com/"
|
||||
},
|
||||
{
|
||||
"name": "Chris Boden",
|
||||
"email": "cboden@gmail.com",
|
||||
"homepage": "https://cboden.dev/"
|
||||
}
|
||||
],
|
||||
"description": "Async DNS resolver for ReactPHP",
|
||||
"keywords": [
|
||||
"async",
|
||||
"dns",
|
||||
"dns-resolver",
|
||||
"reactphp"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/reactphp/dns/issues",
|
||||
"source": "https://github.com/reactphp/dns/tree/v1.9.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/WyriHaximus",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/clue",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-12-20T08:46:54+00:00"
|
||||
},
|
||||
{
|
||||
"name": "react/event-loop",
|
||||
"version": "v1.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/reactphp/event-loop.git",
|
||||
"reference": "be6dee480fc4692cec0504e65eb486e3be1aa6f2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/reactphp/event-loop/zipball/be6dee480fc4692cec0504e65eb486e3be1aa6f2",
|
||||
"reference": "be6dee480fc4692cec0504e65eb486e3be1aa6f2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-event": "~1.0 for ExtEventLoop",
|
||||
"ext-pcntl": "For signal handling support when using the StreamSelectLoop",
|
||||
"ext-uv": "* for ExtUvLoop"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"React\\EventLoop\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Christian Lück",
|
||||
"email": "christian@clue.engineering",
|
||||
"homepage": "https://clue.engineering/"
|
||||
},
|
||||
{
|
||||
"name": "Cees-Jan Kiewiet",
|
||||
"email": "reactphp@ceesjankiewiet.nl",
|
||||
"homepage": "https://wyrihaximus.net/"
|
||||
},
|
||||
{
|
||||
"name": "Jan Sorgalla",
|
||||
"email": "jsorgalla@gmail.com",
|
||||
"homepage": "https://sorgalla.com/"
|
||||
},
|
||||
{
|
||||
"name": "Chris Boden",
|
||||
"email": "cboden@gmail.com",
|
||||
"homepage": "https://cboden.dev/"
|
||||
}
|
||||
],
|
||||
"description": "ReactPHP's core reactor event loop that libraries can use for evented I/O.",
|
||||
"keywords": [
|
||||
"asynchronous",
|
||||
"event-loop"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/reactphp/event-loop/issues",
|
||||
"source": "https://github.com/reactphp/event-loop/tree/v1.2.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/WyriHaximus",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/clue",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-07-11T12:31:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "react/promise",
|
||||
"version": "v2.8.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/reactphp/promise.git",
|
||||
"reference": "f3cff96a19736714524ca0dd1d4130de73dbbbc4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/reactphp/promise/zipball/f3cff96a19736714524ca0dd1d4130de73dbbbc4",
|
||||
"reference": "f3cff96a19736714524ca0dd1d4130de73dbbbc4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^7.0 || ^6.5 || ^5.7 || ^4.8.36"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"React\\Promise\\": "src/"
|
||||
},
|
||||
"files": [
|
||||
"src/functions_include.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jan Sorgalla",
|
||||
"email": "jsorgalla@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "A lightweight implementation of CommonJS Promises/A for PHP",
|
||||
"keywords": [
|
||||
"promise",
|
||||
"promises"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/reactphp/promise/issues",
|
||||
"source": "https://github.com/reactphp/promise/tree/v2.8.0"
|
||||
},
|
||||
"time": "2020-05-12T15:16:56+00:00"
|
||||
},
|
||||
{
|
||||
"name": "react/promise-timer",
|
||||
"version": "v1.8.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/reactphp/promise-timer.git",
|
||||
"reference": "0bbbcc79589e5bfdddba68a287f1cb805581a479"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/reactphp/promise-timer/zipball/0bbbcc79589e5bfdddba68a287f1cb805581a479",
|
||||
"reference": "0bbbcc79589e5bfdddba68a287f1cb805581a479",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3",
|
||||
"react/event-loop": "^1.2",
|
||||
"react/promise": "^3.0 || ^2.7.0 || ^1.2.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"React\\Promise\\Timer\\": "src/"
|
||||
},
|
||||
"files": [
|
||||
"src/functions_include.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Christian Lück",
|
||||
"email": "christian@clue.engineering",
|
||||
"homepage": "https://clue.engineering/"
|
||||
},
|
||||
{
|
||||
"name": "Cees-Jan Kiewiet",
|
||||
"email": "reactphp@ceesjankiewiet.nl",
|
||||
"homepage": "https://wyrihaximus.net/"
|
||||
},
|
||||
{
|
||||
"name": "Jan Sorgalla",
|
||||
"email": "jsorgalla@gmail.com",
|
||||
"homepage": "https://sorgalla.com/"
|
||||
},
|
||||
{
|
||||
"name": "Chris Boden",
|
||||
"email": "cboden@gmail.com",
|
||||
"homepage": "https://cboden.dev/"
|
||||
}
|
||||
],
|
||||
"description": "A trivial implementation of timeouts for Promises, built on top of ReactPHP.",
|
||||
"homepage": "https://github.com/reactphp/promise-timer",
|
||||
"keywords": [
|
||||
"async",
|
||||
"event-loop",
|
||||
"promise",
|
||||
"reactphp",
|
||||
"timeout",
|
||||
"timer"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/reactphp/promise-timer/issues",
|
||||
"source": "https://github.com/reactphp/promise-timer/tree/v1.8.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/WyriHaximus",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/clue",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-12-06T11:08:48+00:00"
|
||||
},
|
||||
{
|
||||
"name": "react/socket",
|
||||
"version": "v1.10.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/reactphp/socket.git",
|
||||
"reference": "d132fde589ea97f4165f2d94b5296499eac125ec"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/reactphp/socket/zipball/d132fde589ea97f4165f2d94b5296499eac125ec",
|
||||
"reference": "d132fde589ea97f4165f2d94b5296499eac125ec",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"evenement/evenement": "^3.0 || ^2.0 || ^1.0",
|
||||
"php": ">=5.3.0",
|
||||
"react/dns": "^1.8",
|
||||
"react/event-loop": "^1.2",
|
||||
"react/promise": "^2.6.0 || ^1.2.1",
|
||||
"react/promise-timer": "^1.4.0",
|
||||
"react/stream": "^1.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"clue/block-react": "^1.2",
|
||||
"phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35",
|
||||
"react/promise-stream": "^1.2"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"React\\Socket\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Christian Lück",
|
||||
"email": "christian@clue.engineering",
|
||||
"homepage": "https://clue.engineering/"
|
||||
},
|
||||
{
|
||||
"name": "Cees-Jan Kiewiet",
|
||||
"email": "reactphp@ceesjankiewiet.nl",
|
||||
"homepage": "https://wyrihaximus.net/"
|
||||
},
|
||||
{
|
||||
"name": "Jan Sorgalla",
|
||||
"email": "jsorgalla@gmail.com",
|
||||
"homepage": "https://sorgalla.com/"
|
||||
},
|
||||
{
|
||||
"name": "Chris Boden",
|
||||
"email": "cboden@gmail.com",
|
||||
"homepage": "https://cboden.dev/"
|
||||
}
|
||||
],
|
||||
"description": "Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP",
|
||||
"keywords": [
|
||||
"Connection",
|
||||
"Socket",
|
||||
"async",
|
||||
"reactphp",
|
||||
"stream"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/reactphp/socket/issues",
|
||||
"source": "https://github.com/reactphp/socket/tree/v1.10.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/WyriHaximus",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/clue",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-11-29T10:08:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "react/stream",
|
||||
"version": "v1.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/reactphp/stream.git",
|
||||
"reference": "7a423506ee1903e89f1e08ec5f0ed430ff784ae9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/reactphp/stream/zipball/7a423506ee1903e89f1e08ec5f0ed430ff784ae9",
|
||||
"reference": "7a423506ee1903e89f1e08ec5f0ed430ff784ae9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"evenement/evenement": "^3.0 || ^2.0 || ^1.0",
|
||||
"php": ">=5.3.8",
|
||||
"react/event-loop": "^1.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"clue/stream-filter": "~1.2",
|
||||
"phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"React\\Stream\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Christian Lück",
|
||||
"email": "christian@clue.engineering",
|
||||
"homepage": "https://clue.engineering/"
|
||||
},
|
||||
{
|
||||
"name": "Cees-Jan Kiewiet",
|
||||
"email": "reactphp@ceesjankiewiet.nl",
|
||||
"homepage": "https://wyrihaximus.net/"
|
||||
},
|
||||
{
|
||||
"name": "Jan Sorgalla",
|
||||
"email": "jsorgalla@gmail.com",
|
||||
"homepage": "https://sorgalla.com/"
|
||||
},
|
||||
{
|
||||
"name": "Chris Boden",
|
||||
"email": "cboden@gmail.com",
|
||||
"homepage": "https://cboden.dev/"
|
||||
}
|
||||
],
|
||||
"description": "Event-driven readable and writable streams for non-blocking I/O in ReactPHP",
|
||||
"keywords": [
|
||||
"event-driven",
|
||||
"io",
|
||||
"non-blocking",
|
||||
"pipe",
|
||||
"reactphp",
|
||||
"readable",
|
||||
"stream",
|
||||
"writable"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/reactphp/stream/issues",
|
||||
"source": "https://github.com/reactphp/stream/tree/v1.2.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/WyriHaximus",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/clue",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-07-11T12:37:55+00:00"
|
||||
},
|
||||
{
|
||||
"name": "swiftmailer/swiftmailer",
|
||||
"version": "v6.3.0",
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -15,8 +15,6 @@ 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', ''),
|
||||
|
|
@ -30,6 +28,17 @@ return [
|
|||
'proxy_registrar_address' => env('ACCOUNT_PROXY_REGISTRAR_ADDRESS', 'sip.domain.com'),
|
||||
'transport_protocol_text' => env('ACCOUNT_TRANSPORT_PROTOCOL_TEXT', 'TLS (recommended), TCP or UDP'),
|
||||
|
||||
/**
|
||||
* Time limit before the API Key and related cookie are expired
|
||||
*/
|
||||
'api_key_expiration_minutes' => env('APP_API_KEY_EXPIRATION_MINUTES', 60),
|
||||
|
||||
/**
|
||||
* External interfaces
|
||||
*/
|
||||
'flexisip_proxy_pid' => env('APP_FLEXISIP_PROXY_PID', '/var/run/flexisip-proxy.pid'),
|
||||
'flexisip_pusher_path' => env('APP_FLEXISIP_PUSHER_PATH', ''),
|
||||
'linphone_daemon_unix_pipe' => env('APP_LINPHONE_DAEMON_UNIX_PATH', null),
|
||||
|
||||
/**
|
||||
* Account provisioning
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
use App\ApiKey;
|
||||
|
||||
class AddLastUsedAtColumnToApiKeysTable extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
ApiKey::truncate();
|
||||
|
||||
Schema::table('api_keys', function (Blueprint $table) {
|
||||
if (DB::getDriverName() == 'sqlite') {
|
||||
$table->dateTime('last_used_at')->default('');
|
||||
} else {
|
||||
$table->dateTime('last_used_at');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
Schema::table('api_keys', function (Blueprint $table) {
|
||||
$table->dropColumn('last_used_at');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -11,6 +11,8 @@
|
|||
</testsuite>
|
||||
<testsuite name="Feature">
|
||||
<directory suffix="Test.php">./tests/Feature</directory>
|
||||
<!-- Exclude the Message test suite as it relies on the linphone-daemon that can't be mocked for the moment -->
|
||||
<exclude>./tests/Feature/AccountMessageTest.php</exclude>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<php>
|
||||
|
|
|
|||
|
|
@ -67,25 +67,6 @@
|
|||
<p class="mb-1">Show some registration statistics</p>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<h5>API Key</h5>
|
||||
|
||||
<p>As an administrator you can generate an API key and use it to request the different API endpoints, <a href="{{ route('api') }}">check the related API documentation</a> to know how to use that key.</p>
|
||||
|
||||
{!! Form::open(['route' => 'admin.api_key.generate']) !!}
|
||||
<div class="form-row">
|
||||
<div class="col-8">
|
||||
<input readonly class="form-control" placeholder="No key yet, press Generate"
|
||||
@if ($account->apiKey)
|
||||
value="{{ $account->apiKey->key }}"
|
||||
@endif
|
||||
>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<button type="submit" class="btn btn-primary">Generate</button>
|
||||
</div>
|
||||
</div>
|
||||
{!! Form::close() !!}
|
||||
@endif
|
||||
|
||||
<h3 class="mt-3">Account information</h3>
|
||||
|
|
@ -103,6 +84,25 @@
|
|||
@endif
|
||||
</div>
|
||||
|
||||
<h3 class="mt-3">API Key</h3>
|
||||
|
||||
<p>You can generate an API key and use it to request the different API endpoints, <a href="{{ route('api') }}">check the related API documentation</a> to know how to use that key.</p>
|
||||
|
||||
{!! Form::open(['route' => 'account.api_key.generate']) !!}
|
||||
<div class="form-row">
|
||||
<div class="col-8">
|
||||
<input readonly class="form-control" placeholder="No key yet, press Generate"
|
||||
@if ($account->apiKey)
|
||||
value="{{ $account->apiKey->key }}"
|
||||
@endif
|
||||
>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<button type="submit" class="btn btn-primary">Generate</button>
|
||||
</div>
|
||||
</div>
|
||||
{!! Form::close() !!}
|
||||
|
||||
@include('parts.account_variables', ['account' => $account])
|
||||
|
||||
@endsection
|
||||
|
|
@ -19,8 +19,7 @@ Restricted endpoints are protected using a DIGEST authentication or an API Key m
|
|||
|
||||
## Using the API Key
|
||||
|
||||
To authenticate using an API Key, you need to @if (config('app.web_panel')) [authenticate to your account panel]({{ route('account.login') }}) @else authenticate to your account panel @endif and be an administrator.
|
||||
On your panel you will then find a form to generate your personnal key.
|
||||
You can retrieve an API Key from @if (config('app.web_panel')) [your account panel]({{ route('account.login') }}) @else your account panel @endif or using <a href="#get-accountsmeapikey">the dedicated API endpoint</a>.
|
||||
|
||||
You can then use your freshly generated key by adding a new `x-api-key` header to your API requests:
|
||||
|
||||
|
|
@ -31,6 +30,15 @@ You can then use your freshly generated key by adding a new `x-api-key` header t
|
|||
> …
|
||||
```
|
||||
|
||||
Or using a cookie:
|
||||
|
||||
```
|
||||
> GET /api/{endpoint}
|
||||
> from: sip:foobar@sip.example.org
|
||||
> Cookie: x-api-key={your-api-key}
|
||||
> …
|
||||
```
|
||||
|
||||
## Using DIGEST
|
||||
|
||||
To discover the available hashing algorythm you MUST send an unauthenticated request to one of the restricted endpoints.<br />
|
||||
|
|
@ -107,6 +115,10 @@ Those endpoints are authenticated and requires an activated account.
|
|||
|
||||
### Accounts
|
||||
|
||||
#### `GET /accounts/me/api_key`
|
||||
Generate and retrieve a fresh API Key.
|
||||
This endpoint is also setting the API Key as a Cookie.
|
||||
|
||||
#### `GET /accounts/me`
|
||||
Retrieve the account information.
|
||||
|
||||
|
|
@ -272,6 +284,16 @@ Add a type to the account.
|
|||
#### `DELETE /accounts/{id}/contacts/{type_id}`
|
||||
Remove a a type from the account.
|
||||
|
||||
### Messages
|
||||
|
||||
#### `POST /messages`
|
||||
Send a message over SIP.
|
||||
|
||||
JSON parameters:
|
||||
|
||||
* `to` required, SIP address of the receiver
|
||||
* `body` required, content of the message
|
||||
|
||||
### Statistics
|
||||
|
||||
#### `GET /statistics/day`
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ Route::group(['middleware' => ['auth.digest_or_key']], function () {
|
|||
Route::get('statistic/week', 'Api\StatisticController@week');
|
||||
Route::get('statistic/day', 'Api\StatisticController@day');
|
||||
|
||||
Route::get('accounts/me/api_key', 'Api\AccountController@generateApiKey')->middleware('cookie', 'cookie.encrypt');
|
||||
|
||||
Route::get('accounts/me', 'Api\AccountController@show');
|
||||
Route::delete('accounts/me', 'Api\AccountController@delete');
|
||||
|
||||
|
|
@ -53,6 +55,10 @@ Route::group(['middleware' => ['auth.digest_or_key']], function () {
|
|||
Route::get('accounts/me/contacts', 'Api\AccountContactController@index');
|
||||
|
||||
Route::group(['middleware' => ['auth.admin']], function () {
|
||||
if (!empty(config('app.linphone_daemon_unix_pipe'))) {
|
||||
Route::post('messages', 'Api\MessageController@send');
|
||||
}
|
||||
|
||||
// Accounts
|
||||
Route::get('accounts/{id}/activate', 'Api\Admin\AccountController@activate');
|
||||
Route::get('accounts/{id}/deactivate', 'Api\Admin\AccountController@deactivate');
|
||||
|
|
|
|||
|
|
@ -61,6 +61,8 @@ if (config('app.web_panel')) {
|
|||
Route::get('panel', 'Account\AccountController@panel')->name('account.panel');
|
||||
Route::get('logout', 'Account\AuthenticateController@logout')->name('account.logout');
|
||||
|
||||
Route::post('api_key', 'Account\AccountController@generateApiKey')->name('account.api_key.generate');
|
||||
|
||||
Route::get('delete', 'Account\AccountController@delete')->name('account.delete');
|
||||
Route::delete('delete', 'Account\AccountController@destroy')->name('account.destroy');
|
||||
|
||||
|
|
@ -76,8 +78,7 @@ if (config('app.web_panel')) {
|
|||
});
|
||||
|
||||
Route::group(['middleware' => 'auth.admin'], function () {
|
||||
Route::post('admin/api_key', 'Admin\AccountController@generateApiKey')->name('admin.api_key.generate');
|
||||
|
||||
// Statistics
|
||||
Route::get('admin/statistics/day', 'Admin\StatisticsController@showDay')->name('admin.statistics.show.day');
|
||||
Route::get('admin/statistics/week', 'Admin\StatisticsController@showWeek')->name('admin.statistics.show.week');
|
||||
Route::get('admin/statistics/month', 'Admin\StatisticsController@showMonth')->name('admin.statistics.show.month');
|
||||
|
|
|
|||
59
flexiapi/tests/Feature/AccountApiKeyTest.php
Normal file
59
flexiapi/tests/Feature/AccountApiKeyTest.php
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
<?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\Password;
|
||||
|
||||
class AccountApiKeyTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
protected $route = '/api/accounts/me/api_key';
|
||||
protected $method = 'GET';
|
||||
|
||||
public function testRefresh()
|
||||
{
|
||||
$password = Password::factory()->create();
|
||||
|
||||
$response0 = $this->generateFirstResponse($password);
|
||||
$response1 = $this->generateSecondResponse($password, $response0)
|
||||
->get($this->route);
|
||||
|
||||
// Get the API Key using the DIGEST method
|
||||
$password->account->refresh();
|
||||
|
||||
$response1->assertStatus(200)
|
||||
->assertSee($password->account->apiKey->key)
|
||||
->assertPlainCookie('x-api-key', $password->account->apiKey->key);
|
||||
|
||||
// Get it again using the key authenticated method
|
||||
$response2 = $this->keyAuthenticated($password->account)
|
||||
->get($this->route);
|
||||
|
||||
$password->account->refresh();
|
||||
|
||||
$response2->assertStatus(200)
|
||||
->assertSee($password->account->apiKey->key)
|
||||
->assertPlainCookie('x-api-key', $password->account->apiKey->key);
|
||||
}
|
||||
}
|
||||
|
|
@ -27,7 +27,6 @@ use App\Admin;
|
|||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Testing\Fluent\AssertableJson;
|
||||
|
||||
use Tests\TestCase;
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@
|
|||
namespace Tests\Feature;
|
||||
|
||||
use App\Password;
|
||||
use App\AccountAction;
|
||||
use App\AccountType;
|
||||
use App\Admin;
|
||||
|
||||
|
|
|
|||
58
flexiapi/tests/Feature/AccountMessageTest.php
Normal file
58
flexiapi/tests/Feature/AccountMessageTest.php
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
/*
|
||||
Flexisip Account Manager is a set of tools to manage SIP accounts.
|
||||
Copyright (C) 2022 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 App\Admin;
|
||||
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Testing\Fluent\AssertableJson;
|
||||
use Tests\TestCase;
|
||||
|
||||
class AccountMessageTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
protected $route = '/api/messages';
|
||||
protected $method = 'POST';
|
||||
|
||||
public function testRequest()
|
||||
{
|
||||
$admin = Admin::factory()->create();
|
||||
$password = $admin->account->passwords()->first();
|
||||
$password->account->generateApiKey();
|
||||
|
||||
$this->keyAuthenticated($password->account)
|
||||
->json($this->method, $this->route, [
|
||||
'to' => '+badid',
|
||||
'body' => 'foobar'
|
||||
])
|
||||
->assertStatus(422);
|
||||
|
||||
$this->keyAuthenticated($password->account)
|
||||
->json($this->method, $this->route, [
|
||||
'to' => 'username@sip.linphone.org',
|
||||
'body' => 'Message content'
|
||||
])
|
||||
->assertStatus(200)
|
||||
->assertJson(function (AssertableJson $json) {
|
||||
$json->has('id');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -20,8 +20,6 @@
|
|||
namespace Tests\Feature;
|
||||
|
||||
use App\Password;
|
||||
use App\Account;
|
||||
use App\Admin;
|
||||
use App\PhoneChangeCode;
|
||||
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
|
|
@ -48,7 +46,7 @@ class AccountPhoneChangeTest extends TestCase
|
|||
// Send a SMS
|
||||
/*$this->keyAuthenticated($password->account)
|
||||
->json($this->method, $this->route.'/request', [
|
||||
'phone' => '+33667545663'
|
||||
'phone' => '+3312345678'
|
||||
])
|
||||
->assertStatus(200);*/
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use Account;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
#%define _datadir %{_datarootdir}
|
||||
#%define _docdir %{_datadir}/doc
|
||||
|
||||
%define build_number 129
|
||||
%define build_number 130
|
||||
%define var_dir /var/opt/belledonne-communications
|
||||
%define opt_dir /opt/belledonne-communications/share/flexisip-account-manager
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue