Page MenuHomePhabricator

D9760.id23443.diff
No OneTemporary

D9760.id23443.diff

diff --git a/src/applications/auth/provider/PhabricatorAuthProviderOAuth1.php b/src/applications/auth/provider/PhabricatorAuthProviderOAuth1.php
--- a/src/applications/auth/provider/PhabricatorAuthProviderOAuth1.php
+++ b/src/applications/auth/provider/PhabricatorAuthProviderOAuth1.php
@@ -9,6 +9,8 @@
const PROPERTY_CONSUMER_SECRET = 'oauth1:consumer:secret';
const PROPERTY_PRIVATE_KEY = 'oauth1:private:key';
+ const TEMPORARY_TOKEN_TYPE = 'oauth1:request:secret';
+
protected function getIDKey() {
return self::PROPERTY_CONSUMER_KEY;
}
@@ -55,6 +57,11 @@
$adapter->setCallbackURI($callback_uri);
$uri = $adapter->getClientRedirectURI();
+
+ $this->saveHandshakeTokenSecret(
+ $client_code,
+ $adapter->getTokenSecret());
+
$response = id(new AphrontRedirectResponse())->setURI($uri);
return array($account, $response);
}
@@ -85,6 +92,10 @@
$adapter->setToken($token);
$adapter->setVerifier($verifier);
+ $client_code = $this->getAuthCSRFCode($request);
+ $token_secret = $this->loadHandshakeTokenSecret($client_code);
+ $adapter->setTokenSecret($token_secret);
+
// NOTE: As a side effect, this will cause the OAuth adapter to request
// an access token.
@@ -197,4 +208,68 @@
parent::willRenderLinkedAccount($viewer, $item, $account);
}
+
+/* -( Temporary Secrets )-------------------------------------------------- */
+
+
+ private function saveHandshakeTokenSecret($client_code, $secret) {
+ $key = $this->getHandshakeTokenKeyFromClientCode($client_code);
+ $type = $this->getTemporaryTokenType(self::TEMPORARY_TOKEN_TYPE);
+
+ // Wipe out an existing token, if one exists.
+ $token = id(new PhabricatorAuthTemporaryTokenQuery())
+ ->setViewer(PhabricatorUser::getOmnipotentUser())
+ ->withObjectPHIDs(array($key))
+ ->withTokenTypes(array($type))
+ ->executeOne();
+ if ($token) {
+ $token->delete();
+ }
+
+ // Save the new secret.
+ id(new PhabricatorAuthTemporaryToken())
+ ->setObjectPHID($key)
+ ->setTokenType($type)
+ ->setTokenExpires(time() + phutil_units('1 hour in seconds'))
+ ->setTokenCode($secret)
+ ->save();
+ }
+
+ private function loadHandshakeTokenSecret($client_code) {
+ $key = $this->getHandshakeTokenKeyFromClientCode($client_code);
+ $type = $this->getTemporaryTokenType(self::TEMPORARY_TOKEN_TYPE);
+
+ $token = id(new PhabricatorAuthTemporaryTokenQuery())
+ ->setViewer(PhabricatorUser::getOmnipotentUser())
+ ->withObjectPHIDs(array($key))
+ ->withTokenTypes(array($type))
+ ->withExpired(false)
+ ->executeOne();
+
+ if (!$token) {
+ throw new Exception(
+ pht(
+ 'Unable to load your OAuth1 token secret from storage. It may '.
+ 'have expired. Try authenticating again.'));
+ }
+
+ return $token->getTokenCode();
+ }
+
+ private function getTemporaryTokenType($core_type) {
+ // Namespace the type so that multiple providers don't step on each
+ // others' toes if a user starts Mediawiki and Bitbucket auth at the
+ // same time.
+
+ return $core_type.':'.$this->getProviderConfig()->getID();
+ }
+
+ private function getHandshakeTokenKeyFromClientCode($client_code) {
+ // NOTE: This is very slightly coersive since the TemporaryToken table
+ // expects an "objectPHID" as an identifier, but nothing about the storage
+ // is bound to PHIDs.
+
+ return 'oauth1:secret/'.$client_code;
+ }
+
}
diff --git a/src/applications/auth/storage/PhabricatorAuthTemporaryToken.php b/src/applications/auth/storage/PhabricatorAuthTemporaryToken.php
--- a/src/applications/auth/storage/PhabricatorAuthTemporaryToken.php
+++ b/src/applications/auth/storage/PhabricatorAuthTemporaryToken.php
@@ -3,7 +3,10 @@
final class PhabricatorAuthTemporaryToken extends PhabricatorAuthDAO
implements PhabricatorPolicyInterface {
+ // TODO: OAuth1 stores a client identifier here, which is not a real PHID.
+ // At some point, we should rename this column to be a little more generic.
protected $objectPHID;
+
protected $tokenType;
protected $tokenExpires;
protected $tokenCode;

File Metadata

Mime Type
text/plain
Expires
Fri, Apr 4, 9:08 PM (1 w, 4 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7599176
Default Alt Text
D9760.id23443.diff (4 KB)

Event Timeline