mirror of
https://gitlab.linphone.org/BC/public/flexisip-account-manager.git
synced 2026-01-17 10:08:05 +00:00
Fix FLEXIAPI-177 Complete vcards-storage and devices related endpoints with their User/Admin ones
This commit is contained in:
parent
c930859c6a
commit
b44d6e1b25
7 changed files with 180 additions and 52 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
41
flexiapi/app/Http/Controllers/Api/Admin/DeviceController.php
Normal file
41
flexiapi/app/Http/Controllers/Api/Admin/DeviceController.php
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
/*
|
||||
Flexisip Account Manager is a set of tools to manage SIP accounts.
|
||||
Copyright (C) 2020 Belledonne Communications SARL, All rights reserved.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\Admin;
|
||||
|
||||
use App\Account;
|
||||
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(int $accountId)
|
||||
{
|
||||
return Account::findOrFail($accountId)->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();
|
||||
}
|
||||
}
|
||||
|
|
@ -428,12 +428,14 @@ Return the updated account.
|
|||
|
||||
## Accounts devices
|
||||
|
||||
### `GET /accounts/me/devices`
|
||||
### `GET /accounts/{id/me}/devices`
|
||||
<span class="badge badge-warning">Admin</span>
|
||||
<span class="badge badge-info">User</span>
|
||||
|
||||
Return the user registered devices.
|
||||
|
||||
### `DELETE /accounts/me/devices/{uuid}`
|
||||
### `DELETE /accounts/{id/me}/devices/{uuid}`
|
||||
<span class="badge badge-warning">Admin</span>
|
||||
<span class="badge badge-info">User</span>
|
||||
|
||||
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`
|
||||
<span class="badge badge-warning">Admin</span>
|
||||
<span class="badge badge-info">User</span>
|
||||
|
||||
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}`
|
||||
<span class="badge badge-warning">Admin</span>
|
||||
<span class="badge badge-info">User</span>
|
||||
|
||||
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`
|
||||
<span class="badge badge-warning">Admin</span>
|
||||
<span class="badge badge-info">User</span>
|
||||
|
||||
Return the list of stored vCards
|
||||
|
||||
### `GET /accounts/me/vcards-storage/{uuid}`
|
||||
### `GET /accounts/{id/me}/vcards-storage/{uuid}`
|
||||
<span class="badge badge-warning">Admin</span>
|
||||
<span class="badge badge-info">User</span>
|
||||
|
||||
Return a stored vCard
|
||||
|
||||
### `DELETE /accounts/me/vcards-storage/{uuid}`
|
||||
### `DELETE /accounts/{id/me}/vcards-storage/{uuid}`
|
||||
<span class="badge badge-warning">Admin</span>
|
||||
<span class="badge badge-info">User</span>
|
||||
|
||||
Delete a stored vCard
|
||||
|
|
|
|||
|
|
@ -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 () {
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue