@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Put some glue in between PhabricatorAuthProvider and the OAuth adapters

Summary: Ref T1536. None of this code is reachable. Glues AuthProvider to OAuthAdapter.

Test Plan: Code is unreachable.

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T1536

Differential Revision: https://secure.phabricator.com/D6160

+129 -14
+12
src/applications/auth/controller/PhabricatorAuthLoginController.php
··· 157 157 )); 158 158 } 159 159 160 + public function buildProviderErrorResponse( 161 + PhabricatorAuthProvider $provider, 162 + $message) { 163 + 164 + $message = pht( 165 + 'Authentication provider ("%s") encountered an error during login. %s', 166 + $provider->getProviderName(), 167 + $message); 168 + 169 + return $this->renderError($message); 170 + } 171 + 160 172 }
+58 -14
src/applications/auth/provider/PhabricatorAuthProvider.php
··· 2 2 3 3 abstract class PhabricatorAuthProvider { 4 4 5 - private $adapter; 6 - 7 - public function setAdapater(PhutilAuthAdapter $adapter) { 8 - $this->adapter = $adapter; 9 - return $this; 10 - } 11 - 12 - public function getAdapater() { 13 - if ($this->adapter === null) { 14 - throw new Exception("Call setAdapter() before getAdapter()!"); 15 - } 16 - return $this->adapter; 17 - } 18 - 19 5 public function getProviderKey() { 20 6 return $this->getAdapter()->getAdapterKey(); 21 7 } ··· 67 53 } 68 54 69 55 abstract public function getProviderName(); 56 + abstract public function getAdapater(); 70 57 abstract public function isEnabled(); 71 58 abstract public function shouldAllowLogin(); 72 59 abstract public function shouldAllowRegistration(); ··· 77 64 public function createProviders() { 78 65 return array($this); 79 66 } 67 + 68 + protected function willSaveAccount(PhabricatorExternalAccount $account) { 69 + return; 70 + } 71 + 72 + protected function loadOrCreateAccount($account_id) { 73 + if (!strlen($account_id)) { 74 + throw new Exception("loadOrCreateAccount(...): empty account ID!"); 75 + } 76 + 77 + $adapter = $this->getAdapter(); 78 + $account = id(new PhabricatorExternalAccount())->loadOneWhere( 79 + 'accountType = %s AND accountDomain = %s AND accountID = %s', 80 + $adapter->getProviderType(), 81 + $adapter->getProviderDomain(), 82 + $account_id); 83 + if (!$account) { 84 + $account = id(new PhabricatorExternalAccount()) 85 + ->setAccountType($adapter->getProviderType()) 86 + ->setAccountDomain($adapter->getProviderDomain()) 87 + ->setAccountID($account_id); 88 + } 89 + 90 + $account->setUsername($adapter->getAccountName()); 91 + $account->setRealName($adapter->getAccountRealName()); 92 + $account->setEmail($adapter->getAccountEmail()); 93 + $account->setAccountURI($adapter->getAccountURI()); 94 + 95 + try { 96 + $name = PhabricatorSlug::normalize($this->getProviderName()); 97 + $name = $name.'-profile.jpg'; 98 + 99 + // TODO: If the image has not changed, we do not need to make a new 100 + // file entry for it, but there's no convenient way to do this with 101 + // PhabricatorFile right now. The storage will get shared, so the impact 102 + // here is negligible. 103 + 104 + $image_uri = $account->getAccountImageURI(); 105 + $image_file = PhabricatorFile::newFromFileDownload( 106 + $image_uri, 107 + array( 108 + 'name' => $name, 109 + )); 110 + 111 + $account->setProfileImagePHID($image_file->getPHID()); 112 + } catch (Exception $ex) { 113 + $account->setProfileImagePHID(null); 114 + } 115 + 116 + $this->willSaveAccount($account); 117 + 118 + $account->save(); 119 + 120 + return $account; 121 + } 122 + 123 + 80 124 81 125 }
+59
src/applications/auth/provider/PhabricatorAuthProviderOAuth.php
··· 1 + <?php 2 + 3 + abstract class PhabricatorAuthProviderOAuth extends PhabricatorAuthProvider { 4 + 5 + public function processLoginRequest( 6 + PhabricatorAuthLoginController $controller) { 7 + 8 + $request = $controller->getRequest(); 9 + $adapter = $this->getAdapter(); 10 + $account = null; 11 + $response = null; 12 + 13 + $error = $request->getStr('error'); 14 + if ($error) { 15 + $response = $controller->buildProviderErrorResponse( 16 + $this, 17 + pht( 18 + 'The OAuth provider returned an error: %s', 19 + $error)); 20 + 21 + return array($account, $response); 22 + } 23 + 24 + $code = $request->getStr('code'); 25 + if (!strlen($code)) { 26 + $response = $controller->buildProviderErrorResponse( 27 + $this, 28 + pht( 29 + 'The OAuth provider did not return a "code" parameter in its '. 30 + 'response.')); 31 + 32 + return array($account, $response); 33 + } 34 + 35 + $adapter->setCode($code); 36 + 37 + // NOTE: As a side effect, this will cause the OAuth adapter to request 38 + // an access token. 39 + 40 + try { 41 + $account_id = $adapter->getAccountID(); 42 + } catch (Exception $ex) { 43 + // TODO: Handle this in a more user-friendly way. 44 + throw $ex; 45 + } 46 + 47 + if (!strlen($account_id)) { 48 + $response = $controller->buildProviderErrorResponse( 49 + $this, 50 + pht( 51 + 'The OAuth provider failed to retrieve an account ID.')); 52 + 53 + return array($account, $response); 54 + } 55 + 56 + return array($this->loadOrCreateAccount($account_id), $response); 57 + } 58 + 59 + }