From 75599dd5abd683b74ca5a75e3ad704c658a07722 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Jaussoin?= Date: Wed, 27 Mar 2024 16:22:01 +0000 Subject: [PATCH] Fix FLEXIAPI-155 Add a new accountServiceAccountUpdatedHook and accountServiceAccountDeletedHook --- CHANGELOG.md | 1 + flexiapi/app/Account.php | 21 ++- .../Controllers/Account/AccountController.php | 19 +-- .../Account/AuthTokenController.php | 4 - .../Account/AuthenticateController.php | 2 - .../Account/PasswordController.php | 2 - .../Admin/AccountAccountTypeController.php | 2 - .../Admin/AccountActionController.php | 4 - .../Admin/AccountContactController.php | 1 - .../Controllers/Admin/AccountController.php | 55 ++------ .../Api/Account/AccountController.php | 17 +-- .../Api/Admin/AccountController.php | 40 ++---- .../Account/Create/Api/AsAdminRequest.php | 42 ++++++ .../Requests/Account/Create/Api/Request.php | 25 ++++ .../Create/Request.php} | 16 +-- .../Account/Create/Web/AsAdminRequest.php | 34 +++++ .../Requests/Account/Create/Web/Request.php | 25 ++++ .../Account/Update/Api/AsAdminRequest.php | 38 ++++++ .../Update/Request.php} | 6 +- .../Account/Update/Web/AsAdminRequest.php | 34 +++++ flexiapi/app/Http/Requests/Api.php | 8 ++ flexiapi/app/Http/Requests/AsAdmin.php | 8 ++ ...CreateAccountWithoutUsernamePhoneCheck.php | 28 ---- flexiapi/app/Libraries/OvhSMS.php | 4 +- flexiapi/app/Services/AccountService.php | 127 +++++++++++++----- .../config/account_service_hooks.php.example | 26 ++++ .../views/admin/account/create_edit.blade.php | 1 - .../api/documentation_markdown.blade.php | 5 +- 28 files changed, 392 insertions(+), 203 deletions(-) create mode 100644 flexiapi/app/Http/Requests/Account/Create/Api/AsAdminRequest.php create mode 100644 flexiapi/app/Http/Requests/Account/Create/Api/Request.php rename flexiapi/app/Http/Requests/{CreateAccountRequest.php => Account/Create/Request.php} (79%) create mode 100644 flexiapi/app/Http/Requests/Account/Create/Web/AsAdminRequest.php create mode 100644 flexiapi/app/Http/Requests/Account/Create/Web/Request.php create mode 100644 flexiapi/app/Http/Requests/Account/Update/Api/AsAdminRequest.php rename flexiapi/app/Http/Requests/{UpdateAccountRequest.php => Account/Update/Request.php} (93%) create mode 100644 flexiapi/app/Http/Requests/Account/Update/Web/AsAdminRequest.php create mode 100644 flexiapi/app/Http/Requests/Api.php create mode 100644 flexiapi/app/Http/Requests/AsAdmin.php delete mode 100644 flexiapi/app/Http/Requests/CreateAccountWithoutUsernamePhoneCheck.php diff --git a/CHANGELOG.md b/CHANGELOG.md index c693f61..8a911e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ v1.5 ---- +- Fix FLEXIAPI-155 Add a new accountServiceAccountUpdatedHook and accountServiceAccountDeletedHook - Fix FLEXIAPI-153 Add phone and email to be changed in the Activity panel - Fix FLEXIAPI-151 Migrate to hCaptcha - Fix FLEXIAPI-150 Use the same account_id parameter for both API and Web routes diff --git a/flexiapi/app/Account.php b/flexiapi/app/Account.php index 2c6941a..f3f5c5e 100644 --- a/flexiapi/app/Account.php +++ b/flexiapi/app/Account.php @@ -120,11 +120,6 @@ class Account extends Authenticatable return $this->hasOne(ActivationExpiration::class); } - public function admin() - { - return $this->hasOne(Admin::class); - } - public function alias() { return $this->hasOne(Alias::class); @@ -430,13 +425,27 @@ class Account extends Authenticatable $this->save(); } - public function hasTombstone() + public function hasTombstone(): bool { return AccountTombstone::where('username', $this->attributes['username']) ->where('domain', $this->attributes['domain']) ->exists(); } + public function createTombstone(): bool + { + if (!$this->hasTombstone()) { + $tombstone = new AccountTombstone(); + $tombstone->username = $this->attributes['username']; + $tombstone->domain = $this->attributes['domain']; + $tombstone->save(); + + return true; + } + + return false; + } + public function failedRecentRecovery(): bool { $oneHourAgo = Carbon::now()->subHour(); diff --git a/flexiapi/app/Http/Controllers/Account/AccountController.php b/flexiapi/app/Http/Controllers/Account/AccountController.php index d5103de..db7c9c05 100644 --- a/flexiapi/app/Http/Controllers/Account/AccountController.php +++ b/flexiapi/app/Http/Controllers/Account/AccountController.php @@ -23,8 +23,7 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use App\Http\Controllers\Controller; -use App\AccountTombstone; -use App\Http\Requests\CreateAccountRequest; +use App\Http\Requests\Account\Create\Web\Request as WebRequest; use App\Services\AccountService; class AccountController extends Controller @@ -48,11 +47,9 @@ class AccountController extends Controller ]); } - public function store(CreateAccountRequest $request) + public function store(WebRequest $request) { - $request->validate(['h-captcha-response' => captchaConfigured() ? 'required|HCaptcha' : '']); - - $account = (new AccountService(api: false))->store($request); + $account = (new AccountService())->store($request); Auth::login($account); @@ -78,14 +75,10 @@ class AccountController extends Controller { $request->validate(['identifier' => 'required|same:identifier_confirm']); - if (!$request->user()->hasTombstone()) { - $tombstone = new AccountTombstone(); - $tombstone->username = $request->user()->username; - $tombstone->domain = $request->user()->domain; - $tombstone->save(); - } + $request->user()->createTombstone(); + + (new AccountService)->destroy($request, $request->user()->id); - $request->user()->delete(); Auth::logout(); return redirect()->route('account.login'); diff --git a/flexiapi/app/Http/Controllers/Account/AuthTokenController.php b/flexiapi/app/Http/Controllers/Account/AuthTokenController.php index 8cc55a8..d22be30 100644 --- a/flexiapi/app/Http/Controllers/Account/AuthTokenController.php +++ b/flexiapi/app/Http/Controllers/Account/AuthTokenController.php @@ -72,8 +72,6 @@ class AuthTokenController extends Controller $authToken->delete(); - $request->session()->flash('success', 'Successfully authenticated'); - return redirect()->route('account.dashboard'); } @@ -87,8 +85,6 @@ class AuthTokenController extends Controller if (!$authToken->account_id) { $authToken->account_id = $request->user()->id; $authToken->save(); - - $request->session()->flash('success', 'External device successfully authenticated'); } return redirect()->route('account.dashboard'); diff --git a/flexiapi/app/Http/Controllers/Account/AuthenticateController.php b/flexiapi/app/Http/Controllers/Account/AuthenticateController.php index 7c9d507..aa0b6ea 100644 --- a/flexiapi/app/Http/Controllers/Account/AuthenticateController.php +++ b/flexiapi/app/Http/Controllers/Account/AuthenticateController.php @@ -103,8 +103,6 @@ class AuthenticateController extends Controller $authToken->delete(); - $request->session()->flash('success', 'Successfully authenticated'); - return redirect()->route('account.dashboard'); } diff --git a/flexiapi/app/Http/Controllers/Account/PasswordController.php b/flexiapi/app/Http/Controllers/Account/PasswordController.php index c213bfc..506cf05 100644 --- a/flexiapi/app/Http/Controllers/Account/PasswordController.php +++ b/flexiapi/app/Http/Controllers/Account/PasswordController.php @@ -49,13 +49,11 @@ class PasswordController extends Controller if ($account->passwords()->count() > 0) { Log::channel('events')->info('Web: Password changed', ['id' => $account->identifier]); - $request->session()->flash('success', 'Password successfully changed'); return redirect()->route('account.dashboard'); } Log::channel('events')->info('Web: Password set for the first time', ['id' => $account->identifier]); - $request->session()->flash('success', 'Password successfully set. Your SIP account creation process is now finished.'); if (!empty($account->email)) { Mail::to($account)->send(new ConfirmedRegistration($account)); diff --git a/flexiapi/app/Http/Controllers/Admin/AccountAccountTypeController.php b/flexiapi/app/Http/Controllers/Admin/AccountAccountTypeController.php index b3c9982..b84ba61 100644 --- a/flexiapi/app/Http/Controllers/Admin/AccountAccountTypeController.php +++ b/flexiapi/app/Http/Controllers/Admin/AccountAccountTypeController.php @@ -53,7 +53,6 @@ class AccountAccountTypeController extends Controller $account->types()->detach($request->get('account_type_id')); $account->types()->attach($request->get('account_type_id')); - $request->session()->flash('success', 'Type successfully added'); Log::channel('events')->info('Web Admin: Account type attached', ['id' => $account->identifier, 'type_id' => $request->get('account_type_id')]); return redirect()->route('admin.account.edit', $account); @@ -65,7 +64,6 @@ class AccountAccountTypeController extends Controller $account->types()->detach($typeId); - $request->session()->flash('success', 'Type successfully removed'); Log::channel('events')->info('Web Admin: Account type detached', ['id' => $account->identifier, 'type_id' => $request->get('account_type_id')]); return redirect()->route('admin.account.edit', $account); diff --git a/flexiapi/app/Http/Controllers/Admin/AccountActionController.php b/flexiapi/app/Http/Controllers/Admin/AccountActionController.php index 60eb88e..f560831 100644 --- a/flexiapi/app/Http/Controllers/Admin/AccountActionController.php +++ b/flexiapi/app/Http/Controllers/Admin/AccountActionController.php @@ -54,7 +54,6 @@ class AccountActionController extends Controller $accountAction->code = $request->get('code'); $accountAction->save(); - $request->session()->flash('success', 'Action successfully created'); Log::channel('events')->info('Web Admin: Account action created', ['id' => $account->identifier, 'action' => $accountAction->key]); return redirect()->route('admin.account.edit', $accountAction->account); @@ -90,7 +89,6 @@ class AccountActionController extends Controller $accountAction->code = $request->get('code'); $accountAction->save(); - $request->session()->flash('success', 'Action successfully updated'); Log::channel('events')->info('Web Admin: Account action updated', ['id' => $account->identifier, 'action' => $accountAction->key]); return redirect()->route('admin.account.edit', $account); @@ -116,8 +114,6 @@ class AccountActionController extends Controller ->firstOrFail(); $accountAction->delete(); - $request->session()->flash('success', 'Action successfully destroyed'); - Log::channel('events')->info('Web Admin: Account action deleted', ['id' => $accountAction->account->identifier, 'action_id' => $accountAction->key]); return redirect()->route('admin.account.edit', $accountAction->account); diff --git a/flexiapi/app/Http/Controllers/Admin/AccountContactController.php b/flexiapi/app/Http/Controllers/Admin/AccountContactController.php index 20615da..f79f39e 100644 --- a/flexiapi/app/Http/Controllers/Admin/AccountContactController.php +++ b/flexiapi/app/Http/Controllers/Admin/AccountContactController.php @@ -77,7 +77,6 @@ class AccountContactController extends Controller $account->contacts()->detach($contact->id); - $request->session()->flash('success', 'Type successfully removed'); Log::channel('events')->info('Web Admin: Account contact removed', ['id' => $account->identifier, 'contact' => $contact->identifier]); return redirect()->route('admin.account.edit', $account); diff --git a/flexiapi/app/Http/Controllers/Admin/AccountController.php b/flexiapi/app/Http/Controllers/Admin/AccountController.php index 97f915b..562a0e7 100644 --- a/flexiapi/app/Http/Controllers/Admin/AccountController.php +++ b/flexiapi/app/Http/Controllers/Admin/AccountController.php @@ -22,12 +22,13 @@ namespace App\Http\Controllers\Admin; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use Illuminate\Support\Facades\Log; -use Carbon\Carbon; use App\Account; use App\ContactsList; -use App\Http\Requests\CreateAccountWithoutUsernamePhoneCheck; +use App\Http\Requests\Account\Create\Web\AsAdminRequest; +use App\Http\Requests\Account\Update\Web\AsAdminRequest as WebAsAdminRequest; use App\Http\Requests\UpdateAccountRequest; +use App\Services\AccountService; class AccountController extends Controller { @@ -79,30 +80,9 @@ class AccountController extends Controller ]); } - public function store(CreateAccountWithoutUsernamePhoneCheck $request) + public function store(AsAdminRequest $request) { - $request->validate([ - 'password' => 'confirmed' - ]); - - $account = new Account; - $account->username = $request->get('username'); - $account->email = $request->get('email'); - $account->display_name = $request->get('display_name'); - $account->domain = resolveDomain($request); - $account->ip_address = $request->ip(); - $account->created_at = Carbon::now(); - $account->user_agent = config('app.name'); - $account->dtmf_protocol = $request->get('dtmf_protocol'); - $account->activated = $request->get('activated') == 'true'; - $account->blocked = $request->get('blocked') == 'true'; - $account->save(); - - $account->phone = $request->get('phone'); - $account->updatePassword($request->get('password')); - - $account->refresh(); - $account->setRole($request->get('role')); + $account = (new AccountService)->store($request); Log::channel('events')->info('Web Admin: Account created', ['id' => $account->identifier]); @@ -122,27 +102,9 @@ class AccountController extends Controller ]); } - public function update(UpdateAccountRequest $request, $id) + public function update(WebAsAdminRequest $request, int $id) { - $request->validate([ - 'password' => 'confirmed', - ]); - - $account = Account::findOrFail($id); - $account->email = $request->get('email'); - $account->display_name = $request->get('display_name'); - $account->dtmf_protocol = $request->get('dtmf_protocol'); - $account->activated = $request->get('activated') == 'true'; - $account->blocked = $request->get('blocked') == 'true'; - $account->save(); - - $account->phone = $request->get('phone'); - - if ($request->get('password')) { - $account->updatePassword($request->get('password')); - } - - $account->setRole($request->get('role')); + $account = (new AccountService)->update($request, $id); Log::channel('events')->info('Web Admin: Account updated', ['id' => $account->identifier]); @@ -172,9 +134,8 @@ class AccountController extends Controller public function destroy(Request $request) { $account = Account::findOrFail($request->get('account_id')); - $account->delete(); - $request->session()->flash('success', 'Account successfully destroyed'); + (new AccountService)->destroy($request, $request->get('account_id')); Log::channel('events')->info('Web Admin: Account deleted', ['id' => $account->identifier]); diff --git a/flexiapi/app/Http/Controllers/Api/Account/AccountController.php b/flexiapi/app/Http/Controllers/Api/Account/AccountController.php index a27a305..ad41366 100644 --- a/flexiapi/app/Http/Controllers/Api/Account/AccountController.php +++ b/flexiapi/app/Http/Controllers/Api/Account/AccountController.php @@ -29,11 +29,10 @@ use Carbon\Carbon; use App\Account; use App\AccountCreationToken; -use App\AccountTombstone; use App\Alias; use App\Http\Controllers\Account\AuthenticateController as WebAuthenticateController; -use App\Http\Requests\CreateAccountRequest; +use App\Http\Requests\Account\Create\Api\Request as ApiRequest; use App\Libraries\OvhSMS; use App\Mail\RegisterConfirmation; @@ -251,7 +250,7 @@ class AccountController extends Controller return $account; } - public function store(CreateAccountRequest $request) + public function store(ApiRequest $request) { return (new AccountService)->store($request); } @@ -334,14 +333,10 @@ class AccountController extends Controller public function delete(Request $request) { - if (!$request->user()->hasTombstone()) { - $tombstone = new AccountTombstone; - $tombstone->username = $request->user()->username; - $tombstone->domain = $request->user()->domain; - $tombstone->save(); - } + $request->user()->createTombstone(); - return Account::where('id', $request->user()->id) - ->delete(); + (new AccountService)->destroy($request, $request->user()->id); + + return true; } } diff --git a/flexiapi/app/Http/Controllers/Api/Admin/AccountController.php b/flexiapi/app/Http/Controllers/Api/Admin/AccountController.php index 5003e28..f4a6259 100644 --- a/flexiapi/app/Http/Controllers/Api/Admin/AccountController.php +++ b/flexiapi/app/Http/Controllers/Api/Admin/AccountController.php @@ -27,10 +27,8 @@ use App\Account; use App\AccountTombstone; use App\AccountType; use App\ContactsList; -use App\Http\Requests\CreateAccountRequest; -use App\Http\Requests\CreateAccountWithoutUsernamePhoneCheck; -use App\Http\Requests\UpdateAccountRequest; -use App\Rules\PasswordAlgorithm; +use App\Http\Requests\Account\Create\Api\AsAdminRequest; +use App\Http\Requests\Account\Update\Api\AsAdminRequest as ApiAsAdminRequest; use App\Services\AccountService; class AccountController extends Controller @@ -55,7 +53,7 @@ class AccountController extends Controller return Account::where('email', $email)->firstOrFail(); } - public function destroy($accountId) + public function destroy(Request $request, int $accountId) { $account = Account::findOrFail($accountId); @@ -66,9 +64,9 @@ class AccountController extends Controller $tombstone->save(); } - Log::channel('events')->info('API Admin: Account destroyed', ['id' => $account->identifier]); + (new AccountService)->destroy($request, $accountId); - $account->delete(); + Log::channel('events')->info('API Admin: Account destroyed', ['id' => $account->identifier]); } public function activate(int $accountId) @@ -126,34 +124,14 @@ class AccountController extends Controller return $account->makeVisible(['provisioning_token']); } - public function store(CreateAccountWithoutUsernamePhoneCheck $request) + public function store(AsAdminRequest $request) { - return (new AccountService)->store($request, asAdmin: true)->makeVisible(['confirmation_key', 'provisioning_token']); + return (new AccountService)->store($request)->makeVisible(['confirmation_key', 'provisioning_token']); } - public function update(UpdateAccountRequest $request, int $accountId) + public function update(ApiAsAdminRequest $request, int $accountId) { - $request->validate([ - 'algorithm' => ['required', new PasswordAlgorithm], - 'admin' => 'boolean|nullable', - 'activated' => 'boolean|nullable' - ]); - - $account = Account::findOrFail($accountId); - $account->username = $request->get('username'); - $account->email = $request->get('email'); - $account->display_name = $request->get('display_name'); - $account->dtmf_protocol = $request->get('dtmf_protocol'); - $account->domain = resolveDomain($request); - $account->user_agent = $request->header('User-Agent') ?? config('app.name'); - $account->admin = $request->has('admin') && (bool)$request->get('admin'); - $account->save(); - - $account->updatePassword($request->get('password'), $request->get('algorithm')); - $account->phone = $request->get('phone'); - - // Full reload - $account = Account::withoutGlobalScopes()->find($account->id); + $account = (new AccountService)->update($request, $accountId); Log::channel('events')->info('API Admin: Account updated', ['id' => $account->identifier]); diff --git a/flexiapi/app/Http/Requests/Account/Create/Api/AsAdminRequest.php b/flexiapi/app/Http/Requests/Account/Create/Api/AsAdminRequest.php new file mode 100644 index 0000000..c036f7d --- /dev/null +++ b/flexiapi/app/Http/Requests/Account/Create/Api/AsAdminRequest.php @@ -0,0 +1,42 @@ + [ 'required', - new NoUppercase, - new IsNotPhoneNumber, - new BlacklistedUsername, - new SIPUsername, + new NoUppercase(), + new IsNotPhoneNumber(), + new BlacklistedUsername(), + new SIPUsername(), Rule::unique('accounts', 'username')->where(function ($query) { $query->where('domain', resolveDomain($this)); }), @@ -37,7 +37,7 @@ class CreateAccountRequest extends FormRequest }), 'filled', ], - 'dictionary' => [new Dictionary], + 'dictionary' => [new Dictionary()], 'password' => 'required|min:3', 'email' => config('app.account_email_unique') ? 'nullable|email|unique:accounts,email' @@ -47,7 +47,7 @@ class CreateAccountRequest extends FormRequest 'nullable', 'unique:aliases,alias', 'unique:accounts,username', - new WithoutSpaces, 'starts_with:+' + new WithoutSpaces(), 'starts_with:+' ] ]; } diff --git a/flexiapi/app/Http/Requests/Account/Create/Web/AsAdminRequest.php b/flexiapi/app/Http/Requests/Account/Create/Web/AsAdminRequest.php new file mode 100644 index 0000000..f340b12 --- /dev/null +++ b/flexiapi/app/Http/Requests/Account/Create/Web/AsAdminRequest.php @@ -0,0 +1,34 @@ +where(function ($query) { $query->where('domain', resolveDomain($this)); })->ignore($this->route('id'), 'id'), - Rule::unique('aliases', 'alias')->ignore($this->route('id'), 'account_id'), + Rule::unique('aliases', 'alias')->ignore($this->route('account_id'), 'account_id'), new WithoutSpaces, 'starts_with:+' ] ]; diff --git a/flexiapi/app/Http/Requests/Account/Update/Web/AsAdminRequest.php b/flexiapi/app/Http/Requests/Account/Update/Web/AsAdminRequest.php new file mode 100644 index 0000000..035fc1d --- /dev/null +++ b/flexiapi/app/Http/Requests/Account/Update/Web/AsAdminRequest.php @@ -0,0 +1,34 @@ +smsService = $smsServices[0]; } - } catch (\GuzzleHttp\Exception\ClientException $e) { + } catch (\Exception $e) { Log::channel('events')->info('OVH SMS API unreachable, check the errors log'); Log::error('OVH SMS API not reachable: ' . $e->getMessage()); } @@ -79,7 +79,7 @@ class OvhSMS // One credit removed $this->api->get('/sms/'. $this->smsService . '/jobs'); - } catch (\GuzzleHttp\Exception\ClientException $e) { + } catch (\Exception $e) { Log::channel('events')->info('OVH SMS not sent, check the errors log'); Log::error('OVH SMS not sent: ' . $e->getMessage()); } diff --git a/flexiapi/app/Services/AccountService.php b/flexiapi/app/Services/AccountService.php index 23cab19..1184caf 100644 --- a/flexiapi/app/Services/AccountService.php +++ b/flexiapi/app/Services/AccountService.php @@ -24,8 +24,9 @@ use App\AccountCreationToken; use App\ActivationExpiration; use App\Alias; use App\EmailChangeCode; -use App\Http\Requests\CreateAccountRequest; use App\Http\Controllers\Account\AuthenticateController as WebAuthenticateController; +use App\Http\Requests\Account\Create\Request as CreateRequest; +use App\Http\Requests\Account\Update\Request as UpdateRequest; use App\Libraries\OvhSMS; use App\Mail\NewsletterRegistration; use App\Mail\RecoverByCode; @@ -33,8 +34,6 @@ use App\Mail\RegisterValidation; use App\PhoneChangeCode; use Illuminate\Support\Facades\Log; -use App\Rules\AccountCreationToken as RulesAccountCreationToken; -use App\Rules\PasswordAlgorithm; use App\Rules\WithoutSpaces; use Carbon\Carbon; use Illuminate\Support\Facades\Mail; @@ -57,33 +56,8 @@ class AccountService /** * Account creation */ - public function store(CreateAccountRequest $request, bool $asAdmin = false): Account + public function store(CreateRequest $request): Account { - $rules = []; - $rules['password'] = 'confirmed'; - $rules['email'] = 'confirmed'; - $rules['terms'] = 'accepted'; - - if ($this->api) { - $rules = []; - $rules['account_creation_token'] = ['required', new RulesAccountCreationToken()]; - - if ($asAdmin) { - $rules = []; - $rules['algorithm'] = ['required', new PasswordAlgorithm()]; - $rules['admin'] = 'boolean|nullable'; - $rules['activated'] = 'boolean|nullable'; - $rules['confirmation_key_expires'] = [ - 'date_format:Y-m-d H:i:s', - 'nullable', - ]; - } - } - - - - $request->validate($rules); - $account = new Account(); $account->username = $request->get('username'); $account->activated = false; @@ -93,7 +67,7 @@ class AccountService $account->user_agent = config('app.name'); $account->dtmf_protocol = $request->get('dtmf_protocol'); - if ($asAdmin) { + if ($request->asAdmin) { $account->email = $request->get('email'); $account->display_name = $request->get('display_name'); $account->activated = $request->has('activated') ? (bool)$request->get('activated') : false; @@ -108,7 +82,7 @@ class AccountService $account->save(); - if ($asAdmin) { + if ($request->asAdmin) { if ((!$request->has('activated') || !(bool)$request->get('activated')) && $request->has('confirmation_key_expires')) { $actionvationExpiration = new ActivationExpiration(); @@ -128,18 +102,23 @@ class AccountService $account->updatePassword($request->get('password'), $request->get('algorithm')); - if ($this->api && !$asAdmin) { + if ($request->api && !$request->asAdmin) { $token = AccountCreationToken::where('token', $request->get('account_creation_token'))->first(); $token->consume(); $token->account_id = $account->id; $token->save(); + + Log::channel('events')->info('API: AccountCreationToken redeemed', ['token' => $request->get('account_creation_token')]); } - Log::channel('events')->info('API: AccountCreationToken redeemed', ['token' => $request->get('account_creation_token')]); + Log::channel('events')->info( + $request->asAdmin + ? 'Account Service as Admin: Account created' + : 'Account Service: Account created', + ['id' => $account->identifier] + ); - Log::channel('events')->info($asAdmin ? 'Account Service as Admin: Account created' : 'Account Service: Account created', ['id' => $account->identifier]); - - if (!$this->api) { + if (!$request->api) { if (!empty(config('app.newsletter_registration_address')) && $request->has('newsletter')) { Mail::to(config('app.newsletter_registration_address'))->send(new NewsletterRegistration($account)); } @@ -152,6 +131,82 @@ class AccountService return Account::withoutGlobalScopes()->find($account->id); } + /** + * Account update + */ + public function update(UpdateRequest $request, int $accountId): ?Account + { + $account = Account::findOrFail($accountId); + + if ($request->asAdmin) { + $account->username = $request->get('username') ?? $account->username; + $account->domain = $request->has('domain') ? resolveDomain($request) : $account->domain; + $account->email = $request->get('email'); + $account->display_name = $request->get('display_name'); + $account->dtmf_protocol = $request->get('dtmf_protocol'); + $account->user_agent = $request->header('User-Agent') ?? config('app.name'); + $account->admin = $request->has('admin') && (bool)$request->get('admin'); + + if ($request->api && $request->has('admin')) { + $account->admin = (bool)$request->get('admin'); + } + + if (!$request->api && $request->has('role')) { + $account->setRole($request->get('role')); + } + + if (!$request->api && $request->has('activated')) { + $account->activated = $request->get('activated') == 'true'; + } + + if (!$request->api && $request->has('blocked')) { + $account->blocked = $request->get('blocked') == 'true'; + } + + if ($request->get('password')) { + $account->updatePassword( + $request->get('password'), + $request->api ? $request->get('algorithm') : null + ); + } + + $account->save(); + + $account->phone = $request->get('phone'); + } + + Log::channel('events')->info( + $request->asAdmin + ? 'Account Service as Admin: Account updated' + : 'Account Service: Account updated', + ['id' => $account->identifier] + ); + + if (function_exists('accountServiceAccountEditedHook')) { + accountServiceAccountEditedHook($request, $account); + } + + return Account::withoutGlobalScopes()->find($account->id); + } + + /** + * Account destroy + */ + public function destroy(Request $request, int $accountId) + { + $account = Account::findOrFail($accountId); + $account->delete(); + + Log::channel('events')->info( + 'Account Service: Account destroyed', + ['id' => $account->identifier] + ); + + if (function_exists('accountServiceAccountDestroyedHook')) { + accountServiceAccountDestroyedHook($request, $account); + } + } + /** * Link a phone number to an account */ diff --git a/flexiapi/config/account_service_hooks.php.example b/flexiapi/config/account_service_hooks.php.example index 19273d5..835a8fa 100644 --- a/flexiapi/config/account_service_hooks.php.example +++ b/flexiapi/config/account_service_hooks.php.example @@ -18,5 +18,31 @@ function accountServiceAccountCreatedHook(Request $request, Account $account) { /* + */ +} + + /** + * @brief Run specific code if an account was edited + * @param Request $request + * @param Account $account + * @return void + */ +function accountServiceAccountEditedHook(Request $request, Account $account) +{ + /* + + */ +} + + /** + * @brief Run specific code if an account was destroed + * @param Request $request + * @param Account $account + * @return void + */ +function accountServiceAccountDestroyedHook(Request $request, Account $account) +{ + /* + */ } \ No newline at end of file diff --git a/flexiapi/resources/views/admin/account/create_edit.blade.php b/flexiapi/resources/views/admin/account/create_edit.blade.php index dbc4633..4adb9b2 100644 --- a/flexiapi/resources/views/admin/account/create_edit.blade.php +++ b/flexiapi/resources/views/admin/account/create_edit.blade.php @@ -255,5 +255,4 @@ Add @endif @endif - @endsection diff --git a/flexiapi/resources/views/api/documentation_markdown.blade.php b/flexiapi/resources/views/api/documentation_markdown.blade.php index fcd6a90..97997c6 100644 --- a/flexiapi/resources/views/api/documentation_markdown.blade.php +++ b/flexiapi/resources/views/api/documentation_markdown.blade.php @@ -310,16 +310,17 @@ JSON parameters: ### `PUT /accounts/{id}` Admin -Update an existing account. +Update an existing account. Ensure to resend all the parameters to not reset them. JSON parameters: * `username` unique username, minimum 6 characters +* `domain` **not configurable by default**. Only configurable if `APP_ADMINS_MANAGE_MULTI_DOMAINS` is set to `true` in the global configuration. Otherwise `APP_SIP_DOMAIN` is used. * `password` required minimum 6 characters * `algorithm` required, values can be `SHA-256` or `MD5` * `display_name` optional, string * `email` optional, must be an email, must be unique if `ACCOUNT_EMAIL_UNIQUE` is set to `true` -* `admin` optional, a boolean, set to `false` by default, create an admin account +* `admin` optional, a boolean, set to `false` by default * `phone` optional, a phone number, set a phone number to the account * `dtmf_protocol` optional, values must be `sipinfo`, `sipmessage` or `rfc2833`