mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 00:42:41 +01:00
Add Persona auth provider
Summary: Ref T3958. Adds a provider for Mozilla's Persona auth. Test Plan: - Created a Persona provider. - Registered a new account with Persona. - Logged in with Persona. - Linked an account with Persona. - Dissolved an account link with Persona. Reviewers: btrahan Reviewed By: btrahan CC: aran Maniphest Tasks: T3958 Differential Revision: https://secure.phabricator.com/D7313
This commit is contained in:
parent
502c6f2d48
commit
0ce4f6d176
5 changed files with 143 additions and 5 deletions
|
@ -1949,6 +1949,20 @@ celerity_register_resource_map(array(
|
||||||
),
|
),
|
||||||
'disk' => '/rsrc/js/application/owners/owners-path-editor.js',
|
'disk' => '/rsrc/js/application/owners/owners-path-editor.js',
|
||||||
),
|
),
|
||||||
|
'javelin-behavior-persona-login' =>
|
||||||
|
array(
|
||||||
|
'uri' => '/res/128fdf56/rsrc/js/application/auth/behavior-persona-login.js',
|
||||||
|
'type' => 'js',
|
||||||
|
'requires' =>
|
||||||
|
array(
|
||||||
|
0 => 'javelin-behavior',
|
||||||
|
1 => 'javelin-resource',
|
||||||
|
2 => 'javelin-stratcom',
|
||||||
|
3 => 'javelin-workflow',
|
||||||
|
4 => 'javelin-util',
|
||||||
|
),
|
||||||
|
'disk' => '/rsrc/js/application/auth/behavior-persona-login.js',
|
||||||
|
),
|
||||||
'javelin-behavior-phabricator-active-nav' =>
|
'javelin-behavior-phabricator-active-nav' =>
|
||||||
array(
|
array(
|
||||||
'uri' => '/res/9c8d3df8/rsrc/js/core/behavior-active-nav.js',
|
'uri' => '/res/9c8d3df8/rsrc/js/core/behavior-active-nav.js',
|
||||||
|
|
|
@ -962,6 +962,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorAuthProviderOAuthGoogle' => 'applications/auth/provider/PhabricatorAuthProviderOAuthGoogle.php',
|
'PhabricatorAuthProviderOAuthGoogle' => 'applications/auth/provider/PhabricatorAuthProviderOAuthGoogle.php',
|
||||||
'PhabricatorAuthProviderOAuthTwitch' => 'applications/auth/provider/PhabricatorAuthProviderOAuthTwitch.php',
|
'PhabricatorAuthProviderOAuthTwitch' => 'applications/auth/provider/PhabricatorAuthProviderOAuthTwitch.php',
|
||||||
'PhabricatorAuthProviderPassword' => 'applications/auth/provider/PhabricatorAuthProviderPassword.php',
|
'PhabricatorAuthProviderPassword' => 'applications/auth/provider/PhabricatorAuthProviderPassword.php',
|
||||||
|
'PhabricatorAuthProviderPersona' => 'applications/auth/provider/PhabricatorAuthProviderPersona.php',
|
||||||
'PhabricatorAuthRegisterController' => 'applications/auth/controller/PhabricatorAuthRegisterController.php',
|
'PhabricatorAuthRegisterController' => 'applications/auth/controller/PhabricatorAuthRegisterController.php',
|
||||||
'PhabricatorAuthStartController' => 'applications/auth/controller/PhabricatorAuthStartController.php',
|
'PhabricatorAuthStartController' => 'applications/auth/controller/PhabricatorAuthStartController.php',
|
||||||
'PhabricatorAuthUnlinkController' => 'applications/auth/controller/PhabricatorAuthUnlinkController.php',
|
'PhabricatorAuthUnlinkController' => 'applications/auth/controller/PhabricatorAuthUnlinkController.php',
|
||||||
|
@ -3116,6 +3117,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorAuthProviderOAuthGoogle' => 'PhabricatorAuthProviderOAuth',
|
'PhabricatorAuthProviderOAuthGoogle' => 'PhabricatorAuthProviderOAuth',
|
||||||
'PhabricatorAuthProviderOAuthTwitch' => 'PhabricatorAuthProviderOAuth',
|
'PhabricatorAuthProviderOAuthTwitch' => 'PhabricatorAuthProviderOAuth',
|
||||||
'PhabricatorAuthProviderPassword' => 'PhabricatorAuthProvider',
|
'PhabricatorAuthProviderPassword' => 'PhabricatorAuthProvider',
|
||||||
|
'PhabricatorAuthProviderPersona' => 'PhabricatorAuthProvider',
|
||||||
'PhabricatorAuthRegisterController' => 'PhabricatorAuthController',
|
'PhabricatorAuthRegisterController' => 'PhabricatorAuthController',
|
||||||
'PhabricatorAuthStartController' => 'PhabricatorAuthController',
|
'PhabricatorAuthStartController' => 'PhabricatorAuthController',
|
||||||
'PhabricatorAuthUnlinkController' => 'PhabricatorAuthController',
|
'PhabricatorAuthUnlinkController' => 'PhabricatorAuthController',
|
||||||
|
|
|
@ -384,6 +384,7 @@ abstract class PhabricatorAuthProvider {
|
||||||
array(
|
array(
|
||||||
'method' => 'optional string',
|
'method' => 'optional string',
|
||||||
'uri' => 'string',
|
'uri' => 'string',
|
||||||
|
'sigil' => 'optional string',
|
||||||
));
|
));
|
||||||
|
|
||||||
$viewer = $request->getUser();
|
$viewer = $request->getUser();
|
||||||
|
@ -404,11 +405,11 @@ abstract class PhabricatorAuthProvider {
|
||||||
->setSpriteIcon($this->getLoginIcon());
|
->setSpriteIcon($this->getLoginIcon());
|
||||||
|
|
||||||
$button = id(new PHUIButtonView())
|
$button = id(new PHUIButtonView())
|
||||||
->setSize(PHUIButtonView::BIG)
|
->setSize(PHUIButtonView::BIG)
|
||||||
->setColor(PHUIButtonView::GREY)
|
->setColor(PHUIButtonView::GREY)
|
||||||
->setIcon($icon)
|
->setIcon($icon)
|
||||||
->setText($button_text)
|
->setText($button_text)
|
||||||
->setSubtext($this->getProviderName());
|
->setSubtext($this->getProviderName());
|
||||||
|
|
||||||
$uri = $attributes['uri'];
|
$uri = $attributes['uri'];
|
||||||
$uri = new PhutilURI($uri);
|
$uri = new PhutilURI($uri);
|
||||||
|
@ -432,6 +433,7 @@ abstract class PhabricatorAuthProvider {
|
||||||
array(
|
array(
|
||||||
'method' => idx($attributes, 'method', 'GET'),
|
'method' => idx($attributes, 'method', 'GET'),
|
||||||
'action' => (string)$uri,
|
'action' => (string)$uri,
|
||||||
|
'sigil' => idx($attributes, 'sigil'),
|
||||||
),
|
),
|
||||||
$content);
|
$content);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorAuthProviderPersona
|
||||||
|
extends PhabricatorAuthProvider {
|
||||||
|
|
||||||
|
private $adapter;
|
||||||
|
|
||||||
|
public function getProviderName() {
|
||||||
|
return pht('Persona');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDescriptionForCreate() {
|
||||||
|
return pht(
|
||||||
|
'Allow users to login or register using Mozilla Persona.');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAdapter() {
|
||||||
|
if (!$this->adapter) {
|
||||||
|
$adapter = new PhutilAuthAdapterPersona();
|
||||||
|
$this->adapter = $adapter;
|
||||||
|
}
|
||||||
|
return $this->adapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function renderLoginForm(
|
||||||
|
AphrontRequest $request,
|
||||||
|
$mode) {
|
||||||
|
|
||||||
|
Javelin::initBehavior(
|
||||||
|
'persona-login',
|
||||||
|
array(
|
||||||
|
'loginURI' => $this->getLoginURI(),
|
||||||
|
));
|
||||||
|
|
||||||
|
return $this->renderStandardLoginButton(
|
||||||
|
$request,
|
||||||
|
$mode,
|
||||||
|
array(
|
||||||
|
'uri' => $this->getLoginURI(),
|
||||||
|
'sigil' => 'persona-login-form',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isLoginFormAButton() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function processLoginRequest(
|
||||||
|
PhabricatorAuthLoginController $controller) {
|
||||||
|
|
||||||
|
$request = $controller->getRequest();
|
||||||
|
$adapter = $this->getAdapter();
|
||||||
|
|
||||||
|
$account = null;
|
||||||
|
$response = null;
|
||||||
|
|
||||||
|
if (!$request->isAjax()) {
|
||||||
|
throw new Exception("Expected this request to come via Ajax.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$assertion = $request->getStr('assertion');
|
||||||
|
if (!$assertion) {
|
||||||
|
throw new Exception("Expected identity assertion.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$adapter->setAssertion($assertion);
|
||||||
|
$adapter->setAudience(PhabricatorEnv::getURI('/'));
|
||||||
|
|
||||||
|
try {
|
||||||
|
$account_id = $adapter->getAccountID();
|
||||||
|
} catch (Exception $ex) {
|
||||||
|
// TODO: Handle this in a more user-friendly way.
|
||||||
|
throw $ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
return array($this->loadOrCreateAccount($account_id), $response);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
41
webroot/rsrc/js/application/auth/behavior-persona-login.js
Normal file
41
webroot/rsrc/js/application/auth/behavior-persona-login.js
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
/**
|
||||||
|
* @provides javelin-behavior-persona-login
|
||||||
|
* @requires javelin-behavior
|
||||||
|
* javelin-resource
|
||||||
|
* javelin-stratcom
|
||||||
|
* javelin-workflow
|
||||||
|
* javelin-util
|
||||||
|
*/
|
||||||
|
|
||||||
|
JX.behavior('persona-login', function(config) {
|
||||||
|
|
||||||
|
JX.Stratcom.listen(
|
||||||
|
'submit',
|
||||||
|
'persona-login-form',
|
||||||
|
function(e) {
|
||||||
|
e.kill();
|
||||||
|
navigator.id.request();
|
||||||
|
});
|
||||||
|
|
||||||
|
var onloaded = function() {
|
||||||
|
// Before installing watch(), log the user out, because we know they don't
|
||||||
|
// have a valid session if they're hitting this page. If we don't do this,
|
||||||
|
// Persona may immediately trigger a login event, which prevents the user
|
||||||
|
// from selecting another authentication mechanism.
|
||||||
|
navigator.id.logout();
|
||||||
|
|
||||||
|
navigator.id.watch({
|
||||||
|
loggedInUser: null,
|
||||||
|
onlogin: onlogin,
|
||||||
|
onlogout: JX.bag
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var onlogin = function(assertion) {
|
||||||
|
new JX.Workflow(config.loginURI, {assertion: assertion})
|
||||||
|
.start();
|
||||||
|
};
|
||||||
|
|
||||||
|
var persona_library = 'https://login.persona.org/include.js';
|
||||||
|
JX.Resource.load(persona_library, onloaded);
|
||||||
|
});
|
Loading…
Reference in a new issue