From 8fd85c00d21d97e49abcf4af7735466b3dfa2b06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Jaussoin?= Date: Mon, 14 Sep 2020 16:41:47 +0200 Subject: [PATCH] Complete the documentation regarding how DotEnv configuration is handled Add a confirmation flow using a email when an account tries to change one --- README.md | 2 + flexiapi/.gitignore | 1 + flexiapi/README.md | 8 ++++ flexiapi/app/Account.php | 7 ++- flexiapi/app/EmailChanged.php | 16 +++++++ .../Controllers/Account/EmailController.php | 45 ++++++++++++++++--- flexiapi/app/Mail/ChangingEmail.php | 29 ++++++++++++ ...0_09_14_120448_add_email_changed_table.php | 24 ++++++++++ .../resources/views/account/email.blade.php | 2 +- .../views/mails/changing_email.blade.php | 24 ++++++++++ .../views/mails/changing_email_text.blade.php | 10 +++++ flexiapi/routes/web.php | 3 +- 12 files changed, 161 insertions(+), 10 deletions(-) create mode 100644 flexiapi/app/EmailChanged.php create mode 100644 flexiapi/app/Mail/ChangingEmail.php create mode 100644 flexiapi/database/migrations/2020_09_14_120448_add_email_changed_table.php create mode 100644 flexiapi/resources/views/mails/changing_email.blade.php create mode 100644 flexiapi/resources/views/mails/changing_email_text.blade.php diff --git a/README.md b/README.md index accc004..10cc7c2 100644 --- a/README.md +++ b/README.md @@ -111,6 +111,8 @@ php artisan migrate:rollback php artisan migrate ``` +This API is having it's own README file in the `flexiapi` directory. + ### 5. Packaging -------------------- To build a rpm package on centos7: diff --git a/flexiapi/.gitignore b/flexiapi/.gitignore index 0f7df0f..a928428 100644 --- a/flexiapi/.gitignore +++ b/flexiapi/.gitignore @@ -2,6 +2,7 @@ /public/hot /public/storage /storage/*.key +/storage/*.sqlite /vendor .env .env.backup diff --git a/flexiapi/README.md b/flexiapi/README.md index 091c971..54ea411 100644 --- a/flexiapi/README.md +++ b/flexiapi/README.md @@ -2,6 +2,14 @@ This tool connects to the Flexisip CLI interface and exposes several endpoints to request and manage it. +## DotEnv configuration + +FlexiAPI relies on [DotEnv](https://github.com/vlucas/phpdotenv) to be configured. This configuration can be accessed using the existing `.env` file that can be itself overwritten by an environnement variables. + +Thoses variables can then be set using Docker-Compose, a bash script or a web-server for example. + +If you're installing FlexiAPI from the RPM package you can find the configuration file at `/etc/flexisip-account-manager/flexiapi.env`. + ## Setup Clone the repository, install the dependencies and generate a key. diff --git a/flexiapi/app/Account.php b/flexiapi/app/Account.php index f1ba598..386d5af 100644 --- a/flexiapi/app/Account.php +++ b/flexiapi/app/Account.php @@ -25,7 +25,7 @@ use Illuminate\Foundation\Auth\User as Authenticatable; class Account extends Authenticatable { protected $connection = 'external'; - protected $with = ['passwords', 'admin']; + protected $with = ['passwords', 'admin', 'emailChanged']; protected $dates = ['creation_time']; public $timestamps = false; @@ -56,6 +56,11 @@ class Account extends Authenticatable return $this->hasOne('App\Admin'); } + public function emailChanged() + { + return $this->hasOne('App\EmailChanged'); + } + public function getIdentifierAttribute() { return $this->attributes['username'].'@'.$this->attributes['domain']; diff --git a/flexiapi/app/EmailChanged.php b/flexiapi/app/EmailChanged.php new file mode 100644 index 0000000..16aabfc --- /dev/null +++ b/flexiapi/app/EmailChanged.php @@ -0,0 +1,16 @@ +belongsTo('App\Account'); + } +} diff --git a/flexiapi/app/Http/Controllers/Account/EmailController.php b/flexiapi/app/Http/Controllers/Account/EmailController.php index 64b5302..a7cb917 100644 --- a/flexiapi/app/Http/Controllers/Account/EmailController.php +++ b/flexiapi/app/Http/Controllers/Account/EmailController.php @@ -2,11 +2,14 @@ namespace App\Http\Controllers\Account; -use App\Http\Controllers\Controller; use Illuminate\Http\Request; use Illuminate\Support\Facades\Mail; +use Illuminate\Support\Str; +use App\Http\Controllers\Controller; +use App\Mail\ChangingEmail; use App\Mail\ChangedEmail; +use App\EmailChanged; class EmailController extends Controller { @@ -17,18 +20,46 @@ class EmailController extends Controller ]); } - public function update(Request $request) + public function requestUpdate(Request $request) { $request->validate([ - 'email' => 'required|unique:external.accounts,email|different:email_current|confirmed|email', + 'email' => 'required|different:email_current|confirmed|email', ]); - $account = $request->user(); - $account->email = $request->get('email'); - $account->save(); + // Remove all the old requests + EmailChanged::where('account_id', $request->user()->id)->delete(); - Mail::to($account)->send(new ChangedEmail()); + // Create a new one + $emailChanged = new EmailChanged; + $emailChanged->new_email = $request->get('email'); + $emailChanged->hash = Str::random(16); + $emailChanged->account_id = $request->user()->id; + $emailChanged->save(); + $request->user()->refresh(); + + Mail::to($request->user())->send(new ChangingEmail($request->user())); + + $request->session()->flash('success', 'An email was sent with a confirmation link. Please click it to update your email address.'); return redirect()->route('account.panel'); } + + public function update(Request $request, string $hash) + { + $account = $request->user(); + + if ($account->emailChanged && $account->emailChanged->hash == $hash) { + $account->email = $account->emailChanged->new_email; + $account->save(); + + Mail::to($account)->send(new ChangedEmail()); + + $account->emailChanged->delete(); + + $request->session()->flash('success', 'Email successfully updated'); + return redirect()->route('account.panel'); + } + + abort(404); + } } diff --git a/flexiapi/app/Mail/ChangingEmail.php b/flexiapi/app/Mail/ChangingEmail.php new file mode 100644 index 0000000..57e50c4 --- /dev/null +++ b/flexiapi/app/Mail/ChangingEmail.php @@ -0,0 +1,29 @@ +_account = $account; + } + + public function build() + { + return $this->view('mails.changing_email') + ->text('mails.changing_email_text') + ->with(['account' => $this->_account]); + } +} diff --git a/flexiapi/database/migrations/2020_09_14_120448_add_email_changed_table.php b/flexiapi/database/migrations/2020_09_14_120448_add_email_changed_table.php new file mode 100644 index 0000000..24ee7b6 --- /dev/null +++ b/flexiapi/database/migrations/2020_09_14_120448_add_email_changed_table.php @@ -0,0 +1,24 @@ +create('email_changed', function (Blueprint $table) { + $table->bigIncrements('id'); + $table->integer('account_id')->unsigned()->unique(); + $table->string('new_email'); + $table->string('hash'); + $table->timestamps(); + }); + } + + public function down() + { + Schema::connection('local')->dropIfExists('email_changed'); + } +} diff --git a/flexiapi/resources/views/account/email.blade.php b/flexiapi/resources/views/account/email.blade.php index 699d654..6542b7b 100644 --- a/flexiapi/resources/views/account/email.blade.php +++ b/flexiapi/resources/views/account/email.blade.php @@ -10,7 +10,7 @@

No email yet

@endif -{!! Form::open(['route' => 'account.email.update']) !!} +{!! Form::open(['route' => 'account.email.request_update']) !!}
{!! Form::label('email', 'New email') !!} {!! Form::email('email', old('email'), ['class' => 'form-control', 'placeholder' => 'bob@example.net', 'required']) !!} diff --git a/flexiapi/resources/views/mails/changing_email.blade.php b/flexiapi/resources/views/mails/changing_email.blade.php new file mode 100644 index 0000000..e93db46 --- /dev/null +++ b/flexiapi/resources/views/mails/changing_email.blade.php @@ -0,0 +1,24 @@ + + + Changing your email address + + +

Hello,

+

+ You requested to change your email address from {{ $account->email }} to {{ $account->emailChanged->email }} on {{ config('app.name') }}. +

+

+ To confirm this change please click on the following link: + + {{ route('account.email.update', ['hash' => $account->emailChanged->hash]) }} + . +

+

+ If you are not at the origin of this change just ignore this message. +

+

+ Regards,
+ {{ config('mail.signature') }} +

+ + diff --git a/flexiapi/resources/views/mails/changing_email_text.blade.php b/flexiapi/resources/views/mails/changing_email_text.blade.php new file mode 100644 index 0000000..89457e0 --- /dev/null +++ b/flexiapi/resources/views/mails/changing_email_text.blade.php @@ -0,0 +1,10 @@ +Hello, + +You requested to change your email address from {{ $account->email }} to {{ $account->emailChanged->email }} on {{ config('app.name') }}. + +To confirm this change please click on the following link: {{ route('account.email.request_update', $account->emailChanged->hash) }}. + +If you are not at the origin of this change just ignore this message. + +Regards, +{{ config('mail.signature') }} \ No newline at end of file diff --git a/flexiapi/routes/web.php b/flexiapi/routes/web.php index c163b9e..9beed05 100644 --- a/flexiapi/routes/web.php +++ b/flexiapi/routes/web.php @@ -51,7 +51,8 @@ Route::group(['middleware' => 'auth'], function () { Route::delete('delete', 'AccountController@destroy')->name('account.destroy'); Route::get('email', 'Account\EmailController@show')->name('account.email'); - Route::post('email', 'Account\EmailController@update')->name('account.email.update'); + Route::post('email/request', 'Account\EmailController@requestUpdate')->name('account.email.request_update'); + Route::get('email/{hash}', 'Account\EmailController@update')->name('account.email.update'); Route::get('password', 'Account\PasswordController@show')->name('account.password'); Route::post('password', 'Account\PasswordController@update')->name('account.password.update');