diff --git a/CHANGELOG.md b/CHANGELOG.md index 55fbf76..770e7f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ v1.5 ---- +- Fix FLEXIAPI-177 Complete vcards-storage and devices related endpoints with their User/Admin ones - Fix FLEXIAPI-176 Improve logs for the deprecated endpoints and AccountCreationToken related serialization - Fix FLEXIAPI-175 and FLEXISIP-231 Rewrite the Redis contacts parser to handle properly SIP uris (thanks @thibault.lemaire !) - Fix FLEXIAPI-174 Check if the phone is valid before trying to recover it (deprecated endpoint) diff --git a/flexiapi/app/Http/Controllers/Api/Account/VcardsStorageController.php b/flexiapi/app/Http/Controllers/Api/Account/VcardsStorageController.php index 4107764..0e483da 100644 --- a/flexiapi/app/Http/Controllers/Api/Account/VcardsStorageController.php +++ b/flexiapi/app/Http/Controllers/Api/Account/VcardsStorageController.php @@ -2,69 +2,34 @@ namespace App\Http\Controllers\Api\Account; +use App\Http\Controllers\Api\Admin\VcardsStorageController as AdminVcardsStorageController; use App\Http\Controllers\Controller; -use App\Rules\Vcard; -use App\VcardStorage; use Illuminate\Http\Request; -use Sabre\VObject; - class VcardsStorageController extends Controller { public function index(Request $request) { - return $request->user()->vcardsStorage()->get()->keyBy('uuid'); + return (new AdminVcardsStorageController)->index($request->user()->id); } public function show(Request $request, string $uuid) { - return $request->user()->vcardsStorage()->where('uuid', $uuid)->firstOrFail(); + return (new AdminVcardsStorageController)->show($request->user()->id, $uuid); } public function store(Request $request) { - $request->validate([ - 'vcard' => ['required', new Vcard()] - ]); - - $vcardo = VObject\Reader::read($request->get('vcard')); - - if ($request->user()->vcardsStorage()->where('uuid', $vcardo->UID)->first()) { - abort(409, 'Vcard already exists'); - } - - $vcard = new VcardStorage(); - $vcard->account_id = $request->user()->id; - $vcard->uuid = $vcardo->UID; - $vcard->vcard = preg_replace('/\r\n?/', "\n", $vcardo->serialize()); - $vcard->save(); - - return $vcard->vcard; + return (new AdminVcardsStorageController)->store($request, $request->user()->id); } public function update(Request $request, string $uuid) { - $request->validate([ - 'vcard' => ['required', new Vcard()] - ]); - - $vcardo = VObject\Reader::read($request->get('vcard')); - - if ($vcardo->UID != $uuid) { - abort(422, 'UUID should be the same'); - } - - $vcard = $request->user()->vcardsStorage()->where('uuid', $uuid)->firstOrFail(); - $vcard->vcard = preg_replace('/\r\n?/', "\n", $vcardo->serialize()); - $vcard->save(); - - return $vcard->vcard; + return (new AdminVcardsStorageController)->update($request, $request->user()->id, $uuid); } public function destroy(Request $request, string $uuid) { - $vcard = $request->user()->vcardsStorage()->where('uuid', $uuid)->firstOrFail(); - - return $vcard->delete(); + return (new AdminVcardsStorageController)->destroy($request->user()->id, $uuid); } } diff --git a/flexiapi/app/Http/Controllers/Api/Admin/DeviceController.php b/flexiapi/app/Http/Controllers/Api/Admin/DeviceController.php new file mode 100644 index 0000000..df7033c --- /dev/null +++ b/flexiapi/app/Http/Controllers/Api/Admin/DeviceController.php @@ -0,0 +1,41 @@ +. +*/ + +namespace App\Http\Controllers\Api\Admin; + +use App\Account; +use App\Http\Controllers\Controller; +use App\Libraries\FlexisipConnector; + +class DeviceController extends Controller +{ + public function index(int $accountId) + { + $connector = new FlexisipConnector; + + return $connector->getDevices(Account::findOrFail($accountId)->identifier); + } + + public function destroy(int $accountId, string $uuid) + { + $connector = new FlexisipConnector; + + return $connector->deleteDevice(Account::findOrFail($accountId)->identifier, $uuid); + } +} diff --git a/flexiapi/app/Http/Controllers/Api/Admin/VcardsStorageController.php b/flexiapi/app/Http/Controllers/Api/Admin/VcardsStorageController.php new file mode 100644 index 0000000..6ffea31 --- /dev/null +++ b/flexiapi/app/Http/Controllers/Api/Admin/VcardsStorageController.php @@ -0,0 +1,71 @@ +vcardsStorage()->get()->keyBy('uuid'); + } + + public function show(int $accountId, string $uuid) + { + return Account::findOrFail($accountId)->vcardsStorage()->where('uuid', $uuid)->firstOrFail(); + } + + public function store(Request $request, int $accountId) + { + $request->validate([ + 'vcard' => ['required', new Vcard()] + ]); + + $vcardo = VObject\Reader::read($request->get('vcard')); + + if (Account::findOrFail($accountId)->vcardsStorage()->where('uuid', $vcardo->UID)->first()) { + abort(409, 'Vcard already exists'); + } + + $vcard = new VcardStorage(); + $vcard->account_id = $accountId; + $vcard->uuid = $vcardo->UID; + $vcard->vcard = preg_replace('/\r\n?/', "\n", $vcardo->serialize()); + $vcard->save(); + + return $vcard->vcard; + } + + public function update(Request $request, int $accountId, string $uuid) + { + $request->validate([ + 'vcard' => ['required', new Vcard()] + ]); + + $vcardo = VObject\Reader::read($request->get('vcard')); + + if ($vcardo->UID != $uuid) { + abort(422, 'UUID should be the same'); + } + + $vcard = Account::findOrFail($accountId)->vcardsStorage()->where('uuid', $uuid)->firstOrFail(); + $vcard->vcard = preg_replace('/\r\n?/', "\n", $vcardo->serialize()); + $vcard->save(); + + return $vcard->vcard; + } + + public function destroy(int $accountId, string $uuid) + { + $vcard = Account::findOrFail($accountId)->vcardsStorage()->where('uuid', $uuid)->firstOrFail(); + + return $vcard->delete(); + } +} diff --git a/flexiapi/resources/views/api/documentation_markdown.blade.php b/flexiapi/resources/views/api/documentation_markdown.blade.php index 7827bb4..d24b277 100644 --- a/flexiapi/resources/views/api/documentation_markdown.blade.php +++ b/flexiapi/resources/views/api/documentation_markdown.blade.php @@ -428,12 +428,14 @@ Return the updated account. ## Accounts devices -### `GET /accounts/me/devices` +### `GET /accounts/{id/me}/devices` +Admin User Return the user registered devices. -### `DELETE /accounts/me/devices/{uuid}` +### `DELETE /accounts/{id/me}/devices/{uuid}` +Admin User Remove one of the user registered devices. @@ -450,9 +452,10 @@ Return the user contacts. Return a user contact. -## Account vCards storage +## vCards storage -### `POST /accounts/me/vcards-storage` +### `POST /accounts/{id/me}/vcards-storage` +Admin User Store a vCard. @@ -461,7 +464,8 @@ JSON parameters: * `vcard`, mandatory, a valid vCard having a mandatory `UID` parameter that is uniquelly identifying it. This `UID` parameter will then be used to manipulate the vcard through the following endpoints as `uuid`. -### `PUT /accounts/me/vcards-storage/{uuid}` +### `PUT /accounts/{id/me}/vcards-storage/{uuid}` +Admin User Update a vCard. @@ -470,17 +474,20 @@ JSON parameters: * `vcard`, mandatory, a valid vCard having a mandatory `UID` parameter that is uniquelly identifying it and is the same as the `uuid` parameter. -### `GET /accounts/me/vcards-storage` +### `GET /accounts/{id/me}/vcards-storage` +Admin User Return the list of stored vCards -### `GET /accounts/me/vcards-storage/{uuid}` +### `GET /accounts/{id/me}/vcards-storage/{uuid}` +Admin User Return a stored vCard -### `DELETE /accounts/me/vcards-storage/{uuid}` +### `DELETE /accounts/{id/me}/vcards-storage/{uuid}` +Admin User Delete a stored vCard diff --git a/flexiapi/routes/api.php b/flexiapi/routes/api.php index fc158d3..776ad6f 100644 --- a/flexiapi/routes/api.php +++ b/flexiapi/routes/api.php @@ -24,6 +24,7 @@ use App\Http\Controllers\Api\Admin\AccountController as AdminAccountController; use App\Http\Controllers\Api\Admin\AccountDictionaryController; use App\Http\Controllers\Api\Admin\AccountTypeController; use App\Http\Controllers\Api\Admin\ContactsListController; +use App\Http\Controllers\Api\Admin\VcardsStorageController as AdminVcardsStorageController; use App\Http\Controllers\Api\StatisticsMessageController; use App\Http\Controllers\Api\StatisticsCallController; use Illuminate\Http\Request; @@ -108,6 +109,9 @@ Route::group(['middleware' => ['auth.jwt', 'auth.digest_or_key', 'auth.check_blo Route::get('{sip}/search', 'search'); Route::get('{email}/search-by-email', 'searchByEmail'); + Route::get('{account_id}/devices', 'Api\Admin\DeviceController@index'); + Route::delete('{account_id}/devices/{uuid}', 'Api\Admin\DeviceController@destroy'); + Route::post('{account_id}/types/{type_id}', 'typeAdd'); Route::delete('{account_id}/types/{type_id}', 'typeRemove'); @@ -125,6 +129,7 @@ Route::group(['middleware' => ['auth.jwt', 'auth.digest_or_key', 'auth.check_blo Route::apiResource('accounts/{id}/actions', AccountActionController::class); Route::apiResource('account_types', AccountTypeController::class); + Route::apiResource('accounts/{account_id}/vcards-storage', AdminVcardsStorageController::class); Route::apiResource('contacts_lists', ContactsListController::class); Route::prefix('contacts_lists')->controller(ContactsListController::class)->group(function () { diff --git a/flexiapi/tests/Feature/ApiAccountVcardsStorageTest.php b/flexiapi/tests/Feature/ApiAccountVcardsStorageTest.php index 8288574..7071c00 100644 --- a/flexiapi/tests/Feature/ApiAccountVcardsStorageTest.php +++ b/flexiapi/tests/Feature/ApiAccountVcardsStorageTest.php @@ -22,21 +22,26 @@ namespace Tests\Feature; use App\Account; use Tests\TestCase; -class ApiAccountVcardsStorageTest extends TestCase +class ApiVcardsStorageTest extends TestCase { protected $route = '/api/accounts/me/vcards-storage'; protected $method = 'POST'; - public function testCrud() + public function testAccountCrud() { + $admin = Account::factory()->admin()->create(); + $admin->generateApiKey(); + $account = Account::factory()->create(); $account->generateApiKey(); + $adminRoute = '/api/accounts/' . $account->id . '/vcards-storage'; + $uid = 'urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6'; $lastVcard = 'BEGIN:VCARD VERSION:4.0 -FN:Simone Perreault +FN:Jhonny English UID:' . $uid . ' END:VCARD '; @@ -47,6 +52,14 @@ VERSION:4.0 FN:Simone Perreault UID:' . $uid2 . ' END:VCARD +'; + $uid3 = 'urn:uuid:a5b33443-687c-4d19-bdd0-b30cf76bfc4d'; + $thirdVcard = +'BEGIN:VCARD +VERSION:4.0 +FN:Jean Jannot +UID:' . $uid3 . ' +END:VCARD '; // Missing vcard @@ -56,6 +69,13 @@ END:VCARD ]) ->assertJsonValidationErrors(['vcard']); + // Admin vcard + $this->keyAuthenticated($admin) + ->json($this->method, $adminRoute, [ + 'foo' => 'bar' + ]) + ->assertJsonValidationErrors(['vcard']); + // Missing UID $this->keyAuthenticated($account) ->json($this->method, $this->route, [ @@ -77,6 +97,12 @@ UID:' . $uid . ' END:VCARD' ])->assertStatus(200); + // Admin create + $this->keyAuthenticated($admin) + ->json($this->method, $adminRoute, [ + 'vcard' => $thirdVcard]) + ->assertStatus(200); + // Again... $this->keyAuthenticated($account) ->json($this->method, $this->route, [ @@ -101,6 +127,10 @@ END:VCARD' 'uuid' => $uid2 ]); + $this->assertDatabaseHas('vcards_storage', [ + 'uuid' => $uid3 + ]); + // Update $this->keyAuthenticated($account) ->json('PUT', $this->route . '/' . $uid, [ @@ -135,6 +165,14 @@ END:VCARD' 'vcard' => $lastVcard ]); + // Admin get + $this->keyAuthenticated($admin) + ->get($adminRoute . '/' . $uid) + ->assertStatus(200) + ->assertJson([ + 'vcard' => $lastVcard + ]); + // Vcard format endpoints /*$this->keyAuthenticated($account) ->get('vcards-storage')