View | Details | Raw Unified | Return to bug 17424
Collapse All | Expand All

(-)a/Koha/REST/V1.pm (-10 / +16 lines)
Lines 110-126 sub authenticate_api_request { Link Here
110
    my $permissions = $authorization->{'permissions'};
110
    my $permissions = $authorization->{'permissions'};
111
111
112
    # Check if the user is authorized
112
    # Check if the user is authorized
113
    if ( C4::Auth::haspermission($user->userid, $permissions)
113
    return $next->($c) if C4::Auth::haspermission($user->userid, $permissions);
114
        or allow_owner($c, $authorization, $user)
114
    if (C4::Context->preference("AccessOwnObjectsInAPI")) {
115
        or allow_guarantor($c, $authorization, $user) ) {
115
        return $next->($c) if allow_owner($c, $authorization, $user);
116
116
        return $next->($c) if allow_guarantor($c, $authorization, $user);
117
        # Return the query errors if exist
117
    } else {
118
        return $c->render_swagger({}, \@query_errors, 400) if @query_errors;
118
        if ($authorization->{'allow-owner'} && allow_owner($c, $authorization,
119
119
            $user) || $authorization->{'allow-guarantor'} && allow_guarantor(
120
        # Everything is ok
120
            $c, $authorization, $user)) {
121
        return $next->($c)
121
                return $c->render_swagger(
122
                { error => "Functionality for accessing own objects has been "
123
                            ."disabled. Permission(s) required to access.",
124
                required_permissions => $permissions },
125
                {},
126
                403
127
            );
128
        }
122
    }
129
    }
123
124
    return $c->render_swagger(
130
    return $c->render_swagger(
125
        { error => "Authorization failure. Missing required permission(s).",
131
        { error => "Authorization failure. Missing required permission(s).",
126
          required_permissions => $permissions },
132
          required_permissions => $permissions },
(-)a/installer/data/mysql/atomicupdate/Bug_17424_add_system_preference_AccessOwnObjectsInAPI.sql (+2 lines)
Line 0 Link Here
1
INSERT IGNORE INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES
2
('AccessOwnObjectsInAPI','1','','If OFF, REST API does not allow access to own objects even if otherwise possible.','YesNo')
(-)a/installer/data/mysql/sysprefs.sql (+1 lines)
Lines 1-4 Link Here
1
INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES
1
INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES
2
('AccessOwnObjectsInAPI','1','','If OFF, REST API does not allow access to own objects even if otherwise possible.','YesNo'),
2
('AcqCreateItem','ordering','ordering|receiving|cataloguing','Define when the item is created : when ordering, when receiving, or in cataloguing module','Choice'),
3
('AcqCreateItem','ordering','ordering|receiving|cataloguing','Define when the item is created : when ordering, when receiving, or in cataloguing module','Choice'),
3
('AcqEnableFiles','0',NULL,'If enabled, allows librarians to upload and attach arbitrary files to invoice records.','YesNo'),
4
('AcqEnableFiles','0',NULL,'If enabled, allows librarians to upload and attach arbitrary files to invoice records.','YesNo'),
4
('AcqItemSetSubfieldsWhenReceiptIsCancelled','', '','Upon cancelling a receipt, update the items subfields if they were created when placing an order (e.g. o=5|a="bar foo")', 'Free'),
5
('AcqItemSetSubfieldsWhenReceiptIsCancelled','', '','Upon cancelling a receipt, update the items subfields if they were created when placing an order (e.g. o=5|a="bar foo")', 'Free'),
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/web_services.pref (+9 lines)
Lines 61-63 Web services: Link Here
61
                no: Disable
61
                no: Disable
62
            - the IdRef webservice from the opac detail page. IdRef allows to request authorities from the Sudoc database.
62
            - the IdRef webservice from the opac detail page. IdRef allows to request authorities from the Sudoc database.
63
            - Please note that this feature is available only for UNIMARC.
63
            - Please note that this feature is available only for UNIMARC.
64
    REST API:
65
        -
66
            - pref: AccessOwnObjectsInAPI
67
              choices:
68
                yes: Enable
69
                no: Disable
70
            - access to API user's own objects. If enabled, basic OPAC operations via REST API are possible even without otherwise
71
            - required permissions (e.g. get your own patron data, renew your own checkout etc.). If disabled, API can
72
            - be used only if user has required permission for the operation.
(-)a/t/db_dependent/api/v1/holds.t (+2 lines)
Lines 19-24 use Modern::Perl; Link Here
19
19
20
use Test::More tests => 4;
20
use Test::More tests => 4;
21
use Test::Mojo;
21
use Test::Mojo;
22
use t::lib::Mocks;
22
use t::lib::TestBuilder;
23
use t::lib::TestBuilder;
23
24
24
use DateTime;
25
use DateTime;
Lines 182-187 subtest "Test endpoints without permission" => sub { Link Here
182
subtest "Test endpoints without permission, but accessing own object" => sub {
183
subtest "Test endpoints without permission, but accessing own object" => sub {
183
    plan tests => 15;
184
    plan tests => 15;
184
185
186
    t::lib::Mocks::mock_preference("AccessOwnObjectsInAPI", 1);
185
    my $borrno_tmp = $post_data->{'borrowernumber'};
187
    my $borrno_tmp = $post_data->{'borrowernumber'};
186
    $post_data->{'borrowernumber'} = int $nopermission->{'borrowernumber'};
188
    $post_data->{'borrowernumber'} = int $nopermission->{'borrowernumber'};
187
    $tx = $t->ua->build_tx(POST => "/api/v1/holds" => json => $post_data);
189
    $tx = $t->ua->build_tx(POST => "/api/v1/holds" => json => $post_data);
(-)a/t/db_dependent/api/v1/patrons.t (+2 lines)
Lines 19-24 use Modern::Perl; Link Here
19
19
20
use Test::More tests => 21;
20
use Test::More tests => 21;
21
use Test::Mojo;
21
use Test::Mojo;
22
use t::lib::Mocks;
22
use t::lib::TestBuilder;
23
use t::lib::TestBuilder;
23
24
24
use C4::Auth;
25
use C4::Auth;
Lines 88-93 $t->request_ok($tx) Link Here
88
  ->status_is(403)
89
  ->status_is(403)
89
  ->json_is('/required_permissions', {"borrowers" => "1"});
90
  ->json_is('/required_permissions', {"borrowers" => "1"});
90
91
92
t::lib::Mocks::mock_preference("AccessOwnObjectsInAPI", 1);
91
# User without permissions, but is the owner of the object
93
# User without permissions, but is the owner of the object
92
$tx = $t->ua->build_tx(GET => "/api/v1/patrons/" . $borrower->{borrowernumber});
94
$tx = $t->ua->build_tx(GET => "/api/v1/patrons/" . $borrower->{borrowernumber});
93
$tx->req->cookies({name => 'CGISESSID', value => $session->id});
95
$tx->req->cookies({name => 'CGISESSID', value => $session->id});
(-)a/t/db_dependent/api/v1/swagger/ownership.t (-1 / +132 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/env perl
2
3
# Copyright 2016 Koha-Suomi
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it under the
8
# terms of the GNU General Public License as published by the Free Software
9
# Foundation; either version 3 of the License, or (at your option) any later
10
# version.
11
#
12
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License along
17
# with Koha; if not, write to the Free Software Foundation, Inc.,
18
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20
use Modern::Perl;
21
22
use Test::More tests => 15;
23
use Test::Mojo;
24
25
use t::lib::TestBuilder;
26
use t::lib::Mocks;
27
28
use C4::Context;
29
30
use Koha::Database;
31
use Koha::Patron;
32
33
my $builder = t::lib::TestBuilder->new();
34
35
my $dbh = C4::Context->dbh;
36
$dbh->{AutoCommit} = 0;
37
$dbh->{RaiseError} = 1;
38
39
$ENV{REMOTE_ADDR} = '127.0.0.1';
40
my $t = Test::Mojo->new('Koha::REST::V1');
41
42
my $categorycode = $builder->build({ source => 'Category' })->{ categorycode };
43
my $branchcode = $builder->build({ source => 'Branch' })->{ branchcode };
44
my $guarantor = $builder->build({
45
    source => 'Borrower',
46
    value => {
47
        branchcode   => $branchcode,
48
        categorycode => $categorycode,
49
        flags        => 0,
50
    }
51
});
52
my $borrower = $builder->build({
53
    source => 'Borrower',
54
    value => {
55
        branchcode   => $branchcode,
56
        categorycode => $categorycode,
57
        flags        => 0,
58
        guarantorid    => $guarantor->{borrowernumber},
59
    }
60
});
61
my $librarian = $builder->build({
62
    source => 'Borrower',
63
    value => {
64
        branchcode   => $branchcode,
65
        categorycode => $categorycode,
66
        flags        => 16,
67
    }
68
});
69
70
my $session = C4::Auth::get_session('');
71
$session->param('number', $borrower->{ borrowernumber });
72
$session->param('id', $borrower->{ userid });
73
$session->param('ip', '127.0.0.1');
74
$session->param('lasttime', time());
75
$session->flush;
76
77
my $session2 = C4::Auth::get_session('');
78
$session2->param('number', $guarantor->{ borrowernumber });
79
$session2->param('id', $guarantor->{ userid });
80
$session2->param('ip', '127.0.0.1');
81
$session2->param('lasttime', time());
82
$session2->flush;
83
84
my $session_librarian = C4::Auth::get_session('');
85
$session_librarian->param('number', $librarian->{ borrowernumber });
86
$session_librarian->param('id', $librarian->{ userid });
87
$session_librarian->param('ip', '127.0.0.1');
88
$session_librarian->param('lasttime', time());
89
$session_librarian->flush;
90
91
t::lib::Mocks::mock_preference("AccessOwnObjectsInAPI", 1);
92
93
# User without permissions, but is the owner of the object
94
my $tx = $t->ua->build_tx(GET => "/api/v1/patrons/" . $borrower->{borrowernumber});
95
$tx->req->cookies({name => 'CGISESSID', value => $session->id});
96
$t->request_ok($tx)
97
  ->status_is(200);
98
99
# User without permissions, but is the guarantor of the owner of the object
100
$tx = $t->ua->build_tx(GET => "/api/v1/patrons/" . $borrower->{borrowernumber});
101
$tx->req->cookies({name => 'CGISESSID', value => $session2->id});
102
$t->request_ok($tx)
103
  ->status_is(200)
104
  ->json_is('/guarantorid', $guarantor->{borrowernumber});
105
106
t::lib::Mocks::mock_preference("AccessOwnObjectsInAPI", 0); # disable access to own objects
107
108
# User without permissions, accessing someone else
109
$tx = $t->ua->build_tx(GET => "/api/v1/patrons/" . $librarian->{borrowernumber});
110
$tx->req->cookies({name => 'CGISESSID', value => $session->id});
111
$t->request_ok($tx)
112
  ->status_is(403)
113
  ->json_like('/error', qr/^Authorization failure. Missing/);
114
115
# Librarian with borrowers flag, should always work
116
$tx = $t->ua->build_tx(GET => "/api/v1/patrons/" . $borrower->{borrowernumber});
117
$tx->req->cookies({name => 'CGISESSID', value => $session_librarian->id});
118
$t->request_ok($tx)
119
  ->status_is(200);
120
121
# User without permissions, but is the owner of the object
122
$tx = $t->ua->build_tx(GET => "/api/v1/patrons/" . $borrower->{borrowernumber});
123
$tx->req->cookies({name => 'CGISESSID', value => $session->id});
124
$t->request_ok($tx)
125
  ->status_is(403)
126
  ->json_like('/error', qr/^Functionality for accessing own objects has been disabled/);
127
128
# User without permissions, but is the guarantor of the owner of the object
129
$tx = $t->ua->build_tx(GET => "/api/v1/patrons/" . $borrower->{borrowernumber});
130
$tx->req->cookies({name => 'CGISESSID', value => $session2->id});
131
$t->request_ok($tx)
132
  ->status_is(403);

Return to bug 17424