From 770e1faab52d3aefc048d9a35c41aae4ad1b9d6d Mon Sep 17 00:00:00 2001
From: Nick Clemens <nick@bywatersolutions.com>
Date: Tue, 17 Jul 2018 14:16:33 +0000
Subject: [PATCH] Bug 21082: Update OverDrive authentication method

Testing will require an OverDrive account, you should be able to obtain a
developer account here:
https://developer.overdrive.com/

You will need to register a SIP connection for patron authentication

To test authentication:
 1 - Set authname default in OD prefs
 2 - Sign in as a patron whose branch matches authname
 3 - Verify the patron can sign into OverDrive
 4 - Set the patrons branch authname to be incorrect
 5 - Verify branch specific authname is used and patron cannot sign in
 6 - Set the default authname to be incorrect and patron's branch
 authname to be correct
 7 - Verofy patron can sign in

To test circulation:
 1 - Fill out all OD prefs and enable circulation
 2 - Sign in to opac
 3 - Verify you have an OverDrive tab
 4 - Click 'Login to Overdrive'
 5 - If password required you shoudl be prompted, otherwise you should be
signed in and see account info
 6 - Test logging out and in
 7 - Log-in, perform a search on the opac - you should see hold/checkout
buttons
 8 - Test the buttons
 9 - After holding/checking out items, check your account page
10 - Verify info is correct
11 - Log out of overdrive
12 - Search catalog click overdrive results
13 - Test "Login to Overdrive" link on OD results
14 - Verify page is reloaded, buttons show and work

Signed-off-by: Sandy Allgood <sandy.allgood@citruslibraries.org>
Signed-off-by: Chris Cormack <chrisc@catalyst.net.nz>
---
 Koha/ExternalContent/OverDrive.pm             | 28 +++++++++++++++++--
 admin/overdrive.pl                            |  1 -
 .../en/modules/opac-overdrive-search.tt       |  3 +-
 .../bootstrap/en/modules/opac-user.tt         |  1 +
 koha-tmpl/opac-tmpl/bootstrap/js/overdrive.js | 16 +++++++----
 opac/svc/overdrive                            | 10 ++++++-
 6 files changed, 49 insertions(+), 10 deletions(-)

