diff --git a/flexiapi/README.md b/flexiapi/README.md
index 6680881..08a647c 100644
--- a/flexiapi/README.md
+++ b/flexiapi/README.md
@@ -130,4 +130,4 @@ This command will set the admin role to any available FlexiSIP account (the exte
php artisan accounts:set-admin {account_id}
-Once one account is declared as administrator, you can directly configure the other ones using the web panel.
\ No newline at end of file
+Once one account is declared as administrator, you can directly configure the other ones using the web panel.
diff --git a/flexiapi/app/Account.php b/flexiapi/app/Account.php
index 4ba38c8..99e5452 100644
--- a/flexiapi/app/Account.php
+++ b/flexiapi/app/Account.php
@@ -59,6 +59,18 @@ class Account extends Authenticatable
});
}
+ public function scopeSip($query, string $sip)
+ {
+ if (\str_contains($sip, '@')) {
+ list($usernane, $domain) = explode('@', $sip);
+
+ return $query->where('username', $usernane)
+ ->where('domain', $domain);
+ };
+
+ return $query->where('id', '<', 0);
+ }
+
public function passwords()
{
return $this->hasMany('App\Password');
diff --git a/flexiapi/app/Http/Controllers/AccountController.php b/flexiapi/app/Http/Controllers/Account/AccountController.php
similarity index 95%
rename from flexiapi/app/Http/Controllers/AccountController.php
rename to flexiapi/app/Http/Controllers/Account/AccountController.php
index 522b8c7..fe9504b 100644
--- a/flexiapi/app/Http/Controllers/AccountController.php
+++ b/flexiapi/app/Http/Controllers/Account/AccountController.php
@@ -17,13 +17,11 @@
along with this program. If not, see
GET /pingReturns pong
GET /accounts/{sip}/infoRetrieve public information about the account.
+Return 404 if the account doesn't exists.
POST /accounts/{sip}/activate/emailActivate an account using a secret code received by email.
+Return 404 if the account doesn't exists or if the code is incorrect, the validated account otherwise.
JSON parameters:
+code the codePOST /accounts/{sip}/activate/phoneActivate an account using a pin code received by phone.
+Return 404 if the account doesn't exists or if the code is incorrect, the validated account otherwise.
JSON parameters:
+code the PIN codeGET /accounts/meRetrieve the account information.
POST /accounts/email/requestChange the account email. An email will be sent to the new email address to confirm the operation.
JSON parameters:
-email the new email addressPOST /accounts/passwordChange the account password.
JSON parameters:
-algorithm required, values can be SHA-256 or MD5old_password required if the password is already set, the old passwordpassword required, the new passwordGET /devicesReturn the user registered devices.
+ +DELETE /devices/{uuid}Remove one of the user registered devices.
+ +Those endpoints are authenticated and requires an admin account.
POST /accountsTo create an account directly from the API.
JSON parameters:
-username unique username, minimum 6 characterspassword required minimum 6 charactersGET /accountsRetrieve all the accounts, paginated.
GET /accounts/{id}Retrieve a specific account.
DELETE /accounts/{id}Delete a specific account and its related information.
GET /accounts/{id}/activateActivate an account.
GET /accounts/{id}/deactivateDeactivate an account.
-GET /pingReturns pong
GET /devicesReturn the user registered devices.
- -DELETE /devices/{uuid}Remove one of the user registered devices.
@endsection diff --git a/flexiapi/routes/api.php b/flexiapi/routes/api.php index 12d9286..2101cae 100644 --- a/flexiapi/routes/api.php +++ b/flexiapi/routes/api.php @@ -26,14 +26,19 @@ Route::middleware('auth:api')->get('/user', function (Request $request) { }); Route::get('ping', 'Api\PingController@ping'); +Route::get('accounts/{sip}/info', 'Api\AccountController@info'); +Route::post('accounts/{sip}/activate/email', 'Api\AccountController@activateEmail'); +Route::post('accounts/{sip}/activate/phone', 'Api\AccountController@activatePhone'); Route::group(['middleware' => ['auth.digest_or_key']], function () { + Route::get('accounts/me', 'Api\AccountController@show'); + Route::delete('accounts/me', 'Api\AccountController@delete'); + Route::get('devices', 'Api\DeviceController@index'); Route::delete('devices/{uuid}', 'Api\DeviceController@destroy'); - Route::get('accounts/me', 'Api\AccountController@show'); - Route::post('accounts/email/request', 'Api\AccountController@requestEmailUpdate'); - Route::post('accounts/password', 'Api\AccountController@passwordUpdate'); + Route::post('accounts/email/request', 'Api\EmailController@requestUpdate'); + Route::post('accounts/password', 'Api\PasswordController@update'); Route::group(['middleware' => ['auth.admin']], function () { Route::get('accounts/{id}/activate', 'Api\Admin\AccountController@activate'); diff --git a/flexiapi/routes/web.php b/flexiapi/routes/web.php index 79ff042..f981c63 100644 --- a/flexiapi/routes/web.php +++ b/flexiapi/routes/web.php @@ -19,20 +19,20 @@ //Route::get('/', 'HomeController@index')->name('home'); -Route::get('/', 'AccountController@home')->name('account.home'); -Route::get('terms', 'AccountController@terms')->name('account.terms'); -Route::get('privacy', 'AccountController@privacy')->name('account.privacy'); +Route::get('/', 'Account\AccountController@home')->name('account.home'); +Route::get('terms', 'Account\AccountController@terms')->name('account.terms'); +Route::get('privacy', 'Account\AccountController@privacy')->name('account.privacy'); Route::get('login', 'Account\AuthenticateController@login')->name('account.login'); Route::post('authenticate', 'Account\AuthenticateController@authenticate')->name('account.authenticate'); Route::get('login/email', 'Account\AuthenticateController@loginEmail')->name('account.login_email'); Route::post('authenticate/email', 'Account\AuthenticateController@authenticateEmail')->name('account.authenticate.email'); -Route::get('authenticate/email/{code}', 'Account\AuthenticateController@authenticateEmailConfirm')->name('account.authenticate.email_confirm'); +Route::get('authenticate/email/{code}', 'Account\AuthenticateController@validateEmail')->name('account.authenticate.email_confirm'); Route::get('login/phone', 'Account\AuthenticateController@loginPhone')->name('account.login_phone'); Route::post('authenticate/phone', 'Account\AuthenticateController@authenticatePhone')->name('account.authenticate.phone'); -Route::post('authenticate/phone/confirm', 'Account\AuthenticateController@authenticatePhoneConfirm')->name('account.authenticate.phone_confirm'); +Route::post('authenticate/phone/confirm', 'Account\AuthenticateController@validatePhone')->name('account.authenticate.phone_confirm'); Route::get('register', 'Account\RegisterController@register')->name('account.register'); @@ -45,11 +45,11 @@ Route::get('register/email', 'Account\RegisterController@registerEmail')->name(' Route::post('register/email', 'Account\RegisterController@storeEmail')->name('account.store.email'); Route::group(['middleware' => 'auth'], function () { - Route::get('panel', 'AccountController@panel')->name('account.panel'); + Route::get('panel', 'Account\AccountController@panel')->name('account.panel'); Route::get('logout', 'Account\AuthenticateController@logout')->name('account.logout'); - Route::get('delete', 'AccountController@delete')->name('account.delete'); - Route::delete('delete', 'AccountController@destroy')->name('account.destroy'); + Route::get('delete', 'Account\AccountController@delete')->name('account.delete'); + Route::delete('delete', 'Account\AccountController@destroy')->name('account.destroy'); Route::get('email', 'Account\EmailController@show')->name('account.email'); Route::post('email/request', 'Account\EmailController@requestUpdate')->name('account.email.request_update'); diff --git a/flexiapi/tests/Feature/AccountApiTest.php b/flexiapi/tests/Feature/AccountApiTest.php index 76df2cf..8376bab 100644 --- a/flexiapi/tests/Feature/AccountApiTest.php +++ b/flexiapi/tests/Feature/AccountApiTest.php @@ -184,6 +184,18 @@ class AccountApiTest extends TestCase $password = Password::factory()->create(); $password->account->generateApiKey(); + /** + * Public information + */ + $this->get($this->route.'/'.$password->account->identifier.'/info') + ->assertStatus(200) + ->assertJson([ + 'activated' => false + ]); + + /** + * Retrieve the authenticated account + */ $this->keyAuthenticated($password->account) ->get($this->route.'/me') ->assertStatus(200) @@ -191,6 +203,91 @@ class AccountApiTest extends TestCase 'username' => $password->account->username, 'activated' => false ]); + + /** + * Retrieve the authenticated account + */ + $this->keyAuthenticated($password->account) + ->delete($this->route.'/me') + ->assertStatus(200); + + /** + * Check again + */ + $this->get($this->route.'/'.$password->account->identifier.'/info') + ->assertStatus(404); + } + + public function testActivateEmail() + { + $confirmationKey = '0123456789abc'; + $password = Password::factory()->create(); + $password->account->generateApiKey(); + $password->account->confirmation_key = $confirmationKey; + $password->account->save(); + + $this->get($this->route.'/'.$password->account->identifier.'/info') + ->assertStatus(200) + ->assertJson([ + 'activated' => false + ]); + + $this->keyAuthenticated($password->account) + ->json($this->method, $this->route.'/blabla/activate/email', [ + 'code' => $confirmationKey + ]) + ->assertStatus(404); + + $this->keyAuthenticated($password->account) + ->json($this->method, $this->route.'/'.$password->account->identifier.'/activate/email', [ + 'code' => $confirmationKey.'longer' + ]) + ->assertStatus(422); + + $this->keyAuthenticated($password->account) + ->json($this->method, $this->route.'/'.$password->account->identifier.'/activate/email', [ + 'code' => 'X123456789abc' + ]) + ->assertStatus(404); + + $this->keyAuthenticated($password->account) + ->json($this->method, $this->route.'/'.$password->account->identifier.'/activate/email', [ + 'code' => $confirmationKey + ]) + ->assertStatus(200); + + $this->get($this->route.'/'.$password->account->identifier.'/info') + ->assertStatus(200) + ->assertJson([ + 'activated' => true + ]); + } + + public function testActivatePhone() + { + $confirmationKey = '0123'; + $password = Password::factory()->create(); + $password->account->generateApiKey(); + $password->account->confirmation_key = $confirmationKey; + $password->account->save(); + + $this->get($this->route.'/'.$password->account->identifier.'/info') + ->assertStatus(200) + ->assertJson([ + 'activated' => false + ]); + + $this->keyAuthenticated($password->account) + ->json($this->method, $this->route.'/'.$password->account->identifier.'/activate/phone', [ + 'code' => $confirmationKey + ]) + ->assertStatus(200); + + $this->get($this->route.'/'.$password->account->identifier.'/info') + ->assertStatus(200) + ->assertJson([ + 'activated' => true + ]); } public function testChangeEmail() @@ -373,7 +470,6 @@ class AccountApiTest extends TestCase ->assertJson([ 'id' => 1 ]); - } public function testDelete() diff --git a/flexisip-account-manager.spec b/flexisip-account-manager.spec index 2aff088..8939faa 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 40 +%define build_number 41 %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"