Skip to content

Instantly share code, notes, and snippets.

@0xMatt
Last active August 29, 2015 14:12
Show Gist options
  • Save 0xMatt/dc9f1498e7ca9b15b4c6 to your computer and use it in GitHub Desktop.
Save 0xMatt/dc9f1498e7ca9b15b4c6 to your computer and use it in GitHub Desktop.
User Authentication
<?php
namespace Modules\System\Http\Controllers\Frontend;
use Modules\System\Http\Requests\Frontend\LoginRequest;
use Modules\System\Http\Requests\Frontend\RegisterRequest;
use Modules\System\Http\Requests\Frontend\ResetRequest;
use Modules\System\Domain\User\UserManager;
use Modules\System\Domain\User\UserRepositoryInterface;
use Modules\System\Domain\User\LoginManager;
use Modules\System\Domain\Validating\ValidatingManager;
use Modules\System\Events\UserEvent;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Http\Request;
use Modules\System\Domain\Validating\ValidatingRepositoryInterface;
use Modules\System\Http\Requests\Frontend\ValidatingRequest;
class AuthController extends \Lithe\Http\FrontendController
{
/**
*/
function __construct()
{
parent::__construct();
$this->middleware('guest', [
'except' => [
'logout',
'external',
'provider',
'confirm',
'postConfirm'
]
]);
}
/**
* Log in with a third party provider
*
* @param LoginManager $manager
* @param string $provider
*/
public function external(LoginManager $manager, $provider)
{
return $manager->send($provider);
}
/**
*
* @param LoginManager $manager
* @param UserRepositoryInterface $repo
* @param unknown $provider
*/
public function provider(LoginManager $manager, UserRepositoryInterface $repo, $provider)
{
if ($manager->receive($provider, $repo)) {
return redirect('/')->withAlert('Logged in successfully!');
}
return redirect('/login')->withAlert([
'An error has occurred, please try again.'
]);
}
public function thinkOfAName()
{
// Set username & password on first log in
}
/**
*
* @return \Illuminate\View\View
*/
public function login()
{
$this->crumbs->add('/login', 'Log In');
return view('auth/login');
}
/**
*
* @param LoginRequest $request
* @param LoginManager $manager
*/
public function postLogin(LoginRequest $request, UserManager $manager)
{
if ($manager->loginWithRequest($request)) {
return redirect()->intended('/')->withAlert('Logged in successfully!');
}
return redirect()->back()->withAlert([
'The credentials you entered did not match a registered account.'
]);
}
/**
*/
public function logout(Request $request, UserManager $manager)
{
$manager->logout($request);
return redirect('/')->withAlert('You have logged out successfully.');
}
/**
*
* @return \Illuminate\View\View
*/
public function register()
{
$this->crumbs->add('/register', 'Register');
return view('auth/register');
}
/**
*
* @param RegisterRequest $request
* @param UserRepositoryInterface $repo
*/
public function postRegister(UserManager $manager, RegisterRequest $request, UserRepositoryInterface $repo, Dispatcher $dispatcher)
{
$dispatcher->fire('user.registering');
$user = $repo->create($request->only('username', 'email', 'password'));
$dispatcher->fire('user.registered', new UserEvent($user, $request));
$manager->loginWithUser($user);
return redirect('/')->withAlert('Your account has been activated successfully, you may need to validate it before you are granted full access to the site.');
}
/**
* Reset password form
*
* @return \Illuminate\View\View
*/
public function forgot()
{
$this->crumbs->add('/forgot', 'Forgot Password');
return view('auth/forgot');
}
/**
* Send the reset confirmation email
*
* @param ResetRequest $request
* @param ValidatingManager $manager
*/
public function postForgot(ResetRequest $request, ValidatingManager $manager, ValidatingRepositoryInterface $repo)
{
$manager->create('forgot', $repo->findByUsernameOrEmail($request->username, $request->email)->user);
return redirect()->back()->withAlert('Your password request process has started, please check your email.');
}
public function reset($token)
{
//
}
public function postReset()
{
//
}
/**
* Confirm a validation
*
* @param ValidatingManager $manager
* @param unknown $token
*/
public function confirm(ValidatingManager $manager, $token = null)
{
// $manager->verify($token);
return view('auth/confirm', compact('token'));
}
/**
*
* @param ValidateRequest $request
* @param ValidatingManager $manager
*/
public function postConfirm(ValidatingRequest $request, ValidatingManager $manager)
{
$manager->validate($request->only('token'));
return redirect('/')->withAlert('You have confirmed your new information successfully and have been logged in.');
}
}
<?php
namespace Modules\System\Domain\User;
use Modules\System\Events\UserEvent;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Http\Request;
use Laravel\Socialite\Contracts\Factory as Socialite;
use Modules\System\Domain\Login\LoginRepositoryInterface;
/**
* @author matthew <[email protected]>
*
*/
class LoginManager
{
/**
*
* @var Guard
*/
protected $auth;
/**
*
* @var Dispatcher
*/
protected $dispatcher;
/**
*
* @var Socialite
*/
protected $socialite;
/**
*
* @var LoginRepositoryInterface
*/
protected $repo;
/**
*
* @param Guard $auth
* @param Dispatcher $dispatcher
* @param Socialite $socialite
* @param LoginRepositoryInterface $repo
*/
function __construct(Guard $auth, Dispatcher $dispatcher, Socialite $socialite, LoginRepositoryInterface $repo)
{
$this->auth = $auth;
$this->dispatcher = $dispatcher;
$this->socialite = $socialite;
$this->repo = $repo;
}
/**
*
* @param unknown $provider
*/
public function send($provider)
{
return $this->socialite->with($provider)->redirect();
}
/**
*
* @param unknown $provider
* @param unknown $repo
* @return boolean
*/
public function receive($provider, $repo)
{
$user = $this->socialite->with($provider)->user();
if (! $login = $this->repo->findByName($provider)) {
return false;
}
$find = $repo->findByEmail($user->email);
if (! $find) {
if (! filter_var($user->email, FILTER_VALIDATE_EMAIL)) {
return redirect('/')->withAlert([
'You don\'t have a valid email set up through your login provider'
]);
}
// Okay, we have no user with this email
$find = $repo->create([
'username' => ($user->nickname !== null) ? $user->nickname : str_replace('_', '.', snake_case($user->name)),
'password' => $user->token,
'email' => $user->email
]);
}
if (! $login->users()->exists($find->id)) {
$login->users()->attach($find->id);
}
$this->auth->login($find, true);
}
}
<?php
namespace Modules\System\Events;
use Modules\System\Domain\User\User;
use Illuminate\Http\Request;
/**
*
* @author matthew <[email protected]>
*
*/
class UserEvent
{
/**
*
* @var Request
*/
protected $request;
/**
*
* @var User
*/
protected $user;
/**
*
* @param User $user
* @param Request $request
*/
public function __construct(User $user, Request $request)
{
$this->user = $user;
$this->request = $request;
}
/**
*
* @return \Modules\System\Domain\User\User
*/
public function getUser()
{
return $this->user;
}
/**
*
* @return \Illuminate\Http\Request
*/
public function getRequest()
{
return $this->request;
}
}
<?php
namespace Modules\System\Domain\User;
use Modules\System\Events\UserEvent;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Http\Request;
/**
* @author matthew <[email protected]>
*
*/
class UserManager
{
/**
*
* @var Guard
*/
protected $auth;
/**
*
* @var Dispatcher
*/
protected $dispatcher;
/**
* Constructor
*
* @param Guard $auth
* @param Dispatcher $dispatcher
*/
function __construct(Guard $auth, Dispatcher $dispatcher)
{
$this->auth = $auth;
$this->dispatcher = $dispatcher;
}
/**
* Create a new user
*
* @param Request $request
* @param UserRepositoryInterface $repo
* @return unknown
*/
public function create(Request $request, UserRepositoryInterface $repo)
{
$this->dispatcher->fire('user.creating');
$user = $this->repo->create($request->only('username', 'email', 'password'));
$this->dispatcher->fire('user.created', new UserEvent($user, $request));
return $user;
}
/**
* Log in the current user
*
* @param Request $request
* @return boolean
*/
public function loginWithRequest(Request $request)
{
if ($this->auth->attempt($request->only('username', 'password'), $request->has('remember'))) {
$this->dispatcher->fire('user.login', new UserEvent($this->auth->user(), $request));
return true;
}
return false;
}
/**
* @param User $user
*/
public function loginWithUser(User $user)
{
return $this->auth->login($user);
}
/**
* Logout the current user
*
* @param Request $request
*/
public function logout(Request $request)
{
$this->dispatcher->fire('user.logout', new UserEvent($this->auth->user(), $request));
$this->auth->logout();
}
}
<?php
namespace Modules\System\Domain\Validating;
use Modules\System\Events\UserEvent;
/**
*
* @author matthew
*
*/
class ValidatingHandler
{
/**
*
* @param ValidatingManager $manager
*/
function __construct(ValidatingManager $manager)
{
$this->manager = $manager;
}
/**
*
* @param unknown $user
*/
public function onRegister(UserEvent $event)
{
// @todo Check if user needs to be validated
$user = $event->getUser();
$user->is_activated = false;
$this->manager->create('register', $user);
}
}
<?php
namespace Modules\System\Domain\Validating;
use Illuminate\Contracts\Mail\Mailer;
use Modules\System\Domain\User\User;
/**
*
* @author matthew
*
*/
class ValidatingMailer
{
/**
*
* @var Mailer
*/
protected $mailer;
/**
*
* @param Mailer $mailer
*/
public function __construct(Mailer $mailer)
{
$this->mailer = $mailer;
}
/**
*
* @param string $token
* @param User $user
*/
public function register($token, User $user)
{
$this->mailer->send('emails.auth.validate', compact('token', 'user'), function ($message) use($user)
{
$message->to($user->email, $user->username)
->subject('Account Verification');
});
}
/**
*
* @param string $token
* @param User $user
*/
public function forgot($token, User $user)
{
$this->mailer->send('emails.auth.forgot', compact('token', 'user'), function ($message) use($user)
{
$message->to($user->email, $user->username)
->subject('Password Retreival');
});
}
}
<?php
namespace Modules\System\Domain\Validating;
use Modules\System\Events\UserEvent;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Http\Request;
use Laravel\Socialite\Contracts\Factory as Socialite;
use Modules\System\Domain\Login\LoginRepositoryInterface;
/**
*
* @author matthew
*
*/
class ValidatingManager
{
/**
*
* @var ValidatingRepositoryInterface
*/
protected $repo;
/**
*
* @var ValidatingMailer
*/
protected $mailer;
/**
*
* @param ValidatingRepositoryInterface $repo
* @param ValidatingMailer $mailer
*/
function __construct(ValidatingRepositoryInterface $repo, ValidatingMailer $mailer)
{
$this->repo = $repo;
$this->mailer = $mailer;
}
/**
*
* @param unknown $type
* @param unknown $user
* @return Validating
*/
public function create($type, $user)
{
$token = str_random(32);
$this->repo->deleteTypesByUserId($type, $user->id);
$validating = $this->repo->create(compact('type', 'token'));
$user->validating()->save($validating);
$this->mailer->$type($token, $user);
return $validating;
}
/**
* @param unknown $token
*/
public function validate($token)
{
$validate = $this->repo->findByToken($token);
// Extact into a factory e.g
// (new ValidatingFactory('register')->execute();
if($validate->type == 'register')
{
$user = $validate->user;
$user->is_activated = 1;
$user->save();
$validate->delete();
return true;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment