summaryrefslogtreecommitdiffstats
path: root/extensions/BrowserID
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/BrowserID')
-rw-r--r--extensions/BrowserID/Config.pm43
-rw-r--r--extensions/BrowserID/Extension.pm49
-rw-r--r--extensions/BrowserID/TODO19
-rw-r--r--extensions/BrowserID/lib/Login.pm126
-rw-r--r--extensions/BrowserID/template/en/default/hook/account/auth/login-additional_methods.html.tmpl52
-rw-r--r--extensions/BrowserID/template/en/default/hook/account/auth/login-small-additional_methods.html.tmpl59
-rw-r--r--extensions/BrowserID/template/en/default/hook/account/create-additional_methods.html.tmpl31
-rw-r--r--extensions/BrowserID/template/en/default/hook/global/user-error-errors.html.tmpl10
-rw-r--r--extensions/BrowserID/web/sign_in_orange.pngbin0 -> 2100 bytes
9 files changed, 389 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..c3d87c958
--- /dev/null
+++ b/extensions/BrowserID/lib/Login.pm
@@ -0,0 +1,126 @@
+# -*- 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;
+use constant user_can_create_account => 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..3a0ecb1cc
--- /dev/null
+++ b/extensions/BrowserID/template/en/default/hook/account/auth/login-additional_methods.html.tmpl
@@ -0,0 +1,52 @@
+[% 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 createHidden(name, value, form) {
+ var field = document.createElement('input');
+ field.type = 'hidden';
+ field.name = name;
+ field.value = value;;
+ form.appendChild(field);
+}
+
+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 form = document.createElement('form');
+ form.action = '[% target FILTER js %]';
+ form.method = 'POST';
+ form.style.display = 'none';
+
+ createHidden('token', '[% issue_hash_token(['login']) FILTER js %]', form);
+ createHidden('Bugzilla_remember', 'on', form);
+ createHidden('browserid_assertion', assertion, form);
+
+ [% FOREACH field = cgi.param() %]
+ [% NEXT IF field.search("^(Bugzilla_(login|password|restrictlogin)|token|browserid_assertion)$") %]
+ [% FOREACH mvalue = cgi.param(field).slice(0) %]
+ createHidden('[% field FILTER js %]',
+ '[% mvalue FILTER html_linebreak FILTER js %]',
+ form);
+ [% END %]
+ [% END %]
+
+ document.body.appendChild(form);
+ form.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..08e68a690
--- /dev/null
+++ b/extensions/BrowserID/template/en/default/hook/account/auth/login-small-additional_methods.html.tmpl
@@ -0,0 +1,59 @@
+[% IF Param('user_info_class').split(',').contains('BrowserID') %]
+<script src="https://browserid.org/include.js" type="text/javascript"></script>
+
+[%# Note this code is a tiny bit different from the other copy; the name of
+ # the variable containing the login url is 'login_target' rather than
+ # 'target' #%]
+
+<script type="text/javascript">
+function createHidden(name, value, form) {
+ var field = document.createElement('input');
+ field.type = 'hidden';
+ field.name = name;
+ field.value = value;;
+ form.appendChild(field);
+}
+
+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 form = document.createElement('form');
+ form.action = '[% login_target FILTER js %]';
+ form.method = 'POST';
+ form.style.display = 'none';
+
+ createHidden('token', '[% issue_hash_token(['login']) FILTER js %]', form);
+ createHidden('Bugzilla_remember', 'on', form);
+ createHidden('browserid_assertion', assertion, form);
+
+ [% FOREACH field = cgi.param() %]
+ [% NEXT IF field.search("^(Bugzilla_(login|password|restrictlogin)|token|browserid_assertion)$") %]
+ [% FOREACH mvalue = cgi.param(field).slice(0) %]
+ createHidden('[% field FILTER js %]',
+ '[% mvalue FILTER html_linebreak FILTER js %]',
+ form);
+ [% END %]
+ [% END %]
+
+ document.body.appendChild(form);
+ form.submit();
+ return true;
+ }
+ });
+}
+YAHOO.util.Event.addListener('login_link[% qs_suffix FILTER js %]','click', function () {
+ var login_link = YAHOO.util.Dom.get('browserid_mini_login[% qs_suffix FILTER js %]');
+ YAHOO.util.Dom.removeClass(login_link, 'bz_default_hidden');
+});
+YAHOO.util.Event.addListener('hide_mini_login[% qs_suffix FILTER js %]','click', function () {
+ var login_link = YAHOO.util.Dom.get('browserid_mini_login[% qs_suffix FILTER js %]');
+ YAHOO.util.Dom.addClass(login_link, 'bz_default_hidden');
+});
+</script>
+
+<span id="browserid_mini_login[% qs_suffix FILTER html %]" class="bz_default_hidden">
+ <img src="extensions/BrowserID/web/sign_in_orange.png" onclick="browserid_sign_in()" style="margin-bottom: -8px"> or
+</span>
+[% END %]
diff --git a/extensions/BrowserID/template/en/default/hook/account/create-additional_methods.html.tmpl b/extensions/BrowserID/template/en/default/hook/account/create-additional_methods.html.tmpl
new file mode 100644
index 000000000..6f75f5cd7
--- /dev/null
+++ b/extensions/BrowserID/template/en/default/hook/account/create-additional_methods.html.tmpl
@@ -0,0 +1,31 @@
+[%# This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ #
+ # This Source Code Form is "Incompatible With Secondary Licenses", as
+ # defined by the Mozilla Public License, v. 2.0.
+ #%]
+
+[% IF Param('user_info_class').split(',').contains('BrowserID') %]
+<script type="text/javascript">
+function browserid_create_account() {
+ 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.
+ document.getElementById('browserid_assertion').value = assertion;
+ document.getElementById('browserid_form').submit();
+ return true;
+ }
+ });
+}
+</script>
+
+Or, use your BrowserID account:
+<img src="extensions/BrowserID/web/sign_in_orange.png" onclick="browserid_create_account()">
+
+<form id="browserid_form" method="POST" action="index.cgi">
+ <input type="hidden" name="token" value="[% issue_hash_token(['login']) FILTER html %]">
+ <input type="hidden" name="browserid_assertion" id="browserid_assertion" value="">
+</form>
+[% 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..ce872abda
--- /dev/null
+++ b/extensions/BrowserID/template/en/default/hook/global/user-error-errors.html.tmpl
@@ -0,0 +1,10 @@
+[% IF error == "browserid_account_too_powerful" %]
+ [% title = "Account Too Powerful" %]
+ Your account is a member of a group which is not permitted to use
+ BrowserID to log in. Please log in with your [% terms.Bugzilla %] username
+ and password.
+ <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
new file mode 100644
index 000000000..65ccda473
--- /dev/null
+++ b/extensions/BrowserID/web/sign_in_orange.png
Binary files differ