Browse Source

Bug 14868: Swagger2-driven Permission checking

Define 'x-koha-permission' for the Swagger2 Operation Object, to automatically
authorize against the required permissions.

This way we immediately tell the API consumer in the Swagger2-definition, which
permissions are needed to access defined resources.
Also we don't need to maintain permissions in multiple locations and we can build
a smart testing framework to help a lot in creating tests for the new REST API.

Signed-off-by: Benjamin Rokseth <benjamin.rokseth@kul.oslo.kommune.no>
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
16.11.x
Olli-Antti Kivilahti 7 years ago
committed by Kyle M Hall
parent
commit
ac1286dacd
  1. 79
      Koha/REST/V1.pm
  2. 1
      api/v1/swagger/swagger.json

79
Koha/REST/V1.pm

@ -18,33 +18,13 @@ package Koha::REST::V1;
use Modern::Perl;
use Mojo::Base 'Mojolicious';
use C4::Auth qw( check_cookie_auth get_session );
use C4::Auth qw( check_cookie_auth get_session haspermission );
use C4::Context;
use Koha::Patrons;
sub startup {
my $self = shift;
my $route = $self->routes->under->to(
cb => sub {
my $c = shift;
# Mojo doesn't use %ENV the way CGI apps do
# Manually pass the remote_address to check_auth_cookie
my $remote_addr = $c->tx->remote_address;
my ($status, $sessionID) = check_cookie_auth(
$c->cookie('CGISESSID'), undef,
{ remote_addr => $remote_addr });
if ($status eq "ok") {
my $session = get_session($sessionID);
my $user = Koha::Patrons->find($session->param('number'));
$c->stash('koha.user' => $user);
}
return 1;
}
);
# Force charset=utf8 in Content-Type header for JSON responses
$self->types->type(json => 'application/json; charset=utf8');
@ -54,9 +34,64 @@ sub startup {
}
$self->plugin(Swagger2 => {
route => $route,
url => $self->home->rel_file("api/v1/swagger/swagger.min.json"),
});
}
=head3 authenticate_api_request
Validates authentication and allows access if authorization is not required or
if authorization is required and user has required permissions to access.
This subroutine is called before every request to API.
=cut
sub authenticate_api_request {
my ($next, $c, $action_spec) = @_;
my ($session, $user);
my $cookie = $c->cookie('CGISESSID');
# Mojo doesn't use %ENV the way CGI apps do
# Manually pass the remote_address to check_auth_cookie
my $remote_addr = $c->tx->remote_address;
my ($status, $sessionID) = check_cookie_auth(
$cookie, undef,
{ remote_addr => $remote_addr });
if ($status eq "ok") {
$session = get_session($sessionID);
$user = Koha::Patrons->find($session->param('number'));
$c->stash('koha.user' => $user);
}
else {
return $c->render_swagger(
{ error => "Authentication failure." },
{},
401
) if $cookie and $action_spec->{'x-koha-permission'};
}
if ($action_spec->{'x-koha-permission'}) {
return $c->render_swagger(
{ error => "Authentication required." },
{},
401
) unless $user;
if (C4::Auth::haspermission($user->userid, $action_spec->{'x-koha-permission'})) {
return $next->($c);
}
else {
return $c->render_swagger(
{ error => "Authorization failure. Missing required permission(s)." },
{},
403
);
}
}
else {
return $next->($c);
}
}
1;

1
api/v1/swagger/swagger.json

@ -13,6 +13,7 @@
}
},
"basePath": "/api/v1",
"x-mojo-around-action": "Koha::REST::V1::authenticate_api_request",
"paths": {
"$ref": "paths.json"
},

Loading…
Cancel
Save