View | Details | Raw Unified | Return to bug 10988
Collapse All | Expand All

(-)koha.original/intranet/htdocs/intranet-tmpl/prog/en/modules/admin/preferences/admin.pref (+17 lines)
Lines 113-115 Administration: Link Here
113
                Solr: Solr
113
                Solr: Solr
114
                Zebra: Zebra
114
                Zebra: Zebra
115
            - is the search engine used.
115
            - is the search engine used.
116
    Google OAuth2:
117
        -
118
            - pref: GoogleOAuth2
119
              choices:
120
                yes: Use
121
                no: "Don't Use"
122
            - Google OAuth2 login.
123
            - 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 .
124
        -
125
            - Google OAuth2 Client ID
126
            - pref: GoogleOAuth2ClientID
127
        -
128
            - Google OAuth2 Client Secret
129
            - pref: GoogleOAuth2ClientSecret
130
        -
131
            - Google OAuth2 Restrict to domain
132
            - pref: GoogleOAuth2Domain
(-)koha.original/lib/C4/Auth.pm (-1 / +10 lines)
Lines 34-40 use POSIX qw/strftime/; Link Here
34
use List::MoreUtils qw/ any /;
34
use List::MoreUtils qw/ any /;
35
35
36
# use utf8;
36
# use utf8;
37
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $debug $ldap $cas $caslogout);
37
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $debug $googleoauth2 $ldap $cas $caslogout);
38
38
39
BEGIN {
39
BEGIN {
40
    sub psgi_env { any { /^psgi\./ } keys %ENV }
40
    sub psgi_env { any { /^psgi\./ } keys %ENV }
Lines 52-57 BEGIN { Link Here
52
                      ParseSearchHistoryCookie
52
                      ParseSearchHistoryCookie
53
                   );
53
                   );
54
    %EXPORT_TAGS = ( EditPermissions => [qw(get_all_subpermissions get_user_subpermissions)] );
54
    %EXPORT_TAGS = ( EditPermissions => [qw(get_all_subpermissions get_user_subpermissions)] );
55
    $googleoauth2= C4::Context->preference('GoogleOAuth2');
55
    $ldap        = C4::Context->config('useldapserver') || 0;
56
    $ldap        = C4::Context->config('useldapserver') || 0;
56
    $cas         = C4::Context->preference('casAuthentication');
57
    $cas         = C4::Context->preference('casAuthentication');
57
    $caslogout   = C4::Context->preference('casLogout');
58
    $caslogout   = C4::Context->preference('casLogout');
Lines 399-404 sub get_template_and_user { Link Here
399
            BranchesLoop              => GetBranchesLoop($opac_name),
400
            BranchesLoop              => GetBranchesLoop($opac_name),
400
            BranchCategoriesLoop      => GetBranchCategories( 'searchdomain', 1, $opac_name ),
401
            BranchCategoriesLoop      => GetBranchCategories( 'searchdomain', 1, $opac_name ),
401
            CalendarFirstDayOfWeek    => (C4::Context->preference("CalendarFirstDayOfWeek") eq "Sunday")?0:1,
402
            CalendarFirstDayOfWeek    => (C4::Context->preference("CalendarFirstDayOfWeek") eq "Sunday")?0:1,
403
            GoogleOAuth2              => (C4::Context->preference("GoogleOAuth2")),
402
            LibraryName               => "" . C4::Context->preference("LibraryName"),
404
            LibraryName               => "" . C4::Context->preference("LibraryName"),
403
            LibraryNameTitle          => "" . $LibraryNameTitle,
405
            LibraryNameTitle          => "" . $LibraryNameTitle,
404
            LoginBranchname           => C4::Context->userenv?C4::Context->userenv->{"branchname"}:"",
406
            LoginBranchname           => C4::Context->userenv?C4::Context->userenv->{"branchname"}:"",
Lines 1092-1097 sub checkauth { Link Here
1092
        );
1094
        );
1093
    }
1095
    }
1094
1096
1097
    if ($googleoauth2) {
1098
        if ($query->param("OAuth2Failed")) {
1099
            my $reason = $query->param('OAuth2Failed');
1100
            $template->param(invalidOAuth2Login => $reason);
1101
        }
1102
    }
1103
1095
    my $self_url = $query->url( -absolute => 1 );
1104
    my $self_url = $query->url( -absolute => 1 );
