mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-29 02:02:41 +01:00
Add bin/auth refresh
for debugging OAuth token refresh issues
Summary: Ref T2852. Provide a script for inspecting/debugging OAuth token refresh. Test Plan: Ran `bin/auth refresh` with various arguments, saw token refreshes. Reviewers: btrahan Reviewed By: btrahan CC: aran Maniphest Tasks: T2852 Differential Revision: https://secure.phabricator.com/D6276
This commit is contained in:
parent
b22e52e40c
commit
c94ef134e4
5 changed files with 161 additions and 3 deletions
|
@ -16,6 +16,7 @@ $args->parseStandardArguments();
|
||||||
|
|
||||||
$workflows = array(
|
$workflows = array(
|
||||||
new PhabricatorAuthManagementRecoverWorkflow(),
|
new PhabricatorAuthManagementRecoverWorkflow(),
|
||||||
|
new PhabricatorAuthManagementRefreshWorkflow(),
|
||||||
new PhabricatorAuthManagementLDAPWorkflow(),
|
new PhabricatorAuthManagementLDAPWorkflow(),
|
||||||
new PhutilHelpArgumentWorkflow(),
|
new PhutilHelpArgumentWorkflow(),
|
||||||
);
|
);
|
||||||
|
|
|
@ -836,6 +836,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorAuthLoginController' => 'applications/auth/controller/PhabricatorAuthLoginController.php',
|
'PhabricatorAuthLoginController' => 'applications/auth/controller/PhabricatorAuthLoginController.php',
|
||||||
'PhabricatorAuthManagementLDAPWorkflow' => 'applications/auth/management/PhabricatorAuthManagementLDAPWorkflow.php',
|
'PhabricatorAuthManagementLDAPWorkflow' => 'applications/auth/management/PhabricatorAuthManagementLDAPWorkflow.php',
|
||||||
'PhabricatorAuthManagementRecoverWorkflow' => 'applications/auth/management/PhabricatorAuthManagementRecoverWorkflow.php',
|
'PhabricatorAuthManagementRecoverWorkflow' => 'applications/auth/management/PhabricatorAuthManagementRecoverWorkflow.php',
|
||||||
|
'PhabricatorAuthManagementRefreshWorkflow' => 'applications/auth/management/PhabricatorAuthManagementRefreshWorkflow.php',
|
||||||
'PhabricatorAuthManagementWorkflow' => 'applications/auth/management/PhabricatorAuthManagementWorkflow.php',
|
'PhabricatorAuthManagementWorkflow' => 'applications/auth/management/PhabricatorAuthManagementWorkflow.php',
|
||||||
'PhabricatorAuthNewController' => 'applications/auth/controller/config/PhabricatorAuthNewController.php',
|
'PhabricatorAuthNewController' => 'applications/auth/controller/config/PhabricatorAuthNewController.php',
|
||||||
'PhabricatorAuthOldOAuthRedirectController' => 'applications/auth/controller/PhabricatorAuthOldOAuthRedirectController.php',
|
'PhabricatorAuthOldOAuthRedirectController' => 'applications/auth/controller/PhabricatorAuthOldOAuthRedirectController.php',
|
||||||
|
@ -2712,6 +2713,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorAuthLoginController' => 'PhabricatorAuthController',
|
'PhabricatorAuthLoginController' => 'PhabricatorAuthController',
|
||||||
'PhabricatorAuthManagementLDAPWorkflow' => 'PhabricatorAuthManagementWorkflow',
|
'PhabricatorAuthManagementLDAPWorkflow' => 'PhabricatorAuthManagementWorkflow',
|
||||||
'PhabricatorAuthManagementRecoverWorkflow' => 'PhabricatorAuthManagementWorkflow',
|
'PhabricatorAuthManagementRecoverWorkflow' => 'PhabricatorAuthManagementWorkflow',
|
||||||
|
'PhabricatorAuthManagementRefreshWorkflow' => 'PhabricatorAuthManagementWorkflow',
|
||||||
'PhabricatorAuthManagementWorkflow' => 'PhutilArgumentWorkflow',
|
'PhabricatorAuthManagementWorkflow' => 'PhutilArgumentWorkflow',
|
||||||
'PhabricatorAuthNewController' => 'PhabricatorAuthProviderConfigController',
|
'PhabricatorAuthNewController' => 'PhabricatorAuthProviderConfigController',
|
||||||
'PhabricatorAuthOldOAuthRedirectController' => 'PhabricatorAuthController',
|
'PhabricatorAuthOldOAuthRedirectController' => 'PhabricatorAuthController',
|
||||||
|
|
|
@ -0,0 +1,144 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthManagementRefreshWorkflow
|
||||||
|
extends PhabricatorAuthManagementWorkflow {
|
||||||
|
|
||||||
|
protected function didConstruct() {
|
||||||
|
$this
|
||||||
|
->setName('refresh')
|
||||||
|
->setExamples('**refresh**')
|
||||||
|
->setSynopsis(
|
||||||
|
pht(
|
||||||
|
'Refresh OAuth access tokens. This is primarily useful for '.
|
||||||
|
'development and debugging.'))
|
||||||
|
->setArguments(
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
'name' => 'user',
|
||||||
|
'param' => 'user',
|
||||||
|
'help' => 'Refresh tokens for a given user.',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'name' => 'type',
|
||||||
|
'param' => 'provider',
|
||||||
|
'help' => 'Refresh tokens for a given provider type.',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'name' => 'domain',
|
||||||
|
'param' => 'domain',
|
||||||
|
'help' => 'Refresh tokens for a given domain.',
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function execute(PhutilArgumentParser $args) {
|
||||||
|
$console = PhutilConsole::getConsole();
|
||||||
|
$viewer = PhabricatorUser::getOmnipotentUser();
|
||||||
|
|
||||||
|
$query = id(new PhabricatorExternalAccountQuery())
|
||||||
|
->setViewer($viewer);
|
||||||
|
|
||||||
|
$username = $args->getArg('user');
|
||||||
|
if (strlen($username)) {
|
||||||
|
$user = id(new PhabricatorPeopleQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withUsernames(array($username))
|
||||||
|
->executeOne();
|
||||||
|
if ($user) {
|
||||||
|
$query->withUserPHIDs(array($user->getPHID()));
|
||||||
|
} else {
|
||||||
|
throw new PhutilArgumentUsageException(
|
||||||
|
pht('No such user "%s"!', $username));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$type = $args->getArg('type');
|
||||||
|
if (strlen($type)) {
|
||||||
|
$query->withAccountTypes(array($type));
|
||||||
|
}
|
||||||
|
|
||||||
|
$domain = $args->getArg('domain');
|
||||||
|
if (strlen($domain)) {
|
||||||
|
$query->withAccountDomains(array($domain));
|
||||||
|
}
|
||||||
|
|
||||||
|
$accounts = $query->execute();
|
||||||
|
|
||||||
|
if (!$accounts) {
|
||||||
|
throw new PhutilArgumentUsageException(
|
||||||
|
pht("No accounts match the arguments!"));
|
||||||
|
} else {
|
||||||
|
$console->writeOut(
|
||||||
|
"%s\n",
|
||||||
|
pht(
|
||||||
|
"Found %s accounts to refresh.",
|
||||||
|
new PhutilNumber(count($accounts))));
|
||||||
|
}
|
||||||
|
|
||||||
|
$providers = PhabricatorAuthProvider::getAllEnabledProviders();
|
||||||
|
|
||||||
|
foreach ($accounts as $account) {
|
||||||
|
$console->writeOut(
|
||||||
|
"%s\n",
|
||||||
|
pht(
|
||||||
|
"Refreshing account #%d (%s/%s).",
|
||||||
|
$account->getID(),
|
||||||
|
$account->getAccountType(),
|
||||||
|
$account->getAccountDomain()));
|
||||||
|
|
||||||
|
$key = $account->getProviderKey();
|
||||||
|
if (empty($providers[$key])) {
|
||||||
|
$console->writeOut(
|
||||||
|
"> %s\n",
|
||||||
|
pht("Skipping, provider is not enabled or does not exist."));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$provider = $providers[$key];
|
||||||
|
if (!($provider instanceof PhabricatorAuthProviderOAuth)) {
|
||||||
|
$console->writeOut(
|
||||||
|
"> %s\n",
|
||||||
|
pht("Skipping, provider is not an OAuth provider."));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$adapter = $provider->getAdapter();
|
||||||
|
if (!$adapter->supportsTokenRefresh()) {
|
||||||
|
$console->writeOut(
|
||||||
|
"> %s\n",
|
||||||
|
pht("Skipping, provider does not support token refresh."));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$refresh_token = $account->getProperty('oauth.token.refresh');
|
||||||
|
if (!$refresh_token) {
|
||||||
|
$console->writeOut(
|
||||||
|
"> %s\n",
|
||||||
|
pht("Skipping, provider has no stored refresh token."));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$console->writeOut(
|
||||||
|
"+ %s\n",
|
||||||
|
pht(
|
||||||
|
"Refreshing token, current token expires in %s seconds.",
|
||||||
|
new PhutilNumber(
|
||||||
|
$account->getProperty('oauth.token.access.expires') - time())));
|
||||||
|
|
||||||
|
$adapter->refreshAccessToken($refresh_token);
|
||||||
|
|
||||||
|
$console->writeOut(
|
||||||
|
"+ %s\n",
|
||||||
|
pht(
|
||||||
|
"Refreshed token, new token expires in %s seconds.",
|
||||||
|
new PhutilNumber($adapter->getAccessTokenExpires() - time())));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$console->writeOut("%s\n", pht("Done."));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -284,9 +284,20 @@ abstract class PhabricatorAuthProviderOAuth extends PhabricatorAuthProvider {
|
||||||
protected function willSaveAccount(PhabricatorExternalAccount $account) {
|
protected function willSaveAccount(PhabricatorExternalAccount $account) {
|
||||||
parent::willSaveAccount($account);
|
parent::willSaveAccount($account);
|
||||||
|
|
||||||
$oauth_token = $this->getAdapter()->getAccessToken();
|
$adapter = $this->getAdapter();
|
||||||
$account->setProperty('oauth.token', $oauth_token);
|
|
||||||
|
|
||||||
|
$oauth_token = $adapter->getAccessToken();
|
||||||
|
$account->setProperty('oauth.token.access', $oauth_token);
|
||||||
|
|
||||||
|
if ($adapter->supportsTokenRefresh()) {
|
||||||
|
$refresh_token = $adapter->getRefreshToken();
|
||||||
|
$account->setProperty('oauth.token.refresh', $refresh_token);
|
||||||
|
} else {
|
||||||
|
$account->setProperty('oauth.token.refresh', null);
|
||||||
|
}
|
||||||
|
|
||||||
|
$expires = $adapter->getAccessTokenExpires();
|
||||||
|
$account->setProperty('oauth.token.access.expires', $expires);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ final class DoorkeeperBridgeAsana extends DoorkeeperBridge {
|
||||||
// right now so this is currently moot.
|
// right now so this is currently moot.
|
||||||
$account = head($accounts);
|
$account = head($accounts);
|
||||||
|
|
||||||
$token = $account->getProperty('oauth.token');
|
$token = $account->getProperty('oauth.token.access');
|
||||||
if (!$token) {
|
if (!$token) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue