From 841c07890e9ce51a5884edbd63ecc10e1ff2fbf1 Mon Sep 17 00:00:00 2001 From: Dave Lawrence Date: Fri, 15 Feb 2013 16:52:12 -0500 Subject: Bug 820936 - Rename BrowserID extension to Persona r=glob --- extensions/Persona/Config.pm | 29 ++++++ extensions/Persona/Extension.pm | 73 ++++++++++++++ extensions/Persona/TODO | 19 ++++ extensions/Persona/lib/Config.pm | 36 +++++++ extensions/Persona/lib/Login.pm | 112 +++++++++++++++++++++ .../en/default/admin/params/browserid.html.tmpl | 22 ++++ .../en/default/admin/params/persona.html.tmpl | 22 ++++ .../auth/login-additional_methods.html.tmpl | 6 ++ .../auth/login-small-additional_methods.html.tmpl | 16 +++ .../account/create-additional_methods.html.tmpl | 31 ++++++ .../hook/global/header-additional_header.html.tmpl | 65 ++++++++++++ .../hook/global/user-error-errors.html.tmpl | 10 ++ extensions/Persona/web/images/persona_sign_in.png | Bin 0 -> 3684 bytes extensions/Persona/web/images/sign_in.png | Bin 0 -> 1993 bytes 14 files changed, 441 insertions(+) create mode 100644 extensions/Persona/Config.pm create mode 100644 extensions/Persona/Extension.pm create mode 100644 extensions/Persona/TODO create mode 100644 extensions/Persona/lib/Config.pm create mode 100644 extensions/Persona/lib/Login.pm create mode 100644 extensions/Persona/template/en/default/admin/params/browserid.html.tmpl create mode 100644 extensions/Persona/template/en/default/admin/params/persona.html.tmpl create mode 100644 extensions/Persona/template/en/default/hook/account/auth/login-additional_methods.html.tmpl create mode 100644 extensions/Persona/template/en/default/hook/account/auth/login-small-additional_methods.html.tmpl create mode 100644 extensions/Persona/template/en/default/hook/account/create-additional_methods.html.tmpl create mode 100644 extensions/Persona/template/en/default/hook/global/header-additional_header.html.tmpl create mode 100644 extensions/Persona/template/en/default/hook/global/user-error-errors.html.tmpl create mode 100644 extensions/Persona/web/images/persona_sign_in.png create mode 100644 extensions/Persona/web/images/sign_in.png (limited to 'extensions/Persona') diff --git a/extensions/Persona/Config.pm b/extensions/Persona/Config.pm new file mode 100644 index 000000000..8709655d1 --- /dev/null +++ b/extensions/Persona/Config.pm @@ -0,0 +1,29 @@ +# 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. + +package Bugzilla::Extension::Persona; +use strict; + +use constant NAME => 'Persona'; + +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/Persona/Extension.pm b/extensions/Persona/Extension.pm new file mode 100644 index 000000000..f288702e8 --- /dev/null +++ b/extensions/Persona/Extension.pm @@ -0,0 +1,73 @@ +# 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. + +package Bugzilla::Extension::Persona; +use strict; +use base qw(Bugzilla::Extension); + +use Bugzilla::Config qw(SetParam write_params); + +our $VERSION = '0.01'; + +sub install_update_db { + # The extension changed from BrowserID to Persona + # so we need to update user_info_class if this system + # was using BrowserID for verification. + my $params = Bugzilla->params || Bugzilla::Config::read_param_file(); + my $user_info_class = $params->{'user_info_class'}; + if ($user_info_class =~ /BrowserID/) { + $user_info_class =~ s/BrowserID/Persona/; + SetParam('user_info_class', $user_info_class); + write_params(); + } +} + +sub auth_login_methods { + my ($self, $args) = @_; + my $modules = $args->{'modules'}; + if (exists($modules->{'Persona'})) { + $modules->{'Persona'} = 'Bugzilla/Extension/Persona/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'} }, "Persona,CGI"); + } + + # The extension changed from BrowserID to Persona + # so we need to retain the current values for the new + # params that will be created. + my $params = Bugzilla->params || Bugzilla::Config::read_param_file(); + my $verify_url = $params->{'browserid_verify_url'}; + my $includejs_url = $params->{'browserid_includejs_url'}; + if ($verify_url && $includejs_url) { + foreach my $param (@{ $panels->{'persona'}->{'params'} }) { + if ($param->{'name'} eq 'persona_verify_url') { + $param->{'default'} = $verify_url; + } + if ($param->{'name'} eq 'persona_includejs_url') { + $param->{'default'} = $includejs_url; + } + } + } +} + +sub config_add_panels { + my ($self, $args) = @_; + my $modules = $args->{panel_modules}; + $modules->{Persona} = "Bugzilla::Extension::Persona::Config"; +} + +__PACKAGE__->NAME; diff --git a/extensions/Persona/TODO b/extensions/Persona/TODO new file mode 100644 index 000000000..ac94a3c42 --- /dev/null +++ b/extensions/Persona/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/Persona/lib/Config.pm b/extensions/Persona/lib/Config.pm new file mode 100644 index 000000000..99c547b16 --- /dev/null +++ b/extensions/Persona/lib/Config.pm @@ -0,0 +1,36 @@ +# 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. + +package Bugzilla::Extension::Persona::Config; + +use strict; +use warnings; + +use Bugzilla::Config::Common; + +our $sortkey = 1350; + +sub get_param_list { + my ($class) = @_; + + my @param_list = ( + { + name => 'persona_verify_url', + type => 't', + default => 'https://verifier.login.persona.org/verify', + }, + { + name => 'persona_includejs_url', + type => 't', + default => 'https://login.persona.org/include.js', + } + ); + + return @param_list; +} + +1; diff --git a/extensions/Persona/lib/Login.pm b/extensions/Persona/lib/Login.pm new file mode 100644 index 000000000..167cc799f --- /dev/null +++ b/extensions/Persona/lib/Login.pm @@ -0,0 +1,112 @@ +# 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. + +package Bugzilla::Extension::Persona::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("persona_assertion"); + # Avoid the assertion being copied into any 'echoes' of the current URL + # in the page. + $cgi->delete('persona_assertion'); + + if (!$assertion || !Bugzilla->params->{persona_verify_url}) { + 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' => 'persona-server-broken' }; + eval { + my $response = $ua->post(Bugzilla->params->{persona_verify_url}, + [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 + # Persona 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('persona_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/Persona/template/en/default/admin/params/browserid.html.tmpl b/extensions/Persona/template/en/default/admin/params/browserid.html.tmpl new file mode 100644 index 000000000..379d12058 --- /dev/null +++ b/extensions/Persona/template/en/default/admin/params/browserid.html.tmpl @@ -0,0 +1,22 @@ +[%# 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. + #%] + +[% + title = "Persona" + desc = "Configure Persona Authentication" +%] + +[% param_descs = { + persona_verify_url => "This is the URL for the Persona authority that the " _ + "user will be verified against. " _ + "Example: https://verifier.login.persona.org/verify.", + persona_includejs_url => "This is the URL needed by Persona to load the necessary " _ + "javascript library for authentication. " _ + "Example: https://persona.org/include.js." + } +%] diff --git a/extensions/Persona/template/en/default/admin/params/persona.html.tmpl b/extensions/Persona/template/en/default/admin/params/persona.html.tmpl new file mode 100644 index 000000000..379d12058 --- /dev/null +++ b/extensions/Persona/template/en/default/admin/params/persona.html.tmpl @@ -0,0 +1,22 @@ +[%# 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. + #%] + +[% + title = "Persona" + desc = "Configure Persona Authentication" +%] + +[% param_descs = { + persona_verify_url => "This is the URL for the Persona authority that the " _ + "user will be verified against. " _ + "Example: https://verifier.login.persona.org/verify.", + persona_includejs_url => "This is the URL needed by Persona to load the necessary " _ + "javascript library for authentication. " _ + "Example: https://persona.org/include.js." + } +%] diff --git a/extensions/Persona/template/en/default/hook/account/auth/login-additional_methods.html.tmpl b/extensions/Persona/template/en/default/hook/account/auth/login-additional_methods.html.tmpl new file mode 100644 index 000000000..b76605948 --- /dev/null +++ b/extensions/Persona/template/en/default/hook/account/auth/login-additional_methods.html.tmpl @@ -0,0 +1,6 @@ +[% IF Param('user_info_class').split(',').contains('Persona') + && Param('persona_includejs_url') %] +

