mirror of
https://we.phorge.it/source/phorge.git
synced 2025-02-20 10:48:40 +01:00
OAuth -- generalize / refactor providers and diagnostics page
Summary: split out from D1595 Test Plan: oauth/facebook/diagnose still looks good! Reviewers: epriestley Reviewed By: epriestley CC: aran, epriestley Differential Revision: https://secure.phabricator.com/D1632
This commit is contained in:
parent
2bcf153e7e
commit
5ba9edff51
6 changed files with 114 additions and 76 deletions
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2011 Facebook, Inc.
|
* Copyright 2012 Facebook, Inc.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -31,57 +31,56 @@ class PhabricatorOAuthDiagnosticsController
|
||||||
|
|
||||||
$provider = $this->provider;
|
$provider = $this->provider;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$auth_enabled = $provider->isProviderEnabled();
|
$auth_enabled = $provider->isProviderEnabled();
|
||||||
$client_id = $provider->getClientID();
|
$client_id = $provider->getClientID();
|
||||||
$client_secret = $provider->getClientSecret();
|
$client_secret = $provider->getClientSecret();
|
||||||
|
$key = $provider->getProviderKey();
|
||||||
|
$name = phutil_escape_html($provider->getProviderName());
|
||||||
|
|
||||||
$res_ok = '<strong style="color: #00aa00;">OK</strong>';
|
$res_ok = '<strong style="color: #00aa00;">OK</strong>';
|
||||||
$res_no = '<strong style="color: #aa0000;">NO</strong>';
|
$res_no = '<strong style="color: #aa0000;">NO</strong>';
|
||||||
$res_na = '<strong style="color: #999999;">N/A</strong>';
|
$res_na = '<strong style="color: #999999;">N/A</strong>';
|
||||||
|
|
||||||
$results = array();
|
$results = array();
|
||||||
|
$auth_key = $key . '.auth-enabled';
|
||||||
if (!$auth_enabled) {
|
if (!$auth_enabled) {
|
||||||
$results['facebook.auth-enabled'] = array(
|
$results[$auth_key] = array(
|
||||||
$res_no,
|
$res_no,
|
||||||
'false',
|
'false',
|
||||||
'Facebook authentication is disabled in the configuration. Edit the '.
|
$name . ' authentication is disabled in the configuration. Edit the '.
|
||||||
'environmental configuration to enable "facebook.auth-enabled".');
|
'Phabricator configuration to enable "'.$auth_key.'".');
|
||||||
} else {
|
} else {
|
||||||
$results['facebook.auth-enabled'] = array(
|
$results[$auth_key] = array(
|
||||||
$res_ok,
|
$res_ok,
|
||||||
'true',
|
'true',
|
||||||
'Facebook authentication is enabled.');
|
$name.' authentication is enabled.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$client_id_key = $key. '.application-id';
|
||||||
if (!$client_id) {
|
if (!$client_id) {
|
||||||
$results['facebook.application-id'] = array(
|
$results[$client_id_key] = array(
|
||||||
$res_no,
|
$res_no,
|
||||||
null,
|
null,
|
||||||
'No Facebook Application ID is configured. Edit the environmental '.
|
'No '.$name.' Application ID is configured. Edit the Phabricator '.
|
||||||
'configuration to specify an application ID in '.
|
'configuration to specify an application ID in '.
|
||||||
'"facebook.application-id". To generate an ID, sign into Facebook, '.
|
'"'.$client_id_key.'". '.$provider->renderGetClientIDHelp());
|
||||||
'install the "Developer" application, and use it to create a new '.
|
|
||||||
'Facebook application.');
|
|
||||||
} else {
|
} else {
|
||||||
$results['facebook.application-id'] = array(
|
$results[$client_id_key] = array(
|
||||||
$res_ok,
|
$res_ok,
|
||||||
$client_id,
|
$client_id,
|
||||||
'Application ID is set.');
|
'Application ID is set.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$client_secret_key = $key.'.application-secret';
|
||||||
if (!$client_secret) {
|
if (!$client_secret) {
|
||||||
$results['facebook.application-secret'] = array(
|
$results[$client_secret_key] = array(
|
||||||
$res_no,
|
$res_no,
|
||||||
null,
|
null,
|
||||||
'No Facebook Application secret is configured. Edit the environmental '.
|
'No '.$name.' Application secret is configured. Edit the '.
|
||||||
'configuration to specify an Application Secret, in '.
|
'Phabricator configuration to specify an Application Secret, in '.
|
||||||
'"facebook.application-secret". You can find the application secret '.
|
'"'.$client_secret_key.'". '.$provider->renderGetClientSecretHelp());
|
||||||
'in the Facebook "Developer" application on Facebook.');
|
|
||||||
} else {
|
} else {
|
||||||
$results['facebook.application-secret'] = array(
|
$results[$client_secret_key] = array(
|
||||||
$res_ok,
|
$res_ok,
|
||||||
"It's a secret!",
|
"It's a secret!",
|
||||||
'Application secret is set.');
|
'Application secret is set.');
|
||||||
|
@ -115,38 +114,24 @@ class PhabricatorOAuthDiagnosticsController
|
||||||
'Internet seems OK.');
|
'Internet seems OK.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$facebook = @file_get_contents("http://facebook.com/", false, $timeout);
|
$test_uris = $provider->getTestURIs();
|
||||||
if ($facebook === false) {
|
foreach ($test_uris as $uri) {
|
||||||
$results['facebook.com'] = array(
|
$success = @file_get_contents($uri, false, $timeout);
|
||||||
|
if ($success === false) {
|
||||||
|
$results[$uri] = array(
|
||||||
$res_no,
|
$res_no,
|
||||||
null,
|
null,
|
||||||
'Unable to make an HTTP request to facebook.com. Facebook may be '.
|
"Unable to make an HTTP request to {$uri}. {$name} may be ".
|
||||||
'down or inaccessible.');
|
'down or inaccessible.');
|
||||||
} else {
|
} else {
|
||||||
$results['facebook.com'] = array(
|
$results[$uri] = array(
|
||||||
$res_ok,
|
$res_ok,
|
||||||
null,
|
null,
|
||||||
'Made a request to facebook.com.');
|
'Made a request to '.$uri.'.');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$graph = @file_get_contents(
|
$test_uri = new PhutilURI($provider->getTokenURI());
|
||||||
"https://graph.facebook.com/me",
|
|
||||||
false,
|
|
||||||
$timeout);
|
|
||||||
if ($graph === false) {
|
|
||||||
$results['Facebook Graph'] = array(
|
|
||||||
$res_no,
|
|
||||||
null,
|
|
||||||
"Unable to make an HTTPS request to graph.facebook.com. ".
|
|
||||||
"The Facebook graph may be down or inaccessible.");
|
|
||||||
} else {
|
|
||||||
$results['Facebook Graph'] = array(
|
|
||||||
$res_ok,
|
|
||||||
null,
|
|
||||||
'Made a request to graph.facebook.com.');
|
|
||||||
}
|
|
||||||
|
|
||||||
$test_uri = new PhutilURI('https://graph.facebook.com/oauth/access_token');
|
|
||||||
$test_uri->setQueryParams(
|
$test_uri->setQueryParams(
|
||||||
array(
|
array(
|
||||||
'client_id' => $client_id,
|
'client_id' => $client_id,
|
||||||
|
@ -162,22 +147,22 @@ class PhabricatorOAuthDiagnosticsController
|
||||||
null,
|
null,
|
||||||
"Unable to perform an application login with your Application ID and ".
|
"Unable to perform an application login with your Application ID and ".
|
||||||
"Application Secret. You may have mistyped or misconfigured them; ".
|
"Application Secret. You may have mistyped or misconfigured them; ".
|
||||||
"Facebook may have revoked your authorization; or Facebook may be ".
|
"{$name} may have revoked your authorization; or {$name} may be ".
|
||||||
"having technical problems.");
|
"having technical problems.");
|
||||||
} else {
|
} else {
|
||||||
if ($token_strict) {
|
if ($token_strict) {
|
||||||
$results['App Login'] = array(
|
$results['App Login'] = array(
|
||||||
$res_ok,
|
$res_ok,
|
||||||
'(A Valid Token)',
|
'(A Valid Token)',
|
||||||
"Raw application login to Facebook works.");
|
"Raw application login to {$name} works.");
|
||||||
} else {
|
} else {
|
||||||
$data = json_decode($token_value, true);
|
$data = json_decode($token_value, true);
|
||||||
if (!is_array($data)) {
|
if (!is_array($data)) {
|
||||||
$results['App Login'] = array(
|
$results['App Login'] = array(
|
||||||
$res_no,
|
$res_no,
|
||||||
$token_value,
|
$token_value,
|
||||||
"Application Login failed but the graph server did not respond ".
|
"Application Login failed but the provider did not respond ".
|
||||||
"with valid JSON error information. Facebook may be experiencing ".
|
"with valid JSON error information. {$name} may be experiencing ".
|
||||||
"technical problems.");
|
"technical problems.");
|
||||||
} else {
|
} else {
|
||||||
$results['App Login'] = array(
|
$results['App Login'] = array(
|
||||||
|
@ -192,6 +177,7 @@ class PhabricatorOAuthDiagnosticsController
|
||||||
}
|
}
|
||||||
|
|
||||||
private function renderResults($results) {
|
private function renderResults($results) {
|
||||||
|
$provider = $this->provider;
|
||||||
|
|
||||||
$rows = array();
|
$rows = array();
|
||||||
foreach ($results as $key => $result) {
|
foreach ($results as $key => $result) {
|
||||||
|
@ -219,20 +205,22 @@ class PhabricatorOAuthDiagnosticsController
|
||||||
'wide',
|
'wide',
|
||||||
));
|
));
|
||||||
|
|
||||||
|
$title = $provider->getProviderName() . ' Auth Diagnostics';
|
||||||
|
|
||||||
$panel_view = new AphrontPanelView();
|
$panel_view = new AphrontPanelView();
|
||||||
$panel_view->setHeader('Facebook Auth Diagnostics');
|
$panel_view->setHeader($title);
|
||||||
$panel_view->appendChild(
|
$panel_view->appendChild(
|
||||||
'<p class="aphront-panel-instructions">These tests may be able to '.
|
'<p class="aphront-panel-instructions">These tests may be able to '.
|
||||||
'help diagnose the root cause of problems you experience with '.
|
'help diagnose the root cause of problems you experience with '.
|
||||||
'Facebook Authentication. Reload the page to run the tests again.</p>');
|
$provider->getProviderName() .
|
||||||
|
' Authentication. Reload the page to run the tests again.</p>');
|
||||||
$panel_view->appendChild($table_view);
|
$panel_view->appendChild($table_view);
|
||||||
|
|
||||||
return $this->buildStandardPageResponse(
|
return $this->buildStandardPageResponse(
|
||||||
$panel_view,
|
$panel_view,
|
||||||
array(
|
array(
|
||||||
'title' => 'Facebook Auth Diagnostics',
|
'title' => $title,
|
||||||
));
|
));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ abstract class PhabricatorOAuthProvider {
|
||||||
const PROVIDER_FACEBOOK = 'facebook';
|
const PROVIDER_FACEBOOK = 'facebook';
|
||||||
const PROVIDER_GITHUB = 'github';
|
const PROVIDER_GITHUB = 'github';
|
||||||
const PROVIDER_GOOGLE = 'google';
|
const PROVIDER_GOOGLE = 'google';
|
||||||
|
const PROVIDER_PHABRICATOR = 'phabricator';
|
||||||
|
|
||||||
private $accessToken;
|
private $accessToken;
|
||||||
|
|
||||||
|
@ -29,10 +30,12 @@ abstract class PhabricatorOAuthProvider {
|
||||||
abstract public function isProviderEnabled();
|
abstract public function isProviderEnabled();
|
||||||
abstract public function isProviderLinkPermanent();
|
abstract public function isProviderLinkPermanent();
|
||||||
abstract public function isProviderRegistrationEnabled();
|
abstract public function isProviderRegistrationEnabled();
|
||||||
abstract public function getRedirectURI();
|
|
||||||
abstract public function getClientID();
|
abstract public function getClientID();
|
||||||
|
abstract public function renderGetClientIDHelp();
|
||||||
abstract public function getClientSecret();
|
abstract public function getClientSecret();
|
||||||
|
abstract public function renderGetClientSecretHelp();
|
||||||
abstract public function getAuthURI();
|
abstract public function getAuthURI();
|
||||||
|
abstract public function getTestURIs();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the provider needs extra stuff in the auth request, return it here.
|
* If the provider needs extra stuff in the auth request, return it here.
|
||||||
|
@ -77,6 +80,14 @@ abstract class PhabricatorOAuthProvider {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is where the OAuth provider will redirect the user after the user
|
||||||
|
* grants Phabricator access.
|
||||||
|
*/
|
||||||
|
final public function getRedirectURI() {
|
||||||
|
$key = $this->getProviderKey();
|
||||||
|
return PhabricatorEnv::getURI('/oauth/'.$key.'/login/');
|
||||||
|
}
|
||||||
|
|
||||||
final public function setAccessToken($access_token) {
|
final public function setAccessToken($access_token) {
|
||||||
$this->accessToken = $access_token;
|
$this->accessToken = $access_token;
|
||||||
|
@ -98,6 +109,9 @@ abstract class PhabricatorOAuthProvider {
|
||||||
case self::PROVIDER_GOOGLE:
|
case self::PROVIDER_GOOGLE:
|
||||||
$class = 'PhabricatorOAuthProviderGoogle';
|
$class = 'PhabricatorOAuthProviderGoogle';
|
||||||
break;
|
break;
|
||||||
|
case self::PROVIDER_PHABRICATOR:
|
||||||
|
$class = 'PhabricatorOAuthProviderPhabricator';
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Exception('Unknown OAuth provider.');
|
throw new Exception('Unknown OAuth provider.');
|
||||||
}
|
}
|
||||||
|
@ -110,6 +124,7 @@ abstract class PhabricatorOAuthProvider {
|
||||||
self::PROVIDER_FACEBOOK,
|
self::PROVIDER_FACEBOOK,
|
||||||
self::PROVIDER_GITHUB,
|
self::PROVIDER_GITHUB,
|
||||||
self::PROVIDER_GOOGLE,
|
self::PROVIDER_GOOGLE,
|
||||||
|
self::PROVIDER_PHABRICATOR,
|
||||||
);
|
);
|
||||||
$providers = array();
|
$providers = array();
|
||||||
foreach ($all as $provider) {
|
foreach ($all as $provider) {
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'infrastructure/env');
|
||||||
|
|
||||||
phutil_require_module('phutil', 'symbols');
|
phutil_require_module('phutil', 'symbols');
|
||||||
phutil_require_module('phutil', 'utils');
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2011 Facebook, Inc.
|
* Copyright 2012 Facebook, Inc.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -40,22 +40,35 @@ class PhabricatorOAuthProviderFacebook extends PhabricatorOAuthProvider {
|
||||||
return PhabricatorEnv::getEnvConfig('facebook.registration-enabled');
|
return PhabricatorEnv::getEnvConfig('facebook.registration-enabled');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getRedirectURI() {
|
|
||||||
return PhabricatorEnv::getURI('/oauth/facebook/login/');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getClientID() {
|
public function getClientID() {
|
||||||
return PhabricatorEnv::getEnvConfig('facebook.application-id');
|
return PhabricatorEnv::getEnvConfig('facebook.application-id');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function renderGetClientIDHelp() {
|
||||||
|
return 'To generate an ID, sign into Facebook, install the "Developer"'.
|
||||||
|
' application, and use it to create a new Facebook application.';
|
||||||
|
}
|
||||||
|
|
||||||
public function getClientSecret() {
|
public function getClientSecret() {
|
||||||
return PhabricatorEnv::getEnvConfig('facebook.application-secret');
|
return PhabricatorEnv::getEnvConfig('facebook.application-secret');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function renderGetClientSecretHelp() {
|
||||||
|
return 'You can find the application secret in the Facebook'.
|
||||||
|
' "Developer" application on Facebook.';
|
||||||
|
}
|
||||||
|
|
||||||
public function getAuthURI() {
|
public function getAuthURI() {
|
||||||
return 'https://www.facebook.com/dialog/oauth';
|
return 'https://www.facebook.com/dialog/oauth';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getTestURIs() {
|
||||||
|
return array(
|
||||||
|
'http://facebook.com',
|
||||||
|
'https://graph.facebook.com/me'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function getTokenURI() {
|
public function getTokenURI() {
|
||||||
return 'https://graph.facebook.com/oauth/access_token';
|
return 'https://graph.facebook.com/oauth/access_token';
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,18 +40,22 @@ class PhabricatorOAuthProviderGitHub extends PhabricatorOAuthProvider {
|
||||||
return PhabricatorEnv::getEnvConfig('github.registration-enabled');
|
return PhabricatorEnv::getEnvConfig('github.registration-enabled');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getRedirectURI() {
|
|
||||||
return PhabricatorEnv::getURI('/oauth/github/login/');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getClientID() {
|
public function getClientID() {
|
||||||
return PhabricatorEnv::getEnvConfig('github.application-id');
|
return PhabricatorEnv::getEnvConfig('github.application-id');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function renderGetClientIDHelp() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public function getClientSecret() {
|
public function getClientSecret() {
|
||||||
return PhabricatorEnv::getEnvConfig('github.application-secret');
|
return PhabricatorEnv::getEnvConfig('github.application-secret');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function renderGetClientSecretHelp() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public function getAuthURI() {
|
public function getAuthURI() {
|
||||||
return 'https://github.com/login/oauth/authorize';
|
return 'https://github.com/login/oauth/authorize';
|
||||||
}
|
}
|
||||||
|
@ -60,6 +64,12 @@ class PhabricatorOAuthProviderGitHub extends PhabricatorOAuthProvider {
|
||||||
return 'https://github.com/login/oauth/access_token';
|
return 'https://github.com/login/oauth/access_token';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getTestURIs() {
|
||||||
|
return array(
|
||||||
|
'http://github.com',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function getUserInfoURI() {
|
public function getUserInfoURI() {
|
||||||
return 'https://github.com/api/v2/json/user/show';
|
return 'https://github.com/api/v2/json/user/show';
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,22 +40,32 @@ class PhabricatorOAuthProviderGoogle extends PhabricatorOAuthProvider {
|
||||||
return PhabricatorEnv::getEnvConfig('google.registration-enabled');
|
return PhabricatorEnv::getEnvConfig('google.registration-enabled');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getRedirectURI() {
|
|
||||||
return PhabricatorEnv::getURI('/oauth/google/login/');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getClientID() {
|
public function getClientID() {
|
||||||
return PhabricatorEnv::getEnvConfig('google.application-id');
|
return PhabricatorEnv::getEnvConfig('google.application-id');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function renderGetClientIDHelp() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public function getClientSecret() {
|
public function getClientSecret() {
|
||||||
return PhabricatorEnv::getEnvConfig('google.application-secret');
|
return PhabricatorEnv::getEnvConfig('google.application-secret');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function renderGetClientSecretHelp() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public function getAuthURI() {
|
public function getAuthURI() {
|
||||||
return 'https://accounts.google.com/o/oauth2/auth';
|
return 'https://accounts.google.com/o/oauth2/auth';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getTestURIs() {
|
||||||
|
return array(
|
||||||
|
'http://www.google.com'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function getTokenURI() {
|
public function getTokenURI() {
|
||||||
return 'https://accounts.google.com/o/oauth2/token';
|
return 'https://accounts.google.com/o/oauth2/token';
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue