| Line 0
          
      
      
        Link Here | 
            
              |  |  | 1 | # Copyright 2014 Catalyst | 
            
              | 2 | # | 
            
              | 3 | # This file is part of Koha. | 
            
              | 4 | # | 
            
              | 5 | # Koha is free software; you can redistribute it and/or modify it under the | 
            
              | 6 | # terms of the GNU General Public License as published by the Free Software | 
            
              | 7 | # Foundation; either version 3 of the License, or (at your option) any later | 
            
              | 8 | # version. | 
            
              | 9 | # | 
            
              | 10 | # Koha is distributed in the hope that it will be useful, but WITHOUT ANY | 
            
              | 11 | # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | 
            
              | 12 | # A PARTICULAR PURPOSE.  See the GNU General Public License for more details. | 
            
              | 13 | # | 
            
              | 14 | # You should have received a copy of the GNU General Public License along | 
            
              | 15 | # with Koha; if not, write to the Free Software Foundation, Inc., | 
            
              | 16 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | 
            
              | 17 |  | 
            
              | 18 | package Koha::ExternalContent::OverDrive; | 
            
              | 19 |  | 
            
              | 20 | use Modern::Perl; | 
            
              | 21 | use Carp; | 
            
              | 22 |  | 
            
              | 23 | use base qw(Koha::ExternalContent); | 
            
              | 24 | use WebService::ILS::OverDrive::Patron; | 
            
              | 25 | use C4::Context; | 
            
              | 26 | use Koha::Logger; | 
            
              | 27 |  | 
            
              | 28 | use constant logger => Koha::Logger->get(); | 
            
              | 29 |  | 
            
              | 30 | =head1 NAME | 
            
              | 31 |  | 
            
              | 32 | Koha::ExternalContent::OverDrive | 
            
              | 33 |  | 
            
              | 34 | =head1 SYNOPSIS | 
            
              | 35 |  | 
            
              | 36 |     use Koha::ExternalContent::OverDrive; | 
            
              | 37 |     my $od_client = Koha::ExternalContent::OverDrive->new(); | 
            
              | 38 |     my $od_auth_url = $od_client->auth_url(); | 
            
              | 39 |  | 
            
              | 40 | =head1 DESCRIPTION | 
            
              | 41 |  | 
            
              | 42 | A (very) thin wrapper around C<WebService::ILS::OverDrive::Patron> | 
            
              | 43 |  | 
            
              | 44 | Takes "OverDrive*" Koha preferences | 
            
              | 45 |  | 
            
              | 46 | =cut | 
            
              | 47 |  | 
            
              | 48 | sub new { | 
            
              | 49 |     my $class  = shift; | 
            
              | 50 |     my $params = shift || {}; | 
            
              | 51 |     $params->{koha_session_id} or croak "No koha_session_id"; | 
            
              | 52 |  | 
            
              | 53 |     my $self = $class->SUPER::new($params); | 
            
              | 54 |     unless ($params->{client}) { | 
            
              | 55 |         my $client_key     = C4::Context->preference('OverDriveClientKey') | 
            
              | 56 |           or croak("OverDriveClientKey pref not set"); | 
            
              | 57 |         my $client_secret  = C4::Context->preference('OverDriveClientSecret') | 
            
              | 58 |           or croak("OverDriveClientSecret pref not set"); | 
            
              | 59 |         my $library_id     = C4::Context->preference('OverDriveLibraryID') | 
            
              | 60 |           or croak("OverDriveLibraryID pref not set"); | 
            
              | 61 |         my ($token, $token_type) = $self->get_token_from_koha_session(); | 
            
              | 62 |         $self->client( WebService::ILS::OverDrive::Patron->new( | 
            
              | 63 |             client_id         => $client_key, | 
            
              | 64 |             client_secret     => $client_secret, | 
            
              | 65 |             library_id        => $library_id, | 
            
              | 66 |             access_token      => $token, | 
            
              | 67 |             access_token_type => $token_type, | 
            
              | 68 |             user_agent_params => { agent => $class->agent_string } | 
            
              | 69 |         ) ); | 
            
              | 70 |     } | 
            
              | 71 |     return $self; | 
            
              | 72 | } | 
            
              | 73 |  | 
            
              | 74 | =head1 METHODS | 
            
              | 75 |  | 
            
              | 76 | L<WebService::ILS::OverDrive::Patron> methods used without mods: | 
            
              | 77 |  | 
            
              | 78 | =over 4 | 
            
              | 79 |  | 
            
              | 80 | =item C<error_message()> | 
            
              | 81 |  | 
            
              | 82 | =back | 
            
              | 83 |  | 
            
              | 84 | C<WebService::ILS::OverDrive::Patron> methods with slightly moded interfaces: | 
            
              | 85 |  | 
            
              | 86 | =head2 auth_url($base_url) | 
            
              | 87 |  | 
            
              | 88 | =head2 auth_by_code($code, $base_url) | 
            
              | 89 |  | 
            
              | 90 | =cut | 
            
              | 91 |  | 
            
              | 92 | use constant AUTH_RETURN_HANDLER => "/cgi-bin/koha/external/overdrive/auth.pl"; | 
            
              | 93 | sub _return_url { | 
            
              | 94 |     my $self = shift; | 
            
              | 95 |     my $page_url = shift or croak "Page url not provided"; | 
            
              | 96 |  | 
            
              | 97 |     my ($base_url, $page) = ($page_url =~ m!^(https?://[^/]+)(.*)!); | 
            
              | 98 |     my $return_url = $base_url.AUTH_RETURN_HANDLER; | 
            
              | 99 |  | 
            
              | 100 |     return wantarray ? ($return_url, $page) : $return_url; | 
            
              | 101 | } | 
            
              | 102 |  | 
            
              | 103 | use constant RETURN_PAGE_SESSION_KEY => "overdrive.return_page"; | 
            
              | 104 | sub get_return_page_from_koha_session { | 
            
              | 105 |     my $self = shift; | 
            
              | 106 |     my $return_page = $self->get_from_koha_session(RETURN_PAGE_SESSION_KEY) || ""; | 
            
              | 107 |     $self->logger->debug("get_return_page_from_koha_session: $return_page"); | 
            
              | 108 |     return $return_page; | 
            
              | 109 | } | 
            
              | 110 | sub set_return_page_in_koha_session { | 
            
              | 111 |     my $self = shift; | 
            
              | 112 |     my $return_page = shift || ""; | 
            
              | 113 |     $self->logger->debug("set_return_page_in_koha_session: $return_page"); | 
            
              | 114 |     return $self->set_in_koha_session( RETURN_PAGE_SESSION_KEY, $return_page ); | 
            
              | 115 | } | 
            
              | 116 |  | 
            
              | 117 | use constant ACCESS_TOKEN_SESSION_KEY => "overdrive.access_token"; | 
            
              | 118 | my $ACCESS_TOKEN_DELIMITER = ":"; | 
            
              | 119 | sub get_token_from_koha_session { | 
            
              | 120 |     my $self = shift; | 
            
              | 121 |     my ($token, $token_type) | 
            
              | 122 |       = split $ACCESS_TOKEN_DELIMITER, $self->get_from_koha_session(ACCESS_TOKEN_SESSION_KEY) || ""; | 
            
              | 123 |     $self->logger->debug("get_token_from_koha_session: ".($token || "(none)")); | 
            
              | 124 |     return ($token, $token_type); | 
            
              | 125 | } | 
            
              | 126 | sub set_token_in_koha_session { | 
            
              | 127 |     my $self = shift; | 
            
              | 128 |     my $token = shift || ""; | 
            
              | 129 |     my $token_type = shift || ""; | 
            
              | 130 |     $self->logger->debug("set_token_in_koha_session: $token $token_type"); | 
            
              | 131 |     return $self->set_in_koha_session( | 
            
              | 132 |         ACCESS_TOKEN_SESSION_KEY, | 
            
              | 133 |         join($ACCESS_TOKEN_DELIMITER, $token, $token_type) | 
            
              | 134 |     ); | 
            
              | 135 | } | 
            
              | 136 |  | 
            
              | 137 | sub is_logged_in { | 
            
              | 138 |     my $self = shift; | 
            
              | 139 |     my ($token, $token_type) = $self->get_token_from_koha_session(); | 
            
              | 140 |     $token ||= $self->auth_by_saved_token; | 
            
              | 141 |     return $token; | 
            
              | 142 | } | 
            
              | 143 |  | 
            
              | 144 | sub auth_url { | 
            
              | 145 |     my $self = shift; | 
            
              | 146 |     my $page_url = shift or croak "Page url not provided"; | 
            
              | 147 |  | 
            
              | 148 |     my ($return_url, $page) = $self->_return_url($page_url); | 
            
              | 149 |     $self->set_return_page_in_koha_session($page); | 
            
              | 150 |     return $self->client->auth_url($return_url); | 
            
              | 151 | } | 
            
              | 152 |  | 
            
              | 153 | sub auth_by_code { | 
            
              | 154 |     my $self = shift; | 
            
              | 155 |     my $code = shift or croak "OverDrive auth code not provided"; | 
            
              | 156 |     my $base_url = shift or croak "App base url not provided"; | 
            
              | 157 |  | 
            
              | 158 |     my ($access_token, $access_token_type, $auth_token) | 
            
              | 159 |       = $self->client->auth_by_code($code, $self->_return_url($base_url)); | 
            
              | 160 |     $access_token or die "Invalid OverDrive code returned"; | 
            
              | 161 |     $self->set_token_in_koha_session($access_token, $access_token_type); | 
            
              | 162 |  | 
            
              | 163 |     $self->koha_patron->set({overdrive_auth_token => $auth_token})->store; | 
            
              | 164 |     return $self->get_return_page_from_koha_session; | 
            
              | 165 | } | 
            
              | 166 |  | 
            
              | 167 | sub auth_by_saved_token { | 
            
              | 168 |     my $self = shift; | 
            
              | 169 |  | 
            
              | 170 |     my $koha_patron = $self->koha_patron; | 
            
              | 171 |     if (my $auth_token = $koha_patron->overdrive_auth_token) { | 
            
              | 172 |         my ($access_token, $access_token_type, $new_auth_token) | 
            
              | 173 |           = $self->client->auth_by_token($auth_token); | 
            
              | 174 |         $self->set_token_in_koha_session($access_token, $access_token_type); | 
            
              | 175 |         $koha_patron->set({overdrive_auth_token => $new_auth_token})->store; | 
            
              | 176 |         return $access_token; | 
            
              | 177 |     } | 
            
              | 178 |  | 
            
              | 179 |     return; | 
            
              | 180 | } | 
            
              | 181 |  | 
            
              | 182 | sub forget { | 
            
              | 183 |     my $self = shift; | 
            
              | 184 |  | 
            
              | 185 |     $self->set_token_in_koha_session("", ""); | 
            
              | 186 |     $self->koha_patron->update({overdrive_auth_token => undef}); | 
            
              | 187 | } | 
            
              | 188 |  | 
            
              | 189 | use vars qw{$AUTOLOAD}; | 
            
              | 190 | sub AUTOLOAD { | 
            
              | 191 |     my $self = shift; | 
            
              | 192 |     (my $method = $AUTOLOAD) =~ s/.*:://; | 
            
              | 193 |     my $od = $self->client; | 
            
              | 194 |     local $@; | 
            
              | 195 |     my $ret = eval { $od->$method(@_) }; | 
            
              | 196 |     if ($@) { | 
            
              | 197 |         if ( $od->is_access_token_error($@) && $self->auth_by_saved_token ) { | 
            
              | 198 |             return $od->$method(@_); | 
            
              | 199 |         } | 
            
              | 200 |         die $@; | 
            
              | 201 |     } | 
            
              | 202 |     return $ret; | 
            
              | 203 | } | 
            
              | 204 | sub DESTROY { } | 
            
              | 205 |  | 
            
              | 206 | 1; |