From 27951dabec81b4b5cf1dd039b3ec4415430cb52c Mon Sep 17 00:00:00 2001 From: Nick Clemens Date: Mon, 14 Feb 2022 16:00:23 +0000 Subject: [PATCH] Bug 29926: Add pasword expiration route for API To test: 1 - prove -v t/db_dependent/api/v1/patrons_password_expiration.t Signed-off-by: Bob Bennhoff --- Koha/REST/V1/Patrons/Password/Expiration.pm | 65 +++++++++++++ .../paths/patrons_password_expiration.yaml | 57 +++++++++++ api/v1/swagger/swagger.yaml | 2 + .../api/v1/patrons_password_expiration.t | 96 +++++++++++++++++++ 4 files changed, 220 insertions(+) create mode 100644 Koha/REST/V1/Patrons/Password/Expiration.pm create mode 100644 api/v1/swagger/paths/patrons_password_expiration.yaml create mode 100755 t/db_dependent/api/v1/patrons_password_expiration.t diff --git a/Koha/REST/V1/Patrons/Password/Expiration.pm b/Koha/REST/V1/Patrons/Password/Expiration.pm new file mode 100644 index 0000000000..de0abb748f --- /dev/null +++ b/Koha/REST/V1/Patrons/Password/Expiration.pm @@ -0,0 +1,65 @@ +package Koha::REST::V1::Patrons::Password::Expiration; + +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use Mojo::Base 'Mojolicious::Controller'; + +use Koha::Patrons; +use Koha::DateUtils qw(dt_from_string); + +use Scalar::Util qw( blessed ); +use Try::Tiny qw( catch try ); + +=head1 NAME + +Koha::REST::V1::Patrons::Password::Expiration + +=head1 API + +=head2 Methods + +=head3 set + +Controller method that sets a patron's password expiration + +=cut + +sub set { + + my $c = shift->openapi->valid_input or return; + + my $patron = Koha::Patrons->find( $c->validation->param('patron_id') ); + my $body = $c->validation->param('body'); + + unless ($patron) { + return $c->render( status => 404, openapi => { error => "Patron not found." } ); + } + + my $password_expiration_date = $body->{expiration_date} // ""; + + return try { + my $pw_expiration_dt = dt_from_string($password_expiration_date); + $patron->password_expiration_date( $pw_expiration_dt)->store(); + return $c->render( status => 200, openapi => "" ); + } + catch { + $c->unhandled_exception($_); + }; +} + +1; diff --git a/api/v1/swagger/paths/patrons_password_expiration.yaml b/api/v1/swagger/paths/patrons_password_expiration.yaml new file mode 100644 index 0000000000..87f7a8a037 --- /dev/null +++ b/api/v1/swagger/paths/patrons_password_expiration.yaml @@ -0,0 +1,57 @@ +--- +"/patrons/{patron_id}/password/expiration": + post: + x-mojo-to: Patrons::Password::Expiration#set + operationId: setPatronPasswordExpiration + tags: + - patrons + summary: Set password expiration for a patron + parameters: + - $ref: ../parameters.yaml#/patron_id_pp + - name: body + in: body + description: A JSON object containing password expiration date + schema: + type: object + properties: + expiration_date: + description: Date to expire password + type: string + required: + - expiration_date + additionalProperties: false + produces: + - application/json + responses: + "200": + description: Password expiration changed + "400": + description: Bad request + schema: + $ref: ../definitions.yaml#/error + "401": + description: Authentication required + schema: + $ref: ../definitions.yaml#/error + "403": + description: Access forbidden + schema: + $ref: ../definitions.yaml#/error + "404": + description: Patron not found + schema: + $ref: ../definitions.yaml#/error + "500": + description: | + Internal server error. Possible `error_code` attribute values: + + * `internal_server_error` + schema: + $ref: ../definitions.yaml#/error + "503": + description: Under maintenance + schema: + $ref: ../definitions.yaml#/error + x-koha-authorization: + permissions: + superlibrarian: "1" diff --git a/api/v1/swagger/swagger.yaml b/api/v1/swagger/swagger.yaml index 7ffd64d52a..bb8c9ac120 100644 --- a/api/v1/swagger/swagger.yaml +++ b/api/v1/swagger/swagger.yaml @@ -173,6 +173,8 @@ paths: $ref: "./paths/patrons_holds.yaml#/~1patrons~1{patron_id}~1holds" "/patrons/{patron_id}/password": $ref: "./paths/patrons_password.yaml#/~1patrons~1{patron_id}~1password" + "/patrons/{patron_id}/password/expiration": + $ref: "./paths/patrons_password_expiration.yaml#/~1patrons~1{patron_id}~1password~1expiration" "/public/biblios/{biblio_id}": $ref: "./paths/biblios.yaml#/~1public~1biblios~1{biblio_id}" "/public/biblios/{biblio_id}/items": diff --git a/t/db_dependent/api/v1/patrons_password_expiration.t b/t/db_dependent/api/v1/patrons_password_expiration.t new file mode 100755 index 0000000000..ae5e4c1bbc --- /dev/null +++ b/t/db_dependent/api/v1/patrons_password_expiration.t @@ -0,0 +1,96 @@ +#!/usr/bin/perl + +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use Test::More tests => 1; + +use Test::Mojo; + +use t::lib::TestBuilder; +use t::lib::Mocks; + +use Koha::Patrons; + +my $schema = Koha::Database->new->schema; +my $builder = t::lib::TestBuilder->new; + +t::lib::Mocks::mock_preference( 'RESTBasicAuth', 1 ); + +my $t = Test::Mojo->new('Koha::REST::V1'); + +subtest 'basic tests' => sub { + + plan tests => 12; + + $schema->storage->txn_begin; + + my $privileged_patron = $builder->build_object( + { + class => 'Koha::Patrons', + value => { flags => 1 } + } + ); + my $password = 'thePassword123'; + $privileged_patron->set_password( + { password => $password, skip_validation => 1 } ); + my $userid = $privileged_patron->userid; + + my $patron = $builder->build_object( { class => 'Koha::Patrons' } ); + + t::lib::Mocks::mock_preference( 'dateformat','us' ); + + my $new_password = 'abc'; + + $t->post_ok( "//$userid:$password@/api/v1/patrons/" + . $patron->id + . "/password/expiration" => json => + { expiration_date => '2021-01-01' } ) + ->status_is(200)->json_is(''); + + $t->post_ok( "//$userid:$password@/api/v1/patrons/" + . $patron->id + . "/password/expiration" => json => + { expiration_date => '01/13/2021' } ) + ->status_is(200)->json_is(''); + + $t->post_ok( "//$userid:$password@/api/v1/patrons/" + . $patron->id + . "/password/expiration" => json => + { expiration_date => '13/01/2021' } ) + ->status_is(500)->json_is({ + error => 'Something went wrong, check Koha logs for details.', + error_code => "internal_server_error" + }); + + $privileged_patron->flags(0)->store(); + + $t->post_ok( "//$userid:$password@/api/v1/patrons/" + . $patron->id + . "/password/expiration" => json => + { expiration_date => '2021-01-01' } ) + ->status_is(403)->json_is({ + error => "Authorization failure. Missing required permission(s).", + "required_permissions" => { + "superlibrarian" => "1" + } + }); + + + + $schema->storage->txn_rollback; +}; -- 2.30.2