. */ namespace App\Http\Controllers; use App\Models\Activity; use App\Models\User; use Illuminate\Support\Facades\Auth; use Carbon\Carbon; use Illuminate\Support\Facades\DB; use League\OAuth2\Client\Provider\Exception\IdentityProviderException; use League\OAuth2\Client\Token\AccessToken; use Illuminate\Support\Facades\Log; use Poniverse\Lib\Client; use Illuminate\Support\Facades\Redirect; use Illuminate\Support\Facades\Request; class AuthController extends Controller { protected $poniverse; public function __construct() { $this->poniverse = new Client(config('poniverse.client_id'), config('poniverse.secret'), new \GuzzleHttp\Client()); } public function getLogin() { if (Auth::guest()) { return redirect( $this->poniverse ->getOAuthProvider(['redirectUri' => action('AuthController@getOAuth')]) ->getAuthorizationUrl()); } return redirect('/'); } public function postLogout() { Auth::logout(); return redirect('/'); } public function getOAuth() { $oauthProvider = $this->poniverse->getOAuthProvider(); try { $accessToken = $oauthProvider->getAccessToken('authorization_code', [ 'code' => Request::query('code'), 'redirect_uri' => action('AuthController@getOAuth'), ]); $this->poniverse->setAccessToken($accessToken); $resourceOwner = $oauthProvider->getResourceOwner($accessToken); } catch (IdentityProviderException $e) { Log::error($e); return redirect('/')->with( 'message', 'Unfortunately we are having problems attempting to log you in at the moment. Please try again at a later time.' ); } /** @var \Poniverse\Lib\Entity\Poniverse\User $poniverseUser */ $poniverseUser = $resourceOwner; $token = DB::table('oauth2_tokens') ->where('external_user_id', '=', $poniverseUser->id) ->where('service', '=', 'poniverse') ->first(); $setData = [ 'access_token' => $accessToken, 'expires' => Carbon::createFromTimestampUTC($accessToken->getExpires()), 'type' => 'Bearer', ]; if (! empty($accessToken->getRefreshToken())) { $setData['refresh_token'] = $accessToken->getRefreshToken(); } if ($token) { //User already exists, update access token and refresh token if provided. DB::table('oauth2_tokens')->where('id', '=', $token->id)->update($setData); return $this->loginRedirect(User::find($token->user_id)); } // Check by login name to see if they already have an account $user = User::findOrCreate($poniverseUser->username, $poniverseUser->display_name, $poniverseUser->email); if ($user->wasRecentlyCreated) { // We need to insert a new token row :O $setData['user_id'] = $user->id; $setData['external_user_id'] = $poniverseUser->id; $setData['service'] = 'poniverse'; DB::table('oauth2_tokens')->insert($setData); // Subscribe the user to default email notifications foreach (Activity::DEFAULT_EMAIL_TYPES as $activityType) { $user->emailSubscriptions()->create(['activity_type' => $activityType]); } } return $this->loginRedirect($user); } /** * Processes requests to update a user's Poniverse information. * * @return \Illuminate\Http\JsonResponse */ public function postPoniverseAccountSync() { $poniverseId = Request::get('id'); $updatedAttribute = Request::get('attribute'); // Only email address updates are supported at this time. if ('email' !== $updatedAttribute) { return \Response::json(['message' => 'Unsupported Poniverse account attribute.'], 400); } $user = User::wherePoniverseId($poniverseId)->first(); /** @var AccessToken $accessToken */ $accessToken = $user->getAccessToken(); if ($accessToken->hasExpired()) { $accessToken = $this->poniverse->getOAuthProvider()->getAccessToken('refresh_token', ['refresh_token' => $accessToken->getRefreshToken()]); $user->setAccessToken($accessToken); } /** @var \Poniverse\Lib\Entity\Poniverse\User $newUserData */ $newUserData = $this->poniverse->getOAuthProvider()->getResourceOwner($accessToken); $user->{$updatedAttribute} = $newUserData->{$updatedAttribute}; $user->save(); return \Response::json(['message' => 'Successfully updated this user!'], 200); } protected function loginRedirect($user, $rememberMe = true) { Auth::login($user, $rememberMe); return redirect('/'); } }