From f3ba51682fdb65458e989a489de452323a699d12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Jaussoin?= Date: Mon, 20 Apr 2020 17:23:58 +0200 Subject: [PATCH] Complete email + SMS authentication Also send an email when the email was changed --- flexiapi/.env.example | 13 + .../Http/Controllers/AccountController.php | 8 +- .../Controllers/AccountEmailController.php | 9 +- flexiapi/app/Libraries/OvhSMS.php | 62 ++++ flexiapi/app/Mail/ChangedEmail.php | 21 ++ flexiapi/app/Mail/PasswordAuthentication.php | 41 +++ flexiapi/composer.json | 1 + flexiapi/composer.lock | 316 +++++++++++++++++- flexiapi/config/ovh.php | 8 + .../resources/views/layouts/account.blade.php | 2 +- .../resources/views/layouts/base.blade.php | 2 +- .../resources/views/layouts/main.blade.php | 2 +- .../views/mails/authentication.blade.php | 19 ++ .../views/mails/authentication_text.blade.php | 9 + .../views/mails/changed_email.blade.php | 15 + .../views/mails/changed_email_text.blade.php | 6 + 16 files changed, 525 insertions(+), 9 deletions(-) create mode 100644 flexiapi/app/Libraries/OvhSMS.php create mode 100644 flexiapi/app/Mail/ChangedEmail.php create mode 100644 flexiapi/app/Mail/PasswordAuthentication.php create mode 100644 flexiapi/config/ovh.php create mode 100644 flexiapi/resources/views/mails/authentication.blade.php create mode 100644 flexiapi/resources/views/mails/authentication_text.blade.php create mode 100644 flexiapi/resources/views/mails/changed_email.blade.php create mode 100644 flexiapi/resources/views/mails/changed_email_text.blade.php diff --git a/flexiapi/.env.example b/flexiapi/.env.example index bce68b9..445afd8 100644 --- a/flexiapi/.env.example +++ b/flexiapi/.env.example @@ -20,3 +20,16 @@ CACHE_DRIVER=file QUEUE_CONNECTION=sync SESSION_DRIVER=cookie SESSION_LIFETIME=120 + +MAIL_DRIVER= +MAIL_HOST= +MAIL_PORT=2525 +MAIL_USERNAME= +MAIL_PASSWORD= +MAIL_FROM_ADDRESS= +MAIL_FROM_NAME= + +OVH_APP_KEY= +OVH_APP_SECRET= +OVH_APP_ENDPOINT=ovh-eu +OVH_APP_CONSUMER_KEY= diff --git a/flexiapi/app/Http/Controllers/AccountController.php b/flexiapi/app/Http/Controllers/AccountController.php index 84d991d..7204657 100644 --- a/flexiapi/app/Http/Controllers/AccountController.php +++ b/flexiapi/app/Http/Controllers/AccountController.php @@ -5,10 +5,13 @@ namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Str; +use Illuminate\Support\Facades\Mail; use App\Account; use App\Rules\SIP; use App\Helpers\Utils; +use App\Libraries\OvhSMS; +use App\Mail\PasswordAuthentication; class AccountController extends Controller { @@ -83,7 +86,7 @@ class AccountController extends Controller $account->confirmation_key = Str::random($this->emailCodeSize); $account->save(); - // TODO send email + Mail::to($account)->send(new PasswordAuthentication($account)); return view('account.authenticate_email', [ 'account' => $account @@ -125,7 +128,8 @@ class AccountController extends Controller $account->confirmation_key = mt_rand(1000, 9999); $account->save(); - // TODO send SMS + $ovhSMS = new OvhSMS; + $ovhSMS->send($request->get('phone'), 'Your Linphone validation code is '.$account->confirmation_key); return view('account.authenticate_phone', [ 'account' => $account diff --git a/flexiapi/app/Http/Controllers/AccountEmailController.php b/flexiapi/app/Http/Controllers/AccountEmailController.php index b181cd7..cf0665f 100644 --- a/flexiapi/app/Http/Controllers/AccountEmailController.php +++ b/flexiapi/app/Http/Controllers/AccountEmailController.php @@ -3,6 +3,9 @@ namespace App\Http\Controllers; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Mail; + +use App\Mail\ChangedEmail; class AccountEmailController extends Controller { @@ -15,16 +18,16 @@ class AccountEmailController extends Controller public function update(Request $request) { - // TODO exists doesn't already exists $request->validate([ - 'email' => 'required|email', - 'email_confirm' => 'required|same:email' + 'email' => 'required|confirmed|email|unique:external.accounts,email', ]); $account = $request->user(); $account->email = $request->get('email'); $account->save(); + Mail::to($account)->send(new ChangedEmail()); + return redirect()->route('account.index'); } } diff --git a/flexiapi/app/Libraries/OvhSMS.php b/flexiapi/app/Libraries/OvhSMS.php new file mode 100644 index 0000000..f89f5a1 --- /dev/null +++ b/flexiapi/app/Libraries/OvhSMS.php @@ -0,0 +1,62 @@ +. +*/ + +namespace App\Libraries; + +use App\Device; +use Ovh\Api; + +class OvhSMS +{ + private $_api; + private $_smsService; + + public function __construct() + { + $this->_api = new Api( + config('ovh.app_key'), + config('ovh.app_secret'), + config('ovh.app_endpoint'), + config('ovh.app_consumer_key') + ); + + $smsServices = $this->_api->get('/sms/'); + if (!empty($smsServices)) $this->_smsService = $smsServices[0]; + } + + public function send(string $to, string $message) + { + $content = (object) [ + 'charset' => 'UTF-8', + 'class' => 'phoneDisplay', + 'coding' => '7bit', + 'message' => $message, + 'noStopClause' => false, + 'priority' => 'high', + 'receivers' => [ $to ], + 'senderForResponse' => true, + 'validityPeriod' => 2880 + ]; + + $resultPostJob = $this->_api->post('/sms/'. $this->_smsService . '/jobs', $content); + // One credit removed + + $smsJobs = $this->_api->get('/sms/'. $this->_smsService . '/jobs'); + } +} \ No newline at end of file diff --git a/flexiapi/app/Mail/ChangedEmail.php b/flexiapi/app/Mail/ChangedEmail.php new file mode 100644 index 0000000..bcd56c7 --- /dev/null +++ b/flexiapi/app/Mail/ChangedEmail.php @@ -0,0 +1,21 @@ +view('mails.changed_email') + ->text('mails.changed_email_text'); + } +} diff --git a/flexiapi/app/Mail/PasswordAuthentication.php b/flexiapi/app/Mail/PasswordAuthentication.php new file mode 100644 index 0000000..d459a1c --- /dev/null +++ b/flexiapi/app/Mail/PasswordAuthentication.php @@ -0,0 +1,41 @@ +_account = $account; + } + + /** + * Build the message. + * + * @return $this + */ + public function build() + { + return $this->view('mails.authentication') + ->text('mails.authentication_text') + ->with([ + 'link' => route('account.authenticate_email_confirm', [$this->_account->confirmation_key]) + ]); + } +} diff --git a/flexiapi/composer.json b/flexiapi/composer.json index 2d3e593..a760434 100644 --- a/flexiapi/composer.json +++ b/flexiapi/composer.json @@ -13,6 +13,7 @@ "laravel/framework": "^6.2", "laravel/tinker": "^2.0", "laravelcollective/html": "^6.1", + "ovh/ovh": "^2.0", "propaganistas/laravel-phone": "^4.2" }, "require-dev": { diff --git a/flexiapi/composer.lock b/flexiapi/composer.lock index db55f47..40380bb 100644 --- a/flexiapi/composer.lock +++ b/flexiapi/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "1188abce9cc741a1318f4f7db580e86f", + "content-hash": "06757402a3ada8adde19707d8311f9f1", "packages": [ { "name": "dnoegel/php-xdg-base-dir", @@ -451,6 +451,195 @@ "description": "Locale functions required by libphonenumber-for-php", "time": "2019-10-09T18:53:14+00:00" }, + { + "name": "guzzlehttp/guzzle", + "version": "6.5.3", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "aab4ebd862aa7d04f01a4b51849d657db56d882e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/aab4ebd862aa7d04f01a4b51849d657db56d882e", + "reference": "aab4ebd862aa7d04f01a4b51849d657db56d882e", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.0", + "guzzlehttp/psr7": "^1.6.1", + "php": ">=5.5", + "symfony/polyfill-intl-idn": "^1.11" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", + "psr/log": "^1.1" + }, + "suggest": { + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.5-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "time": "2020-04-18T10:38:46+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "v1.3.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "shasum": "" + }, + "require": { + "php": ">=5.5.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "time": "2016-12-20T10:07:11+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "1.6.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "239400de7a173fe9901b9ac7c06497751f00727a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/239400de7a173fe9901b9ac7c06497751f00727a", + "reference": "239400de7a173fe9901b9ac7c06497751f00727a", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0", + "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "ext-zlib": "*", + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8" + }, + "suggest": { + "zendframework/zend-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Schultze", + "homepage": "https://github.com/Tobion" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "time": "2019-07-01T23:21:34+00:00" + }, { "name": "laravel/framework", "version": "v6.18.5", @@ -1236,6 +1425,41 @@ ], "time": "2019-11-29T22:36:02+00:00" }, + { + "name": "ovh/ovh", + "version": "v2.0.1", + "source": { + "type": "git", + "url": "https://github.com/ovh/php-ovh.git", + "reference": "25a97501a150dff8a7848c372b5826395aab4df2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ovh/php-ovh/zipball/25a97501a150dff8a7848c372b5826395aab4df2", + "reference": "25a97501a150dff8a7848c372b5826395aab4df2", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "^6.0" + }, + "require-dev": { + "phpdocumentor/phpdocumentor": "2.*", + "phpunit/phpunit": "4.*", + "squizlabs/php_codesniffer": "1.*" + }, + "type": "library", + "autoload": { + "psr-4": { + "Ovh\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Wrapper for OVH APIs", + "time": "2016-02-10T13:16:38+00:00" + }, { "name": "paragonie/random_compat", "version": "v9.99.99", @@ -1446,6 +1670,56 @@ ], "time": "2017-02-14T16:28:37+00:00" }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2016-08-06T14:39:51+00:00" + }, { "name": "psr/log", "version": "1.1.3", @@ -1613,6 +1887,46 @@ ], "time": "2020-04-07T06:44:48+00:00" }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "time": "2019-03-08T08:55:37+00:00" + }, { "name": "ramsey/uuid", "version": "3.9.3", diff --git a/flexiapi/config/ovh.php b/flexiapi/config/ovh.php new file mode 100644 index 0000000..c586f86 --- /dev/null +++ b/flexiapi/config/ovh.php @@ -0,0 +1,8 @@ + env('OVH_APP_KEY', ''), + 'app_secret' => env('OVH_APP_SECRET', ''), + 'app_endpoint' => env('OVH_APP_ENDPOINT', 'ovh-eu'), + 'app_consumer_key' => env('OVH_APP_CONSUMER_KEY', ''), +]; \ No newline at end of file diff --git a/flexiapi/resources/views/layouts/account.blade.php b/flexiapi/resources/views/layouts/account.blade.php index f155f4d..b21e785 100644 --- a/flexiapi/resources/views/layouts/account.blade.php +++ b/flexiapi/resources/views/layouts/account.blade.php @@ -5,7 +5,7 @@