Bug 33653: Use filter_by_active instead
[koha.git] / Koha / Auth / Client / OAuth.pm
1 package Koha::Auth::Client::OAuth;
2
3 # Copyright Theke Solutions 2022
4 #
5 # This file is part of Koha.
6 #
7 # Koha is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # Koha is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20 use Modern::Perl;
21
22 use JSON qw( decode_json );
23 use MIME::Base64 qw{ decode_base64url };
24 use Koha::Patrons;
25 use Mojo::UserAgent;
26 use Mojo::Parameters;
27
28 use base qw( Koha::Auth::Client );
29
30 =head1 NAME
31
32 Koha::Auth::Client::OAuth - Koha OAuth Client
33
34 =head1 API
35
36 =head2 Class methods
37
38 =head3 _get_data_and_patron
39
40     my $mapping = $object->_get_data_and_patron(
41         {   provider => $provider,
42             data     => $data,
43             config   => $config
44         }
45     );
46
47 Maps OAuth raw data to a patron schema, and returns a patron if it can.
48
49 =cut
50
51 sub _get_data_and_patron {
52     my ( $self, $params ) = @_;
53
54     my $provider = $params->{provider};
55     my $data     = $params->{data};
56     my $config   = $params->{config};
57
58     my $patron;
59     my $mapped_data;
60
61     my $mapping = decode_json( $provider->mapping );
62     my $matchpoint = $provider->matchpoint;
63
64     if ( $data->{id_token} ) {
65         my ( $header_part, $claims_part, $footer_part ) = split( /\./, $data->{id_token} );
66
67         my $claim = decode_json( decode_base64url($claims_part) );
68
69         foreach my $key ( keys %$mapping ) {
70             my $pkey = $mapping->{$key};
71             $mapped_data->{$key} = $claim->{$pkey}
72               if defined $claim->{$pkey};
73         }
74
75         my $value = $mapped_data->{$matchpoint};
76
77         my $matchpoint_rs = Koha::Patrons->search( { $matchpoint => $value } );
78
79         if ( defined $value and $matchpoint_rs->count ) {
80             $patron = $matchpoint_rs->next;
81         }
82     }
83
84     if ( defined $config->{userinfo_url} ) {
85         my $access_token = $data->{access_token};
86         my $ua           = Mojo::UserAgent->new;
87         my $tx           = $ua->get( $config->{userinfo_url} => { Authorization => "Bearer $access_token" } );
88         my $code         = $tx->res->code || 'No response';
89
90         return if $code ne '200';
91         my $claim =
92             $tx->res->headers->content_type =~ m!^(application/json|text/javascript)(;\s*charset=\S+)?$!
93           ? $tx->res->json
94           : Mojo::Parameters->new( $tx->res->body )->to_hash;
95
96         foreach my $key ( keys %$mapping ) {
97             my $pkey  = $mapping->{$key};
98             my $value = $self->_traverse_hash( { base => $claim, keys => $pkey } );
99             $mapped_data->{$key} = $value
100               if defined $value;
101         }
102
103         unless ($patron) {
104             my $value = $mapped_data->{$matchpoint};
105
106             my $matchpoint_rs = Koha::Patrons->search( { $matchpoint => $value } );
107
108             if ( defined $value and $matchpoint_rs->count ) {
109                 $patron = $matchpoint_rs->next;
110             }
111         }
112
113     }
114
115     return ( $mapped_data, $patron );
116 }
117
118 1;