mirror of
https://gitlab.linphone.org/BC/public/flexisip-account-manager.git
synced 2026-01-27 07:29:19 +00:00
Fix FLEXIAPI-212 Add CoTURN credentials support in the provisioning
This commit is contained in:
parent
23e61fdc38
commit
12ef6d472e
6 changed files with 134 additions and 11 deletions
|
|
@ -7,6 +7,7 @@ v1.6
|
|||
- Fix FLEXIAPI-203 Implement domain based Linphone configuration, add documentation, complete API endpoints, complete provisioning XML
|
||||
- Fix FLEXIAPI-208 Add SMS templates documentation
|
||||
- Fix FLEXIAPI-211 Add a JSON validation middleware + test
|
||||
- Fix FLEXIAPI-212 Add CoTURN credentials support in the provisioning
|
||||
|
||||
v1.5
|
||||
---
|
||||
|
|
|
|||
|
|
@ -106,6 +106,13 @@ MAIL_VERIFY_PEER=true
|
|||
MAIL_VERIFY_PEER_NAME=true
|
||||
MAIL_SIGNATURE="The Example Team"
|
||||
|
||||
# CoTURN
|
||||
|
||||
COTURN_SERVER_HOST= # IP or domain name
|
||||
COTURN_SESSION_TTL_MINUTES=1440 # 60 * 24
|
||||
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_APP_KEY=
|
||||
OVH_APP_SECRET=
|
||||
|
|
|
|||
|
|
@ -50,7 +50,9 @@ class ProvisioningController extends Controller
|
|||
})
|
||||
->firstOrFail();
|
||||
|
||||
if ($account->activationExpired()) abort(404);
|
||||
if ($account->activationExpired()) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
$params = ['provisioning_token' => $provisioningToken];
|
||||
|
||||
|
|
@ -235,6 +237,7 @@ class ProvisioningController extends Controller
|
|||
if ($section == null) {
|
||||
$section = $dom->createElement('section');
|
||||
$section->setAttribute('name', 'proxy_0');
|
||||
$config->appendChild($section);
|
||||
}
|
||||
|
||||
$entry = $dom->createElement('entry', $account->fullIdentifier);
|
||||
|
|
@ -246,17 +249,89 @@ class ProvisioningController extends Controller
|
|||
provisioningProxyHook($section, $request, $account);
|
||||
}
|
||||
|
||||
$config->appendChild($section);
|
||||
|
||||
$passwords = $account->passwords()->get();
|
||||
$authInfoIndex = 0;
|
||||
|
||||
// CoTURN
|
||||
if (config('app.coturn_session_ttl_minutes') > 0
|
||||
&& !empty(config('app.coturn_server_host'))
|
||||
&& !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
|
||||
$section = $xpath->query("//section[@name='net']")->item(0);
|
||||
|
||||
if ($section == null) {
|
||||
$section = $dom->createElement('section');
|
||||
$section->setAttribute('name', 'net');
|
||||
$config->appendChild($section);
|
||||
}
|
||||
|
||||
$ref = Str::random(8);
|
||||
|
||||
$entry = $dom->createElement('entry', $ref);
|
||||
$entry->setAttribute('name', 'nat_policy_ref');
|
||||
$section->appendChild($entry);
|
||||
|
||||
// nat_policy_0
|
||||
$section = $dom->createElement('section');
|
||||
$section->setAttribute('name', 'nat_policy_0');
|
||||
$config->appendChild($section);
|
||||
|
||||
$entry = $dom->createElement('entry', $ref);
|
||||
$entry->setAttribute('name', 'ref');
|
||||
$section->appendChild($entry);
|
||||
|
||||
$entry = $dom->createElement('entry', config('app.coturn_server_host'));
|
||||
$entry->setAttribute('name', 'stun_server');
|
||||
$section->appendChild($entry);
|
||||
|
||||
$entry = $dom->createElement('entry', $username);
|
||||
$entry->setAttribute('name', 'stun_server_username');
|
||||
$section->appendChild($entry);
|
||||
|
||||
$entry = $dom->createElement('entry', 'turn,ice');
|
||||
$entry->setAttribute('name', 'protocols');
|
||||
$section->appendChild($entry);
|
||||
|
||||
// auth_info_x
|
||||
$section = $xpath->query("//section[@name='auth_info_" . $authInfoIndex . "']")->item(0);
|
||||
|
||||
if ($section == null) {
|
||||
$section = $dom->createElement('section');
|
||||
$section->setAttribute('name', 'auth_info_' . $authInfoIndex);
|
||||
$config->appendChild($section);
|
||||
$authInfoIndex++;
|
||||
}
|
||||
|
||||
$entry = $dom->createElement('entry', $username);
|
||||
$entry->setAttribute('name', 'username');
|
||||
$section->appendChild($entry);
|
||||
|
||||
$entry = $dom->createElement('entry', $password);
|
||||
$entry->setAttribute('name', 'passwd');
|
||||
$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) {
|
||||
$section = $xpath->query("//section[@name='auth_info_" . $authInfoIndex . "']")->item(0);
|
||||
|
||||
if ($section == null) {
|
||||
$section = $dom->createElement('section');
|
||||
$section->setAttribute('name', 'auth_info_' . $authInfoIndex);
|
||||
$config->appendChild($section);
|
||||
}
|
||||
|
||||
$entry = $dom->createElement('entry', $account->username);
|
||||
|
|
@ -284,8 +359,6 @@ class ProvisioningController extends Controller
|
|||
provisioningAuthHook($section, $request, $password);
|
||||
}
|
||||
|
||||
$config->appendChild($section);
|
||||
|
||||
$authInfoIndex++;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,6 +50,14 @@ return [
|
|||
*/
|
||||
'account_creation_token_retry_minutes' => env('APP_API_ACCOUNT_CREATION_TOKEN_RETRY_MINUTES', 60),
|
||||
|
||||
/**
|
||||
* CoTURN authentication in the provisioning
|
||||
*/
|
||||
'coturn_server_host' => env('COTURN_SERVER_HOST', null),
|
||||
'coturn_session_ttl_minutes' => (int)env('COTURN_SESSION_TTL_MINUTES', 60 * 24),
|
||||
'coturn_static_auth_secret' => env('COTURN_STATIC_AUTH_SECRET', null),
|
||||
'coturn_realm' => env('COTURN_REALM', null),
|
||||
|
||||
/**
|
||||
* External interfaces
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
[auth_info_0]
|
||||
test=foobar
|
||||
|
||||
[auth_info_1]
|
||||
blabla=gnap
|
||||
|
|
@ -95,7 +95,7 @@ class AccountProvisioningTest extends TestCase
|
|||
])->get($this->accountRoute)->assertStatus(302);
|
||||
}
|
||||
|
||||
public function testAuthenticatedProvisioning()
|
||||
public function testAuthenticatedWithPasswordProvisioning()
|
||||
{
|
||||
$password = Password::factory()->create();
|
||||
$password->account->generateApiKey();
|
||||
|
|
@ -342,4 +342,43 @@ class AccountProvisioningTest extends TestCase
|
|||
->get($this->route . '/' . $account->provisioning_token)
|
||||
->assertStatus(410);
|
||||
}
|
||||
|
||||
public function testCoTURN()
|
||||
{
|
||||
$account = Account::factory()->create();
|
||||
$account->generateApiKey();
|
||||
|
||||
$host = 'coturn.tld';
|
||||
$realm = 'realm.tld';
|
||||
|
||||
config()->set('app.coturn_server_host', $host);
|
||||
config()->set('app.coturn_static_auth_secret', 'secret');
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'x-linphone-provisioning' => true,
|
||||
])
|
||||
->keyAuthenticated($account)
|
||||
->get($this->accountRoute)
|
||||
->assertStatus(200)
|
||||
->assertHeader('Content-Type', 'application/xml')
|
||||
->assertSee($host)
|
||||
->assertSee('nat_policy_ref')
|
||||
->assertSee('stun_server_username')
|
||||
->assertSee('nat_policy_0')
|
||||
->assertDontSee('realm')
|
||||
->assertDontSee($realm);
|
||||
|
||||
config()->set('app.coturn_realm', $realm);
|
||||
|
||||
$response = $this->withHeaders([
|
||||
'x-linphone-provisioning' => true,
|
||||
])
|
||||
->keyAuthenticated($account)
|
||||
->get($this->accountRoute)
|
||||
->assertStatus(200)
|
||||
->assertHeader('Content-Type', 'application/xml')
|
||||
->assertSee($host)
|
||||
->assertSee('realm')
|
||||
->assertSee($realm);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue