Bug 14868: Swagger2-driven Permission checking
[koha.git] / Koha / REST / V1.pm
1 package Koha::REST::V1;
2
3 # This file is part of Koha.
4 #
5 # Koha is free software; you can redistribute it and/or modify it under the
6 # terms of the GNU General Public License as published by the Free Software
7 # Foundation; either version 3 of the License, or (at your option) any later
8 # version.
9 #
10 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
11 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License along
15 # with Koha; if not, write to the Free Software Foundation, Inc.,
16 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
18 use Modern::Perl;
19 use Mojo::Base 'Mojolicious';
20
21 use C4::Auth qw( check_cookie_auth get_session haspermission );
22 use C4::Context;
23 use Koha::Patrons;
24
25 sub startup {
26     my $self = shift;
27
28     # Force charset=utf8 in Content-Type header for JSON responses
29     $self->types->type(json => 'application/json; charset=utf8');
30
31     my $secret_passphrase = C4::Context->config('api_secret_passphrase');
32     if ($secret_passphrase) {
33         $self->secrets([$secret_passphrase]);
34     }
35
36     $self->plugin(Swagger2 => {
37         url => $self->home->rel_file("api/v1/swagger/swagger.min.json"),
38     });
39 }
40
41 =head3 authenticate_api_request
42
43 Validates authentication and allows access if authorization is not required or
44 if authorization is required and user has required permissions to access.
45
46 This subroutine is called before every request to API.
47
48 =cut
49
50 sub authenticate_api_request {
51     my ($next, $c, $action_spec) = @_;
52
53     my ($session, $user);
54     my $cookie = $c->cookie('CGISESSID');
55     # Mojo doesn't use %ENV the way CGI apps do
56     # Manually pass the remote_address to check_auth_cookie
57     my $remote_addr = $c->tx->remote_address;
58     my ($status, $sessionID) = check_cookie_auth(
59                                             $cookie, undef,
60                                             { remote_addr => $remote_addr });
61     if ($status eq "ok") {
62         $session = get_session($sessionID);
63         $user = Koha::Patrons->find($session->param('number'));
64         $c->stash('koha.user' => $user);
65     }
66     else {
67         return $c->render_swagger(
68             { error => "Authentication failure." },
69             {},
70             401
71         ) if $cookie and $action_spec->{'x-koha-permission'};
72     }
73
74     if ($action_spec->{'x-koha-permission'}) {
75         return $c->render_swagger(
76             { error => "Authentication required." },
77             {},
78             401
79         ) unless $user;
80
81         if (C4::Auth::haspermission($user->userid, $action_spec->{'x-koha-permission'})) {
82             return $next->($c);
83         }
84         else {
85             return $c->render_swagger(
86                 { error => "Authorization failure. Missing required permission(s)." },
87                 {},
88                 403
89             );
90         }
91     }
92     else {
93         return $next->($c);
94     }
95 }
96
97 1;