1096
    $template->param(
1105
    $template->param(
1097
        url         => $self_url,
1106
        url         => $self_url,
(-)koha.original/opac/cgi-bin/opac/svc/googleoauth2 (+130 lines)
Line 0 Link Here
1
opyright vanoudt@gmail.com 2014
2
# Based on persona code from chris@bigballofwax.co.nz 2013
3
# 
4
# This file is part of Koha.
5
# 
6
# Koha is free software; you can redistribute it and/or modify it under the
7
# terms of the GNU General Public License as published by the Free Software
8
# Foundation; either version 3 of the License, or (at your option) any later
9
# version.
10
# 
11
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
12
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
14
# 
15
# You should have received a copy of the GNU General Public License along
16
# with Koha; if not, write to the Free Software Foundation, Inc.,
17
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
#
19
#
20
# Basic OAuth2 authentication for google goes like this
21
# First: get your clientid, clientsecret from google. At this stage, tell google that
22
# your redirect url is /cgi-bin/koha/svc/oauthlogin
23
#
24
# The first thing that happens when this script is called is that one gets redirected
25
# to an authentication url from google
26
#
27
# If successful, that then redirects back to this script, setting a CODE parameter
28
# which we use to look up a json authentication token. This token includes an encrypted 
29
# json id_token, which we round-trip back to google to decrypt. Finally, we can extract
30
# the email address from this.
31
#
32
# There is some room for improvement here.
33
# In particular, Google recommends verifying and decrypting the id_token locally, which means caching
34
# some information and updating it daily. But that would make things a lot faster
35
36
use strict;
37
use warnings;
38
use CGI qw/escape/;
39
use C4::Auth;
40
use C4::Context;
41
use C4::Output;
42
43
use LWP::UserAgent; 
44
use HTTP::Request::Common qw{ POST };
45
use JSON;
46
47
my $scope="openid email";
48
my $host = C4::Context->preference('OPACBaseURL');
49
my $restricttodomain = C4::Context->preference('GoogleOAuth2Domain');
50
my $redirecturl = 'http://' . $host . '/cgi-bin/koha/svc/googleoauth2';
51
my $issuer = 'accounts.google.com';
52
my $clientid = C4::Context->preference('GoogleOAuth2ClientID');
53
my $clientsecret = C4::Context->preference('GoogleOAuth2ClientSecret');
54
55
my $query = new CGI;
56
57
sub loginfailed {
58
  my $query = shift;
59
  my $reason = shift;
60
  $query->delete('code');
61
  $query->param('OAuth2Failed'=>$reason);
62
  my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
63
    {
64
        template_name   => 'opac-user.tmpl',
65
        query           => $query,
66
        type            => 'opac',
67
        authnotrequired => 0,
68
        flagsrequired   => { borrow => 1 },
69
    }
70
  );
71
  $template->param( 'invalidOAuth2Login' => $reason );
72
  $template->param( 'loginprompt' => 1);
73
  output_html_with_http_headers $query, $cookie, $template->output;
74
}
75
#die $query->param('code');
76
if (defined $query->param('error')) {
77
       loginfailed($query, 'An authentication error occurred. (Error:' . $query->param('error') . ')');
78
} elsif (defined $query->param('code')) {
79
       my $code=$query->param('code');
80
       my $ua = LWP::UserAgent->new();
81
       my $request = POST('https://accounts.google.com/o/oauth2/token', [
82
                        code => $code,
83
                        client_id => $clientid,
84
                        client_secret => $clientsecret,
85
                       redirect_uri => $redirecturl,
86
                               grant_type => 'authorization_code',
87
                        $scope => $scope
88
    ]);
89
       my $response =  $ua->request($request)->decoded_content ;
90
       my $json = decode_json ( $response);
91
       if ( exists($json->{'id_token'}) ) {
92
               $request = POST('https://www.googleapis.com/oauth2/v1/tokeninfo', [
93
                       id_token => $json->{'id_token'}
94
               ]);
95
               $response = $ua->request($request)->decoded_content;
96
               $json = decode_json ( $response);
97
               # Confirm (as google suggests) that the issuer and audience are what we expect them to be
98
               if (($json->{'issuer'} eq $issuer) && ($json->{'audience'} eq $clientid) && exists($json->{'email'})) {
99
                       my $email = $json->{'email'};
100
                       my ( $userid, $cookie, $sessionID ) =
101
                            checkauth( $query, 1,  { borrow => 1 }, 'opac', $email );
102
                       if ($userid) { # A valid user has logged in
103
                               print $query->redirect( -uri => '/cgi-bin/koha/opac-user.pl', -cookie => $cookie );
104
                       } else {
105
                               loginfailed($query, 'The email address you are trying to use is not associated with a borrower in this library.');
106
                       }
107
               } else { # something went wrong with getting appropriate credentials
108
                       loginfailed($query, 'Failed to get proper credentials from google.');
109
               }
110
       } else { # Failed to get ID Token
111
               loginfailed($query, 'An authentication error occurred. (Error: No ID Token was supplied)');
112
       }       
113
114
} else {
115
    my  $prompt = '';
116
    $prompt = $query->param('reauthenticate') unless not (defined $query->param('reauthenticate'));
117
118
    my $authorisationurl =  'https://accounts.google.com/o/oauth2/auth?' .
119
                            'response_type=code&' .
120
                            'redirect_uri=' . escape ( $redirecturl ) . '&' .
121
                            'client_id=' . escape ( $clientid ) . '&' .
122
                            'scope=' . escape ( $scope ) . '&';
123
   if ( $restricttodomain ne '' ) {
124
      $authorisationurl .= 'hd=' . $restricttodomain . '&';
125
   }
126
    $authorisationurl .=    'prompt=' . escape ( $query->param('reauthenticate') );
127
       print $query->redirect($authorisationurl);
128
}
129
130
(-)koha.original/opac/htdocs/opac-tmpl/bootstrap/en/includes/masthead.inc (-4 / +12 lines)
Lines 58-64 Link Here
58
                                                <li role="presentation"><a href="/cgi-bin/koha/opac-shelves.pl?display=privateshelves" tabindex="-1" role="menuitem" class="listmenulink">New list</a></li>
58
                                                <li role="presentation"><a href="/cgi-bin/koha/opac-shelves.pl?display=privateshelves" tabindex="-1" role="menuitem" class="listmenulink">New list</a></li>
59
                                            [% END %]
59
                                            [% END %]
60
                                        [% ELSE %]
60
                                        [% ELSE %]
61
                                            <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>
61
                                           [% IF ( GoogleOAuth2 ) %]
62
                                               <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>
63
                                            [% ELSE %]
64
                                               <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>
65
                                           [% END %]
62
                                        [% END # / IF loggedinusername %]
66
                                        [% END # / IF loggedinusername %]
63
                                    [% END # / IF opacuserlogin %]
67
                                    [% END # / IF opacuserlogin %]
64
                                </ul> <!-- / .dropdown-menu -->
68
                                </ul> <!-- / .dropdown-menu -->
Lines 71-78 Link Here
71
                        <div id="members">
75
                        <div id="members">
72
                            <ul class="nav pull-right">
76
                            <ul class="nav pull-right">
73
                                [% UNLESS ( loggedinusername ) %]
77
                                [% UNLESS ( loggedinusername ) %]
74
                                    <li><a href="/cgi-bin/koha/opac-user.pl" class="loginModal-trigger" role="button" data-toggle="modal">Log in to your account</a></li>
78
                                   [% IF ( GoogleOAuth2 ) %]
75
                                [% END %]
79
                                       <li><a href="/cgi-bin/koha/svc/googleoauth2" role="button" data-toggle="modal">Log in to your account</a></li>
80
                                   [% ELSE %]
81
                                          <li><a href="/cgi-bin/koha/opac-user.pl"  class="loginModal-trigger" role="button" data-toggle="modal">Log in to your account</a></li>
82
                                   [% END %]
83
				[% END %]
76
                                [% IF ( loggedinusername ) %]
84
                                [% IF ( loggedinusername ) %]
77
                                    <li><p class="members navbar-text">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></p></li>
85
                                    <li><p class="members navbar-text">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></p></li>
78
                                    <li class="divider-vertical"></li>
86
                                    <li class="divider-vertical"></li>
Lines 284-287 Link Here
284
                <a href="#" data-dismiss="modal" aria-hidden="true" class="cancel">Cancel</a>
292
                <a href="#" data-dismiss="modal" aria-hidden="true" class="cancel">Cancel</a>
285
            </div>
293
            </div>
286
        </form> <!-- /#auth -->
294
        </form> <!-- /#auth -->
287
    </div>  <!-- /#modalAuth  -->
295
    </div>  <!-- /#modalAuth  -->
(-)koha.original/opac/htdocs/opac-tmpl/bootstrap/en/modules/opac-auth.tt (+9 lines)
Lines 84-89 Link Here
84
84
85
                            [% END # / IF casAuthentication %]
85
                            [% END # / IF casAuthentication %]
86
86
87
                           [% IF ( invalidOAuth2Login ) %]
88
                               <h4>Automatic Login</h4>
89
                               <p>Sorry, your automatic login failed. <span class="error">[% invalidOAuth2Login %]</span></p>
90
                               <p>Please note that automatic login will only work if you are using the email address registered with this library.</p>
91
                               <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>
92
                               <h4>Local login</h4>
93
                               <p>If you can't login automatically, you can still login in manually: </p>
94
                           [% END %]
95
87
                            <form action="[% url %]" name="auth" id="auth" method="post">
96
                            <form action="[% url %]" name="auth" id="auth" method="post">
88
                                <input type="hidden" name="koha_login_context" value="opac" />
97
                                <input type="hidden" name="koha_login_context" value="opac" />
89
                                <fieldset class="brief">
98
                                <fieldset class="brief">
(-)koha.original/opac/htdocs/opac-tmpl/ccsr/en/includes/top-bar.inc (-1 / +5 lines)
Lines 55-61 Link Here
55
      [% IF ( opacuserlogin ) %]
55
      [% IF ( opacuserlogin ) %]
56
        <ul>
56
        <ul>
57
    [% UNLESS ( loggedinusername ) %]
57
    [% UNLESS ( loggedinusername ) %]
58
                   <li><a href="/cgi-bin/koha/opac-user.pl">Log in to your account</a></li>[% END %]
58
        [% IF ( GoogleOAuth2 ) %]
59
               <li><a href="/cgi-bin/koha/svc/googleoauth2">Log in to your account</a></li>
60
        [% ELSE %]
61
               <li><a href="/cgi-bin/koha/opac-user.pl">Log in to your account</a></li>
62
        [% END %]
59
                [% IF ( loggedinusername ) %]
63
                [% IF ( loggedinusername ) %]
60
                    <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>
64
                    <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>
61
65
(-)koha.original/opac/htdocs/opac-tmpl/prog/en/includes/masthead.inc (-1 / +5 lines)
Lines 2-8 Link Here
2
  [% IF ( opacuserlogin ) %]
2
  [% IF ( opacuserlogin ) %]
3
	<ul>
3
	<ul>
4
[% UNLESS ( loggedinusername ) %]
4
[% UNLESS ( loggedinusername ) %]
5
               <li><a href="/cgi-bin/koha/opac-user.pl">Log in to your account</a></li>[% END %]
5
        [% IF ( GoogleOAuth2 ) %]
6
               <li><a href="/cgi-bin/koha/svc/googleoauth2">Log in to your account</a></li>
7
        [% ELSE %]
8
               <li><a href="/cgi-bin/koha/opac-user.pl">Log in to your account</a></li>
9
        [% END %]
6
            [% IF ( loggedinusername ) %]
10
            [% IF ( loggedinusername ) %]
7
                <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>
11
                <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>
8
12
(-)koha.original/opac/htdocs/opac-tmpl/prog/en/modules/opac-auth.tt (+9 lines)
Lines 73-78 please choose against which one you woul Link Here
73
73
74
[% END %]
74
[% END %]
75
75
76
[% IF ( invalidOAuth2Login ) %]
77
<h4>Automatic Login</h4>
78
<p>Sorry, your automatic login failed. <span class="error">[% invalidOAuth2Login %]</span></p>
79
<p>Please note that automatic login will only work if you are using the email address registered with this library.</p>
80
<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>
81
<h4>Local login</h4>
82
<p>If you can't login automatically, you can still login in manually: </p>
83
[% END %]
84
76
<form action="[% url %]" name="auth" id="auth" method="post">
85
<form action="[% url %]" name="auth" id="auth" method="post">
77
  <input type="hidden" name="koha_login_context" value="opac" />
86
  <input type="hidden" name="koha_login_context" value="opac" />
78
<fieldset class="brief">[% FOREACH INPUT IN INPUTS %]
87
<fieldset class="brief">[% FOREACH INPUT IN INPUTS %]

Return to bug 10988