Commit 1ff70b6d authored by Nicolas Widart's avatar Nicolas Widart

Squashed 'Modules/User/' changes from 8b9a95b..4417311

4417311 Abstract the final reset password part
c8be3b4 Using the user repository on complete reset
c46ed46 Fixing reset complete route
cacca3d Removing unused imports
38f5999 Abstracting first reset pwd step
f891810 Correct the module name
1fa89b3 User the user repository
97094e3 Merge branch 'feature/decouple_authentication' into develop
e72ee46 Abstract the user activation actions
661f9dd Fix confirm pwd link
f0555ae Fix email views
747351a Fix event name
d6ac09b Import the sentinel exceptions
60d7f9e Abstracting the registration
ab67c78 Abstracting the logout method
73c729c Abstracting the Login action
f474bb6 Bind the interface to the sentinel implementation
3478dd7 Adding first pass to a Auth interface

git-subtree-dir: Modules/User
git-subtree-split: 44173119c4e3c8ddff1f075fe915d8965d6f153c
parent 6994f095
......@@ -6,9 +6,26 @@ use Illuminate\Support\Facades\Event;
use Laracasts\Commander\CommandHandler;
use Modules\User\Events\UserHasBegunResetProcess;
use Modules\User\Exceptions\UserNotFoundException;
use Modules\User\Repositories\AuthenticationRepository;
use Modules\User\Repositories\UserRepository;
class BeginResetProcessCommandHandler implements CommandHandler
{
/**
* @var UserRepository
*/
private $user;
/**
* @var AuthenticationRepository
*/
private $auth;
public function __construct(UserRepository $user, AuthenticationRepository $auth)
{
$this->user = $user;
$this->auth = $auth;
}
/**
* Handle the command
*
......@@ -20,14 +37,14 @@ class BeginResetProcessCommandHandler implements CommandHandler
{
$user = $this->findUser((array) $command);
$reminder = Reminder::exists($user) ?: Reminder::create($user);
$code = $this->auth->createReminderCode($user);
Event::fire('Modules.Session.Events.UserHasBegunResetProcess', new UserHasBegunResetProcess($user, $reminder));
Event::fire('Modules.User.Events.UserHasBegunResetProcess', new UserHasBegunResetProcess($user, $code));
}
private function findUser($credentials)
{
$user = Sentinel::findByCredentials((array) $credentials);
$user = $this->user->findByCredentials((array) $credentials);
if ($user) {
return $user;
}
......
<?php namespace Modules\User\Commands;
use Cartalyst\Sentinel\Laravel\Facades\Reminder;
use Cartalyst\Sentinel\Laravel\Facades\Sentinel;
use Laracasts\Commander\CommandHandler;
use Modules\User\Exceptions\InvalidOrExpiredResetCode;
use Modules\User\Exceptions\UserNotFoundException;
use Modules\User\Repositories\AuthenticationRepository;
use Modules\User\Repositories\UserRepository;
class CompleteResetProcessCommandHandler implements CommandHandler
{
protected $input;
/**
* @var UserRepository
*/
private $user;
/**
* @var AuthenticationRepository
*/
private $auth;
public function __construct(UserRepository $user, AuthenticationRepository $auth)
{
$this->user = $user;
$this->auth = $auth;
}
/**
* Handle the command
......@@ -21,11 +36,9 @@ class CompleteResetProcessCommandHandler implements CommandHandler
{
$this->input = $command;
$this->form->validate((array) $this->input);
$user = $this->findUser();
if (!Reminder::complete($user, $this->input->code, $this->input->password)) {
if (!$this->auth->completeResetPassword($user, $this->input->code, $this->input->password)) {
throw new InvalidOrExpiredResetCode;
}
......@@ -34,7 +47,7 @@ class CompleteResetProcessCommandHandler implements CommandHandler
public function findUser()
{
$user = Sentinel::findById($this->input->userId);
$user = $this->user->find($this->input->userId);
if ($user) {
return $user;
}
......
......@@ -4,11 +4,28 @@ use Cartalyst\Sentinel\Laravel\Facades\Sentinel;
use Illuminate\Support\Facades\Event;
use Laracasts\Commander\CommandHandler;
use Modules\User\Events\UserHasRegistered;
use Modules\User\Repositories\AuthenticationRepository;
use Modules\User\Repositories\RoleRepository;
class RegisterNewUserCommandHandler implements CommandHandler
{
protected $input;
/**
* @var AuthenticationRepository
*/
private $auth;
/**
* @var RoleRepository
*/
private $role;
public function __construct(AuthenticationRepository $auth, RoleRepository $role)
{
$this->auth = $auth;
$this->role = $role;
}
/**
* Handle the command
*
......@@ -23,20 +40,20 @@ class RegisterNewUserCommandHandler implements CommandHandler
$this->assignUserToUsersGroup($user);
Event::fire('Modules.Session.Events.UserHasRegistered', new UserHasRegistered($user));
Event::fire('Modules.User.Events.UserHasRegistered', new UserHasRegistered($user));
return $user;
}
private function createUser()
{
return Sentinel::getUserRepository()->create((array) $this->input);
return $this->auth->register((array) $this->input);
}
private function assignUserToUsersGroup($user)
{
$group = Sentinel::findRoleByName('User');
$role = $this->role->findByName('User');
$group->users()->attach($user);
$this->auth->assignRole($user, $role);
}
}
......@@ -3,11 +3,11 @@
class UserHasBegunResetProcess
{
public $user;
public $reminder;
public $code;
public function __construct($user, $reminder)
public function __construct($user, $code)
{
$this->user = $user;
$this->reminder = $reminder;
$this->code = $code;
}
}
<?php namespace Modules\User\Http\Controllers;
use Cartalyst\Sentinel\Checkpoints\NotActivatedException;
use Cartalyst\Sentinel\Checkpoints\ThrottlingException;
use Cartalyst\Sentinel\Laravel\Facades\Sentinel;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\View;
use Laracasts\Commander\CommanderTrait;
......@@ -13,13 +10,20 @@ use Modules\User\Http\Requests\LoginRequest;
use Modules\User\Http\Requests\RegisterRequest;
use Modules\User\Http\Requests\ResetCompleteRequest;
use Modules\User\Http\Requests\ResetRequest;
use Modules\User\Repositories\AuthenticationRepository;
class AuthController
{
use CommanderTrait;
public function __construct()
/**
* @var AuthenticationRepository
*/
private $auth;
public function __construct(AuthenticationRepository $auth)
{
$this->auth = $auth;
}
public function getLogin()
......@@ -34,19 +38,14 @@ class AuthController
'password' => $request->password
];
$remember = (bool)$request->get('remember_me', false);
try {
if (Sentinel::authenticate($credentials, $remember)) {
Flash::success('Successfully logged in.');
return Redirect::route('dashboard.index', compact('user'));
}
Flash::error('Invalid login or password.');
} catch (NotActivatedException $e) {
Flash::error('Account not yet validated. Please check your email.');
} catch (ThrottlingException $e) {
$delay = $e->getDelay();
Flash::error("Your account is blocked for {$delay} second(s).");
$error = $this->auth->login($credentials, $remember);
if (!$error) {
Flash::success('Successfully logged in.');
return Redirect::route('dashboard.index');
}
Flash::error($error);
return Redirect::back()->withInput();
}
......@@ -66,11 +65,21 @@ class AuthController
public function getLogout()
{
Sentinel::logout();
$this->auth->logout();
return Redirect::route('login');
}
public function getActivate($userId, $code)
{
if ($this->auth->activate($userId, $code)) {
Flash::success('Account activated. You can now login.');
return Redirect::route('login');
}
Flash::error('There was an error with the activation.');
return Redirect::route('register');
}
public function getReset()
{
return View::make('user::public.reset.begin');
......@@ -105,16 +114,13 @@ class AuthController
);
} catch (UserNotFoundException $e) {
Flash::error('The user no longer exists.');
return Redirect::back()->withInput();
} catch(InvalidOrExpiredResetCode $e) {
} catch (InvalidOrExpiredResetCode $e) {
Flash::error('Invalid or expired reset code.');
return Redirect::back()->withInput();
}
Flash::success('Password has been reset. You can now login with your new password.');
return Redirect::route('login');
}
}
<?php namespace Modules\User\Listeners;
use Cartalyst\Sentinel\Laravel\Facades\Activation;
use Illuminate\Mail\Message;
use Illuminate\Support\Facades\Mail;
use Laracasts\Commander\Events\EventListener;
use Modules\User\Repositories\AuthenticationRepository;
class SendRegistrationConfirmationEmail extends EventListener
{
/**
* @var AuthenticationRepository
*/
private $auth;
public function __construct(AuthenticationRepository $auth)
{
$this->auth = $auth;
}
public function whenUserHasRegistered($event)
{
$user = $event->user;
$activation = Activation::create($user);
$activation = $this->auth->createActivation($user);
$data = [
'user' => $user,
'activationcode' => $activation->code
];
Mail::queue('session::emails.welcome',$data,
Mail::queue('user::emails.welcome',$data,
function (Message $m) use ($user) {
$m->to($user->email)->subject('Welcome.');
}
......
......@@ -9,9 +9,9 @@ class SendResetCodeEmail extends EventListener
public function whenUserHasBegunResetProcess($event)
{
$user = $event->user;
$code = $event->reminder->code;
$code = $event->code;
Mail::queue('SessionModule::emails.reminder', compact('user', 'code'), function(Message $m) use ($user)
Mail::queue('user::emails.reminder', compact('user', 'code'), function(Message $m) use ($user)
{
$m->to($user->email)->subject('Reset your account password.');
});
......
......@@ -82,6 +82,10 @@ class UserServiceProvider extends ServiceProvider
'Modules\User\Repositories\RoleRepository',
'Modules\User\Repositories\Sentinel\SentinelRoleRepository'
);
$this->app->bind(
'Modules\User\Repositories\AuthenticationRepository',
'Modules\User\Repositories\Sentinel\SentinelAuthenticationRepository'
);
}
private function registerMiddleware($router)
......
<?php namespace Modules\User\Repositories;
interface AuthenticationRepository
{
/**
* Authenticate a user
* @param array $credentials
* @param bool $remember Remember the user
* @return mixed
*/
public function login(array $credentials, $remember = false);
/**
* Register a new user.
* @param array $user
* @return bool
*/
public function register(array $user);
/**
* Activate the given used id
* @param int $userId
* @param string $code
* @return mixed
*/
public function activate($userId, $code);
/**
* Assign a role to the given user.
* @param \Modules\User\Repositories\UserRepository $user
* @param \Modules\User\Repositories\RoleRepository $role
* @return mixed
*/
public function assignRole($user, $role);
/**
* Log the user out of the application.
* @return mixed
*/
public function logout();
/**
* Create an activation code for the given user
* @param $user
* @return mixed
*/
public function createActivation($user);
/**
* Create a reminders code for the given user
* @param $user
* @return mixed
*/
public function createReminderCode($user);
/**
* Completes the reset password process
* @param $user
* @param string $code
* @param string $password
* @return bool
*/
public function completeResetPassword($user, $code, $password);
}
......@@ -39,4 +39,11 @@ interface RoleRepository
* @return mixed
*/
public function delete($id);
/**
* Find a role by its name
* @param string $name
* @return mixed
*/
public function findByName($name);
}
<?php namespace Modules\User\Repositories\Sentinel;
use Cartalyst\Sentinel\Checkpoints\NotActivatedException;
use Cartalyst\Sentinel\Checkpoints\ThrottlingException;
use Cartalyst\Sentinel\Laravel\Facades\Activation;
use Cartalyst\Sentinel\Laravel\Facades\Reminder;
use Cartalyst\Sentinel\Laravel\Facades\Sentinel;
use Modules\User\Repositories\AuthenticationRepository;
class SentinelAuthenticationRepository implements AuthenticationRepository
{
/**
* Authenticate a user
* @param array $credentials
* @param bool $remember Remember the user
* @return mixed
*/
public function login(array $credentials, $remember = false)
{
try {
if (Sentinel::authenticate($credentials, $remember)) {
return false;
}
return 'Invalid login or password.';
} catch (NotActivatedException $e) {
return 'Account not yet validated. Please check your email.';
} catch (ThrottlingException $e) {
$delay = $e->getDelay();
return "Your account is blocked for {$delay} second(s).";
}
}
/**
* Register a new user.
* @param array $user
* @return bool
*/
public function register(array $user)
{
return Sentinel::getUserRepository()->create((array) $user);
}
/**
* Assign a role to the given user.
* @param \Modules\User\Repositories\UserRepository $user
* @param \Modules\User\Repositories\RoleRepository $role
* @return mixed
*/
public function assignRole($user, $role)
{
return $role->users()->attach($user);
}
/**
* Log the user out of the application.
* @return bool
*/
public function logout()
{
return Sentinel::logout();
}
/**
* Activate the given used id
* @param int $userId
* @param string $code
* @return mixed
*/
public function activate($userId, $code)
{
$user = Sentinel::findById($userId);
return Activation::complete($user, $code);
}
/**
* Create an activation code for the given user
* @param \Modules\User\Repositories\UserRepository $user
* @return mixed
*/
public function createActivation($user)
{
return Activation::create($user);
}
/**
* Create a reminders code for the given user
* @param \Modules\User\Repositories\UserRepository $user
* @return mixed
*/
public function createReminderCode($user)
{
$reminder = Reminder::exists($user) ?: Reminder::create($user);
return $reminder->code;
}
/**
* Completes the reset password process
* @param $user
* @param string $code
* @param string $password
* @return bool
*/
public function completeResetPassword($user, $code, $password)
{
return Reminder::complete($user, $code, $password);
}
}
......@@ -69,4 +69,14 @@ class SentinelRoleRepository implements RoleRepository
return $role->delete();
}
/**
* Find a role by its name
* @param string $name
* @return mixed
*/
public function findByName($name)
{
return Sentinel::findRoleByName($name);
}
}
......@@ -2,7 +2,7 @@
use Cartalyst\Sentinel\Laravel\Facades\Activation;
use Cartalyst\Sentinel\Laravel\Facades\Sentinel;
use Modules\Session\Exceptions\UserNotFoundException;
use Modules\User\Exceptions\UserNotFoundException;
use Modules\User\Repositories\UserRepository;
class SentinelUserRepository implements UserRepository
......@@ -113,4 +113,14 @@ class SentinelUserRepository implements UserRepository
throw new UserNotFoundException;
}
/**
* Find a user by its credentials
* @param array $credentials
* @return mixed
*/
public function findByCredentials(array $credentials)
{
return Sentinel::findByCredentials($credentials);
}
}
......@@ -57,4 +57,11 @@ interface UserRepository
* @return mixed
*/
public function delete($id);
/**
* Find a user by its credentials
* @param array $credentials
* @return mixed
*/
public function findByCredentials(array $credentials);
}
......@@ -72,7 +72,7 @@ background-color: #f6f6f6;
</tr>
<tr style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0; padding: 0;">
<td class="content-block" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
To reset your password, complete this form: {{ URL::to("reset/{$user['id']}/{$code}") }}.
To reset your password, complete this form: {{ URL::to("auth/reset/{$user['id']}/{$code}") }}.
</td>
</tr>
<tr style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0; padding: 0;">
......
......@@ -82,7 +82,7 @@ background-color: #f6f6f6;
</tr>
<tr style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0; padding: 0;">
<td class="content-block" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
<a href="{{ URL::to('activate/' . $user['id'] . '/' . $activationcode) }}" class="btn-primary" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; color: #FFF; text-decoration: none; line-height: 2; font-weight: bold; text-align: center; cursor: pointer; display: inline-block; border-radius: 5px; text-transform: capitalize; background: #348eda; margin: 0; padding: 0; border-color: #348eda; border-style: solid; border-width: 10px 20px;">Confirm email address</a>
<a href="{{ URL::to('auth/activate/' . $user['id'] . '/' . $activationcode) }}" class="btn-primary" style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; color: #FFF; text-decoration: none; line-height: 2; font-weight: bold; text-align: center; cursor: pointer; display: inline-block; border-radius: 5px; text-transform: capitalize; background: #348eda; margin: 0; padding: 0; border-color: #348eda; border-style: solid; border-width: 10px 20px;">Confirm email address</a>
</td>
</tr>
<tr style="font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0; padding: 0;">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment