[geeklog-cvs] geeklog: Proper resynch for a Facebook based user account. It wi...

geeklog-cvs at lists.geeklog.net geeklog-cvs at lists.geeklog.net
Sun Feb 13 09:37:34 EST 2011


changeset 8104:4e8d1f4ade80
url:  http://project.geeklog.net/cgi-bin/hgwebdir.cgi/geeklog/rev/4e8d1f4ade80
user: Tom <websitemaster at cogeco.net>
date: Sun Feb 13 09:36:23 2011 -0500
description:
Proper resynch for a Facebook based user account. It will not re-authenticate if it is not required. (Contributor: Mark Howard)

diffstat:

 public_html/usersettings.php                 |   73 ++++++++++-----
 system/classes/oauth/facebook.auth.class.php |  112 +++++++++++++++++++++---
 system/classes/oauthhelper.class.php         |  123 ++++++++++++++++----------
 3 files changed, 220 insertions(+), 88 deletions(-)

diffs (truncated from 612 to 300 lines):

diff -r 61d374e877c6 -r 4e8d1f4ade80 public_html/usersettings.php
--- a/public_html/usersettings.php	Sat Feb 12 23:12:18 2011 +0100
+++ b/public_html/usersettings.php	Sun Feb 13 09:36:23 2011 -0500
@@ -981,12 +981,15 @@
             }
         }
     }
-             
+
     // a quick spam check with the unfiltered field contents
     $profile = '<h1>' . $LANG04[1] . ' ' . $_USER['username'] . '</h1><p>';
-    $profile .= (empty($service)) ? COM_createLink($A['homepage'], $A['homepage']) . '<br' . XHTML . '>' : '';
+    // this is a hack, for some reason remoteservice links made SPAMX SLV check barf
+    if (empty($service)) {
+        $profile .= COM_createLink($A['homepage'], $A['homepage']) . '<br' . XHTML . '>';
+    }
     $profile .= $A['location'] . '<br' . XHTML . '>' . $A['sig'] . '<br' . XHTML . '>'
-             . $A['about'] . '<br' . XHTML . '>' . $A['pgpkey'] . '</p>';
+                . $A['about'] . '<br' . XHTML . '>' . $A['pgpkey'] . '</p>';
     $result = PLG_checkforSpam ($profile, $_CONF['spamx']);
     if ($result > 0) {
         COM_displayMessageAndAbort ($result, 'spamx', 403, 'Forbidden');
@@ -1116,20 +1119,26 @@
                     $status = -1;
                     $msg = 115; // Remote service has been disabled.
                 } else {
-                    // Send request to OAuth Service for user information
-                    require_once $_CONF['path_system'] . 'classes/oauthhelper.class.php';
-        
-                    $consumer = new OAuthConsumer($service);
-
                     $query[] = '';
                     $callback_url = $_CONF['site_url'] . '/usersettings.php?mode=synch&oauth_login=' . $service;
 
-                    $url = $consumer->find_identity_info($callback_url, $query);
-                    if (empty($url)) {
-                        $msg = 110; // Can not get URL for authentication.'
+                    if ($service == 'oauth.facebook') {
+                        // facebook does resynch during refresh
+                        return COM_refresh($callback_url);
                     } else {
-                        header('Location: ' . $url);
-                        exit;
+                        // all other services use reauth/callback method
+                        // send request to OAuth Service for user information
+                        require_once $_CONF['path_system'] . 'classes/oauthhelper.class.php';
+            
+                        $consumer = new OAuthConsumer($service);
+    
+                        $url = $consumer->find_identity_info($callback_url, $query);
+                        if (empty($url)) {
+                            $msg = 110; // Can not get URL for authentication.'
+                        } else {
+                            header('Location: ' . $url);
+                            exit;
+                        }
                     }
                 }            
             }
