mirror of
https://gitlab.linphone.org/BC/public/flexisip-account-manager.git
synced 2026-04-17 19:58:27 +00:00
Fix #92 Add two new endpoints regarding email account reset and account search per email for admins
This commit is contained in:
parent
63e13502dc
commit
716789592e
8 changed files with 96 additions and 14 deletions
|
|
@ -21,7 +21,6 @@ namespace App\Http\Controllers\Admin;
|
|||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Carbon\Carbon;
|
||||
|
||||
|
|
@ -31,7 +30,6 @@ use App\Alias;
|
|||
use App\ExternalAccount;
|
||||
use App\Http\Requests\CreateAccountRequest;
|
||||
use App\Http\Requests\UpdateAccountRequest;
|
||||
use App\Http\Controllers\Account\AuthenticateController as WebAuthenticateController;
|
||||
use App\Rules\BlacklistedUsername;
|
||||
use App\Rules\IsNotPhoneNumber;
|
||||
use App\Rules\NoUppercase;
|
||||
|
|
|
|||
|
|
@ -33,11 +33,13 @@ use App\ActivationExpiration;
|
|||
use App\Admin;
|
||||
use App\Alias;
|
||||
use App\Http\Controllers\Account\AuthenticateController as WebAuthenticateController;
|
||||
use App\Mail\PasswordAuthentication;
|
||||
use App\Rules\BlacklistedUsername;
|
||||
use App\Rules\IsNotPhoneNumber;
|
||||
use App\Rules\NoUppercase;
|
||||
use App\Rules\SIPUsername;
|
||||
use App\Rules\WithoutSpaces;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class AccountController extends Controller
|
||||
{
|
||||
|
|
@ -56,6 +58,11 @@ class AccountController extends Controller
|
|||
return Account::sip($sip)->firstOrFail();
|
||||
}
|
||||
|
||||
public function searchByEmail(Request $request, string $email)
|
||||
{
|
||||
return Account::where('email', $email)->firstOrFail();
|
||||
}
|
||||
|
||||
public function destroy($id)
|
||||
{
|
||||
$account = Account::findOrFail($id);
|
||||
|
|
@ -183,7 +190,7 @@ class AccountController extends Controller
|
|||
// Full reload
|
||||
$account = Account::withoutGlobalScopes()->find($account->id);
|
||||
|
||||
Log::channel('events')->info('API: Admin: Account created', ['id' => $account->identifier]);
|
||||
Log::channel('events')->info('API Admin: Account created', ['id' => $account->identifier]);
|
||||
|
||||
return response()->json($account->makeVisible(['confirmation_key', 'provisioning_token']));
|
||||
}
|
||||
|
|
@ -207,4 +214,18 @@ class AccountController extends Controller
|
|||
|
||||
return Account::findOrFail($id)->types()->detach($typeId);
|
||||
}
|
||||
|
||||
public function recoverByEmail(int $id)
|
||||
{
|
||||
$account = Account::findOrFail($id);
|
||||
$account->provision();
|
||||
$account->confirmation_key = Str::random(WebAuthenticateController::$emailCodeSize);
|
||||
$account->save();
|
||||
|
||||
Log::channel('events')->info('API Admin: Sending recovery email', ['id' => $account->identifier]);
|
||||
|
||||
Mail::to($account)->send(new PasswordAuthentication($account));
|
||||
|
||||
return response()->json($account->makeVisible(['confirmation_key', 'provisioning_token']));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddEmailIndexToAccountsTable extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
Schema::table('accounts', function (Blueprint $table) {
|
||||
$table->index('email');
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
Schema::table('accounts', function (Blueprint $table) {
|
||||
$table->dropIndex('accounts_email_index');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -279,10 +279,18 @@ Retrieve all the accounts, paginated.
|
|||
<span class="badge badge-warning">Admin</span>
|
||||
Retrieve a specific account.
|
||||
|
||||
### `POST /accounts/{id}/recover-by-email`
|
||||
<span class="badge badge-warning">Admin</span>
|
||||
Send the account recovery email containing a fresh `provisioning_token` and `confirmation_key`
|
||||
|
||||
### `GET /accounts/{sip}/search`
|
||||
<span class="badge badge-warning">Admin</span>
|
||||
Search for a specific account by sip address.
|
||||
|
||||
### `GET /accounts/{email}/search-by-email`
|
||||
<span class="badge badge-warning">Admin</span>
|
||||
Search for a specific account by email.
|
||||
|
||||
### `DELETE /accounts/{id}`
|
||||
<span class="badge badge-warning">Admin</span>
|
||||
Delete a specific account and its related information.
|
||||
|
|
|
|||
|
|
@ -84,9 +84,12 @@ Route::group(['middleware' => ['auth.digest_or_key']], function () {
|
|||
Route::get('accounts/{id}/deactivate', 'Api\Admin\AccountController@deactivate');
|
||||
Route::get('accounts/{id}/provision', 'Api\Admin\AccountController@provision');
|
||||
|
||||
Route::post('accounts/{id}/recover-by-email', 'Api\Admin\AccountController@recoverByEmail');
|
||||
|
||||
Route::post('accounts', 'Api\Admin\AccountController@store');
|
||||
Route::get('accounts', 'Api\Admin\AccountController@index');
|
||||
Route::get('accounts/{sip}/search', 'Api\Admin\AccountController@search');
|
||||
Route::get('accounts/{email}/search-by-email', 'Api\Admin\AccountController@searchByEmail');
|
||||
Route::get('accounts/{id}', 'Api\Admin\AccountController@show');
|
||||
Route::delete('accounts/{id}', 'Api\Admin\AccountController@destroy');
|
||||
|
||||
|
|
|
|||
|
|
@ -188,9 +188,9 @@ class AccountProvisioningTest extends TestCase
|
|||
->assertStatus(201)
|
||||
->assertJson([
|
||||
'token' => true
|
||||
])->content();
|
||||
]);
|
||||
|
||||
$authToken = json_decode($response)->token;
|
||||
$authToken = $response->json('token');
|
||||
|
||||
$password = Password::factory()->create();
|
||||
$password->account->generateApiKey();
|
||||
|
|
|
|||
|
|
@ -64,9 +64,9 @@ class ApiAccountApiKeyTest extends TestCase
|
|||
->assertStatus(201)
|
||||
->assertJson([
|
||||
'token' => true
|
||||
])->content();
|
||||
]);
|
||||
|
||||
$authToken = json_decode($response)->token;
|
||||
$authToken = $response->json('token');
|
||||
|
||||
// Try to retrieve an API key from the un-attached auth_token
|
||||
$response = $this->json($this->method, $this->route . '/' . $authToken)
|
||||
|
|
@ -95,9 +95,9 @@ class ApiAccountApiKeyTest extends TestCase
|
|||
->assertStatus(200)
|
||||
->assertJson([
|
||||
'api_key' => true
|
||||
])->content();
|
||||
]);
|
||||
|
||||
$apiKey = json_decode($response)->api_key;
|
||||
$apiKey = $response->json('api_key');
|
||||
|
||||
// Re-retrieve
|
||||
$this->json($this->method, $this->route . '/' . $authToken)
|
||||
|
|
@ -106,8 +106,7 @@ class ApiAccountApiKeyTest extends TestCase
|
|||
// Check the if the API key can be used for the account
|
||||
$response = $this->withHeaders(['x-api-key' => $apiKey])
|
||||
->json($this->method, '/api/accounts/me')
|
||||
->assertStatus(200)
|
||||
->content();
|
||||
->assertStatus(200);
|
||||
|
||||
// Try with a wrong From
|
||||
$response = $this->withHeaders([
|
||||
|
|
@ -115,10 +114,9 @@ class ApiAccountApiKeyTest extends TestCase
|
|||
'From' => 'sip:baduser@server.tld'
|
||||
])
|
||||
->json($this->method, '/api/accounts/me')
|
||||
->assertStatus(200)
|
||||
->content();
|
||||
->assertStatus(200);
|
||||
|
||||
// Check if the account was correctly attached
|
||||
$this->assertEquals(json_decode($response)->email, $password->account->email);
|
||||
$this->assertEquals($response->json('email'), $password->account->email);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1007,6 +1007,38 @@ class ApiAccountTest extends TestCase
|
|||
'id' => $password->account->id,
|
||||
'activated' => true
|
||||
]);
|
||||
|
||||
$this->keyAuthenticated($admin->account)
|
||||
->get($this->route . '/' . $password->account->email . '/search-by-email')
|
||||
->assertStatus(200)
|
||||
->assertJson([
|
||||
'id' => $password->account->id,
|
||||
'activated' => true
|
||||
]);
|
||||
|
||||
$this->keyAuthenticated($admin->account)
|
||||
->get($this->route . '/wrong@email.com/search-by-email')
|
||||
->assertStatus(404);
|
||||
}
|
||||
|
||||
public function testRecoverByEmail()
|
||||
{
|
||||
$email = 'collision@email.com';
|
||||
|
||||
$account = Password::factory()->create();
|
||||
$account->account->email = $email;
|
||||
$account->account->save();
|
||||
|
||||
$admin = Admin::factory()->create();
|
||||
$admin->account->generateApiKey();
|
||||
$admin->account->save();
|
||||
|
||||
$response = $this->keyAuthenticated($admin->account)
|
||||
->post($this->route . '/' . $account->id . '/recover-by-email')
|
||||
->assertStatus(200);
|
||||
|
||||
$this->assertNotEquals($response->json('confirmation_key'), $account->confirmation_key);
|
||||
$this->assertNotEquals($response->json('provisioning_token'), $account->provisioning_token);
|
||||
}
|
||||
|
||||
public function testGetAll()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue