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>
This commit is contained in:
Olli-Antti Kivilahti 2015-09-14 15:20:20 +03:00 committed by Kyle M Hall
parent 49df1cc10f
commit ac1286dacd
2 changed files with 58 additions and 22 deletions

View file

@ -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;

View file

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