diff --git a/src/applications/auth/management/PhabricatorAuthManagementRefreshWorkflow.php b/src/applications/auth/management/PhabricatorAuthManagementRefreshWorkflow.php index e9b65abac4..97957d7c91 100644 --- a/src/applications/auth/management/PhabricatorAuthManagementRefreshWorkflow.php +++ b/src/applications/auth/management/PhabricatorAuthManagementRefreshWorkflow.php @@ -126,13 +126,14 @@ final class PhabricatorAuthManagementRefreshWorkflow new PhutilNumber( $account->getProperty('oauth.token.access.expires') - time()))); - $adapter->refreshAccessToken($refresh_token); + $provider->getOAuthAccessToken($account, $force_refresh = true); $console->writeOut( "+ %s\n", pht( "Refreshed token, new token expires in %s seconds.", - new PhutilNumber($adapter->getAccessTokenExpires() - time()))); + new PhutilNumber( + $account->getProperty('oauth.token.access.expires') - time()))); } diff --git a/src/applications/auth/provider/PhabricatorAuthProviderOAuth.php b/src/applications/auth/provider/PhabricatorAuthProviderOAuth.php index e83aa81e69..16b45d53cb 100644 --- a/src/applications/auth/provider/PhabricatorAuthProviderOAuth.php +++ b/src/applications/auth/provider/PhabricatorAuthProviderOAuth.php @@ -283,7 +283,11 @@ abstract class PhabricatorAuthProviderOAuth extends PhabricatorAuthProvider { protected function willSaveAccount(PhabricatorExternalAccount $account) { parent::willSaveAccount($account); + $this->synchronizeOAuthAccount($account); + } + protected function synchronizeOAuthAccount( + PhabricatorExternalAccount $account) { $adapter = $this->getAdapter(); $oauth_token = $adapter->getAccessToken(); @@ -300,4 +304,43 @@ abstract class PhabricatorAuthProviderOAuth extends PhabricatorAuthProvider { $account->setProperty('oauth.token.access.expires', $expires); } + public function getOAuthAccessToken( + PhabricatorExternalAccount $account, + $force_refresh = false) { + + if ($account->getProviderKey() !== $this->getProviderKey()) { + throw new Exception("Account does not match provider!"); + } + + if (!$force_refresh) { + $access_expires = $account->getProperty('oauth.token.access.expires'); + $access_token = $account->getProperty('oauth.token.access'); + + // Don't return a token with fewer than this many seconds remaining until + // it expires. + $shortest_token = 60; + + if ($access_token) { + if ($access_expires > (time() + $shortest_token)) { + return $access_token; + } + } + } + + $refresh_token = $account->getProperty('oauth.token.refresh'); + if ($refresh_token) { + $adapter = $this->getAdapter(); + if ($adapter->supportsTokenRefresh()) { + $adapter->refreshAccessToken($refresh_token); + + $this->synchronizeOAuthAccount($account); + $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); + $account->save(); + unset($unguarded); + } + } + + return null; + } + } diff --git a/src/applications/doorkeeper/bridge/DoorkeeperBridgeAsana.php b/src/applications/doorkeeper/bridge/DoorkeeperBridgeAsana.php index d40e08dad0..21ed1f5427 100644 --- a/src/applications/doorkeeper/bridge/DoorkeeperBridgeAsana.php +++ b/src/applications/doorkeeper/bridge/DoorkeeperBridgeAsana.php @@ -35,7 +35,7 @@ final class DoorkeeperBridgeAsana extends DoorkeeperBridge { // right now so this is currently moot. $account = head($accounts); - $token = $account->getProperty('oauth.token.access'); + $token = $provider->getOAuthAccessToken($account); if (!$token) { return; }