From e37288a1ba8a4e1ea0735e8df3062eddd67d39f9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tim=20D=C3=BCsterhus?= Date: Sun, 9 Aug 2015 17:31:34 +0200 Subject: [PATCH] Guard against GitHub randomly changing the access_token --- .../lib/action/GithubAuthAction.class.php | 81 +++++++++---------- .../lib/form/AccountManagementForm.class.php | 5 +- .../files/lib/form/RegisterForm.class.php | 2 +- 3 files changed, 41 insertions(+), 47 deletions(-) diff --git a/wcfsetup/install/files/lib/action/GithubAuthAction.class.php b/wcfsetup/install/files/lib/action/GithubAuthAction.class.php index fec9eca2c6..5cc1f8b7cb 100644 --- a/wcfsetup/install/files/lib/action/GithubAuthAction.class.php +++ b/wcfsetup/install/files/lib/action/GithubAuthAction.class.php @@ -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) { diff --git a/wcfsetup/install/files/lib/form/AccountManagementForm.class.php b/wcfsetup/install/files/lib/form/AccountManagementForm.class.php index 908f381e8e..d6bec4efb2 100644 --- a/wcfsetup/install/files/lib/form/AccountManagementForm.class.php +++ b/wcfsetup/install/files/lib/form/AccountManagementForm.class.php @@ -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'); diff --git a/wcfsetup/install/files/lib/form/RegisterForm.class.php b/wcfsetup/install/files/lib/form/RegisterForm.class.php index 2a3407eaaa..8fb39a3efd 100644 --- a/wcfsetup/install/files/lib/form/RegisterForm.class.php +++ b/wcfsetup/install/files/lib/form/RegisterForm.class.php @@ -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'); -- 2.20.1