43a4b3c22c
It implements only the "client credentials" flow with no scopes support. API clients are tied to an existing patron and have the same permissions as the patron they are tied to. API Clients are defined in $KOHA_CONF. Test plan: 0. Install Net::OAuth2::AuthorizationServer 0.16 1. In $KOHA_CONF, add an <api_client> element under <config>: <api_client> <client_id>$CLIENT_ID</client_id> <client_secret>$CLIENT_SECRET</client_secret> <patron_id>X</patron_id> <!-- X is an existing borrowernumber --> </api_client> 2. Apply patch, run updatedatabase.pl and reload starman 3. Install Firefox extension RESTer [1] 4. In RESTer, go to "Authorization" tab and create a new OAuth2 configuration: - OAuth flow: Client credentials - Access Token Request Method: POST - Access Token Request Endpoint: http://$KOHA_URL/api/v1/oauth/token - Access Token Request Client Authentication: Credentials in request body - Client ID: $CLIENT_ID - Client Secret: $CLIENT_SECRET 5. Click on the newly created configuration to generate a new token (which will be valid only for an hour) 6. In RESTer, set HTTP method to GET and url to http://$KOHA_URL/api/v1/patrons then click on SEND If patron X has permission 'borrowers', it should return 200 OK with the list of patrons Otherwise it should return 403 with the list of required permissions (Please test both cases) 7. Wait an hour (or run the following SQL query: UPDATE oauth_access_tokens SET expires = 0) and repeat step 6. You should have a 403 Forbidden status, and the token must have been removed from the database. 8. Create a bunch of tokens using RESTer, make some of them expires using the previous SQL query, and run the following command: misc/cronjobs/cleanup_database.pl --oauth-tokens Verify that expired tokens were removed, and that the others are still there 9. prove t/db_dependent/api/v1/oauth.t [1] https://addons.mozilla.org/en-US/firefox/addon/rester/ Signed-off-by: Josef Moravec <josef.moravec@gmail.com> Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io> Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
101 lines
3.1 KiB
Perl
Executable file
101 lines
3.1 KiB
Perl
Executable file
#!/usr/bin/env perl
|
|
|
|
# This file is part of Koha.
|
|
#
|
|
# Koha is free software; you can redistribute it and/or modify it under the
|
|
# terms of the GNU General Public License as published by the Free Software
|
|
# Foundation; either version 3 of the License, or (at your option) any later
|
|
# version.
|
|
#
|
|
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License along
|
|
# with Koha; if not, write to the Free Software Foundation, Inc.,
|
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
use Modern::Perl;
|
|
|
|
use Test::More tests => 1;
|
|
use Test::Mojo;
|
|
|
|
use Koha::Database;
|
|
|
|
use t::lib::Mocks;
|
|
use t::lib::TestBuilder;
|
|
|
|
my $t = Test::Mojo->new('Koha::REST::V1');
|
|
my $schema = Koha::Database->new->schema;
|
|
my $builder = t::lib::TestBuilder->new();
|
|
|
|
subtest '/oauth/token tests' => sub {
|
|
plan tests => 19;
|
|
|
|
$schema->storage->txn_begin;
|
|
|
|
my $patron = $builder->build({
|
|
source => 'Borrower',
|
|
value => {
|
|
surname => 'Test OAuth',
|
|
flags => 0,
|
|
},
|
|
});
|
|
|
|
# Missing parameter grant_type
|
|
$t->post_ok('/api/v1/oauth/token')
|
|
->status_is(400);
|
|
|
|
# Wrong grant type
|
|
$t->post_ok('/api/v1/oauth/token', form => { grant_type => 'password' })
|
|
->status_is(400)
|
|
->json_is({error => 'Unimplemented grant type'});
|
|
|
|
# No client_id/client_secret
|
|
$t->post_ok('/api/v1/oauth/token', form => { grant_type => 'client_credentials' })
|
|
->status_is(403)
|
|
->json_is({error => 'unauthorized_client'});
|
|
|
|
my ($client_id, $client_secret) = ('client1', 'secr3t');
|
|
t::lib::Mocks::mock_config('api_client', {
|
|
'client_id' => $client_id,
|
|
'client_secret' => $client_secret,
|
|
patron_id => $patron->{borrowernumber},
|
|
});
|
|
|
|
my $formData = {
|
|
grant_type => 'client_credentials',
|
|
client_id => $client_id,
|
|
client_secret => $client_secret,
|
|
};
|
|
$t->post_ok('/api/v1/oauth/token', form => $formData)
|
|
->status_is(200)
|
|
->json_is('/expires_in' => 3600)
|
|
->json_is('/token_type' => 'Bearer')
|
|
->json_has('/access_token');
|
|
|
|
my $access_token = $t->tx->res->json->{access_token};
|
|
|
|
# Without access token, it returns 401
|
|
$t->get_ok('/api/v1/patrons')->status_is(401);
|
|
|
|
# With access token, but without permissions, it returns 403
|
|
my $tx = $t->ua->build_tx(GET => '/api/v1/patrons');
|
|
$tx->req->headers->authorization("Bearer $access_token");
|
|
$t->request_ok($tx)->status_is(403);
|
|
|
|
# With access token and permissions, it returns 200
|
|
$builder->build({
|
|
source => 'UserPermission',
|
|
value => {
|
|
borrowernumber => $patron->{borrowernumber},
|
|
module_bit => 4, # borrowers
|
|
code => 'edit_borrowers',
|
|
},
|
|
});
|
|
$tx = $t->ua->build_tx(GET => '/api/v1/patrons');
|
|
$tx->req->headers->authorization("Bearer $access_token");
|
|
$t->request_ok($tx)->status_is(200);
|
|
|
|
$schema->storage->txn_rollback;
|
|
};
|