diff options
Diffstat (limited to 'extensions/BrowserID')
-rw-r--r-- | extensions/BrowserID/Config.pm | 43 | ||||
-rw-r--r-- | extensions/BrowserID/Extension.pm | 49 | ||||
-rw-r--r-- | extensions/BrowserID/TODO | 19 | ||||
-rw-r--r-- | extensions/BrowserID/lib/Login.pm | 125 | ||||
-rw-r--r-- | extensions/BrowserID/template/en/default/hook/account/auth/login-additional_methods.html.tmpl | 57 | ||||
-rw-r--r-- | extensions/BrowserID/template/en/default/hook/account/auth/login-small-additional_methods.html.tmpl | 36 | ||||
-rw-r--r-- | extensions/BrowserID/template/en/default/hook/global/user-error-errors.html.tmpl | 9 | ||||
-rw-r--r-- | extensions/BrowserID/web/sign_in_orange.png | bin | 0 -> 2100 bytes |
8 files changed, 338 insertions, 0 deletions
diff --git a/extensions/BrowserID/Config.pm b/extensions/BrowserID/Config.pm new file mode 100644 index 000000000..a55ea8ff0 --- /dev/null +++ b/extensions/BrowserID/Config.pm @@ -0,0 +1,43 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the BrowserID Bugzilla Extension. +# +# The Initial Developer of the Original Code is the Mozilla Foundation. +# Portions created by the Initial Developer are Copyright (C) 2011 the +# Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Gervase Markham <gerv@gerv.net> + +package Bugzilla::Extension::BrowserID; +use strict; + +use constant NAME => 'BrowserID'; + +use constant REQUIRED_MODULES => [ + { + package => 'JSON', + module => 'JSON', + version => 0, + }, + { + package => 'libwww-perl', + module => 'LWP::UserAgent', + version => 0, + }, +]; + +use constant OPTIONAL_MODULES => [ +]; + +__PACKAGE__->NAME; diff --git a/extensions/BrowserID/Extension.pm b/extensions/BrowserID/Extension.pm new file mode 100644 index 000000000..873cca8e3 --- /dev/null +++ b/extensions/BrowserID/Extension.pm @@ -0,0 +1,49 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the BrowserID Bugzilla Extension. +# +# The Initial Developer of the Original Code is the Mozilla Foundation. +# Portions created by the Initial Developer are Copyright (C) 2011 the +# Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Gervase Markham <gerv@gerv.net> + +package Bugzilla::Extension::BrowserID; +use strict; +use base qw(Bugzilla::Extension); + +our $VERSION = '0.01'; + +sub auth_login_methods { + my ($self, $args) = @_; + my $modules = $args->{'modules'}; + if (exists($modules->{'BrowserID'})) { + $modules->{'BrowserID'} = 'Bugzilla/Extension/BrowserID/Login.pm'; + } +} + +sub config_modify_panels { + my ($self, $args) = @_; + my $panels = $args->{'panels'}; + my $auth_panel_params = $panels->{'auth'}->{'params'}; + + my ($user_info_class) = + grep { $_->{'name'} eq 'user_info_class' } @$auth_panel_params; + + if ($user_info_class) { + push(@{ $user_info_class->{'choices'} }, "BrowserID,CGI"); + } +} + +__PACKAGE__->NAME; diff --git a/extensions/BrowserID/TODO b/extensions/BrowserID/TODO new file mode 100644 index 000000000..ac94a3c42 --- /dev/null +++ b/extensions/BrowserID/TODO @@ -0,0 +1,19 @@ +ToDo: + +* Cache the LWP::UserAgent in Login.pm? + +* Fix Bugzilla::Auth::Login::Stack to allow failure part way down the chain + (currently, it seems that both CGI and BrowserID have to be last in order + to report login failures correctly.) + +* JS inclusions noticeably slow page load. Do we want a local copy of + browserid.js? Do the browserid folks object to that? How can we get good + performance? How can we avoid including it in every logged-in page? Can we + do demand loading onclick, and/or load-on-reveal? + +* Fix -8px margin-bottom hack in login-small-additional_methods.html.tmpl + + + + + diff --git a/extensions/BrowserID/lib/Login.pm b/extensions/BrowserID/lib/Login.pm new file mode 100644 index 000000000..03d33cf6d --- /dev/null +++ b/extensions/BrowserID/lib/Login.pm @@ -0,0 +1,125 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the BrowserID Bugzilla Extension. +# +# The Initial Developer of the Original Code is the Mozilla Foundation. +# Portions created by the Initial Developer are Copyright (C) 2011 the +# Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Gervase Markham <gerv@gerv.net> + +package Bugzilla::Extension::BrowserID::Login; +use strict; +use base qw(Bugzilla::Auth::Login); + +use Bugzilla::Constants; +use Bugzilla::Util; +use Bugzilla::Error; +use Bugzilla::Token; + +use JSON; +use LWP::UserAgent; + +use constant requires_verification => 0; +use constant is_automatic => 1; + +sub get_login_info { + my ($self) = @_; + + my $cgi = Bugzilla->cgi; + + my $assertion = $cgi->param("browserid_assertion"); + # Avoid the assertion being copied into any 'echoes' of the current URL + # in the page. + $cgi->delete('browserid_assertion'); + + if (!$assertion) { + return { failure => AUTH_NODATA }; + } + + my $token = $cgi->param("token"); + $cgi->delete('token'); + check_hash_token($token, ['login']); + + my $urlbase = new URI(correct_urlbase()); + my $audience = $urlbase->scheme . "://" . $urlbase->host_port; + + my $ua = new LWP::UserAgent(); + + my $info = { 'status' => 'browserid-server-broken' }; + eval { + my $response = $ua->post("https://browserid.org/verify", + [assertion => $assertion, + audience => $audience]); + + $info = decode_json($response->content()); + }; + + if ($info->{'status'} eq "okay" && + $info->{'audience'} eq $audience && + ($info->{'expires'} / 1000) > time()) + { + my $login_data = { + 'username' => $info->{'email'} + }; + + my $result = + Bugzilla::Auth::Verify->create_or_update_user($login_data); + return $result if $result->{'failure'}; + + my $user = $result->{'user'}; + + # You can restrict people in a particular group from logging in using + # BrowserID by making that group a member of a group called + # "no-browser-id". + # + # If you have your "createemailregexp" set up in such a way that a + # newly-created account is a member of "no-browser-id", this code will + # create an account for them and then fail their login. Which isn't + # great, but they can still use normal-Bugzilla-login password + # recovery. + if ($user->in_group('no-browser-id')) { + # We use a custom error here, for greater clarity, rather than + # returning a failure code. + ThrowUserError('browserid_account_too_powerful'); + } + + $login_data->{'user'} = $user; + $login_data->{'user_id'} = $user->id; + + return $login_data; + } + else { + return { failure => AUTH_LOGINFAILED }; + } +} + +# Pinched from Bugzilla::Auth::Login::CGI +sub fail_nodata { + my ($self) = @_; + my $cgi = Bugzilla->cgi; + my $template = Bugzilla->template; + + if (Bugzilla->usage_mode != USAGE_MODE_BROWSER) { + ThrowUserError('login_required'); + } + + print $cgi->header(); + $template->process("account/auth/login.html.tmpl", + { 'target' => $cgi->url(-relative=>1) }) + || ThrowTemplateError($template->error()); + exit; +} + +1; diff --git a/extensions/BrowserID/template/en/default/hook/account/auth/login-additional_methods.html.tmpl b/extensions/BrowserID/template/en/default/hook/account/auth/login-additional_methods.html.tmpl new file mode 100644 index 000000000..2b6f4b85a --- /dev/null +++ b/extensions/BrowserID/template/en/default/hook/account/auth/login-additional_methods.html.tmpl @@ -0,0 +1,57 @@ +[% IF Param('user_info_class').split(',').contains('BrowserID') %] + +[% USE Bugzilla %] +[% cgi = Bugzilla.cgi %] + +<script src="https://browserid.org/include.js" type="text/javascript"></script> + +<script type="text/javascript"> +function browserid_sign_in() { + navigator.id.getVerifiedEmail(function(assertion) { + if (assertion) { + // This code will be invoked once the user has successfully + // selected an email address they control to sign in with. + var browseridForm = document.createElement('form'); + browseridForm.action = '[% target FILTER js %]'; + browseridForm.method = 'POST'; + browseridForm.style.display = 'none'; + + var tokenField = document.createElement('input'); + tokenField.type = 'hidden'; + tokenField.name = 'token'; + tokenField.value = '[% issue_hash_token(['login']) FILTER js %]'; + browseridForm.appendChild(tokenField); + + var assertionField = document.createElement('input'); + assertionField.type = 'hidden'; + assertionField.name = 'browserid_assertion'; + assertionField.value = assertion; + browseridForm.appendChild(assertionField); + + var hidden_fields =[]; + var field_count = 0; + [% FOREACH field = cgi.param() %] + [% NEXT IF field.search("^(Bugzilla_(login|password|restrictlogin)|token|browserid_assertion)$") %] + [% FOREACH mvalue = cgi.param(field).slice(0) %] + hidden_fields[field_count] = document.createElement('input'); + hidden_fields[field_count].type = 'hidden'; + hidden_fields[field_count].name = '[% field FILTER js %]'; + hidden_fields[field_count].value = '[% mvalue FILTER html_linebreak FILTER js %]'; + browseridForm.appendChild(hidden_fields[field_count]); + [% END %] + field_count++; + [% END %] + + document.body.appendChild(browseridForm); + browseridForm.submit(); + return true; + } + }); +} +</script> + +<p> +Or, log in with BrowserID: +<img src="extensions/BrowserID/web/sign_in_orange.png" onclick="browserid_sign_in()"> +</p> +[% END %] diff --git a/extensions/BrowserID/template/en/default/hook/account/auth/login-small-additional_methods.html.tmpl b/extensions/BrowserID/template/en/default/hook/account/auth/login-small-additional_methods.html.tmpl new file mode 100644 index 000000000..26d5ff609 --- /dev/null +++ b/extensions/BrowserID/template/en/default/hook/account/auth/login-small-additional_methods.html.tmpl @@ -0,0 +1,36 @@ +[% IF Param('user_info_class').split(',').contains('BrowserID') %] +<script src="https://browserid.org/include.js" type="text/javascript"></script> + +<script type="text/javascript"> +function browserid_sign_in() { + navigator.id.getVerifiedEmail(function(assertion) { + if (assertion) { + // This code will be invoked once the user has successfully + // selected an email address they control to sign in with. + var browseridForm = document.createElement('form'); + browseridForm.action = '[% login_target FILTER js %]'; + browseridForm.method = 'POST'; + browseridForm.style.display = 'none'; + + var tokenField = document.createElement('input'); + tokenField.type = 'hidden'; + tokenField.name = 'token'; + tokenField.value = '[% issue_hash_token(['login']) FILTER js %]'; + browseridForm.appendChild(tokenField); + + var assertionField = document.createElement('input'); + assertionField.type = 'hidden'; + assertionField.name = 'browserid_assertion'; + assertionField.value = assertion; + browseridForm.appendChild(assertionField); + + document.body.appendChild(browseridForm); + browseridForm.submit(); + return true; + } + }); +} +</script> + +<img src="extensions/BrowserID/web/sign_in_orange.png" onclick="browserid_sign_in()" style="margin-bottom: -8px"> or +[% END %] diff --git a/extensions/BrowserID/template/en/default/hook/global/user-error-errors.html.tmpl b/extensions/BrowserID/template/en/default/hook/global/user-error-errors.html.tmpl new file mode 100644 index 000000000..ba8297a28 --- /dev/null +++ b/extensions/BrowserID/template/en/default/hook/global/user-error-errors.html.tmpl @@ -0,0 +1,9 @@ +[% IF error == "browserid_account_too_powerful" %] + [% title = "Account Too Powerful" %] + Your account's macho studliness is too much for BrowserID. I'm afraid you + will have to log in using the conventional method. + <br><br> + (BrowserID logins are disabled for accounts which are members of certain + particularly sensitive groups, while we gain experience with the + technology.) +[% END %] diff --git a/extensions/BrowserID/web/sign_in_orange.png b/extensions/BrowserID/web/sign_in_orange.png Binary files differnew file mode 100644 index 000000000..65ccda473 --- /dev/null +++ b/extensions/BrowserID/web/sign_in_orange.png |