@@ -, +, @@ where YYY is existing borrowernumber for a borrower that does not have any permissions --- Koha/REST/V1/Patron.pm | 4 +++- t/db_dependent/api/v1/patrons.t | 27 ++++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) --- a/Koha/REST/V1/Patron.pm +++ a/Koha/REST/V1/Patron.pm @@ -20,6 +20,7 @@ use Modern::Perl; use Mojo::Base 'Mojolicious::Controller'; use C4::Auth qw( haspermission checkpw_internal ); +use C4::Context; use Koha::Patrons; sub list { @@ -60,8 +61,9 @@ sub changepassword { my $user = $c->stash('koha.user'); my $patron = Koha::Patrons->find($args->{borrowernumber}); + my $OpacPasswordChange = C4::Context->preference("OpacPasswordChange"); unless ( $user - && ( $user->borrowernumber == $args->{borrowernumber} + && ( ($OpacPasswordChange && $user->borrowernumber == $args->{borrowernumber}) || haspermission($user->userid, {borrowers => 1}) ) ) { return $c->$cb({ error => "You don't have the required permission" }, 403); --- a/t/db_dependent/api/v1/patrons.t +++ a/t/db_dependent/api/v1/patrons.t @@ -17,7 +17,7 @@ use Modern::Perl; -use Test::More tests => 26; +use Test::More tests => 30; use Test::Mojo; use t::lib::TestBuilder; use t::lib::Mocks; @@ -45,6 +45,8 @@ my $borrower = $builder->build({ value => { branchcode => $branchcode, categorycode => $categorycode, + flags => 0, + password => Koha::AuthUtils::hash_password($password), } }); @@ -83,6 +85,13 @@ $session->param('ip', '127.0.0.1'); $session->param('lasttime', time()); $session->flush; +my $session_nopermission = C4::Auth::get_session(''); +$session_nopermission->param('number', $borrower->{ borrowernumber }); +$session_nopermission->param('id', $borrower->{ userid }); +$session_nopermission->param('ip', '127.0.0.1'); +$session_nopermission->param('lasttime', time()); +$session_nopermission->flush; + $tx = $t->ua->build_tx(GET => '/api/v1/patrons'); $tx->req->cookies({name => 'CGISESSID', value => $session->id}); $tx->req->env({REMOTE_ADDR => '127.0.0.1'}); @@ -125,4 +134,20 @@ $t->request_ok($tx) ->status_is(400) ->json_is('/error', "Password cannot contain trailing whitespaces."); +$password_obj = { + current_password => $password, + new_password => "new password", +}; +t::lib::Mocks::mock_preference("OpacPasswordChange", 0); +$tx = $t->ua->build_tx(PATCH => '/api/v1/patrons/'.$borrower->{borrowernumber}.'/password' => json => $password_obj); +$tx->req->cookies({name => 'CGISESSID', value => $session_nopermission->id}); +$t->request_ok($tx) + ->status_is(403); + +t::lib::Mocks::mock_preference("OpacPasswordChange", 1); +$tx = $t->ua->build_tx(PATCH => '/api/v1/patrons/'.$borrower->{borrowernumber}.'/password' => json => $password_obj); +$tx->req->cookies({name => 'CGISESSID', value => $session_nopermission->id}); +$t->request_ok($tx) + ->status_is(200); + $schema->storage->txn_rollback; --