middleware('guest', ['except' => 'logout']); $this->generator = $generator; } public function logout(Request $request) { $this->guard()->logout(); $request->session()->invalidate(); return redirect()->back(); } protected function attemptLogin(Request $request) { $isSuccessful = $this->guard()->attempt($this->credentials($request)); if ($isSuccessful) { /** @var User $user */ $user = $this->guard()->user(); // Update the social media ID if successful login and it was referred by the SSO provider $loginData = $request->getSession()->get('ssoLoginData'); if (!is_null($loginData)) { unset($loginData['name']); unset($loginData['email']); $user->fill($loginData); $user->save(); $request->getSession()->remove('ssoLoginData'); } } return $isSuccessful; } protected function credentials(Request $request) { $result = $request->only($this->username(), 'password'); // Only allow activated users to login $result['is_activated'] = true; return $result; } /** * Show the application's login form. * * @return \Illuminate\Http\Response */ public function showLoginForm(Request $request) { $previousUrl = MiscHelper::ensureHasTrailingSlash($this->generator->previous(false)); $homeUrl = MiscHelper::ensureHasTrailingSlash(route('home')); if (UserConfig::get('social_user_feeds') && (empty($previousUrl) || $previousUrl == $homeUrl)) { $previousUrl = route('userActivityFeed'); } $request->getSession()->put('url.intended', $previousUrl); return Theme::render('auth.v2_unified', [ 'active_tab' => 'login', 'info' => $request->session()->get('info'), 'is_sso' => false ]); } /** * Show the application's login form (for a social media-linked account). * * @return \Illuminate\Http\Response */ public function showLoginFormSso(Request $request) { // Social media login info $loginData = $request->getSession()->get('ssoLoginData'); if (is_null($loginData)) { // No SSO data in session, use the normal login screen return redirect(route('login')); } return Theme::render('auth.v2_unified', [ 'active_tab' => 'login', 'info' => $request->session()->get('info'), 'is_sso' => true, 'login_data' => $loginData ]); } /** * Redirect the user to the Facebook authentication page. * * @return \Illuminate\Http\Response */ public function redirectToFacebook() { $socialite = $this->setSocialiteConfigForFacebook(); if (is_null($socialite)) { return redirect(route('login')); } return $socialite->driver('facebook')->redirect(); } /** * Redirect the user to the Google authentication page. * * @return \Illuminate\Http\Response */ public function redirectToGoogle() { $socialite = $this->setSocialiteConfigForGoogle(); if (is_null($socialite)) { return redirect(route('login')); } return $socialite->driver('google')->redirect(); } /** * Redirect the user to the Twitter authentication page. * * @return \Illuminate\Http\Response */ public function redirectToTwitter() { $socialite = $this->setSocialiteConfigForTwitter(); if (is_null($socialite)) { return redirect(route('login')); } return $socialite->driver('twitter')->redirect(); } /** * Obtain the user information from Facebook. * * @return \Illuminate\Http\Response */ public function handleFacebookCallback(Request $request) { $socialite = $this->setSocialiteConfigForFacebook(); if (is_null($socialite)) { return redirect(route('login')); } $facebookUser = $socialite->driver('facebook')->user(); return $this->processSocialMediaLogin($request, 'facebook_id', $facebookUser); } /** * Obtain the user information from Google. * * @return \Illuminate\Http\Response */ public function handleGoogleCallback(Request $request) { $socialite = $this->setSocialiteConfigForGoogle(); if (is_null($socialite)) { return redirect(route('login')); } $googleUser = $socialite->driver('google')->user(); return $this->processSocialMediaLogin($request, 'google_id', $googleUser); } /** * Obtain the user information from Twitter. * * @return \Illuminate\Http\Response */ public function handleTwitterCallback(Request $request) { $socialite = $this->setSocialiteConfigForTwitter(); if (is_null($socialite)) { return redirect(route('login')); } $twitterUser = $socialite->driver('twitter')->user(); return $this->processSocialMediaLogin($request, 'twitter_id', $twitterUser); } private function getSocialMediaConfig($socialMediaEnabledField, $socialMediaExternalServiceIdField) { if (boolval(UserConfig::get($socialMediaEnabledField))) { $externalServiceID = intval(UserConfig::get($socialMediaExternalServiceIdField)); $externalService = ExternalService::where('id', $externalServiceID)->first(); return $externalService; } return null; } private function processSocialMediaLogin(Request $request, $socialMediaIdField, $socialMediaUser) { $userBySocialMediaId = User::where($socialMediaIdField, $socialMediaUser->getId())->first(); if (!is_null($userBySocialMediaId)) { // We have an existing user for this Facebook ID - log them in $this->guard()->login($userBySocialMediaId); return redirect(route('home')); } // Some providers (*cough*Twitter*cough*) don't give e-mail addresses without explicit permission/additional // verification if (!is_null($socialMediaUser->email)) { $userByEmailAddress = User::where('email', $socialMediaUser->getEmail())->first(); if (!is_null($userByEmailAddress)) { // We have an existing user with the e-mail address associated with the Facebook account // Prompt for the password for that account $request->getSession()->put('ssoLoginData', [ 'name' => $socialMediaUser->getName(), 'email' => $socialMediaUser->getEmail(), $socialMediaIdField => $socialMediaUser->getId(), 'is_activated' => true ]); return redirect(route('auth.login_sso')); } } // We don't have an existing user - prompt for registration $request->getSession()->put('ssoRegisterData', [ 'name' => $socialMediaUser->getName(), 'email' => $socialMediaUser->getEmail(), $socialMediaIdField => $socialMediaUser->getId(), 'is_activated' => true ]); return redirect(route('auth.register_sso')); } private function setSocialiteConfigForFacebook() { $facebookConfig = $this->getSocialMediaConfig( 'social_facebook_login', 'facebook_external_service_id' ); if (is_null($facebookConfig)) { return null; } $socialite = app()->make(\Laravel\Socialite\Contracts\Factory::class); $socialite->extend( 'facebook', function ($app) use ($socialite, $facebookConfig) { $config = [ 'client_id' => trim(decrypt($facebookConfig->app_id)), 'client_secret' => trim(decrypt($facebookConfig->app_secret)), 'redirect' => route('login_callback.facebook') ]; return $socialite->buildProvider(FacebookProvider::class, $config); } ); return $socialite; } private function setSocialiteConfigForGoogle() { $googleConfig = $this->getSocialMediaConfig( 'social_google_login', 'google_external_service_id' ); if (is_null($googleConfig)) { return null; } $socialite = app()->make(\Laravel\Socialite\Contracts\Factory::class); $socialite->extend( 'google', function ($app) use ($socialite, $googleConfig) { $config = [ 'client_id' => trim(decrypt($googleConfig->app_id)), 'client_secret' => trim(decrypt($googleConfig->app_secret)), 'redirect' => route('login_callback.google') ]; return $socialite->buildProvider(GoogleProvider::class, $config); } ); return $socialite; } private function setSocialiteConfigForTwitter() { $twitterConfig = $this->getSocialMediaConfig( 'social_twitter_login', 'twitter_external_service_id' ); if (is_null($twitterConfig)) { return null; } $socialite = app()->make(\Laravel\Socialite\Contracts\Factory::class); $socialite->extend( 'twitter', function ($app) use ($socialite, $twitterConfig) { $config = [ 'identifier' => trim(decrypt($twitterConfig->app_id)), 'secret' => trim(decrypt($twitterConfig->app_secret)), 'callback_uri' => route('login_callback.twitter') ]; return new TwitterProvider($app['request'], new TwitterServer($config)); } ); return $socialite; } }