diff --git a/flexiapi/resources/views/account/panel.blade.php b/flexiapi/resources/views/account/panel.blade.php
index acc4027..257e8ff 100644
--- a/flexiapi/resources/views/account/panel.blade.php
+++ b/flexiapi/resources/views/account/panel.blade.php
@@ -67,25 +67,6 @@
Show some registration statistics
-
- API Key
-
- As an administrator you can generate an API key and use it to request the different API endpoints, check the related API documentation to know how to use that key.
-
- {!! Form::open(['route' => 'admin.api_key.generate']) !!}
-
-{!! Form::close() !!}
@endif
Account information
@@ -103,6 +84,25 @@
@endif
+API Key
+
+You can generate an API key and use it to request the different API endpoints, check the related API documentation to know how to use that key.
+
+{!! Form::open(['route' => 'account.api_key.generate']) !!}
+
+{!! Form::close() !!}
+
@include('parts.account_variables', ['account' => $account])
@endsection
\ No newline at end of file
diff --git a/flexiapi/resources/views/api/documentation_markdown.blade.php b/flexiapi/resources/views/api/documentation_markdown.blade.php
index a93b8c6..a83c435 100644
--- a/flexiapi/resources/views/api/documentation_markdown.blade.php
+++ b/flexiapi/resources/views/api/documentation_markdown.blade.php
@@ -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 the dedicated API endpoint.
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.
@@ -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`
diff --git a/flexiapi/routes/api.php b/flexiapi/routes/api.php
index 7a0a824..b821dac 100644
--- a/flexiapi/routes/api.php
+++ b/flexiapi/routes/api.php
@@ -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');
diff --git a/flexiapi/routes/web.php b/flexiapi/routes/web.php
index 746dd15..9a59f02 100644
--- a/flexiapi/routes/web.php
+++ b/flexiapi/routes/web.php
@@ -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');
diff --git a/flexiapi/tests/Feature/AccountApiKeyTest.php b/flexiapi/tests/Feature/AccountApiKeyTest.php
new file mode 100644
index 0000000..96be79b
--- /dev/null
+++ b/flexiapi/tests/Feature/AccountApiKeyTest.php
@@ -0,0 +1,59 @@
+.
+*/
+
+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);
+ }
+}
\ No newline at end of file
diff --git a/flexiapi/tests/Feature/AccountApiTest.php b/flexiapi/tests/Feature/AccountApiTest.php
index 6a68ce7..4edd726 100644
--- a/flexiapi/tests/Feature/AccountApiTest.php
+++ b/flexiapi/tests/Feature/AccountApiTest.php
@@ -27,7 +27,6 @@ use App\Admin;
use Carbon\Carbon;
use Illuminate\Foundation\Testing\RefreshDatabase;
-use Illuminate\Testing\Fluent\AssertableJson;
use Tests\TestCase;
diff --git a/flexiapi/tests/Feature/AccountContactsTest.php b/flexiapi/tests/Feature/AccountContactsTest.php
index 2236588..72eb1c7 100644
--- a/flexiapi/tests/Feature/AccountContactsTest.php
+++ b/flexiapi/tests/Feature/AccountContactsTest.php
@@ -20,7 +20,6 @@
namespace Tests\Feature;
use App\Password;
-use App\AccountAction;
use App\AccountType;
use App\Admin;
diff --git a/flexiapi/tests/Feature/AccountMessageTest.php b/flexiapi/tests/Feature/AccountMessageTest.php
new file mode 100644
index 0000000..1b3db7a
--- /dev/null
+++ b/flexiapi/tests/Feature/AccountMessageTest.php
@@ -0,0 +1,58 @@
+.
+*/
+
+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');
+ });
+ }
+}
\ No newline at end of file
diff --git a/flexiapi/tests/Feature/AccountPhoneChangeTest.php b/flexiapi/tests/Feature/AccountPhoneChangeTest.php
index f190f94..039225e 100644
--- a/flexiapi/tests/Feature/AccountPhoneChangeTest.php
+++ b/flexiapi/tests/Feature/AccountPhoneChangeTest.php
@@ -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);*/
}
diff --git a/flexiapi/tests/Feature/AccountProvisioningTest.php b/flexiapi/tests/Feature/AccountProvisioningTest.php
index f808b6b..8d6e49a 100644
--- a/flexiapi/tests/Feature/AccountProvisioningTest.php
+++ b/flexiapi/tests/Feature/AccountProvisioningTest.php
@@ -19,7 +19,6 @@
namespace Tests\Feature;
-use Account;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
diff --git a/flexisip-account-manager.spec b/flexisip-account-manager.spec
index 1b8ef61..787f2c9 100644
--- a/flexisip-account-manager.spec
+++ b/flexisip-account-manager.spec
@@ -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