Browse Source

Update Facebook auth with new SDK - refs #8264

Angel Fernando Quiroz Campos 8 years ago
parent
commit
ef3ba79e44

+ 0 - 5
index.php

@@ -24,11 +24,6 @@ if (!api_is_anonymous()) {
     $header_title = " ";
 }
 
-// Facebook connexion, if activated
-/*if (api_is_facebook_auth_activated() && !api_get_user_id()) {
-    facebookConnect();
-}
-*/
 $controller = new IndexManager($header_title);
 
 //Actions

+ 142 - 77
main/auth/external_login/facebook.inc.php

@@ -13,19 +13,9 @@
 
 require_once dirname(__FILE__) . '/../../inc/global.inc.php';
 require_once dirname(__FILE__) . '/facebook.init.php';
-require_once dirname(__FILE__) . '/facebook-php-sdk/autoload.php';
-
-use Facebook\FacebookSession;
-use Facebook\FacebookRedirectLoginHelper;
-use Facebook\FacebookRequest;
-use Facebook\FacebookSDKException;
-use Facebook\FacebookRequestException;
 
 require_once dirname(__FILE__) . '/functions.inc.php';
 
-// dont rename $facebook_config to $facebookConfig otherwise get a "Facebook\\FacebookSDKException"
-FacebookSession::setDefaultApplication($facebook_config['appId'], $facebook_config['secret']);
-
 /**
  * This function connect to facebook and retrieves the user info
  * If user does not exist in chamilo, it creates it and logs in
@@ -33,74 +23,144 @@ FacebookSession::setDefaultApplication($facebook_config['appId'], $facebook_conf
  */
 function facebookConnect()
 {
-    global $facebook_config;
-    global $helper;
+    $fb = new \Facebook\Facebook([
+        'app_id' => $GLOBALS['facebook_config']['appId'],
+        'app_secret' => $GLOBALS['facebook_config']['secret'],
+        'default_graph_version' => 'v2.2'
+    ]);
+
+    $helper = $fb->getRedirectLoginHelper();
+
+    try {
+        $accessToken = $helper->getAccessToken();
+    } catch(Facebook\Exceptions\FacebookResponseException $e) {
+        Display::addFlash(
+            Display::return_message('Facebook Graph returned an error: ' . $e->getMessage(), 'error')
+        );
+
+        header('Location: ' . api_get_path(WEB_PATH));
+        exit;
+    } catch(Facebook\Exceptions\FacebookSDKException $e) {
+        Display::addFlash(
+            Display::return_message('Facebook SDK returned an error: ' . $e->getMessage(), 'error')
+        );
+
+        header('Location: ' . api_get_path(WEB_PATH));
+        exit;
+    }
+
+    if (!isset($accessToken)) {
+        if (!$helper->getError()) {
+            return;
+        }
+
+        if (isset($_GET['loginFailed'])) {
+            return;
+        }
+
+        $error = implode('<br>', [
+            'Error: ' . $helper->getError(),
+            'Error Code: ' . $helper->getErrorCode(),
+            'Error Reason: ' . $helper->getErrorReason(),
+            'Error Description: ' . $helper->getErrorDescription()
+        ]);
+
+        Display::addFlash(
+            Display::return_message($error, 'error', false)
+        );
+
+        header('Location: ' . api_get_path(WEB_PATH));
+        exit;
+    }
+
+    $oAuth2Client = $fb->getOAuth2Client();
+    $tokenMetadata = $oAuth2Client->debugToken($accessToken);
+    $tokenMetadata->validateAppId($GLOBALS['facebook_config']['appId']);
+    $tokenMetadata->validateExpiration();
+
+    if (!$accessToken->isLongLived()) {
+        try {
+            $accessToken = $oAuth2Client->getLongLivedAccessToken($accessToken);
+        } catch (Facebook\Exceptions\FacebookSDKException $e) {
+            Display::addFlash(
+                Display::return_message('Error getting long-lived access token: ' . $e->getMessage(), 'error')
+            );
+
+            header('Location: ' . api_get_path(WEB_PATH));
+            exit;
+        }
+    }
 
     try {
-        $helper = new FacebookRedirectLoginHelper($facebook_config['return_url']);
-        $session = $helper->getSessionFromRedirect();
-        // see if we have a session
-        if (isset($session)) {
-            // graph api request for user data
-            $request = new FacebookRequest($session, 'GET', '/me?fields=id,first_name,last_name,email,locale');
-            $response = $request->execute();
-            // get response
-            $graphObject = $response->getGraphObject(Facebook\GraphUser::className());
-            $username = changeToValidChamiloLogin($graphObject->getProperty('email'));
-            $email = $graphObject->getProperty('email');
-            $locale = $graphObject->getProperty('locale');
-            $language = facebookPluginGetLanguage($locale);
-            if (!$language) {
-                $language='en_US';
-            }
-
-            //Checks if user already exists in chamilo
-            $u = array(
-                'firstname' => $graphObject->getProperty('first_name'),
-                'lastname' => $graphObject->getProperty('last_name'),
-                'status' => STUDENT,
-                'email' => $graphObject->getProperty('email'),
-                'username' => $username,
-                'language' => $language,
-                'password' => 'facebook',
-                'auth_source' => 'facebook',
-                // 'courses' => $user_info['courses'],
-                // 'profile_link' => $user_info['profile_link'],
-                // 'worldwide_bu' => $user_info['worlwide_bu'],
-                // 'manager' => $user_info['manager'],
-                'extra' => array()
+        $response = $fb->get('/me?fields=id,first_name,last_name,locale,email', $accessToken->getValue());
+    } catch(Facebook\Exceptions\FacebookResponseException $e) {
+        Display::addFlash(
+            Display::return_message('Graph returned an error: ' . $e->getMessage(), 'error')
+        );
+
+        header('Location: ' . api_get_path(WEB_PATH));
+        exit;
+    } catch(Facebook\Exceptions\FacebookSDKException $e) {
+        Display::addFlash(
+            Display::return_message('Facebook SDK returned an error: ' . $e->getMessage(), 'error')
+        );
+
+        header('Location: ' . api_get_path(WEB_PATH));
+        exit;
+    }
+
+    $user = $response->getGraphUser();
+    $language = facebookPluginGetLanguage($user['locale']);
+
+    if (!$language) {
+        $language = 'en_US';
+    }
+
+    $u = [
+        'firstname' => $user->getFirstName(),
+        'lastname' => $user->getLastName(),
+        'status' => STUDENT,
+        'email' => $user->getEmail(),
+        'username' => changeToValidChamiloLogin($user->getEmail()),
+        'language' => $language,
+        'password' => 'facebook',
+        'auth_source' => 'facebook',
+        'extra' => array()
+    ];
+    $chamiloUinfo = api_get_user_info_from_email($user->getEmail());
+
+    $_user['uidReset'] = true;
+    $_user['language'] = $language;
+
+    if ($chamiloUinfo === false) {
+        // We have to create the user
+        $chamilo_uid = external_add_user($u);
+
+        if ($chamilo_uid === false) {
+            Display::addFlash(
+                Display::return_message(get_lang('UserNotRegistered'), 'error')
             );
 
-            $chamiloUinfo = api_get_user_info_from_email($email);
-            if ($chamiloUinfo === false) {
-                // we have to create the user
-                $chamilo_uid = external_add_user($u);
-                if ($chamilo_uid !== false) {
-                    $_user['user_id'] = $chamilo_uid;
-                    $_user['uidReset'] = true;
-                    $_SESSION['_user'] = $_user;
-                    header('Location:' . api_get_path(WEB_PATH));
-                    exit();
-                } else {
-                    return false;
-                }
-            } else {
-                // User already exists, update info and login
-                $chamilo_uid = $chamiloUinfo['user_id'];
-                $u['user_id'] = $chamilo_uid;
-                external_update_user($u);
-                $_user['user_id'] = $chamilo_uid;
-                $_user['uidReset'] = true;
-                $_SESSION['_user'] = $_user;
-                header('Location:' . api_get_path(WEB_PATH));
-                exit();
-            }
+            header('Location: ' . api_get_path(WEB_PATH));
+            exit;
         }
-    } catch (FacebookRequestException $ex) {
-        echo $ex;
-    } catch (Exception $ex) {
-        // When validation fails or other local issues
+
+        $_user['user_id'] = $chamilo_uid;
+        $_SESSION['_user'] = $_user;
+
+        header('Location: ' . api_get_path(WEB_PATH));
+        exit();
     }
+
+    // User already exists, update info and login
+    $chamilo_uid = $chamiloUinfo['user_id'];
+    $u['user_id'] = $chamilo_uid;
+    external_update_user($u);
+    $_user['user_id'] = $chamilo_uid;
+    $_SESSION['_user'] = $_user;
+
+    header('Location: ' . api_get_path(WEB_PATH));
+    exit();
 }
 
 /**
@@ -109,11 +169,16 @@ function facebookConnect()
  */
 function facebookGetLoginUrl()
 {
-    global $facebook_config;
-    $helper = new FacebookRedirectLoginHelper($facebook_config['return_url']);
-    $loginUrl =   $helper->getLoginUrl(
-        array('scope' => 'email')
-    );
+    $fb = new \Facebook\Facebook([
+        'app_id' => $GLOBALS['facebook_config']['appId'],
+        'app_secret' => $GLOBALS['facebook_config']['secret'],
+        'default_graph_version' => 'v2.2'
+    ]);
+
+    $helper = $fb->getRedirectLoginHelper();
+    $loginUrl = $helper->getLoginUrl(api_get_path(WEB_PATH) . '?action=fbconnect', [
+        'email'
+    ]);
 
     return $loginUrl;
 }

+ 1 - 1
main/inc/lib/usermanager.lib.php

@@ -860,7 +860,7 @@ class UserManager
         $encrypt_method = '',
         $send_email = false,
         $reset_password = 0,
-        $address
+        $address = null
     ) {
         $hook = HookUpdateUser::create();
         if (!empty($hook)) {

+ 1 - 1
main/install/configuration.dist.php

@@ -67,7 +67,7 @@ $_configuration['url_append'] = '{URL_APPEND_PATH}';
 // $extAuthSource["extldap"]["newUser"] = $_configuration['root_sys']."main/auth/external_login/newUser.ldap.php";
 //
 // FACEBOOK IMPLEMENTATION BASED ON external_login info
-// -> Uncomment the line bellow to activate Facebook Auth AND edit main/auth/external_login/ldap.conf.php for configuration
+// -> Uncomment the line bellow to activate Facebook Auth AND edit app/config/auth.conf.php for configuration
 // $_configuration['facebook_auth'] = 1;
 //
 // OTHER EXTERNAL LOGIN INFORMATION