Bugzilla – Attachment 29594 Details for
Bug 10988
Allow login via Google OAuth2 (OpenID Connect)
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Allow Google OAuth2 Login
0001-Bug-10988-Google-OAuth2-Support.patch (text/plain), 19.46 KB, created by
Nicholas van Oudtshoorn
on 2014-07-10 03:08:18 UTC
(
hide
)
Description:
Allow Google OAuth2 Login
Filename:
MIME Type:
Creator:
Nicholas van Oudtshoorn
Created:
2014-07-10 03:08:18 UTC
Size:
19.46 KB
patch
obsolete
>From b127b3a6e968d239f3307cef148625edff344510 Mon Sep 17 00:00:00 2001 >From: Nicholas van Oudtshoorn <vanoudt@gmail.com> >Date: Thu, 10 Jul 2014 11:01:07 +0800 >Subject: [PATCH] Bug 10988 - Google OAuth2 Support Update to apply cleanly to > master >Content-Type: text/plain; charset="utf-8" > >--- > C4/Auth.pm | 11 +- > .../atomicupdate/bug_10988_add_GoogleOauth.sql | 2 + > installer/data/mysql/sysprefs.sql | 4 + > installer/data/mysql/updatedatabase.pl | 7 ++ > .../prog/en/modules/admin/preferences/admin.pref | 17 +++ > .../opac-tmpl/bootstrap/en/includes/masthead.inc | 8 ++ > .../opac-tmpl/bootstrap/en/modules/opac-auth.tt | 9 ++ > koha-tmpl/opac-tmpl/ccsr/en/includes/top-bar.inc | 6 +- > koha-tmpl/opac-tmpl/prog/en/includes/masthead.inc | 6 +- > koha-tmpl/opac-tmpl/prog/en/modules/opac-auth.tt | 9 ++ > opac/svc/googleoauth2 | 131 +++++++++++++++++++++ > 11 files changed, 207 insertions(+), 3 deletions(-) > create mode 100644 installer/data/mysql/atomicupdate/bug_10988_add_GoogleOauth.sql > create mode 100644 opac/svc/googleoauth2 > >diff --git a/C4/Auth.pm b/C4/Auth.pm >index c04253a..a4beebe 100644 >--- a/C4/Auth.pm >+++ b/C4/Auth.pm >@@ -36,7 +36,7 @@ use POSIX qw/strftime/; > use List::MoreUtils qw/ any /; > > # use utf8; >-use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $debug $ldap $cas $caslogout); >+use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $debug $googleoauth2 $ldap $cas $caslogout); > > BEGIN { > sub psgi_env { any { /^psgi\./ } keys %ENV } >@@ -53,6 +53,7 @@ BEGIN { > &get_all_subpermissions &get_user_subpermissions > ); > %EXPORT_TAGS = ( EditPermissions => [qw(get_all_subpermissions get_user_subpermissions)] ); >+ $googleoauth2= C4::Context->preference('GoogleOAuth2'); > $ldap = C4::Context->config('useldapserver') || 0; > $cas = C4::Context->preference('casAuthentication'); > $caslogout = C4::Context->preference('casLogout'); >@@ -412,6 +413,7 @@ sub get_template_and_user { > BranchesLoop => GetBranchesLoop($opac_name), > BranchCategoriesLoop => GetBranchCategories( 'searchdomain', 1, $opac_name ), > CalendarFirstDayOfWeek => (C4::Context->preference("CalendarFirstDayOfWeek") eq "Sunday")?0:1, >+ GoogleOAuth2 => (C4::Context->preference("GoogleOAuth2")), > LibraryName => "" . C4::Context->preference("LibraryName"), > LibraryNameTitle => "" . $LibraryNameTitle, > LoginBranchname => C4::Context->userenv?C4::Context->userenv->{"branchname"}:"", >@@ -1122,6 +1124,13 @@ sub checkauth { > ); > } > >+ if ($googleoauth2) { >+ if ($query->param("OAuth2Failed")) { >+ my $reason = $query->param('OAuth2Failed'); >+ $template->param(invalidOAuth2Login => $reason); >+ } >+ } >+ > my $self_url = $query->url( -absolute => 1 ); > $template->param( > url => $self_url, >diff --git a/installer/data/mysql/atomicupdate/bug_10988_add_GoogleOauth.sql b/installer/data/mysql/atomicupdate/bug_10988_add_GoogleOauth.sql >new file mode 100644 >index 0000000..39e1727 >--- /dev/null >+++ b/installer/data/mysql/atomicupdate/bug_10988_add_GoogleOauth.sql >@@ -0,0 +1,2 @@ >+-- Adding GoogleOAuth2 support >+INSERT INTO `systempreferences` (`variable`, `value`, `options`, `explanation`, `type`) VALUES ('GoogleOAuth2', '0', NULL, 'if ON, allows the use of Google OAuth2 for login', 'YesNo'), ('GoogleOAuth2ClientID', '', NULL, 'Client ID for the web app registered with google', 'Free'), ('GoogleOAuth2ClientSecret', '', NULL, 'Client Secret for the web app registered with google', 'Free'), ('GoogleOAuth2Domain', '', NULL, 'Restrict OAuth2 to this domain. Leave blank for all google domains', 'Free'); >diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql >index ed427ea..1d329bb 100644 >--- a/installer/data/mysql/sysprefs.sql >+++ b/installer/data/mysql/sysprefs.sql >@@ -126,6 +126,10 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` > ('FRBRizeEditions','0','','If ON, Koha will query one or more ISBN web services for associated ISBNs and display an Editions tab on the details pages','YesNo'), > ('gist','0','','Default Goods and Services tax rate NOT in %, but in numeric form (0.12 for 12%), set to 0 to disable GST','Integer'), > ('GoogleJackets','0',NULL,'if ON, displays jacket covers from Google Books API','YesNo'), >+('GoogleOAuth2', '0', NULL, 'if ON, allows the use of Google OAuth2 for login', 'YesNo'), >+('GoogleOAuth2ClientID', '', NULL, 'Client ID for the web app registered with google', 'Free'), >+('GoogleOAuth2ClientSecret', '', NULL, 'Client Secret for the web app registered with google', 'Free'), >+('GoogleOAuth2Domain', '', NULL, 'Restrict OAuth2 to this domain. Leave blank for all google domains', 'Free'), > ('hidelostitems','0','','If ON, disables display of\"lost\" items in OPAC.','YesNo'), > ('HidePatronName','0','','If this is switched on, patron\'s cardnumber will be shown instead of their name on the holds and catalog screens','YesNo'), > ('hide_marc','0',NULL,'If ON, disables display of MARC fields, subfield codes & indicators (still shows data)','YesNo'), >diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl >index 1030454..41e634e 100755 >--- a/installer/data/mysql/updatedatabase.pl >+++ b/installer/data/mysql/updatedatabase.pl >@@ -8570,6 +8570,13 @@ if ( CheckVersion($DBversion) ) { > SetVersion($DBversion); > } > >+$DBversion = "3.17.00.010"; >+if ( CheckVersion($DBversion) ) { >+ $dbh->do("INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('GoogleOAuth2', '0', NULL, 'if ON, allows the use of Google OAuth2 for login', 'YesNo'), ('GoogleOAuth2ClientID', '', NULL, 'Client ID for the web app registered with google', 'Free'),('GoogleOAuth2ClientSecret', '', NULL, 'Client Secret for the web app registered with google', 'Free'),('GoogleOAuth2Domain', '', NULL, 'Restrict OAuth2 to this domain. Leave blank for all google domains', 'Free')"); >+ print "Upgrade to $DBversion done (Bug 10988: Allow login via Google OAuth2)\n"; >+ SetVersion($DBversion); >+} >+ > =head1 FUNCTIONS > > =head2 TableExists($table) >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/admin.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/admin.pref >index 1215ac1..d53c8d8 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/admin.pref >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/admin.pref >@@ -113,3 +113,20 @@ Administration: > Solr: Solr > Zebra: Zebra > - is the search engine used. >+ Google OAuth2: >+ - >+ - pref: GoogleOAuth2 >+ choices: >+ yes: Use >+ no: "Don't Use" >+ - Google OAuth2 login. >+ - You will need to select OAuth2 when creating an app in the google cloud console, and set the web origin to your_opac_url and the redirect url to your_opac_url/cgi-bin/koha/svc/oauthlogin . >+ - >+ - Google OAuth2 Client ID >+ - pref: GoogleOAuth2ClientID >+ - >+ - Google OAuth2 Client Secret >+ - pref: GoogleOAuth2ClientSecret >+ - >+ - Google OAuth2 Restrict to domain >+ - pref: GoogleOAuth2Domain >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/includes/masthead.inc b/koha-tmpl/opac-tmpl/bootstrap/en/includes/masthead.inc >index b035047..4e28440 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/includes/masthead.inc >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/includes/masthead.inc >@@ -58,6 +58,12 @@ > <li role="presentation"><a href="/cgi-bin/koha/opac-shelves.pl?display=privateshelves" tabindex="-1" role="menuitem" class="listmenulink">New list</a></li> > [% END %] > [% ELSE %] >+ [% IF Koha.Preference( 'GoogleOAuth2' ) == 1 %] >+ <li role="presentation"><a href="/cgi-bin/koha/svc/googleoauth2" tabindex="-1" class="menu-inactive" role="menuitem">Log in to create your own lists</a></li> >+ [% ELSE %] >+ <li role="presentation"><a href="/cgi-bin/koha/opac-user.pl" tabindex="-1" class="menu-inactive loginModal-trigger" role="menuitem">Log in to create your own lists</a></li> >+ [% END %] >+ > <li role="presentation"><a href="/cgi-bin/koha/opac-user.pl" tabindex="-1" class="menu-inactive loginModal-trigger" role="menuitem">Log in to create your own lists</a></li> > [% END # / IF loggedinusername %] > [% END # / IF opacuserlogin %] >@@ -75,6 +81,8 @@ > [% IF Koha.Preference('casAuthentication') %] > [%# CAS authentication is too complicated for modal window %] > <li><a href="/cgi-bin/koha/opac-user.pl">Log in to your account</a></li> >+ [% ELSIF Koha.Preference( 'GoogleOAuth2' ) == 1 %] >+ <li><a href="/cgi-bin/koha/svc/googleoauth2" role="button">Log in to your account</a></li> > [% ELSE %] > <li><a href="/cgi-bin/koha/opac-user.pl" class="loginModal-trigger" role="button" data-toggle="modal">Log in to your account</a></li> > [% END %] >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-auth.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-auth.tt >index f2196dd..8143a6e 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-auth.tt >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-auth.tt >@@ -84,6 +84,15 @@ > > [% END # / IF casAuthentication %] > >+ [% IF ( invalidOAuth2Login ) %] >+ <h4>Automatic Login</h4> >+ <p>Sorry, your automatic login failed. <span class="error">[% invalidOAuth2Login %]</span></p> >+ <p>Please note that automatic login will only work if you are using the email address registered with this library.</p> >+ <p>If you want to, you can try to <a href="/cgi-bin/koha/svc/googleoauth2?reauthenticate=select_account">login using a differen account</a> >+ <h4>Local login</h4> >+ <p>If you can't login automatically, you can still login in manually: </p> >+ [% END %] >+ > <form action="[% url %]" name="auth" id="auth" method="post"> > <input type="hidden" name="koha_login_context" value="opac" /> > <fieldset class="brief"> >diff --git a/koha-tmpl/opac-tmpl/ccsr/en/includes/top-bar.inc b/koha-tmpl/opac-tmpl/ccsr/en/includes/top-bar.inc >index a6ff978..731d5ce 100644 >--- a/koha-tmpl/opac-tmpl/ccsr/en/includes/top-bar.inc >+++ b/koha-tmpl/opac-tmpl/ccsr/en/includes/top-bar.inc >@@ -55,7 +55,11 @@ > [% IF ( opacuserlogin ) %] > <ul> > [% UNLESS ( loggedinusername ) %] >- <li><a href="/cgi-bin/koha/opac-user.pl">Log in to your account</a></li>[% END %] >+ [% IF ( GoogleOAuth2 ) %] >+ <li><a href="/cgi-bin/koha/svc/googleoauth2">Log in to your account</a></li> >+ [% ELSE %] >+ <li><a href="/cgi-bin/koha/opac-user.pl">Log in to your account</a></li> >+ [% END %] > [% IF ( loggedinusername ) %] > <li><span class="members">Welcome, <a href="/cgi-bin/koha/opac-user.pl"><span class="loggedinusername">[% FOREACH USER_INF IN USER_INFO %][% USER_INF.title %] [% USER_INF.firstname %] [% USER_INF.surname %][% END %]</span></a></span></li> > >diff --git a/koha-tmpl/opac-tmpl/prog/en/includes/masthead.inc b/koha-tmpl/opac-tmpl/prog/en/includes/masthead.inc >index 28449fc..d2ae3ca 100644 >--- a/koha-tmpl/opac-tmpl/prog/en/includes/masthead.inc >+++ b/koha-tmpl/opac-tmpl/prog/en/includes/masthead.inc >@@ -2,7 +2,11 @@ > [% IF ( opacuserlogin ) %] > <ul> > [% UNLESS ( loggedinusername ) %] >- <li><a href="/cgi-bin/koha/opac-user.pl">Log in to your account</a></li>[% END %] >+ [% IF ( GoogleOAuth2 ) %] >+ <li><a href="/cgi-bin/koha/svc/googleoauth2">Log in to your account</a></li> >+ [% ELSE %] >+ <li><a href="/cgi-bin/koha/opac-user.pl">Log in to your account</a></li> >+ [% END %] > [% IF ( loggedinusername ) %] > <li><span class="members">Welcome, <a href="/cgi-bin/koha/opac-user.pl"><span class="loggedinusername">[% FOREACH USER_INF IN USER_INFO %][% USER_INF.title %] [% USER_INF.firstname %] [% USER_INF.surname %][% END %]</span></a></span></li> > >diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-auth.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-auth.tt >index c06e234..9443416 100644 >--- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-auth.tt >+++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-auth.tt >@@ -73,6 +73,15 @@ please choose against which one you would like to authenticate: </p> > > [% END %] > >+[% IF ( invalidOAuth2Login ) %] >+<h4>Automatic Login</h4> >+<p>Sorry, your automatic login failed. <span class="error">[% invalidOAuth2Login %]</span></p> >+<p>Please note that automatic login will only work if you are using the email address registered with this library.</p> >+<p>If you want to, you can try to <a href="/cgi-bin/koha/svc/googleoauth2?reauthenticate=select_account">login using a differen account</a> >+<h4>Local login</h4> >+<p>If you can't login automatically, you can still login in manually: </p> >+[% END %] >+ > <form action="[% url %]" name="auth" id="auth" method="post"> > <input type="hidden" name="koha_login_context" value="opac" /> > <fieldset class="brief">[% FOREACH INPUT IN INPUTS %] >diff --git a/opac/svc/googleoauth2 b/opac/svc/googleoauth2 >new file mode 100644 >index 0000000..2225776 >--- /dev/null >+++ b/opac/svc/googleoauth2 >@@ -0,0 +1,131 @@ >+#!/bin/perl -w >+# Copyright chris@bigballofwax.co.nz 2013 >+# >+# This file is part of Koha. >+# >+# Koha is free software; you can redistribute it and/or modify it under the >+# terms of the GNU General Public License as published by the Free Software >+# Foundation; either version 3 of the License, or (at your option) any later >+# version. >+# >+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >+# A PARTICULAR PURPOSE. See the GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License along >+# with Koha; if not, write to the Free Software Foundation, Inc., >+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >+# >+# >+# Basic OAuth2 authentication for google goes like this >+# First: get your clientid, clientsecret from google. At this stage, tell google that >+# your redirect url is /cgi-bin/koha/svc/oauthlogin >+# >+# The first thing that happens when this script is called is that one gets redirected >+# to an authentication url from google >+# >+# If successful, that then redirects back to this script, setting a CODE parameter >+# which we use to look up a json authentication token. This token includes an encrypted >+# json id_token, which we round-trip back to google to decrypt. Finally, we can extract >+# the email address from this. >+# >+# There is LOTS of room for improvement here. >+# 1. move the clientid, clientsecret to systempreferences >+# 2. use the OPACBaseURL preference to compute the redirecturl >+# 4. Google recommends verifying and decrypting the id_token locally, which means caching >+# some information and updating it daily. But that would make things a lot faster >+ >+use strict; >+use warnings; >+use CGI qw/escape/; >+use C4::Auth; >+use C4::Context; >+use C4::Output; >+ >+use LWP::UserAgent; >+use HTTP::Request::Common qw{ POST }; >+use JSON; >+ >+my $scope="openid email"; >+my $host = C4::Context->preference('OPACBaseURL'); >+my $restricttodomain = C4::Context->preference('GoogleOAuth2Domain'); >+my $redirecturl = 'http://' . $host . '/cgi-bin/koha/svc/googleoauth2'; >+my $issuer = 'accounts.google.com'; >+my $clientid = C4::Context->preference('GoogleOAuth2ClientID'); >+my $clientsecret = C4::Context->preference('GoogleOAuth2ClientSecret'); >+ >+my $query = new CGI; >+ >+sub loginfailed { >+ my $query = shift; >+ my $reason = shift; >+ $query->delete('code'); >+ $query->param('OAuth2Failed'=>$reason); >+ my ( $template, $borrowernumber, $cookie ) = get_template_and_user( >+ { >+ template_name => 'opac-user.tmpl', >+ query => $query, >+ type => 'opac', >+ authnotrequired => 0, >+ flagsrequired => { borrow => 1 }, >+ } >+ ); >+ $template->param( 'invalidOAuth2Login' => $reason ); >+ $template->param( 'loginprompt' => 1); >+ output_html_with_http_headers $query, $cookie, $template->output; >+} >+#die $query->param('code'); >+if (defined $query->param('error')) { >+ loginfailed($query, 'An authentication error occurred. (Error:' . $query->param('error') . ')'); >+} elsif (defined $query->param('code')) { >+ my $code=$query->param('code'); >+ my $ua = LWP::UserAgent->new(); >+ my $request = POST('https://accounts.google.com/o/oauth2/token', [ >+ code => $code, >+ client_id => $clientid, >+ client_secret => $clientsecret, >+ redirect_uri => $redirecturl, >+ grant_type => 'authorization_code', >+ $scope => $scope >+ ]); >+ my $response = $ua->request($request)->decoded_content ; >+ my $json = decode_json ( $response); >+ if ( exists($json->{'id_token'}) ) { >+ $request = POST('https://www.googleapis.com/oauth2/v1/tokeninfo', [ >+ id_token => $json->{'id_token'} >+ ]); >+ $response = $ua->request($request)->decoded_content; >+ $json = decode_json ( $response); >+ # Confirm (as google suggests) that the issuer and audience are what we expect them to be >+ if (($json->{'issuer'} eq $issuer) && ($json->{'audience'} eq $clientid) && exists($json->{'email'})) { >+ my $email = $json->{'email'}; >+ my ( $userid, $cookie, $sessionID ) = >+ checkauth( $query, 1, { borrow => 1 }, 'opac', $email ); >+ if ($userid) { # A valid user has logged in >+ print $query->redirect( -uri => '/cgi-bin/koha/opac-user.pl', -cookie => $cookie ); >+ } else { >+ loginfailed($query, 'The email address you are trying to use is not associated with a borrower in this library.'); >+ } >+ } else { # something went wrong with getting appropriate credentials >+ loginfailed($query, 'Failed to get proper credentials from google.'); >+ } >+ } else { # Failed to get ID Token >+ loginfailed($query, 'An authentication error occurred. (Error: No ID Token was supplied)'); >+ } >+ >+} else { >+ my $prompt = ''; >+ $prompt = $query->param('reauthenticate') unless not (defined $query->param('reauthenticate')); >+ >+ my $authorisationurl = 'https://accounts.google.com/o/oauth2/auth?' . >+ 'response_type=code&' . >+ 'redirect_uri=' . escape ( $redirecturl ) . '&' . >+ 'client_id=' . escape ( $clientid ) . '&' . >+ 'scope=' . escape ( $scope ) . '&'; >+ if ( $restricttodomain ne '' ) { >+ $authorisationurl .= 'hd=' . $restricttodomain . '&'; >+ } >+ $authorisationurl .= 'prompt=' . escape ( $query->param('reauthenticate') ); >+ print $query->redirect($authorisationurl); >+} >+ >-- >1.8.3.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 10988
:
21740
|
21936
|
21938
|
21939
|
25343
|
25570
|
25684
|
29594
|
29595
|
30014
|
30015
|
36354
|
36355
|
40087
|
40252
|
40442
|
40979
|
41663
|
43791
|
43792
|
43938
|
45667
|
45668
|
45895
|
46016
|
46473
|
46474
|
47780
|
47781
|
47782
|
49785
|
49786
|
49787