+ +

+[% END %] diff --git a/extensions/Persona/template/en/default/hook/account/auth/login-small-additional_methods.html.tmpl b/extensions/Persona/template/en/default/hook/account/auth/login-small-additional_methods.html.tmpl new file mode 100644 index 000000000..0cee286bd --- /dev/null +++ b/extensions/Persona/template/en/default/hook/account/auth/login-small-additional_methods.html.tmpl @@ -0,0 +1,16 @@ +[% IF Param('user_info_class').split(',').contains('Persona') + && Param('persona_includejs_url') %] + + + or + +[% END %] diff --git a/extensions/Persona/template/en/default/hook/account/create-additional_methods.html.tmpl b/extensions/Persona/template/en/default/hook/account/create-additional_methods.html.tmpl new file mode 100644 index 000000000..9bf95b780 --- /dev/null +++ b/extensions/Persona/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('Persona') %] + + +Or, use your Persona account: + + +
+ + +
+[% END %] diff --git a/extensions/Persona/template/en/default/hook/global/header-additional_header.html.tmpl b/extensions/Persona/template/en/default/hook/global/header-additional_header.html.tmpl new file mode 100644 index 000000000..d4cc2132e --- /dev/null +++ b/extensions/Persona/template/en/default/hook/global/header-additional_header.html.tmpl @@ -0,0 +1,65 @@ +[%# 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. + #%] + +[% RETURN IF user.login + || !Param('persona_includejs_url') + || !Param('user_info_class').split(',').contains('Persona') %] + +[% USE Bugzilla %] +[% cgi = Bugzilla.cgi %] + +[% login_target = cgi.url("-relative" => 1, "-query" => 1) %] +[% IF !login_target OR login_target.match("^token.cgi") %] + [% login_target = "index.cgi" %] +[% END %] + +[% login_target = urlbase _ login_target %] + + + + diff --git a/extensions/Persona/template/en/default/hook/global/user-error-errors.html.tmpl b/extensions/Persona/template/en/default/hook/global/user-error-errors.html.tmpl new file mode 100644 index 000000000..bf7b865ac --- /dev/null +++ b/extensions/Persona/template/en/default/hook/global/user-error-errors.html.tmpl @@ -0,0 +1,10 @@ +[% IF error == "persona_account_too_powerful" %] + [% title = "Account Too Powerful" %] + Your account is a member of a group which is not permitted to use + Persona to log in. Please log in with your [% terms.Bugzilla %] username + and password. +

+ (Persona 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/Persona/web/images/persona_sign_in.png b/extensions/Persona/web/images/persona_sign_in.png new file mode 100644 index 000000000..ab88a7154 Binary files /dev/null and b/extensions/Persona/web/images/persona_sign_in.png differ diff --git a/extensions/Persona/web/images/sign_in.png b/extensions/Persona/web/images/sign_in.png new file mode 100644 index 000000000..82594ba82 Binary files /dev/null and b/extensions/Persona/web/images/sign_in.png differ -- cgit v1.2.3-24-g4f1b