Bug 23805: Update 'Pay' to 'PAYMENT' for consistency
[srvgit] / t / db_dependent / api / v1 / oauth.t
index 2748fe2..d91666c 100755 (executable)
 
 use Modern::Perl;
 
-use Test::More tests => 2;
+use Test::More;
 use Test::MockModule;
 use Test::Mojo;
 
+use MIME::Base64;
+use Module::Load::Conditional qw(can_load);
+
+use Koha::ApiKeys;
 use Koha::Database;
 use Koha::Patrons;
 
@@ -31,17 +35,18 @@ my $t = Test::Mojo->new('Koha::REST::V1');
 my $schema  = Koha::Database->new->schema;
 my $builder = t::lib::TestBuilder->new();
 
+if ( can_load( modules => { 'Net::OAuth2::AuthorizationServer' => undef } ) ) {
+    plan tests => 2;
+}
+else {
+    plan skip_all => 'Net::OAuth2::AuthorizationServer not available';
+}
+
 subtest '/oauth/token tests' => sub {
-    plan tests => 27;
 
-    $schema->storage->txn_begin;
+    plan tests => 10;
 
-    my $patron = $builder->build_object({
-        class => 'Koha::Patrons',
-        value  => {
-            flags => 0 # no permissions
-        },
-    });
+    t::lib::Mocks::mock_preference('RESTOAuth2ClientCredentials', 0);
 
     # Missing parameter grant_type
     $t->post_ok('/api/v1/oauth/token')
@@ -59,60 +64,20 @@ subtest '/oauth/token tests' => sub {
         ->status_is(403)
         ->json_is({error => 'unauthorized_client'});
 
-    my $api_key = Koha::ApiKey->new({ patron_id => $patron->id, description => 'blah' })->store;
-
-    my $formData = {
-        grant_type    => 'client_credentials',
-        client_id     => $api_key->client_id,
-        client_secret => $api_key->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);
+    subtest 'Client credentials in body' => sub {
 
-    # With access token and permissions, it returns 200
-    $patron->flags(2**4)->store;
-    $tx = $t->ua->build_tx(GET => '/api/v1/patrons');
-    $tx->req->headers->authorization("Bearer $access_token");
-    $t->request_ok($tx)->status_is(200);
+        plan tests => 19;
 
-    # expire token
-    my $token = Koha::OAuthAccessTokens->find($access_token);
-    $token->expires( time - 1 )->store;
-    $tx = $t->ua->build_tx( GET => '/api/v1/patrons' );
-    $tx->req->headers->authorization("Bearer $access_token");
-    $t->request_ok($tx)
-      ->status_is(401);
+        run_oauth_tests( 'body' );
+    };
 
-    # revoke key
-    $api_key->active(0)->store;
-    $t->post_ok('/api/v1/oauth/token', form => $formData)
-        ->status_is(403)
-        ->json_is({ error => 'unauthorized_client' });
+    subtest 'Client credentials in Authorization header' => sub {
 
-    # disable client credentials grant
-    t::lib::Mocks::mock_preference('RESTOAuth2ClientCredentials', 0);
 
-    # enable API key
-    $api_key->active(1)->store;
-    # Wrong grant type
-    $t->post_ok('/api/v1/oauth/token', form => $formData )
-        ->status_is(400)
-        ->json_is({ error => 'Unimplemented grant type' });
+        plan tests => 19;
 
-    $schema->storage->txn_rollback;
+        run_oauth_tests( 'header' );
+    };
 };
 
 subtest 'Net::OAuth2::AuthorizationServer missing tests' => sub {
@@ -151,3 +116,105 @@ subtest 'Net::OAuth2::AuthorizationServer missing tests' => sub {
       ->json_is( { error => 'Unimplemented grant type' } );
 
 };
+
+sub run_oauth_tests {
+    my ( $test_case ) = @_;
+
+    $schema->storage->txn_begin;
+
+    my $patron = $builder->build_object({
+        class => 'Koha::Patrons',
+        value  => {
+            flags => 0 # no permissions
+        },
+    });
+
+    my $api_key = Koha::ApiKey->new({ patron_id => $patron->id, description => 'blah' })->store;
+
+    t::lib::Mocks::mock_preference( 'RESTOAuth2ClientCredentials', 1 );
+
+    my $formData;
+    my $client_id     = $api_key->client_id;
+    my $client_secret = $api_key->secret;
+
+    if ( $test_case eq 'header' ) {
+
+        $formData = { grant_type => 'client_credentials' };
+
+        $t->post_ok("//$client_id:$client_secret@/api/v1/oauth/token", form => $formData)
+          ->status_is(200)
+          ->json_is('/expires_in' => 3600)
+          ->json_is('/token_type' => 'Bearer')
+          ->json_has('/access_token');
+    } else {
+
+        $formData = {
+            grant_type    => 'client_credentials',
+            client_id     => $api_key->client_id,
+            client_secret => $api_key->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
+    $patron->flags(2**4)->store;
+    $tx = $t->ua->build_tx(GET => '/api/v1/patrons');
+    $tx->req->headers->authorization("Bearer $access_token");
+    $t->request_ok($tx)->status_is(200);
+
+    # expire token
+    my $token = Koha::OAuthAccessTokens->find($access_token);
+    $token->expires( time - 1 )->store;
+    $tx = $t->ua->build_tx( GET => '/api/v1/patrons' );
+    $tx->req->headers->authorization("Bearer $access_token");
+    $t->request_ok($tx)
+      ->status_is(401);
+
+    # revoke key
+    $api_key->active(0)->store;
+
+    if ( $test_case eq 'header' ) {
+        $t->post_ok("//$client_id:$client_secret@/api/v1/oauth/token", form => $formData)
+          ->status_is(403)
+          ->json_is({ error => 'unauthorized_client' });
+    } else {
+        $t->post_ok('/api/v1/oauth/token', form => $formData)
+          ->status_is(403)
+          ->json_is({ error => 'unauthorized_client' });
+    }
+
+    # disable client credentials grant
+   t::lib::Mocks::mock_preference('RESTOAuth2ClientCredentials', 0);
+
+    # enable API key
+    $api_key->active(1)->store;
+
+    # Wrong grant type
+    if ( $test_case eq 'header' ) {
+        $t->post_ok("//$client_id:$client_secret@/api/v1/oauth/token", form => $formData )
+          ->status_is(400)
+          ->json_is({ error => 'Unimplemented grant type' });
+    }
+    else {
+        $t->post_ok('/api/v1/oauth/token', form => $formData )
+          ->status_is(400)
+          ->json_is({ error => 'Unimplemented grant type' });
+    }
+
+    $schema->storage->txn_rollback;
+}