From 1ce9e4742acbdf0bf0ad623ad641951e03bb67fb Mon Sep 17 00:00:00 2001 From: Olli-Antti Kivilahti Date: Mon, 14 Sep 2015 15:20:20 +0300 Subject: [PATCH] Bug 14868: Swagger2-driven Permission checking A hasty downgrade from 13920, utilizing new features implemented by the Mojolicious::Plugin::Swagger2-author, to make it possible to implement more complex authentication/authorization scenarios with the Plugin. 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. --- Koha/REST/V1.pm | 62 ++++++++++++++++++++++++++++++++++++++--------------- api/v1/swagger.json | 7 ++++++ 2 files changed, 52 insertions(+), 17 deletions(-) diff --git a/Koha/REST/V1.pm b/Koha/REST/V1.pm index 7d7102d..9dad30c 100644 --- a/Koha/REST/V1.pm +++ b/Koha/REST/V1.pm @@ -3,34 +3,62 @@ 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 Koha::Borrowers; sub startup { my $self = shift; - my $route = $self->routes->under->to( - cb => sub { - my $c = shift; - - my ($status, $sessionID) = check_cookie_auth($c->cookie('CGISESSID')); - if ($status eq "ok") { - my $session = get_session($sessionID); - my $user = Koha::Borrowers->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'); $self->plugin(Swagger2 => { - route => $route, url => $self->home->rel_file("api/v1/swagger.json"), }); } +sub authenticate_api_request { + my ($next, $c, $action_spec) = @_; + + # Go to the action if the Authorization header is valid + my ($session, $user); + my $cookie = $c->tx->req->cookie('CGISESSID'); + my ($status, $sessionID) = check_cookie_auth($cookie->value) if $cookie; + if ($status eq "ok") { + $session = get_session($sessionID); + $user = Koha::Borrowers->find($session->param('number')); + $c->stash('koha.user' => $user); + } + else { + return $c->render_swagger( + {errors => [{message => "Invalid authorization key", path => "/"}]}, + {}, + 401 + ); + } + + if ($action_spec->{'x-koha-permission'}) { + if (C4::Auth::haspermission($user, $action_spec->{'x-koha-permission'})) { + return $next->($c); + } + else { + return $c->render_swagger( + {errors => [{message => "No permission", path => "/"}]}, + {}, + 401 + ); + } + } + else { + return $next->($c); + } + + #If everything else fails, DO NOT authenticate by default! + return $c->render_swagger( + {errors => [{message => "Something bad happened when authenticating request", path => "/"}]}, + {}, + 500 + ); +} + 1; diff --git a/api/v1/swagger.json b/api/v1/swagger.json index a20cb20..d297eb0 100644 --- a/api/v1/swagger.json +++ b/api/v1/swagger.json @@ -13,10 +13,14 @@ } }, "basePath": "/api/v1", + "x-mojo-around-action": "Koha::REST::V1::authenticate_api_request", "paths": { "/borrowers": { "get": { "x-mojo-controller": "Koha::REST::V1::Borrowers", + "x-koha-permission": { + "borrowers": "1" + }, "operationId": "listBorrowers", "tags": ["borrowers"], "produces": [ @@ -44,6 +48,9 @@ "/borrowers/{borrowernumber}": { "get": { "x-mojo-controller": "Koha::REST::V1::Borrowers", + "x-koha-permission": { + "borrowers": "1" + }, "operationId": "getBorrower", "tags": ["borrowers"], "parameters": [ -- 1.9.1