diff --git a/Koha/ExternalContent/OverDrive.pm b/Koha/ExternalContent/OverDrive.pm
index da84a4d19e..628e76122e 100644
--- a/Koha/ExternalContent/OverDrive.pm
+++ b/Koha/ExternalContent/OverDrive.pm
@@ -121,7 +121,7 @@ sub auth_url {
 
 =head2 auth_by_code($code, $base_url)
 
-  To be called in external/overdrive/auth.pl upon return from OverDrive auth
+  To be called in external/overdrive/auth.pl upon return from OverDrive Granted auth
 
 =cut
 
@@ -141,6 +141,30 @@ sub auth_by_code {
     return $self->get_return_page_from_koha_session;
 }
 
+=head2 auth_by_userid($userid, $password, $website_id, $authorization_name)
+
+  To be called to check auth of patron using OverDrive Patron Authentication method
+  This requires a SIP connection configured with OverDrive
+
+=cut
+
+sub auth_by_userid {
+    my $self = shift;
+    my $userid = shift or croak "No user provided";
+    my $password = shift;
+    croak "No password provided" unless ($password || !C4::Context->preference("OverDrivePasswordRequired"));
+    my $website_id = shift or croak "OverDrive Library ID not provided";
+    my $authorization_name = shift or croak "OverDrive Authname not provided";
+
+    my ($access_token, $access_token_type, $auth_token)
+      = $self->client->auth_by_user_id($userid, $password, $website_id, $authorization_name);
+    $access_token or die "Invalid OverDrive code returned";
+    $self->set_token_in_koha_session($access_token, $access_token_type);
+
+    $self->koha_patron->set({overdrive_auth_token => $auth_token})->store;
+    return $self->get_return_page_from_koha_session;
+}
+
 use constant AUTH_RETURN_HANDLER => "/cgi-bin/koha/external/overdrive/auth.pl";
 sub _return_url {
     my $self = shift;
@@ -208,7 +232,7 @@ sub auth_by_saved_token {
 
     if (my $auth_token = $koha_patron->overdrive_auth_token) {
         my ($access_token, $access_token_type, $new_auth_token)
-          = $self->client->auth_by_token($auth_token);
+          = $self->client->make_access_token_request();
         $self->set_token_in_koha_session($access_token, $access_token_type);
         $koha_patron->set({overdrive_auth_token => $new_auth_token})->store;
         return $access_token;
diff --git a/admin/overdrive.pl b/admin/overdrive.pl
index 489bf0ad40..c7359f263d 100755
--- a/admin/overdrive.pl
+++ b/admin/overdrive.pl
@@ -30,7 +30,6 @@ my $input         = CGI->new;
 my @branchcodes   = $input->multi_param('branchcode');
 my @authnames     = $input->multi_param('authname');
 my $op            = $input->param('op');
-my @messages;
 
 our ( $template, $loggedinuser, $cookie ) = get_template_and_user(
     {   template_name   => 'admin/overdrive.tt',
diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-overdrive-search.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-overdrive-search.tt
index f4154f93ef..1c2548bcef 100644
--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-overdrive-search.tt
+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-overdrive-search.tt
@@ -64,6 +64,7 @@
 [% Asset.js("js/overdrive.js") | $raw %]
 [% Asset.js("lib/jquery/plugins/jquery.rating.js") | $raw %]
 <script>
+var OD_password_required = [% IF Koha.Preference('OverDrivePasswordRequired') %]1[% ELSE %]0[% END %];
 var querystring = "[% q |replace( "'", "\'" ) |replace( '\n', '\\n' ) |replace( '\r', '\\r' ) | html %]";
 var results_per_page = [% OPACnumSearchResults | html %];
 
@@ -188,7 +189,7 @@ $( document ).ready( function() {
     [% IF ( overdrive_error ) %]
     KOHA.OverDriveCirculation.display_error("#breadcrumbs", "[% overdrive_error.dquote | html %]");
     [% END %]
-    [% IF ( loggedinusername and OverDriveCirculation ) %]
+    [% IF ( loggedinusername and Koha.Preference('OverDriveCirculation') ) %]
     KOHA.OverDriveCirculation.with_account_details("#breadcrumbs", function() {
         search( 0 );
     });
diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-user.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-user.tt
index c7b50e8713..5b671401a8 100644
--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-user.tt
+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-user.tt
@@ -1058,6 +1058,7 @@
     [% IF Koha.Preference('OverDriveCirculation') %]
     [% Asset.js("js/overdrive.js") | $raw %]
     <script>
+    var OD_password_required = [% IF Koha.Preference('OverDrivePasswordRequired') %]1[% ELSE %]0[% END %];
     $(document).ready(function() {
         [% IF ( overdrive_error ) %]
             KOHA.OverDriveCirculation.display_error("#opac-user-overdrive", "[% overdrive_error.dquote | html %]");
diff --git a/koha-tmpl/opac-tmpl/bootstrap/js/overdrive.js b/koha-tmpl/opac-tmpl/bootstrap/js/overdrive.js
index 5cf8170b03..7063cd1007 100644
--- a/koha-tmpl/opac-tmpl/bootstrap/js/overdrive.js
+++ b/koha-tmpl/opac-tmpl/bootstrap/js/overdrive.js
@@ -71,7 +71,8 @@ KOHA.OverDriveCirculation = new function() {
     var login_link = $('<a href="#">')
         .click(function(e) {
             e.preventDefault();
-            login(window.open());
+            var passwd = OD_password_required ? prompt("Please enter your password") : "";
+            login(passwd);
         })
         .text(_("Login to OverDrive account"));
     var login_div = $('<div class="overdrive-login">').append(login_link);
@@ -193,11 +194,16 @@ KOHA.OverDriveCirculation = new function() {
         });
     }
 
-    function login(w) {
-        svc_ajax('get', { action: "login" }, function(data) {
+    function login(p) {
+        svc_ajax('get', { action: "login", password: p }, function(data) {
             details = null;
-            if (data.login_url) {
-                w.location = data.login_url;
+            if( data.login_success ){
+                $(login_div).detach();
+                if( $("#overdrive-results-page").length > 0 ){
+                    location.reload();
+                } else {
+                KOHA.OverDriveCirculation.display_account_details( $("#opac-user-overdrive") );
+                }
             }
         });
     }
diff --git a/opac/svc/overdrive b/opac/svc/overdrive
index cf7df9dd63..6fb949dc05 100755
--- a/opac/svc/overdrive
+++ b/opac/svc/overdrive
@@ -24,6 +24,8 @@ use JSON qw(encode_json);
 use C4::Auth qw(checkauth);
 use C4::Output;
 use Koha::Logger;
+use Koha::Patrons;
+use Koha::Library::OverDriveInfos;
 use Koha::ExternalContent::OverDrive;
 
 my $logger = Koha::Logger->get({ interface => 'opac' });
@@ -43,7 +45,13 @@ local $@;
 eval {
         {
             $action eq 'login' && do {
-                $data{login_url} = $od->auth_url($page_url);
+                my $password = $cgi->param("password") // q{} ;
+                my $patron = Koha::Patrons->find({ userid => $user });
+                my $branch_info = Koha::Library::OverDriveInfos->find( $patron->branchcode ) if $patron;
+                my $branch_authname = $branch_info->authname if $branch_info;
+                my $authname = $branch_authname || C4::Context->preference('OverDriveAuthname');
+                $od->auth_by_userid($user, $password,C4::Context->preference('OverDriveWebsiteID'),$authname);
+                $data{login_success} = 1;
                 last;
             };
 
-- 
2.19.0