Commit a5a97f21 authored by Hugh Davenport's avatar Hugh Davenport
Browse files

Add ability to register with a BrowserID (bug #986004)



When a user clicks on "BrowserID Login", one of three things will happen
1- If they have an account, they will login
2- If they don't but there is one authinstance with browserid is present
    AND it has weautocreateusers enabled, then they will get an account
    in that institution, and login
3- If none of the above is true, they will get redirected to a register
    page, which follows same self registration pattern as the internal
    authentication with the "confirm email" step removed.

Change-Id: Idde3166e0664bf2acdc1da32271125e91d43af9c
Signed-off-by: default avatarHugh Davenport <hugh@catalyst.net.nz>
parent 9e3e0367
......@@ -30,6 +30,7 @@ $string['description'] = 'Authenticate using a BrowserID';
$string['badassertion'] = 'The given BrowserID assertion is not valid: %s';
$string['badverification'] = 'Mahara did not receive valid JSON output from the BrowserID verifier.';
$string['login'] = 'BrowserID Login';
$string['register'] = 'BrowserID Register';
$string['missingassertion'] = 'BrowserID did not return an alpha-numeric assertion.';
$string['emailalreadyclaimed'] = "Another user account has already claimed the email address '%s'.";
......
......@@ -259,6 +259,10 @@ EOF;
class BrowserIDUser extends LiveUser {
public function login($email) {
// This will do one of 3 things
// 1 - If a user has an account, log them in
// 2 - If a user doesn't have an account, and there is an auth method (which also has weautocreate), create acc and login
// 3 - If a user doesn't have an account, and there is more than one auth method, show a registration page
$sql = "SELECT
a.id, i.name AS institutionname
FROM
......@@ -322,7 +326,40 @@ class BrowserIDUser extends LiveUser {
$this->authenticate($user, $auth->instanceid);
}
else {
list($form, $registerconfirm) = auth_generate_registration_form('register', 'browserid', '/register.php');
if (!$form) {
throw new AuthUnknownUserException(get_string('emailnotfound', 'auth.browserid', $email));
}
if (record_exists('usr', 'email', $email)
|| record_exists('artefact_internal_profile_email', 'email', $email)) {
throw new AuthUnknownUserException(get_string('emailalreadytaken', 'auth.internal', $email));
}
$form['elements']['email'] = array(
'type' => 'hidden',
'value' => $email
);
$form['elements']['authtype'] = array(
'type' => 'hidden',
'value' => 'browserid'
);
list($formhtml, $js) = auth_generate_registration_form_js($form, $registerconfirm);
$registerdescription = get_string('registerwelcome');
if ($registerterms = get_config('registerterms')) {
$registerdescription .= ' ' . get_string('registeragreeterms');
}
$registerdescription .= ' ' . get_string('registerprivacy');
$smarty = smarty(array('jquery'));
$smarty->assign('register_form', $formhtml);
$smarty->assign('registerdescription', $registerdescription);
if ($registerterms) {
$smarty->assign('termsandconditions', get_site_page_content('termsandconditions'));
}
$smarty->assign('PAGEHEADING', get_string('register', 'auth.browserid'));
$smarty->assign('INLINEJAVASCRIPT', $js);
$smarty->display('register.tpl');
die;
}
}
}
......@@ -28,34 +28,44 @@ safe_require('auth', 'browserid');
define('BROWSERID_VERIFIER_URL', 'https://browserid.org/verify');
$assertion = param_variable('assertion', null);
if (!$assertion) {
throw new AuthInstanceException(get_string('missingassertion','auth.browserid'));
if (!session_id()) {
session_start();
}
// Send the assertion to the verification service
$request = array(
if (empty($_SESSION['browseridexpires']) || time() >= $_SESSION['browseridexpires']) {
$assertion = param_variable('assertion', null);
if (!$assertion) {
throw new AuthInstanceException(get_string('missingassertion','auth.browserid'));
}
// Send the assertion to the verification service
$request = array(
CURLOPT_URL => BROWSERID_VERIFIER_URL,
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => 'assertion='.urlencode($assertion).'&audience='.get_audience(),
);
);
$response = mahara_http_request($request);
$response = mahara_http_request($request);
if (empty($response->data)) {
if (empty($response->data)) {
throw new AuthInstanceException(get_string('badverification','auth.browserid'));
}
$jsondata = json_decode($response->data);
if (empty($jsondata)) {
}
$jsondata = json_decode($response->data);
if (empty($jsondata)) {
throw new AuthInstanceException(get_string('badverification','auth.browserid'));
}
}
if ($jsondata->status != 'okay') {
if ($jsondata->status != 'okay') {
throw new AuthInstanceException(get_string('badassertion','auth.browserid', htmlspecialchars($jsondata->reason)));
}
$_SESSION['browseridexpires'] = $jsondata->expires/1000;
$_SESSION['browseridemail'] = $jsondata->email;
}
$USER = new BrowserIDUser;
$USER->login($jsondata->email);
$USER->login($_SESSION['browseridemail']);
unset($_SESSION['browseridexpires']);
unset($_SESSION['browseridemail']);
redirect();
function get_audience() {
......
......@@ -1858,6 +1858,7 @@ function user_login_tries_to_zero() {
}
function auth_generate_registration_form($formname, $authname='internal', $goto) {
require_once(get_config('libroot').'antispam.php');
$elements = array(
'firstname' => array(
'type' => 'text',
......@@ -2197,11 +2198,16 @@ function auth_register_submit(Pieform $form, $values) {
get_string('approvalemailmessagehtml', 'auth.internal', $values['firstname'], get_config('sitename'), get_config('sitename')));
$_SESSION['registeredokawaiting'] = true;
}
else {
if ($values['authtype'] == 'browserid') {
redirect('/register.php?key='.$values['key']);
}
else {
email_user($user, null,
get_string('registeredemailsubject', 'auth.internal', get_config('sitename')),
get_string('registeredemailmessagetext', 'auth.internal', $values['firstname'], get_config('sitename'), get_config('wwwroot'), $values['key'], get_config('sitename')),
get_string('registeredemailmessagehtml', 'auth.internal', $values['firstname'], get_config('sitename'), get_config('wwwroot'), $values['key'], get_config('wwwroot'), $values['key'], get_config('sitename')));
}
// Add a marker in the session to say that the user has registered
$_SESSION['registered'] = true;
}
......
......@@ -596,10 +596,12 @@
<FIELD NAME="pending" TYPE="int" LENGTH="1" DEFAULT="0" NOTNULL="true"/>
<FIELD NAME="reason" TYPE="text" NOTNULL="false"/>
<FIELD NAME="extra" TYPE="text" NOTNULL="false"/>
<FIELD NAME="authtype" TYPE="char" LENGTH="255" DEFAULT="internal" NOTNULL="true"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id" />
<KEY NAME="institution" TYPE="foreign" FIELDS="institution" REFTABLE="institution" REFFIELDS="name"/>
<KEY NAME="authtype" TYPE="foreign" FIELDS="authtype" REFTABLE="auth_installed" REFFIELDS="name"/>
</KEYS>
</TABLE>
<TABLE NAME="usr_infectedupload">
......
......@@ -2883,5 +2883,15 @@ function xmldb_core_upgrade($oldversion=0) {
add_field($table, $field);
}
if ($oldversion < 2012051500) {
$table = new XMLDBTable('usr_registration');
$field = new XMLDBField('authtype');
$field->setAttributes(XMLDB_TYPE_CHAR, 255, null, XMLDB_NOTNULL, null, null, null, 'internal');
add_field($table, $field);
$key = new XMLDBKey('authtype');
$key->setAttributes(XMLDB_KEY_FOREIGN, array('authtype'), 'auth_installed', array('name'));
add_key($table, $key);
}
return $status;
}
......@@ -28,7 +28,7 @@
defined('INTERNAL') || die();
$config = new StdClass;
$config->version = 2012042800;
$config->version = 2012051500;
$config->release = '1.6.0dev';
$config->minupgradefrom = 2008040200;
$config->minupgraderelease = '1.0.0 (release tag 1.0.0_RELEASE)';
......
......@@ -62,7 +62,7 @@ if (is_logged_in()) {
// Step two of registration (first as it's the easiest): the user has
// registered, show them a screen telling them this.
if (!empty($_SESSION['registered'])) {
if (!$key && !empty($_SESSION['registered'])) {
unset($_SESSION['registered']);
die_info(get_string('registeredok', 'auth.internal'));
}
......@@ -108,9 +108,9 @@ if (isset($key)) {
}
$registration->lastlogin = db_format_timestamp(time());
$authinstance = get_record('auth_instance', 'institution', $registration->institution, 'authname', 'internal');
$authinstance = get_record('auth_instance', 'institution', $registration->institution, 'authname', $registration->authtype ? $registration->authtype : 'internal');
if (false == $authinstance) {
throw new ConfigException('No internal auth instance for institution');
throw new ConfigException('No ' . ($registration->authtype ? $registration->authtype : 'internal') . ' auth instance for institution');
}
if (!empty($registration->extra)) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment