1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-29 10:12:41 +01:00

Store OAuth tokens and more OAuth account info.

Summary:

Test Plan:

Reviewers:

CC:
This commit is contained in:
epriestley 2011-02-22 10:24:49 -08:00
parent 21286a723e
commit 063269a00a
7 changed files with 164 additions and 32 deletions

View file

@ -0,0 +1,6 @@
alter table phabricator_user.user_oauthinfo add accountURI varchar(255);
alter table phabricator_user.user_oauthinfo add accountName varchar(255);
alter table phabricator_user.user_oauthinfo add token varchar(255);
alter table phabricator_user.user_oauthinfo add tokenExpires int unsigned;
alter table phabricator_user.user_oauthinfo add tokenScope varchar(255);
alter table phabricator_user.user_oauthinfo add tokenStatus varchar(255);

View file

@ -21,6 +21,7 @@ class PhabricatorOAuthLoginController extends PhabricatorAuthController {
private $provider;
private $userID;
private $accessToken;
private $tokenExpires;
public function shouldRequireLogin() {
return false;
@ -91,6 +92,13 @@ class PhabricatorOAuthLoginController extends PhabricatorAuthController {
if (!$token) {
return $this->buildErrorResponse(new PhabricatorOAuthFailureView());
}
if (idx($data, 'expires')) {
$this->tokenExpires = time() + $data['expires'];
}
} else {
$this->tokenExpires = $request->getInt('expires');
}
$userinfo_uri = new PhutilURI($provider->getUserInfoURI());
@ -148,6 +156,7 @@ class PhabricatorOAuthLoginController extends PhabricatorAuthController {
'<p>Link your '.$provider_name.' account to your Phabricator '.
'account?</p>');
$dialog->addHiddenInput('token', $token);
$dialog->addHiddenInput('expires', $this->tokenExpires);
$dialog->addSubmitButton('Link Accounts');
$dialog->addCancelButton('/settings/page/'.$provider_key.'/');
@ -156,8 +165,7 @@ class PhabricatorOAuthLoginController extends PhabricatorAuthController {
$oauth_info = new PhabricatorUserOAuthInfo();
$oauth_info->setUserID($current_user->getID());
$oauth_info->setOAuthProvider($provider_key);
$oauth_info->setOAuthUID($user_id);
$this->configureOAuthInfo($oauth_info);
$oauth_info->save();
return id(new AphrontRedirectResponse())
@ -170,6 +178,10 @@ class PhabricatorOAuthLoginController extends PhabricatorAuthController {
if ($known_oauth) {
$known_user = id(new PhabricatorUser())->load($known_oauth->getUserID());
$session_key = $known_user->establishSession('web');
$this->configureOAuthInfo($known_oauth);
$known_oauth->save();
$request->setCookie('phusr', $known_user->getUsername());
$request->setCookie('phsid', $session_key);
return id(new AphrontRedirectResponse())
@ -184,31 +196,17 @@ class PhabricatorOAuthLoginController extends PhabricatorAuthController {
$known_email = id(new PhabricatorUser())
->loadOneWhere('email = %s', $oauth_email);
if ($known_email) {
$known_oauth = id(new PhabricatorUserOAuthInfo())->loadOneWhere(
'userID = %d AND oauthProvider = %s',
$known_email->getID(),
$provider->getProviderKey());
if ($known_oauth) {
$provider_name = $provider->getName();
throw new Exception(
"The email associated with the ".$provider_name." account you ".
"just logged in with is already associated with another ".
"Phabricator account which is, in turn, associated with a ".
$provider_name." account different from the one you just logged ".
"in with.");
}
$dialog = new AphrontDialogView();
$dialog->setUser($current_user);
$dialog->setTitle('Already Linked to Another Account');
$dialog->appendChild(
'<p>The '.$provider_name.' account you just authorized has an '.
'email address which is already in use by another Phabricator '.
'account. To link the accounts, log in to your Phabricator '.
'account and then go to Settings.</p>');
$dialog->addCancelButton('/login/');
$oauth_info = new PhabricatorUserOAuthInfo();
$oauth_info->setUserID($known_email->getID());
$oauth_info->setOAuthProvider($provider->getProviderKey());
$oauth_info->setOAuthUID($user_id);
$oauth_info->save();
$session_key = $known_email->establishSession('web');
$request->setCookie('phusr', $known_email->getUsername());
$request->setCookie('phsid', $session_key);
return id(new AphrontRedirectResponse())
->setURI('/');
return id(new AphrontDialogResponse())->setDialog($dialog);
}
}
@ -279,8 +277,7 @@ class PhabricatorOAuthLoginController extends PhabricatorAuthController {
$oauth_info = new PhabricatorUserOAuthInfo();
$oauth_info->setUserID($user->getID());
$oauth_info->setOAuthProvider($provider->getProviderKey());
$oauth_info->setOAuthUID($user_id);
$this->configureOAuthInfo($oauth_info);
$oauth_info->save();
$session_key = $user->establishSession('web');
@ -312,6 +309,7 @@ class PhabricatorOAuthLoginController extends PhabricatorAuthController {
$form = new AphrontFormView();
$form
->addHiddenInput('token', $token)
->addHiddenInput('expires', $this->tokenExpires)
->setUser($request->getUser())
->setAction($provider->getRedirectURI())
->appendChild(
@ -410,8 +408,45 @@ class PhabricatorOAuthLoginController extends PhabricatorAuthController {
return null;
}
private function retrieveAccountURI() {
switch ($this->provider->getProviderKey()) {
case PhabricatorOAuthProvider::PROVIDER_FACEBOOK:
return $this->userData['link'];
case PhabricatorOAuthProvider::PROVIDER_GITHUB:
$username = $this->retrieveUsernameSuggestion();
if ($username) {
return 'https://github.com/'.$username;
}
return null;
}
return null;
}
private function retreiveRealNameSuggestion() {
return $this->userData['name'];
}
private function configureOAuthInfo(PhabricatorUserOAuthInfo $oauth_info) {
$provider = $this->provider;
$oauth_info->setOAuthProvider($provider->getProviderKey());
$oauth_info->setOAuthUID($this->retrieveUserID());
$oauth_info->setAccountURI($this->retrieveAccountURI());
$oauth_info->setAccountName($this->retrieveUserNameSuggestion());
$oauth_info->setToken($this->accessToken);
$oauth_info->setTokenStatus(PhabricatorUserOAuthInfo::TOKEN_STATUS_GOOD);
// If we have out-of-date expiration info, just clear it out. Then replace
// it with good info if the provider gave it to us.
$expires = $oauth_info->getTokenExpires();
if ($expires <= time()) {
$expires = null;
}
if ($this->tokenExpires) {
$expires = $this->tokenExpires;
}
$oauth_info->setTokenExpires($expires);
}
}

View file

@ -348,8 +348,15 @@ class PhabricatorUserSettingsController extends PhabricatorPeopleController {
->appendChild(
id(new AphrontFormStaticControl())
->setLabel($provider_name.' ID')
->setValue($oauth_info->getOAuthUID()));
->setValue($oauth_info->getOAuthUID()))
->appendChild(
id(new AphrontFormStaticControl())
->setLabel($provider_name.' Name')
->setValue($oauth_info->getAccountName()))
->appendChild(
id(new AphrontFormStaticControl())
->setLabel($provider_name.' URI')
->setValue($oauth_info->getAccountURI()));
$unlink = 'Unlink '.$provider_name.' Account';
$unlink_form = new AphrontFormView();
@ -363,6 +370,45 @@ class PhabricatorUserSettingsController extends PhabricatorPeopleController {
id(new AphrontFormSubmitControl())
->addCancelButton('/oauth/'.$provider_key.'/unlink/', $unlink));
$forms['Unlink Account'] = $unlink_form;
$expires = $oauth_info->getTokenExpires();
if ($expires) {
if ($expires <= time()) {
$expires = "Expired";
} else {
$expires = phabricator_format_timestamp($expires);
}
} else {
$expires = 'No Information Available';
}
$scope = $oauth_info->getTokenScope();
if (!$scope) {
$scope = 'No Information Available';
}
$status = $oauth_info->getTokenStatus();
$status = PhabricatorUserOAuthInfo::getReadableTokenStatus($status);
$token_form = new AphrontFormView();
$token_form
->setUser($user)
->appendChild(
'<p class="aphront-from-instructions">insert rap about tokens</p>')
->appendChild(
id(new AphrontFormStaticControl())
->setLabel('Token Status')
->setValue($status))
->appendChild(
id(new AphrontFormStaticControl())
->setLabel('Expires')
->setValue($expires))
->appendChild(
id(new AphrontFormStaticControl())
->setLabel('Scope')
->setValue($scope));
$forms['Account Token Information'] = $token_form;
}
$panel = new AphrontPanelView();

View file

@ -25,6 +25,7 @@ phutil_require_module('phabricator', 'view/form/control/textarea');
phutil_require_module('phabricator', 'view/form/error');
phutil_require_module('phabricator', 'view/layout/panel');
phutil_require_module('phabricator', 'view/layout/sidenav');
phutil_require_module('phabricator', 'view/utils');
phutil_require_module('phutil', 'markup');
phutil_require_module('phutil', 'utils');

View file

@ -18,8 +18,43 @@
class PhabricatorUserOAuthInfo extends PhabricatorUserDAO {
const TOKEN_STATUS_NONE = 'none';
const TOKEN_STATUS_GOOD = 'good';
const TOKEN_STATUS_FAIL = 'fail';
const TOKEN_STATUS_EXPIRED = 'xpyr';
protected $userID;
protected $oauthProvider;
protected $oauthUID;
protected $accountURI;
protected $accountName;
protected $token;
protected $tokenExpires;
protected $tokenScope;
protected $tokenStatus;
public function getTokenStatus() {
if (!$this->token) {
return self::TOKEN_STATUS_NONE;
}
if ($this->tokenExpires && $this->tokenExpires <= time()) {
return self::TOKEN_STATUS_EXPIRED;
}
return $this->tokenStatus;
}
public static function getReadableTokenStatus($status) {
static $map = array(
self::TOKEN_STATUS_NONE => 'No Token',
self::TOKEN_STATUS_GOOD => 'Token Good',
self::TOKEN_STATUS_FAIL => 'Token Failed',
self::TOKEN_STATUS_EXPIRED => 'Token Expired',
);
return idx($map, $status, 'Unknown');
}
}

View file

@ -8,5 +8,7 @@
phutil_require_module('phabricator', 'applications/people/storage/base');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorUserOAuthInfo.php');

View file

@ -27,8 +27,15 @@ function phabricator_format_relative_time($duration) {
function phabricator_format_timestamp($epoch) {
$difference = (time() - $epoch);
if ($difference < 0) {
$difference = -$difference;
$relative = 'from now';
} else {
$relative = 'ago';
}
if ($difference < 60 * 60 * 24) {
return phabricator_format_relative_time($difference).' ago';
return phabricator_format_relative_time($difference).' '.$relative;
} else if (date('Y') == date('Y', $epoch)) {
return date('M j, g:i A', $epoch);
} else {