Guard against GitHub randomly changing the access_token
authorTim Düsterhus <duesterhus@woltlab.com>
Sun, 9 Aug 2015 15:31:34 +0000 (17:31 +0200)
committerTim Düsterhus <duesterhus@woltlab.com>
Sun, 9 Aug 2015 15:32:04 +0000 (17:32 +0200)
wcfsetup/install/files/lib/action/GithubAuthAction.class.php
wcfsetup/install/files/lib/form/AccountManagementForm.class.php
wcfsetup/install/files/lib/form/RegisterForm.class.php

index fec9eca2c6c50f9bead3fbadec9c61a8afc40a93..5cc1f8b7cbcf57e2fe53dc3ebbe2b0faa8a42cc5 100644 (file)
@@ -64,8 +64,26 @@ class GithubAuthAction extends AbstractAction {
                        // check whether the token is okay
                        if (isset($data['error'])) throw new IllegalLinkException();
                        
+                       try {
+                               // fetch userdata
+                               $request = new HTTPRequest('https://api.github.com/user?access_token='.$data['access_token']);
+                               $request->execute();
+                               $reply = $request->getReply();
+                               $userData = JSON::decode(StringUtil::trim($reply['body']));
+                       }
+                       catch (SystemException $e) {
+                               // force logging
+                               $e->getExceptionID();
+                               throw new IllegalLinkException();
+                       }
+                       
                        // check whether a user is connected to this github account
-                       $user = $this->getUser($data['access_token']);
+                       $user = $this->getUser($userData['id']);
+                       if (!$user->userID) {
+                               $user = $this->getUser($data['access_token']);
+                               $userEditor = new UserEditor($user);
+                               $userEditor->update(array('authData' => 'github:'.$userData['id']));
+                       }
                        
                        if ($user->userID) {
                                // a user is already connected, but we are logged in, break
@@ -91,19 +109,6 @@ class GithubAuthAction extends AbstractAction {
                                }
                        }
                        else {
-                               try {
-                                       // fetch userdata
-                                       $request = new HTTPRequest('https://api.github.com/user?access_token='.$data['access_token']);
-                                       $request->execute();
-                                       $reply = $request->getReply();
-                                       $userData = JSON::decode(StringUtil::trim($reply['body']));
-                               }
-                               catch (SystemException $e) {
-                                       // force logging
-                                       $e->getExceptionID();
-                                       throw new IllegalLinkException();
-                               }
-                               
                                WCF::getSession()->register('__3rdPartyProvider', 'github');
                                // save data for connection
                                if (WCF::getUser()->userID) {
@@ -117,34 +122,22 @@ class GithubAuthAction extends AbstractAction {
                                        WCF::getSession()->register('__githubData', $userData);
                                        WCF::getSession()->register('__username', $userData['login']);
                                        
-                                       // check whether user has entered a public email
-                                       if (isset($userData) && isset($userData['email']) && $userData['email'] !== null) {
-                                               WCF::getSession()->register('__email', $userData['email']);
-                                       }
-                                       // fetch emails via api
-                                       else {
-                                               try {
-                                                       $request = new HTTPRequest('https://api.github.com/user/emails?access_token='.$data['access_token']);
-                                                       $request->execute();
-                                                       $reply = $request->getReply();
-                                                       $emails = JSON::decode(StringUtil::trim($reply['body']));
-                                                       
-                                                       // handle future response as well a current response (see. http://developer.github.com/v3/users/emails/)
-                                                       if (is_string($emails[0])) {
-                                                               $email = $emails[0];
-                                                       }
-                                                       else {
-                                                               $email = $emails[0]['email'];
-                                                               foreach ($emails as $tmp) {
-                                                                       if ($tmp['primary']) $email = $tmp['email'];
-                                                                       break;
-                                                               }
-                                                       }
-                                                       WCF::getSession()->register('__email', $email);
+                                       try {
+                                               $request = new HTTPRequest('https://api.github.com/user/emails?access_token='.$data['access_token']);
+                                               $request->execute();
+                                               $reply = $request->getReply();
+                                               $emails = JSON::decode(StringUtil::trim($reply['body']));
+                                               
+                                               // search primary email
+                                               $email = $emails[0]['email'];
+                                               foreach ($emails as $tmp) {
+                                                       if ($tmp['primary']) $email = $tmp['email'];
+                                                       break;
                                                }
-                                               catch (SystemException $e) { }
+                                               WCF::getSession()->register('__email', $email);
+                                       }
+                                       catch (SystemException $e) {
                                        }
-                                       
                                        WCF::getSession()->register('__githubToken', $data['access_token']);
                                        
                                        // we assume that bots won't register on github first
@@ -172,17 +165,17 @@ class GithubAuthAction extends AbstractAction {
        }
        
        /**
-        * Fetches the User with the given access-token.
+        * Fetches the User with the given identifier.
         * 
-        * @param       string                  $token
+        * @param       string                  $identifier
         * @return      \wcf\data\user\User
         */
-       public function getUser($token) {
+       public function getUser($identifier) {
                $sql = "SELECT  userID
                        FROM    wcf".WCF_N."_user
                        WHERE   authData = ?";
                $statement = WCF::getDB()->prepareStatement($sql);
-               $statement->execute(array('github:'.$token));
+               $statement->execute(array('github:'.$identifier));
                $row = $statement->fetchArray();
                
                if ($row === false) {
index 908f381e8e64beb2a3ecf9ee318aab22db724bdf..d6bec4efb268a293674ccb08eef79cba0f001efe 100644 (file)
@@ -376,8 +376,9 @@ class AccountManagementForm extends AbstractForm {
                
                // 3rdParty
                if (GITHUB_PUBLIC_KEY !== '' && GITHUB_PRIVATE_KEY !== '') {
-                       if ($this->githubConnect && WCF::getSession()->getVar('__githubToken')) {
-                               $updateParameters['authData'] = 'github:'.WCF::getSession()->getVar('__githubToken');
+                       if ($this->githubConnect && WCF::getSession()->getVar('__githubData')) {
+                               $githubData = WCF::getSession()->getVar('__githubData');
+                               $updateParameters['authData'] = 'github:'.$githubData['id'];
                                $success[] = 'wcf.user.3rdparty.github.connect.success';
                                
                                WCF::getSession()->unregister('__githubToken');
index 2a3407eaaae675f50cc1f0c54273f379746d527d..8fb39a3efd7b6865ef0bf1945396d06bf4db5513 100644 (file)
@@ -300,7 +300,7 @@ class RegisterForm extends UserAddForm {
                                        if (WCF::getSession()->getVar('__githubData')) {
                                                $githubData = WCF::getSession()->getVar('__githubData');
                                                
-                                               $this->additionalFields['authData'] = 'github:'.WCF::getSession()->getVar('__githubToken');
+                                               $this->additionalFields['authData'] = 'github:'.$githubData['id'];
                                                
                                                WCF::getSession()->unregister('__githubData');
                                                WCF::getSession()->unregister('__githubToken');