|
Line 0
Link Here
|
|
|
1 |
package Koha::OAuth; |
| 2 |
|
| 3 |
use Modern::Perl; |
| 4 |
use Net::OAuth2::AuthorizationServer::ClientCredentialsGrant; |
| 5 |
use Koha::OAuthAccessTokens; |
| 6 |
use Koha::OAuthAccessToken; |
| 7 |
|
| 8 |
sub grant { |
| 9 |
my $grant = Net::OAuth2::AuthorizationServer::ClientCredentialsGrant->new( |
| 10 |
verify_client_cb => \&_verify_client_cb, |
| 11 |
store_access_token_cb => \&_store_access_token_cb, |
| 12 |
verify_access_token_cb => \&_verify_access_token_cb |
| 13 |
); |
| 14 |
|
| 15 |
return $grant; |
| 16 |
} |
| 17 |
|
| 18 |
sub _verify_client_cb { |
| 19 |
my (%args) = @_; |
| 20 |
|
| 21 |
my ($client_id, $scopes_ref, $client_secret) |
| 22 |
= @args{ qw/ client_id scopes client_secret / }; |
| 23 |
|
| 24 |
my $clients = C4::Context->config('api_client'); |
| 25 |
$clients = [ $clients ] unless ref $clients eq 'ARRAY'; |
| 26 |
my ($client) = grep { $_->{client_id} eq $client_id } @$clients; |
| 27 |
return (0, 'unauthorized_client') unless $client; |
| 28 |
|
| 29 |
return (0, 'access_denied') unless $client_secret eq $client->{client_secret}; |
| 30 |
|
| 31 |
$client->{scope} //= []; |
| 32 |
$client->{scope} = [ $client->{scope} ] if ref $client->{scope} ne 'ARRAY'; |
| 33 |
my $client_scopes = []; |
| 34 |
foreach my $scope ( @{ $scopes_ref // [] } ) { |
| 35 |
if (!grep { $_ eq $scope } @{ $client->{scope} }) { |
| 36 |
return (0, 'invalid_scope'); |
| 37 |
} |
| 38 |
push @$client_scopes, $scope; |
| 39 |
} |
| 40 |
|
| 41 |
return (1, undef, $client_scopes); |
| 42 |
} |
| 43 |
|
| 44 |
sub _store_access_token_cb { |
| 45 |
my ( %args ) = @_; |
| 46 |
|
| 47 |
my ( $client_id, $access_token, $expires_in, $scopes_ref ) |
| 48 |
= @args{ qw/ client_id access_token expires_in scopes / }; |
| 49 |
|
| 50 |
my $at = Koha::OAuthAccessToken->new({ |
| 51 |
access_token => $access_token, |
| 52 |
scope => join (' ', @$scopes_ref), |
| 53 |
expires => time + $expires_in, |
| 54 |
client_id => $client_id, |
| 55 |
}); |
| 56 |
$at->store; |
| 57 |
|
| 58 |
return; |
| 59 |
} |
| 60 |
|
| 61 |
sub _verify_access_token_cb { |
| 62 |
my (%args) = @_; |
| 63 |
|
| 64 |
my ($access_token, $scopes_ref) = @args{qw(access_token scopes)}; |
| 65 |
|
| 66 |
my $at = Koha::OAuthAccessTokens->find($access_token); |
| 67 |
if ($at) { |
| 68 |
if ( $at->expires <= time ) { |
| 69 |
# need to revoke the access token |
| 70 |
$at->delete; |
| 71 |
|
| 72 |
return (0, 'invalid_grant') |
| 73 |
} elsif ( $scopes_ref ) { |
| 74 |
foreach my $scope ( @{ $scopes_ref // [] } ) { |
| 75 |
unless ($at->has_scope($scope)) { |
| 76 |
return (0, 'invalid_grant'); |
| 77 |
} |
| 78 |
} |
| 79 |
} |
| 80 |
|
| 81 |
return $at->unblessed; |
| 82 |
} |
| 83 |
|
| 84 |
return (0, 'invalid_grant') |
| 85 |
}; |
| 86 |
|
| 87 |
1; |