mirror of
https://gitlab.linphone.org/BC/public/flexisip-account-manager.git
synced 2026-01-17 10:08:05 +00:00
Fix FLEXIAPI-213 Add TURN credentials support in the API as defined in...
This commit is contained in:
parent
12ef6d472e
commit
648936514f
9 changed files with 65 additions and 32 deletions
|
|
@ -8,6 +8,7 @@ v1.6
|
||||||
- Fix FLEXIAPI-208 Add SMS templates documentation
|
- Fix FLEXIAPI-208 Add SMS templates documentation
|
||||||
- Fix FLEXIAPI-211 Add a JSON validation middleware + test
|
- Fix FLEXIAPI-211 Add a JSON validation middleware + test
|
||||||
- Fix FLEXIAPI-212 Add CoTURN credentials support in the provisioning
|
- Fix FLEXIAPI-212 Add CoTURN credentials support in the provisioning
|
||||||
|
- Fix FLEXIAPI-213 Add TURN credentials support in the API as defined in draft-uberti-behave-turn-rest-00
|
||||||
|
|
||||||
v1.5
|
v1.5
|
||||||
---
|
---
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,6 @@ MAIL_SIGNATURE="The Example Team"
|
||||||
COTURN_SERVER_HOST= # IP or domain name
|
COTURN_SERVER_HOST= # IP or domain name
|
||||||
COTURN_SESSION_TTL_MINUTES=1440 # 60 * 24
|
COTURN_SESSION_TTL_MINUTES=1440 # 60 * 24
|
||||||
COTURN_STATIC_AUTH_SECRET= # static-auth-secret in the coturn configuration
|
COTURN_STATIC_AUTH_SECRET= # static-auth-secret in the coturn configuration
|
||||||
COTURN_REALM= # realm in the coturn configuration, empty by default
|
|
||||||
|
|
||||||
# OVH SMS API variables
|
# OVH SMS API variables
|
||||||
OVH_APP_KEY=
|
OVH_APP_KEY=
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,30 @@ function markdownDocumentationView(string $view): string
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hasCoTURNConfigured(): bool
|
||||||
|
{
|
||||||
|
return config('app.coturn_session_ttl_minutes') > 0
|
||||||
|
&& !empty(config('app.coturn_server_host'))
|
||||||
|
&& !empty(config('app.coturn_static_auth_secret'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCoTURNCredentials(): array
|
||||||
|
{
|
||||||
|
$user = Str::random(8);
|
||||||
|
$secret = config('app.coturn_static_auth_secret');
|
||||||
|
|
||||||
|
$ttl = config('app.coturn_session_ttl_minutes') * 60;
|
||||||
|
$time = time() + $ttl;
|
||||||
|
|
||||||
|
$username = $time . ':' . Str::random(16);
|
||||||
|
$password = base64_encode(hash_hmac('sha1', $username, $secret, true));
|
||||||
|
|
||||||
|
return [
|
||||||
|
'username' => $username,
|
||||||
|
'password' => $password,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
function parseSIP(string $sipAdress): array
|
function parseSIP(string $sipAdress): array
|
||||||
{
|
{
|
||||||
return explode('@', \substr($sipAdress, 4));
|
return explode('@', \substr($sipAdress, 4));
|
||||||
|
|
|
||||||
|
|
@ -253,16 +253,8 @@ class ProvisioningController extends Controller
|
||||||
$authInfoIndex = 0;
|
$authInfoIndex = 0;
|
||||||
|
|
||||||
// CoTURN
|
// CoTURN
|
||||||
if (config('app.coturn_session_ttl_minutes') > 0
|
if (hasCoTURNConfigured()) {
|
||||||
&& !empty(config('app.coturn_server_host'))
|
list($username, $password) = array_values(getCoTURNCredentials());
|
||||||
&& !empty(config('app.coturn_static_auth_secret'))) {
|
|
||||||
$user = 'foo';
|
|
||||||
$secret = config('app.coturn_static_auth_secret');
|
|
||||||
|
|
||||||
$ttl = config('app.coturn_session_ttl_minutes') * 60;
|
|
||||||
$time = time() + $ttl;
|
|
||||||
$username = $time . ':' . Str::random(16);
|
|
||||||
$password = base64_encode(hash_hmac('sha1', $username, $secret, true));
|
|
||||||
|
|
||||||
// net
|
// net
|
||||||
$section = $xpath->query("//section[@name='net']")->item(0);
|
$section = $xpath->query("//section[@name='net']")->item(0);
|
||||||
|
|
@ -317,12 +309,6 @@ class ProvisioningController extends Controller
|
||||||
$entry = $dom->createElement('entry', $password);
|
$entry = $dom->createElement('entry', $password);
|
||||||
$entry->setAttribute('name', 'passwd');
|
$entry->setAttribute('name', 'passwd');
|
||||||
$section->appendChild($entry);
|
$section->appendChild($entry);
|
||||||
|
|
||||||
if (!empty(config('app.coturn_realm'))) {
|
|
||||||
$entry = $dom->createElement('entry', config('app.coturn_realm'));
|
|
||||||
$entry->setAttribute('name', 'realm');
|
|
||||||
$section->appendChild($entry);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($passwords as $password) {
|
foreach ($passwords as $password) {
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,27 @@ class AccountController extends Controller
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get services credentials
|
||||||
|
*/
|
||||||
|
public function turnService(Request $request)
|
||||||
|
{
|
||||||
|
if (hasCoturnConfigured()) {
|
||||||
|
list($username, $password) = array_values(getCoTURNCredentials());
|
||||||
|
|
||||||
|
return [
|
||||||
|
'username' => $username,
|
||||||
|
'password' => $password,
|
||||||
|
'ttl' => config('app.coturn_session_ttl_minutes') * 60,
|
||||||
|
'uris' => [
|
||||||
|
'turn:' . config('app.coturn_server_host'),
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return abort(404, 'No TURN service configured');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* /!\ Dangerous endpoint, disabled by default
|
* /!\ Dangerous endpoint, disabled by default
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,6 @@ return [
|
||||||
'coturn_server_host' => env('COTURN_SERVER_HOST', null),
|
'coturn_server_host' => env('COTURN_SERVER_HOST', null),
|
||||||
'coturn_session_ttl_minutes' => (int)env('COTURN_SESSION_TTL_MINUTES', 60 * 24),
|
'coturn_session_ttl_minutes' => (int)env('COTURN_SESSION_TTL_MINUTES', 60 * 24),
|
||||||
'coturn_static_auth_secret' => env('COTURN_STATIC_AUTH_SECRET', null),
|
'coturn_static_auth_secret' => env('COTURN_STATIC_AUTH_SECRET', null),
|
||||||
'coturn_realm' => env('COTURN_REALM', null),
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* External interfaces
|
* External interfaces
|
||||||
|
|
|
||||||
|
|
@ -364,6 +364,11 @@ This endpoint is also setting the API Key as a Cookie.
|
||||||
|
|
||||||
Retrieve the account information.
|
Retrieve the account information.
|
||||||
|
|
||||||
|
### `GET /accounts/me/services/turn`
|
||||||
|
<span class="badge badge-info">User</span>
|
||||||
|
|
||||||
|
If configured, returns valid TURN credentials following the [draft-uberti-behave-turn-rest-00 IEFT Draft](https://datatracker.ietf.org/doc/html/draft-uberti-behave-turn-rest-00).
|
||||||
|
|
||||||
### `GET /accounts/me/provision`
|
### `GET /accounts/me/provision`
|
||||||
<span class="badge badge-info">User</span>
|
<span class="badge badge-info">User</span>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,8 @@ Route::group(['middleware' => ['auth.jwt', 'auth.digest_or_key', 'auth.check_blo
|
||||||
Route::prefix('accounts/me')->group(function () {
|
Route::prefix('accounts/me')->group(function () {
|
||||||
Route::get('api_key', 'Api\Account\ApiKeyController@generate')->middleware('cookie', 'cookie.encrypt');
|
Route::get('api_key', 'Api\Account\ApiKeyController@generate')->middleware('cookie', 'cookie.encrypt');
|
||||||
|
|
||||||
|
Route::get('services/turn', 'Api\Account\AccountController@turnService');
|
||||||
|
|
||||||
Route::get('/', 'Api\Account\AccountController@show');
|
Route::get('/', 'Api\Account\AccountController@show');
|
||||||
Route::delete('/', 'Api\Account\AccountController@delete');
|
Route::delete('/', 'Api\Account\AccountController@delete');
|
||||||
Route::get('provision', 'Api\Account\AccountController@provision');
|
Route::get('provision', 'Api\Account\AccountController@provision');
|
||||||
|
|
|
||||||
|
|
@ -351,6 +351,10 @@ class AccountProvisioningTest extends TestCase
|
||||||
$host = 'coturn.tld';
|
$host = 'coturn.tld';
|
||||||
$realm = 'realm.tld';
|
$realm = 'realm.tld';
|
||||||
|
|
||||||
|
$this->keyAuthenticated($account)
|
||||||
|
->get('/api/accounts/me/services/turn')
|
||||||
|
->assertStatus(404);
|
||||||
|
|
||||||
config()->set('app.coturn_server_host', $host);
|
config()->set('app.coturn_server_host', $host);
|
||||||
config()->set('app.coturn_static_auth_secret', 'secret');
|
config()->set('app.coturn_static_auth_secret', 'secret');
|
||||||
|
|
||||||
|
|
@ -364,21 +368,13 @@ class AccountProvisioningTest extends TestCase
|
||||||
->assertSee($host)
|
->assertSee($host)
|
||||||
->assertSee('nat_policy_ref')
|
->assertSee('nat_policy_ref')
|
||||||
->assertSee('stun_server_username')
|
->assertSee('stun_server_username')
|
||||||
->assertSee('nat_policy_0')
|
->assertSee('nat_policy_0');
|
||||||
->assertDontSee('realm')
|
|
||||||
->assertDontSee($realm);
|
|
||||||
|
|
||||||
config()->set('app.coturn_realm', $realm);
|
$this->keyAuthenticated($account)
|
||||||
|
->get('/api/accounts/me/services/turn')
|
||||||
$response = $this->withHeaders([
|
|
||||||
'x-linphone-provisioning' => true,
|
|
||||||
])
|
|
||||||
->keyAuthenticated($account)
|
|
||||||
->get($this->accountRoute)
|
|
||||||
->assertStatus(200)
|
->assertStatus(200)
|
||||||
->assertHeader('Content-Type', 'application/xml')
|
->assertJson([
|
||||||
->assertSee($host)
|
'ttl' => config()->get('app.coturn_session_ttl_minutes') * 60
|
||||||
->assertSee('realm')
|
]);
|
||||||
->assertSee($realm);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue