1
0
Fork 0
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:
epriestley 2013-10-14 14:34:57 -07:00
parent 502c6f2d48
commit 0ce4f6d176
5 changed files with 143 additions and 5 deletions

View file

@ -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',

View file

@ -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',

View file

@ -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);
} }

View file

@ -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);
}
}

View 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);
});