@@ -1400,28 +1409,42 @@
                 $msg = 114; // Your re-synch with your remote account has failed but your other account information has been successfully saved.
             } else {
                 $query = array_merge($_GET, $_POST);
-                $service = $_GET['oauth_login'];  
-                $callback_url = $_CONF['site_url'] . '/usersettings.php?mode=synch&oauth_login=' . $service;
+                $service = $query['oauth_login'];
     
                 require_once $_CONF['path_system'] . 'classes/oauthhelper.class.php';
 
                 $consumer = new OAuthConsumer($service);
-                $callback_query_string = $consumer->getCallback_query_string();
-                $cancel_query_string = $consumer->getCancel_query_string();
 
-                if (!isset($query[$callback_query_string]) && (empty($cancel_query_string) || !isset($query[$cancel_query_string]))) {
-                    $msg = 114; // Your re-synch with your remote account has failed but your other account information has been successfully saved.
-                } elseif (isset($query[$callback_query_string])) {
-                    $oauth_userinfo = $consumer->sreq_userinfo_response($query);
+                if ($service == 'oauth.facebook') {
+                    // facebook resynchronizations are easier to perform
+                    // we'll use a FB consumer-specific hack/method
+                    $oauth_userinfo = $consumer->refresh_userinfo();
                     if (empty($oauth_userinfo)) {
-                        $msg = 111; // Authentication error.
+                        $msg = 114; // account information saved but resynch failed
+                        COM_errorLog($MESSAGE[$msg]);
                     } else {
                         $consumer->doSynch($oauth_userinfo);
                     }
-                } elseif (!empty($cancel_query_string) && isset($query[$cancel_query_string])) {
-                        $msg = 112; // Certification has been canceled.
                 } else {
-                    $msg = 91; // You specified an invalid identity URL.
+                    // standard OAuth services utilize multiple callback method
+                    $callback_url = $_CONF['site_url'] . '/usersettings.php?mode=synch&oauth_login=' . $service;
+                    $callback_query_string = $consumer->getCallback_query_string();
+                    $cancel_query_string = $consumer->getCancel_query_string();
+    
+                    if (!isset($query[$callback_query_string]) && (empty($cancel_query_string) || !isset($query[$cancel_query_string]))) {
+                        $msg = 114; // Your re-synch with your remote account has failed but your other account information has been successfully saved.
+                    } elseif (isset($query[$callback_query_string])) {
+                        $oauth_userinfo = $consumer->sreq_userinfo_response($query);
+                        if (empty($oauth_userinfo)) {
+                            $msg = 111; // Authentication error.
+                        } else {
+                            $consumer->doSynch($oauth_userinfo);
+                        }
+                    } elseif (!empty($cancel_query_string) && isset($query[$cancel_query_string])) {
+                            $msg = 112; // Certification has been canceled.
+                    } else {
+                        $msg = 91; // You specified an invalid identity URL.
+                    }
                 }
             }   
             
diff -r 61d374e877c6 -r 4e8d1f4ade80 system/classes/oauth/facebook.auth.class.php
--- a/system/classes/oauth/facebook.auth.class.php	Sat Feb 12 23:12:18 2011 +0100
+++ b/system/classes/oauth/facebook.auth.class.php	Sun Feb 13 09:36:23 2011 -0500
@@ -43,14 +43,18 @@
     public $url_userinfo_photo = 'https://graph.facebook.com/me/picture';
     public $callback_query_string = 'code';
     public $cancel_query_string = 'error_reason';
-    
+
     public function __construct() {
         $this->request = new HTTP_Request2;
         $this->request->setConfig('ssl_verify_peer', false);
         $this->request->setHeader('Accept-Encoding', '.*');
     }
-    
+
     public function find_identity_info($callback_url, $query) {
+        // COM_errorLog("FB:find_identity_info()----------------------");
+        // COM_errorLog("clearing cookies");
+        SEC_setCookie($_COOKIE['request_token'], '', time() - 10000);
+        SEC_setCookie($_COOKIE['request_token_secret'], '', time() - 10000);
         $params = array(
             'client_id' => $this->consumer_key,
             'redirect_uri' => $callback_url,
@@ -58,13 +62,16 @@
         );
         return $this->url_authorize . '?' . http_build_query($params, null, '&');
     }
-    
+
     public function sreq_userinfo_response($query) {
         global $_CONF;
-        
+
+        // COM_errorLog("FB:sreq_userinfo_response()------------------");
         $userinfo = array();
-        
+
         try {
+            // COM_errorLog("upon entry, _COOKIE[request_token]={$_COOKIE['request_token']}");
+            // COM_errorLog("upon entry, _COOKIE[request_token_secret]={$_COOKIE['request_token_secret']}");
             $verifier = $query[$this->callback_query_string];
             $callback_url = $_CONF['site_url'] . '/users.php?oauth_login=facebook';
             $params = array(
@@ -73,41 +80,116 @@
                 'client_secret' => $this->consumer_secret,
                 'code' => $verifier,
             );
+
+            // first request obtains access token
+
             $url_auth = $this->url_accessToken . '?' . http_build_query($params, null, '&');
+            // COM_errorLog("FB:sreq_userinfo_response() req1: " . $url_auth);
             $this->request->setUrl($url_auth);
             $response = $this->request->send();
             $rdata = $response->getBody();
+            // COM_errorLog("FB:sreq_userinfo_response() rsp1: " . $rdata);
             parse_str($rdata, $data);
             if (isset($data['access_token'])) {
                 $this->token = $data['access_token'];
+                SEC_setCookie('request_token', $data['access_token']);
             } else {
+                // COM_errorLog("error: access_token not retrieved");
                 $data = json_decode($rdata);
                 if (!empty($data->error)) {
                     $this->errormsg = $data->error->message;
                 }
-                return;
+                return; // early exit
             }
-            
+
+            // second request obtains what basic user info that the graphs API
+            // will give us without additional requests (everything but photo)
+
             $params = array('access_token' => $this->token);
             $url_me = $this->url_userinfo . '?' . http_build_query($params, null, '&');
+            // COM_errorLog("FB:sreq_userinfo_response() req2: " . $url_me);
             $this->request->setUrl($url_me);
             $response = $this->request->send();
             $rdata = $response->getBody();
+            // COM_errorLog("FB:sreq_userinfo_response() rsp2: " . $rdata);
             $data = json_decode($rdata);
             if (!empty($data->error)) {
                 $this->errormsg = $data->error->message;
                 return;
             }
             $userinfo = $data;
-            
+
+            // third request retrieves the user's photo URL
+
             $url_photo = $this->url_userinfo_photo . '?' . http_build_query($params, null, '&');
             $this->request->setUrl($url_photo);
+            // COM_errorLog("FB:sreq_serinfo_response() req3: " . $url_photo);
             $response = $this->request->send();
-            $rdata = $response->getHeader();
-            $userinfo->photo = $rdata['location'];
+            if(($response->getStatus() == '302') AND ($response->getReasonPhrase() == 'Found')) {
+                $header = $response->getHeader();
+                $userinfo->photo_url = $header['location'];
+                // COM_errorLog("photo_url=" . $userinfo->photo_url);
+            } else {
+                $userinfo->photo_url = '';
+                // COM_errorLog("photo_url=(null)");
+            }
+
         } catch (Exception $e) {
             $this->errormsg = get_class($e) . ': ' . $e->getMessage();
         }
+        // COM_errorLog("upon exit, request_token cookie={$this->token}");
+        // COM_errorLog("upon entry, request_token secret cookie={$this->token_secret}");
+        return $userinfo;
+    }
+
+    public function refresh_userinfo() {
+
+        // COM_errorLog("FB:refresh_userinfo()------------------");
+        $userinfo = array();
+
+        try {
+            // COM_errorLog("upon entry, _COOKIE[request_token]={$_COOKIE['request_token']}");
+            // COM_errorLog("upon entry, _COOKIE[request_token_secret]={$_COOKIE['request_token_secret']}");
+
+            // retrieve the access token
+            $this->token = $_COOKIE['request_token'];
+            if(empty($this->token)) {
+                exit;
+            } else {
+                // retrieve the userinfo
+                $params = array('access_token' => $this->token);
+                $url_me = $this->url_userinfo . '?' . http_build_query($params, null, '&');
+                // COM_errorLog("FB:refresh_userinfo() req1: " . $url_me);
+                $this->request->setUrl($url_me);
+                $response = $this->request->send();
+                $rdata = $response->getBody();
+                // COM_errorLog("FB:refresh_userinfo() rsp1: " . $rdata);
+                $data = json_decode($rdata);
+                if (!empty($data->error)) {
+                    $this->errormsg = $data->error->message;
+                    return;
+                }
+                $userinfo = $data;
+
+                // retrieve the user's photo URL
+                $url_photo = $this->url_userinfo_photo . '?' . http_build_query($params, null, '&');
+                $this->request->setUrl($url_photo);
+                // COM_errorLog("FB:refresh_userinfo() req2: " . $url_photo);
+                $response = $this->request->send();
+                if(($response->getStatus() == '302') AND ($response->getReasonPhrase() == 'Found')) {
+                    $header = $response->getHeader();
+                    $userinfo->photo_url = $header['location'];
+                    // COM_errorLog("photo_url=" . $userinfo->photo_url);
+                } else {
+                    $userinfo->photo_url = '';
+                    // COM_errorLog("photo_url=(null)");
+                }
+            }
+
+        } catch (Exception $e) {
+            $this->errormsg = get_class($e) . ': ' . $e->getMessage();
+        }
+
         return $userinfo;
     }
 
@@ -121,7 +203,7 @@
             'homepage'       => $info->link,
             'remoteusername' => addslashes($info->id),
             'remoteservice'  => 'oauth.facebook',
-            'remotephoto'    => $info->photo,
+            'remotephoto'    => $info->photo_url,
         );
         return $users;
     }
@@ -138,11 +220,11 @@
 
 if ( !function_exists('json_decode') ){
     function json_decode($json)
-    { 
+    {
         // Author: walidator.info 2009
         $comment = false;
         $out = '$x=';
-       
+



More information about the geeklog-cvs mailing list