Add a "refresh" action for external accounts

Summary:
Ref T1536. This is equivalent to logging out and logging back in again, but a bit less disruptive for users. For some providers (like Google), this may eventually do something different (Google has a "force" parameter which forces re-auth and is ostensibly required to refresh long-lived tokens).

Broadly, this process fixes OAuth accounts with busted access tokens so we can do API stuff. For other accounts, it mostly just syncs profile pictures.

Test Plan:
Refreshed LDAP and Oauth accounts, linked OAuth accounts, hit error conditions.

{F47390}
{F47391}
{F47392}
{F47393}
{F47394}
{F47395}

Reviewers: btrahan, chad

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T1536

Differential Revision: https://secure.phabricator.com/D6290
This commit is contained in:
epriestley
2013-06-24 15:58:27 -07:00
parent e826842179
commit fe71b34c68
8 changed files with 108 additions and 22 deletions

View File

@@ -3,10 +3,12 @@
final class PhabricatorAuthLinkController
extends PhabricatorAuthController {
private $action;
private $providerKey;
public function willProcessRequest(array $data) {
$this->providerKey = $data['pkey'];
$this->action = $data['action'];
}
public function processRequest() {
@@ -19,12 +21,27 @@ final class PhabricatorAuthLinkController
return new Aphront404Response();
}
if (!$provider->shouldAllowAccountLink()) {
return $this->renderErrorPage(
pht('Account Not Linkable'),
array(
pht('This provider is not configured to allow linking.'),
));
switch ($this->action) {
case 'link':
if (!$provider->shouldAllowAccountLink()) {
return $this->renderErrorPage(
pht('Account Not Linkable'),
array(
pht('This provider is not configured to allow linking.'),
));
}
break;
case 'refresh':
if (!$provider->shouldAllowAccountRefresh()) {
return $this->renderErrorPage(
pht('Account Not Refreshable'),
array(
pht('This provider does not allow refreshing.'),
));
}
break;
default:
return new Aphront400Response();
}
$account = id(new PhabricatorExternalAccount())->loadOneWhere(
@@ -32,20 +49,47 @@ final class PhabricatorAuthLinkController
$provider->getProviderType(),
$provider->getProviderDomain(),
$viewer->getPHID());
if ($account) {
return $this->renderErrorPage(
pht('Account Already Linked'),
array(
pht(
'Your Phabricator account is already linked to an external '.
'account for this provider.'),
));
switch ($this->action) {
case 'link':
if ($account) {
return $this->renderErrorPage(
pht('Account Already Linked'),
array(
pht(
'Your Phabricator account is already linked to an external '.
'account for this provider.'),
));
}
break;
case 'refresh':
if (!$account) {
return $this->renderErrorPage(
pht('No Account Linked'),
array(
pht(
'You do not have a linked account on this provider, and thus '.
'can not refresh it.'),
));
}
break;
default:
return new Aphront400Response();
}
$panel_uri = '/settings/panel/external/';
$request->setCookie('phcid', Filesystem::readRandomCharacters(16));
$form = $provider->buildLinkForm($this);
switch ($this->action) {
case 'link':
$form = $provider->buildLinkForm($this);
break;
case 'refresh':
$form = $provider->buildRefreshForm($this);
break;
default:
return new Aphront400Response();
}
if ($provider->isLoginFormAButton()) {
require_celerity_resource('auth-css');
@@ -57,6 +101,19 @@ final class PhabricatorAuthLinkController
$form);
}
switch ($this->action) {
case 'link':
$name = pht('Link Account');
$title = pht('Link %s Account', $provider->getProviderName());
break;
case 'refresh':
$name = pht('Refresh Account');
$title = pht('Refresh %s Account', $provider->getProviderName());
break;
default:
return new Aphront400Response();
}
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addCrumb(
id(new PhabricatorCrumbView())
@@ -64,7 +121,7 @@ final class PhabricatorAuthLinkController
->setHref($panel_uri));
$crumbs->addCrumb(
id(new PhabricatorCrumbView())
->setName($provider->getProviderName()));
->setName($provider->getProviderName($name)));
return $this->buildApplicationPage(
array(
@@ -72,7 +129,7 @@ final class PhabricatorAuthLinkController
$form,
),
array(
'title' => pht('Link %s Account', $provider->getProviderName()),
'title' => $title,
'dust' => true,
'device' => true,
));