X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/dec0cbb1b25d139c504923a15b4ce884562c7404..refs/pull/72/head:/app/Http/Controllers/Auth/AuthController.php diff --git a/app/Http/Controllers/Auth/AuthController.php b/app/Http/Controllers/Auth/AuthController.php index 0d4f6b844..fef87d5c8 100644 --- a/app/Http/Controllers/Auth/AuthController.php +++ b/app/Http/Controllers/Auth/AuthController.php @@ -1,17 +1,17 @@ middleware('guest', ['only' => ['getLogin', 'postLogin', 'getRegister']]); + $this->middleware('guest', ['only' => ['getLogin', 'postLogin', 'getRegister', 'postRegister']]); $this->socialAuthService = $socialAuthService; $this->emailConfirmationService = $emailConfirmationService; $this->userRepo = $userRepo; + $this->username = config('auth.method') === 'standard' ? 'email' : 'username'; parent::__construct(); } /** * Get a validator for an incoming registration request. - * * @param array $data * @return \Illuminate\Contracts\Validation\Validator */ @@ -68,31 +69,15 @@ class AuthController extends Controller ]); } - /** - * Create a new user instance after a valid registration. - * - * @param array $data - * @return User - */ - protected function create(array $data) - { - return User::create([ - 'name' => $data['name'], - 'email' => $data['email'], - 'password' => bcrypt($data['password']), - ]); - } - protected function checkRegistrationAllowed() { - if(!\Setting::get('registration-enabled')) { + if (!\Setting::get('registration-enabled')) { throw new UserRegistrationException('Registrations are currently disabled.', '/login'); } } /** * Show the application registration form. - * * @return \Illuminate\Http\Response */ public function getRegister() @@ -104,7 +89,6 @@ class AuthController extends Controller /** * Handle a registration request for the application. - * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response * @throws UserRegistrationException @@ -120,30 +104,101 @@ class AuthController extends Controller ); } - if(\Setting::get('registration-restrict')) { + $userData = $request->all(); + return $this->registerUser($userData); + } + + + /** + * Overrides the action when a user is authenticated. + * If the user authenticated but does not exist in the user table we create them. + * @param Request $request + * @param Authenticatable $user + * @return \Illuminate\Http\RedirectResponse + */ + protected function authenticated(Request $request, Authenticatable $user) + { + // Explicitly log them out for now if they do no exist. + if (!$user->exists) auth()->logout($user); + + if (!$user->exists && $user->email === null && !$request->has('email')) { + $request->flash(); + session()->flash('request-email', true); + return redirect('/login'); + } + + if (!$user->exists && $user->email === null && $request->has('email')) { + $user->email = $request->get('email'); + } + + if (!$user->exists) { + $user->save(); + $this->userRepo->attachDefaultRole($user); + auth()->login($user); + } + + return redirect()->intended($this->redirectPath()); + } + + /** + * Register a new user after a registration callback. + * @param $socialDriver + * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector + * @throws UserRegistrationException + */ + protected function socialRegisterCallback($socialDriver) + { + $socialUser = $this->socialAuthService->handleRegistrationCallback($socialDriver); + $socialAccount = $this->socialAuthService->fillSocialAccount($socialDriver, $socialUser); + + // Create an array of the user data to create a new user instance + $userData = [ + 'name' => $socialUser->getName(), + 'email' => $socialUser->getEmail(), + 'password' => str_random(30) + ]; + return $this->registerUser($userData, $socialAccount); + } + + /** + * The registrations flow for all users. + * @param array $userData + * @param bool|false|SocialAccount $socialAccount + * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector + * @throws UserRegistrationException + * @throws \BookStack\Exceptions\ConfirmationEmailException + */ + protected function registerUser(array $userData, $socialAccount = false) + { + if (\Setting::get('registration-restrict')) { $restrictedEmailDomains = explode(',', str_replace(' ', '', \Setting::get('registration-restrict'))); - $userEmailDomain = $domain = substr(strrchr($request->get('email'), "@"), 1); - if(!in_array($userEmailDomain, $restrictedEmailDomains)) { + $userEmailDomain = $domain = substr(strrchr($userData['email'], "@"), 1); + if (!in_array($userEmailDomain, $restrictedEmailDomains)) { throw new UserRegistrationException('That email domain does not have access to this application', '/register'); } } - $newUser = $this->create($request->all()); - $newUser->attachRoleId(\Setting::get('registration-role'), 1); + $newUser = $this->userRepo->registerNew($userData); + if ($socialAccount) { + $newUser->socialAccounts()->save($socialAccount); + } - if(\Setting::get('registration-confirmation') || \Setting::get('registration-restrict')) { + if (\Setting::get('registration-confirmation') || \Setting::get('registration-restrict')) { $newUser->email_confirmed = false; $newUser->save(); $this->emailConfirmationService->sendConfirmation($newUser); return redirect('/register/confirm'); } + $newUser->email_confirmed = true; + auth()->login($newUser); + session()->flash('success', 'Thanks for signing up! You are now registered and signed in.'); return redirect($this->redirectPath()); } /** - * Show the page to tell the user to check thier email + * Show the page to tell the user to check their email * and confirm their address. */ public function getRegisterConfirmation() @@ -151,6 +206,18 @@ class AuthController extends Controller return view('auth/register-confirm'); } + /** + * View the confirmation email as a standard web page. + * @param $token + * @return \Illuminate\View\View + * @throws UserRegistrationException + */ + public function viewConfirmEmail($token) + { + $confirmation = $this->emailConfirmationService->getEmailConfirmationFromToken($token); + return view('emails/email-confirmation', ['token' => $confirmation->token]); + } + /** * Confirms an email via a token and logs the user into the system. * @param $token @@ -191,24 +258,19 @@ class AuthController extends Controller ]); $user = $this->userRepo->getByEmail($request->get('email')); $this->emailConfirmationService->sendConfirmation($user); - \Session::flash('success', 'Confirmation email resent, Please check your inbox.'); + session()->flash('success', 'Confirmation email resent, Please check your inbox.'); return redirect('/register/confirm'); } /** * Show the application login form. - * * @return \Illuminate\Http\Response */ public function getLogin() { - - if (view()->exists('auth.authenticate')) { - return view('auth.authenticate'); - } - $socialDrivers = $this->socialAuthService->getActiveDrivers(); - return view('auth.login', ['socialDrivers' => $socialDrivers]); + $authMethod = config('auth.method'); + return view('auth/login', ['socialDrivers' => $socialDrivers, 'authMethod' => $authMethod]); } /** @@ -218,19 +280,41 @@ class AuthController extends Controller */ public function getSocialLogin($socialDriver) { + session()->put('social-callback', 'login'); return $this->socialAuthService->startLogIn($socialDriver); } + /** + * Redirect to the social site for authentication intended to register. + * @param $socialDriver + * @return mixed + */ + public function socialRegister($socialDriver) + { + $this->checkRegistrationAllowed(); + session()->put('social-callback', 'register'); + return $this->socialAuthService->startRegister($socialDriver); + } + /** * The callback for social login services. - * * @param $socialDriver * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector * @throws SocialSignInException */ public function socialCallback($socialDriver) { - return $this->socialAuthService->handleCallback($socialDriver); + if (session()->has('social-callback')) { + $action = session()->pull('social-callback'); + if ($action == 'login') { + return $this->socialAuthService->handleLoginCallback($socialDriver); + } elseif ($action == 'register') { + return $this->socialRegisterCallback($socialDriver); + } + } else { + throw new SocialSignInException('No action defined', '/login'); + } + return redirect()->back(); } /**