X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/cd6572b61af2165133468d2562d04dffdca8fca8..refs/pull/1527/head:/app/Http/Controllers/Auth/RegisterController.php diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php index 8b0ef309a..a285899cc 100644 --- a/app/Http/Controllers/Auth/RegisterController.php +++ b/app/Http/Controllers/Auth/RegisterController.php @@ -2,19 +2,25 @@ namespace BookStack\Http\Controllers\Auth; -use BookStack\Exceptions\ConfirmationEmailException; +use BookStack\Auth\Access\EmailConfirmationService; +use BookStack\Auth\Access\SocialAuthService; +use BookStack\Auth\SocialAccount; +use BookStack\Auth\User; +use BookStack\Auth\UserRepo; +use BookStack\Exceptions\SocialDriverNotConfigured; +use BookStack\Exceptions\SocialSignInAccountNotUsed; use BookStack\Exceptions\SocialSignInException; use BookStack\Exceptions\UserRegistrationException; -use BookStack\Repos\UserRepo; -use BookStack\Services\EmailConfirmationService; -use BookStack\Services\SocialAuthService; -use BookStack\User; +use BookStack\Http\Controllers\Controller; use Exception; +use Illuminate\Foundation\Auth\RegistersUsers; +use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; use Illuminate\Http\Response; +use Illuminate\Routing\Redirector; +use Illuminate\View\View; +use Laravel\Socialite\Contracts\User as SocialUser; use Validator; -use BookStack\Http\Controllers\Controller; -use Illuminate\Foundation\Auth\RegistersUsers; class RegisterController extends Controller { @@ -47,17 +53,17 @@ class RegisterController extends Controller * Create a new controller instance. * * @param SocialAuthService $socialAuthService - * @param EmailConfirmationService $emailConfirmationService + * @param \BookStack\Auth\EmailConfirmationService $emailConfirmationService * @param UserRepo $userRepo */ public function __construct(SocialAuthService $socialAuthService, EmailConfirmationService $emailConfirmationService, UserRepo $userRepo) { - $this->middleware('guest')->except(['socialCallback', 'detachSocialAccount']); + $this->middleware('guest')->only(['getRegister', 'postRegister', 'socialRegister']); $this->socialAuthService = $socialAuthService; $this->emailConfirmationService = $emailConfirmationService; $this->userRepo = $userRepo; - $this->redirectTo = baseUrl('/'); - $this->redirectPath = baseUrl('/'); + $this->redirectTo = url('/'); + $this->redirectPath = url('/'); parent::__construct(); } @@ -70,7 +76,7 @@ class RegisterController extends Controller protected function validator(array $data) { return Validator::make($data, [ - 'name' => 'required|max:255', + 'name' => 'required|min:2|max:255', 'email' => 'required|email|max:255|unique:users', 'password' => 'required|min:6', ]); @@ -90,6 +96,7 @@ class RegisterController extends Controller /** * Show the application registration form. * @return Response + * @throws UserRegistrationException */ public function getRegister() { @@ -100,21 +107,14 @@ class RegisterController extends Controller /** * Handle a registration request for the application. - * @param Request|\Illuminate\Http\Request $request - * @return Response + * @param Request|Request $request + * @return RedirectResponse|Redirector * @throws UserRegistrationException - * @throws \Illuminate\Foundation\Validation\ValidationException */ public function postRegister(Request $request) { $this->checkRegistrationAllowed(); - $validator = $this->validator($request->all()); - - if ($validator->fails()) { - $this->throwValidationException( - $request, $validator - ); - } + $this->validator($request->all())->validate(); $userData = $request->all(); return $this->registerUser($userData); @@ -138,26 +138,28 @@ class RegisterController extends Controller * The registrations flow for all users. * @param array $userData * @param bool|false|SocialAccount $socialAccount - * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector + * @param bool $emailVerified + * @return RedirectResponse|Redirector * @throws UserRegistrationException - * @throws ConfirmationEmailException */ - protected function registerUser(array $userData, $socialAccount = false) + protected function registerUser(array $userData, $socialAccount = false, $emailVerified = false) { - if (setting('registration-restrict')) { - $restrictedEmailDomains = explode(',', str_replace(' ', '', setting('registration-restrict'))); - $userEmailDomain = $domain = substr(strrchr($userData['email'], "@"), 1); + $registrationRestrict = setting('registration-restrict'); + + if ($registrationRestrict) { + $restrictedEmailDomains = explode(',', str_replace(' ', '', $registrationRestrict)); + $userEmailDomain = $domain = mb_substr(mb_strrchr($userData['email'], "@"), 1); if (!in_array($userEmailDomain, $restrictedEmailDomains)) { throw new UserRegistrationException(trans('auth.registration_email_domain_invalid'), '/register'); } } - $newUser = $this->userRepo->registerNew($userData); + $newUser = $this->userRepo->registerNew($userData, $emailVerified); if ($socialAccount) { $newUser->socialAccounts()->save($socialAccount); } - if (setting('registration-confirmation') || setting('registration-restrict')) { + if ((setting('registration-confirmation') || $registrationRestrict) && !$emailVerified) { $newUser->save(); try { @@ -180,13 +182,13 @@ class RegisterController extends Controller */ public function getRegisterConfirmation() { - return view('auth/register-confirm'); + return view('auth.register-confirm'); } /** * Confirms an email via a token and logs the user into the system. * @param $token - * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector + * @return RedirectResponse|Redirector * @throws UserRegistrationException */ public function confirmEmail($token) @@ -204,17 +206,17 @@ class RegisterController extends Controller /** * Shows a notice that a user's email address has not been confirmed, * Also has the option to re-send the confirmation email. - * @return \Illuminate\View\View + * @return View */ public function showAwaitingConfirmation() { - return view('auth/user-unconfirmed'); + return view('auth.user-unconfirmed'); } /** * Resend the confirmation email * @param Request $request - * @return \Illuminate\View\View + * @return View */ public function resendConfirmation(Request $request) { @@ -230,7 +232,6 @@ class RegisterController extends Controller return redirect('/register/confirm'); } - $this->emailConfirmationService->sendConfirmation($user); session()->flash('success', trans('auth.email_confirm_resent')); return redirect('/register/confirm'); } @@ -239,6 +240,8 @@ class RegisterController extends Controller * Redirect to the social site for authentication intended to register. * @param $socialDriver * @return mixed + * @throws UserRegistrationException + * @throws SocialDriverNotConfigured */ public function socialRegister($socialDriver) { @@ -250,28 +253,52 @@ class RegisterController extends Controller /** * The callback for social login services. * @param $socialDriver - * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector + * @param Request $request + * @return RedirectResponse|Redirector * @throws SocialSignInException + * @throws UserRegistrationException + * @throws SocialDriverNotConfigured */ - public function socialCallback($socialDriver) + public function socialCallback($socialDriver, Request $request) { - 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 { + if (!session()->has('social-callback')) { throw new SocialSignInException(trans('errors.social_no_action_defined'), '/login'); } + + // Check request for error information + if ($request->has('error') && $request->has('error_description')) { + throw new SocialSignInException(trans('errors.social_login_bad_response', [ + 'socialAccount' => $socialDriver, + 'error' => $request->get('error_description'), + ]), '/login'); + } + + $action = session()->pull('social-callback'); + + // Attempt login or fall-back to register if allowed. + $socialUser = $this->socialAuthService->getSocialUser($socialDriver); + if ($action == 'login') { + try { + return $this->socialAuthService->handleLoginCallback($socialDriver, $socialUser); + } catch (SocialSignInAccountNotUsed $exception) { + if ($this->socialAuthService->driverAutoRegisterEnabled($socialDriver)) { + return $this->socialRegisterCallback($socialDriver, $socialUser); + } + throw $exception; + } + } + + if ($action == 'register') { + return $this->socialRegisterCallback($socialDriver, $socialUser); + } + return redirect()->back(); } /** * Detach a social account from a user. * @param $socialDriver - * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector + * @return RedirectResponse|Redirector */ public function detachSocialAccount($socialDriver) { @@ -280,14 +307,16 @@ class RegisterController extends Controller /** * Register a new user after a registration callback. - * @param $socialDriver - * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector + * @param string $socialDriver + * @param SocialUser $socialUser + * @return RedirectResponse|Redirector * @throws UserRegistrationException */ - protected function socialRegisterCallback($socialDriver) + protected function socialRegisterCallback(string $socialDriver, SocialUser $socialUser) { - $socialUser = $this->socialAuthService->handleRegistrationCallback($socialDriver); + $socialUser = $this->socialAuthService->handleRegistrationCallback($socialDriver, $socialUser); $socialAccount = $this->socialAuthService->fillSocialAccount($socialDriver, $socialUser); + $emailVerified = $this->socialAuthService->driverAutoConfirmEmailEnabled($socialDriver); // Create an array of the user data to create a new user instance $userData = [ @@ -295,7 +324,6 @@ class RegisterController extends Controller 'email' => $socialUser->getEmail(), 'password' => str_random(30) ]; - return $this->registerUser($userData, $socialAccount); + return $this->registerUser($userData, $socialAccount, $emailVerified); } - -} \ No newline at end of file +}