Page MenuHomePhabricator

D8612.id.diff
No OneTemporary

D8612.id.diff

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -107,6 +107,7 @@
'PhutilAuthAdapterOAuthTwitch' => 'auth/PhutilAuthAdapterOAuthTwitch.php',
'PhutilAuthAdapterOAuthTwitter' => 'auth/PhutilAuthAdapterOAuthTwitter.php',
'PhutilAuthAdapterPersona' => 'auth/PhutilAuthAdapterPersona.php',
+ 'PhutilAuthConfigurationException' => 'auth/exception/PhutilAuthConfigurationException.php',
'PhutilAuthCredentialException' => 'auth/exception/PhutilAuthCredentialException.php',
'PhutilAuthException' => 'auth/exception/PhutilAuthException.php',
'PhutilAuthUserAbortedException' => 'auth/exception/PhutilAuthUserAbortedException.php',
@@ -357,6 +358,7 @@
'nonempty' => 'utils/utils.php',
'phlog' => 'error/phlog.php',
'pht' => 'internationalization/pht.php',
+ 'phutil_censor_credentials' => 'utils/utils.php',
'phutil_console_confirm' => 'console/format.php',
'phutil_console_format' => 'console/format.php',
'phutil_console_get_terminal_width' => 'console/format.php',
@@ -520,6 +522,7 @@
'PhutilAuthAdapterOAuthTwitch' => 'PhutilAuthAdapterOAuth',
'PhutilAuthAdapterOAuthTwitter' => 'PhutilAuthAdapterOAuth1',
'PhutilAuthAdapterPersona' => 'PhutilAuthAdapter',
+ 'PhutilAuthConfigurationException' => 'PhutilAuthException',
'PhutilAuthCredentialException' => 'PhutilAuthException',
'PhutilAuthException' => 'Exception',
'PhutilAuthUserAbortedException' => 'PhutilAuthException',
diff --git a/src/auth/PhutilAuthAdapterOAuthGoogle.php b/src/auth/PhutilAuthAdapterOAuthGoogle.php
--- a/src/auth/PhutilAuthAdapterOAuthGoogle.php
+++ b/src/auth/PhutilAuthAdapterOAuthGoogle.php
@@ -14,11 +14,21 @@
}
public function getAccountID() {
- return $this->getOAuthAccountData('email');
+ $emails = $this->getOAuthAccountData('emails', array());
+ foreach ($emails as $email) {
+ if (idx($email, 'type') == 'account') {
+ return idx($email, 'value');
+ }
+ }
+
+ throw new Exception(
+ pht(
+ 'Expected to retrieve an "account" email from Google Plus API call ',
+ 'to identify account, but failed.'));
}
public function getAccountEmail() {
- return $this->getOAuthAccountData('email');
+ return $this->getAccountID();
}
public function getAccountName() {
@@ -38,7 +48,20 @@
}
public function getAccountRealName() {
- return $this->getOAuthAccountData('name');
+ $name = $this->getOAuthAccountData('name', array());
+
+ // TODO: This could probably be made cleaner by looking up the API, but
+ // this should work to unbreak logins.
+
+ $parts = array();
+ $parts[] = idx($name, 'givenName');
+ unset($name['givenName']);
+ $parts[] = idx($name, 'familyName');
+ unset($name['familyName']);
+ $parts = array_merge($parts, $name);
+ $parts = array_filter($parts);
+
+ return implode(' ', $parts);
}
protected function getAuthenticateBaseURI() {
@@ -51,8 +74,8 @@
public function getScope() {
$scopes = array(
- 'https://www.googleapis.com/auth/userinfo.email',
- 'https://www.googleapis.com/auth/userinfo.profile',
+ 'email',
+ 'profile',
);
return implode(' ', $scopes);
@@ -71,11 +94,16 @@
}
protected function loadOAuthAccountData() {
- $uri = new PhutilURI('https://www.googleapis.com/oauth2/v1/userinfo');
+ $uri = new PhutilURI('https://www.googleapis.com/plus/v1/people/me');
$uri->setQueryParam('access_token', $this->getAccessToken());
$future = new HTTPSFuture($uri);
- list($body) = $future->resolvex();
+ list($status, $body) = $future->resolve();
+
+ if ($status->isError()) {
+ $this->tryToThrowSpecializedError($status, $body);
+ throw $status;
+ }
$data = json_decode($body, true);
if (!is_array($data)) {
@@ -87,4 +115,44 @@
return $data;
}
+ private function tryToThrowSpecializedError($status, $raw_body) {
+ if (!($status instanceof HTTPFutureResponseStatusHTTP)) {
+ return;
+ }
+
+ if ($status->getStatusCode() != 403) {
+ return;
+ }
+
+ $body = phutil_json_decode($raw_body);
+ if (!$body) {
+ return;
+ }
+
+ if (empty($body['error']['errors'][0])) {
+ return;
+ }
+
+ $error = $body['error']['errors'][0];
+ $domain = idx($error, 'domain');
+ $reason = idx($error, 'reason');
+
+ if ($domain == 'usageLimits' && $reason == 'accessNotConfigured') {
+ throw new PhutilAuthConfigurationException(
+ pht(
+ 'Google returned an "accessNotConfigured" error. This usually means '.
+ 'you need to enable the "Google+ API" in your Google Cloud Console, '.
+ 'under "APIs".'.
+ "\n\n".
+ 'Around March 2014, Google made some API changes which require this '.
+ 'configuration adjustment. (If you are unable to log into '.
+ 'Phabricator, use "bin/auth recover" to recover access to an '.
+ 'administrator account.)'.
+ "\n\n".
+ 'Full HTTP Response'.
+ "\n\n%s",
+ $raw_body));
+ }
+ }
+
}
diff --git a/src/auth/exception/PhutilAuthConfigurationException.php b/src/auth/exception/PhutilAuthConfigurationException.php
new file mode 100644
--- /dev/null
+++ b/src/auth/exception/PhutilAuthConfigurationException.php
@@ -0,0 +1,8 @@
+<?php
+
+/**
+ * Authentication is not configured correctly.
+ */
+final class PhutilAuthConfigurationException extends PhutilAuthException {
+
+}

File Metadata

Mime Type
text/plain
Expires
Thu, Jan 9, 1:22 PM (6 h, 38 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6978899
Default Alt Text
D8612.id.diff (5 KB)

Event Timeline