Created
May 20, 2016 05:48
-
-
Save aliukevicius/f616a941f7b9f602841e6fa832dbc24e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Facebook\FacebookSession; | |
use Facebook\FacebookRedirectLoginHelper; | |
use Facebook\FacebookRequest; | |
use App\Repositories\Oauth\OauthRepositoryInterface; | |
use App\Repositories\User\UserRepositoryInterface; | |
use App\Entities\User as UserEntity; | |
use App\Repositories\UserProfile\UserProfileRepositoryInterface; | |
use App\Exceptions\ValidationException; | |
use App\Services\Validators\UserValidator; | |
use App\Repositories\File\FileRepositoryInterface; | |
use App\Entities\File; | |
class OauthController extends \BaseController { | |
protected $userRepository; | |
protected $userProfileRepository; | |
protected $fileRepository; | |
public function __construct( | |
OauthRepositoryInterface $oauthRepositoryInterface, | |
UserRepositoryInterface $userRepositoryInterface, | |
UserProfileRepositoryInterface $userProfileRepositoryInterface, | |
FileRepositoryInterface $fileRepositoryInterface, | |
UserValidator $validator | |
) | |
{ | |
$this->repository = $oauthRepositoryInterface; | |
$this->userRepository = $userRepositoryInterface; | |
$this->userProfileRepository = $userProfileRepositoryInterface; | |
$this->validator = $validator; | |
$this->fileRepository = $fileRepositoryInterface; | |
$this->translationFile = 'oauth'; | |
} | |
public function fbAuth() | |
{ | |
$error = Input::get('error'); | |
$authAction = Session::get('fbAuthAction'); | |
if ($error != null) { | |
if ($authAction == 'register') { | |
return $this->returnResponse('user.registerForm'); | |
} else if ($authAction == 'linkAccount') { | |
return $this->returnResponse('user.profileEditForm'); | |
} else { | |
return Redirect::to('/'); | |
} | |
} | |
$loginHelper = $this->getFbLoginHelper(Request::url()); | |
try { | |
$session = $loginHelper->getSessionFromRedirect(); | |
} catch(\Exception $ex) { | |
Notification::error($this->t('oAuthError')); | |
return Redirect::to('/'); | |
} | |
if ($session) { | |
// authentication successful. | |
$request = new FacebookRequest($session, 'GET', '/me'); | |
$response = $request->execute(); | |
$fbUserData = $response->getGraphObject()->asArray(); | |
$request = new FacebookRequest($session, 'GET', '/me/permissions'); | |
$response = $request->execute(); | |
$permissions = $response->getGraphObject()->asArray(); | |
// check if we have permission to see users email address | |
foreach ($permissions as $p) { | |
if ($p->permission == 'email' && $p->status != 'granted') { | |
// we need to know that on next auth attempt we need to rerequest permissions | |
Session::set('fbAuthReRequestPermissions', true); | |
Notification::error(t('oauth.fbNeedEmailPermission')); | |
if ($authAction == 'linkAccount') { | |
return $this->returnResponse('user.profileEditForm'); | |
} else { | |
return Redirect::to('/'); // redirect user to frontPage | |
} | |
} | |
} | |
// we have needed permission and don't need to reRequest them nex time | |
Session::remove('fbAuthReRequestPermissions'); | |
$token = $session->getAccessToken()->extend(); // get extended token | |
if ($authAction == 'register') { | |
$oAuth = $this->repository->getOauth('facebook', $fbUserData['id']); | |
// if user with this FB account doesn't exist | |
if ($oAuth == null) { | |
$userData = [ | |
'email' => $fbUserData['email'], | |
// set random string as password. Until user changes his password he won't be able to login with password | |
'password' => 'oauth', // just so we know that user doesn`t have real password | |
'status' => UserEntity::$statusIncompleteProfile, // because we don't get Fb picture | |
]; | |
try { | |
$this->validator->isValidOauthRegsiter($userData, $this->translationFile); // check if email is unique | |
} catch (ValidationException $e) { | |
return $this->returnResponse('user.registerForm', null, $this->t('oauthRegisterDublicateEmail')); | |
} | |
$gender = 'M'; | |
if (isset($fbUserData['gender'])) { | |
$gender = $fbUserData['gender'] == 'male' ? 'M' : 'F'; | |
} | |
$userProfileData = [ | |
'first_name' => $fbUserData['first_name'], | |
'last_name' => $fbUserData['last_name'], | |
'sex' => $gender, | |
'public_phone' => 1, | |
'public_additional_phone' => 1 | |
]; | |
$user = $this->userRepository->create($userData); | |
$this->userRepository->addUserRole($user->user_id, 'Authenticated'); | |
$userProfileData['user_id'] = $user->user_id; | |
// get user picture from FB | |
$ch = curl_init(); | |
curl_setopt($ch, CURLOPT_URL, 'http://graph.facebook.com/'.$fbUserData['id'].'/picture?redirect=0&height=250&type=normal&width=200'); | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); | |
curl_setopt($ch, CURLOPT_FRESH_CONNECT, TRUE); | |
$pictureData = json_decode(curl_exec ($ch), true); | |
curl_close($ch); | |
if (isset($pictureData['data']['url'])) { // check if we have the picture data | |
$file = $this->fileRepository->addFileFromUrl($pictureData['data']['url'], $user->user_id, File::$statusPermanent); | |
$userProfileData['profile_picture'] = $file->file_id; | |
} | |
$this->userProfileRepository->create($userProfileData); | |
$this->repository->create([ | |
'user_id' => $user->user_id, | |
'provider' => 'facebook', | |
'token' => (string) $token, | |
'provider_id' => $fbUserData['id'], | |
'expires' => $token->getExpiresAt()->format('Y-m-d H:i:s'), | |
]); | |
CAuth::loginUsingId($user->user_id); | |
Event::fire('user.registered.facebook', [$user]); | |
return $this->returnResponse('user.profileEditForm'); | |
} else { // FB user already linked with our systems user. Just log in the user | |
$user = $oAuth->user; | |
if ($user != null) { | |
$oAuth = $this->repository->update($oAuth->oauth_id, [ | |
'token' => (string) $token, | |
'expires' => $token->getExpiresAt()->format('Y-m-d H:i:s') | |
]); | |
CAuth::login($user); | |
} else { | |
$authErrors[] = $this->t('oAuthError'); | |
} | |
} | |
return Redirect::to('/'); | |
} else if ($authAction == 'linkAccount') { | |
$oAuth = $this->repository->getOauth('facebook', $fbUserData['id']); | |
if ($oAuth == null) { | |
$app = $this->getApp(); | |
$this->repository->create([ | |
'user_id' => $app->user->user_id, | |
'provider' => 'facebook', | |
'token' => (string) $token, | |
'provider_id' => $fbUserData['id'], | |
'expires' => $token->getExpiresAt()->format('Y-m-d H:i:s'), | |
]); | |
return $this->returnResponse('user.profileEditForm', $this->t('facebbokAccountLinked')); | |
} else { // user FB user already linked with our systems user. Just logg in the user | |
return $this->returnResponse('user.profileEditForm', null, $this->t('facebookProfileLinkedWithOtherUser')); | |
} | |
} else { | |
$oAuth = $this->repository->getOauth('facebook', $fbUserData['id']); | |
if ($oAuth != null) { | |
$user = $oAuth->user; | |
if ($user != null) { | |
$oAuth = $this->repository->update($oAuth->oauth_id, [ | |
'token' => (string) $token, | |
'expires' => $token->getExpiresAt()->format('Y-m-d H:i:s') | |
]); | |
CAuth::login($user); | |
} else { | |
$authErrors[] = $this->t('oAuthError'); | |
} | |
} else { // no user found linked with this FB account | |
return $this->returnResponse('user.loginForm', null, $this->t('oauthLoginFacebookNoUser')); | |
} | |
return Redirect::to('/'); | |
} | |
} | |
// we should`t get to this point but if we get here get into panic mode and throw up. | |
throw new Exception("Facebook authentication error. Cant acquire session."); | |
} | |
/** | |
* Do Facebook authentication redirect | |
* | |
* @param $type - action type for which we performing this authentication | |
* @return \Illuminate\Http\RedirectResponse | |
*/ | |
protected function doFbAuth($type) | |
{ | |
Session::set('fbAuthAction', $type); | |
$scopes = \Config::get('oauth.providers.Facebook.scope'); | |
$loginHelper = $this->getFbLoginHelper(URL::to('/oauth/fb')); | |
$reRequestPermissions = Session::get('fbAuthReRequestPermissions', false); | |
if ($reRequestPermissions) { | |
return Redirect::to($loginHelper->getReRequestUrl($scopes)); | |
} | |
return Redirect::to($loginHelper->getLoginUrl($scopes)); | |
} | |
/** | |
* Login via oAuth provider | |
*/ | |
public function login() | |
{ | |
return $this->doFbAuth('login'); | |
} | |
/** | |
* Register via oAuth provider | |
*/ | |
public function register() | |
{ | |
return $this->doFbAuth('register'); | |
} | |
/** | |
* Link account with oAuth provider | |
*/ | |
public function linkAccount() | |
{ | |
return $this->doFbAuth('linkAccount'); | |
} | |
protected function getFbLoginHelper($redirectBackTo) | |
{ | |
if (session_status() == PHP_SESSION_NONE) { | |
session_start(); | |
} | |
$appId = \Config::get('oauth.providers.Facebook.client_id'); | |
$appSecret = \Config::get('oauth.providers.Facebook.client_secret'); | |
FacebookSession::setDefaultApplication($appId, $appSecret); | |
$helper = new FacebookRedirectLoginHelper($redirectBackTo); | |
return $helper; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment