@@ -, +, @@ $ ktd --shell k$ prove t/db_dependent/api/v1/password_validation.t --- Koha/REST/V1/Auth/Password.pm | 30 +++++++++++++++------ api/v1/swagger/paths/auth.yaml | 20 +++++++++++--- t/db_dependent/api/v1/password_validation.t | 24 +++++++---------- 3 files changed, 48 insertions(+), 26 deletions(-) --- a/Koha/REST/V1/Auth/Password.pm +++ a/Koha/REST/V1/Auth/Password.pm @@ -40,19 +40,33 @@ Controller method that checks a patron's password sub validate { my $c = shift->openapi->valid_input or return; - my $body = $c->validation->param('body'); - my $userid = $body->{userid} // ''; - my $patron = Koha::Patrons->find({ userid => $userid }); - unless ($patron) { - return $c->render( status => 400, openapi => { error => "Validation failed" } ); + my $body = $c->req->json; + + my $identifier = $body->{identifier}; + my $userid = $body->{userid}; + + unless ( defined $identifier or defined $userid ) { + return $c->render( + status => 400, + openapi => { error => "Validation failed" }, + ); } - my $password = $body->{password} // ""; + if ( defined $identifier and defined $userid ) { + return $c->render( + status => 400, + openapi => { error => "Bad request. Only one identifier attribute can be passed." }, + ); + } + + $identifier //= $userid; + + my $password = $body->{password} // ""; return try { - my ($status, $cardnumber, $userid) = C4::Auth::checkpw($patron->userid, $password ); - unless ( $status ) { + my ( $status, $cardnumber, $userid ) = C4::Auth::checkpw( $identifier, $password ); + unless ($status) { return $c->render( status => 400, openapi => { error => "Validation failed" } --- a/api/v1/swagger/paths/auth.yaml +++ a/api/v1/swagger/paths/auth.yaml @@ -1062,18 +1062,30 @@ parameters: - name: body in: body - description: A JSON object containing username and password information + description: | + A JSON object containing a patron identifier and password information. + + The identifier will be used to match patrons on the database using the + following order: + + * userid + * cardnumber + + Optionally, you can specify the `userid` attribute if you don't want it + to be checked against the patron cardnumbers. schema: type: object properties: - userid: - description: Username + identifier: + description: A patron identifier (`userid` or `cardnumber`) type: string password: description: Password (plain text) type: string + userid: + description: A patron userid + type: string required: - - userid - password additionalProperties: false produces: --- a/t/db_dependent/api/v1/password_validation.t +++ a/t/db_dependent/api/v1/password_validation.t @@ -136,8 +136,7 @@ subtest 'Password validation - authorized requests tests' => sub { }; $t->post_ok( "//$userid:$password@/api/v1/auth/password/validation" => json => $json ) - ->status_is(204, 'Validating using `cardnumber` works') - ->content_is(q{}); + ->status_is( 204, 'Validating using `cardnumber` works' )->content_is(q{}); $json = { identifier => $librarian->cardnumber, @@ -145,8 +144,7 @@ subtest 'Password validation - authorized requests tests' => sub { }; $t->post_ok( "//$userid:$password@/api/v1/auth/password/validation" => json => $json ) - ->status_is(204, 'Validating using `cardnumber` works') - ->content_is(q{}); + ->status_is( 204, 'Validating using `cardnumber` works' )->content_is(q{}); $json = { identifier => $deleted_cardnumber, @@ -154,8 +152,8 @@ subtest 'Password validation - authorized requests tests' => sub { }; $t->post_ok( "//$userid:$password@/api/v1/auth/password/validation" => json => $json ) - ->status_is(400, 'Validating using and invalid identifier fails') - ->json_is({ error => 'Validation failed' }); + ->status_is( 400, 'Validating using and invalid identifier fails' ) + ->json_is( { error => 'Validation failed' } ); $json = { identifier => $deleted_userid, @@ -163,8 +161,8 @@ subtest 'Password validation - authorized requests tests' => sub { }; $t->post_ok( "//$userid:$password@/api/v1/auth/password/validation" => json => $json ) - ->status_is(400, 'Validating using and invalid identifier fails') - ->json_is({ error => 'Validation failed' }); + ->status_is( 400, 'Validating using and invalid identifier fails' ) + ->json_is( { error => 'Validation failed' } ); $json = { password => $password, @@ -172,8 +170,7 @@ subtest 'Password validation - authorized requests tests' => sub { }; $t->post_ok( "//$userid:$password@/api/v1/auth/password/validation" => json => $json ) - ->status_is(400, 'Validating using and invalid userid fails') - ->json_is({ error => 'Validation failed' }); + ->status_is( 400, 'Validating using and invalid userid fails' )->json_is( { error => 'Validation failed' } ); $json = { password => $password, @@ -181,8 +178,7 @@ subtest 'Password validation - authorized requests tests' => sub { }; $t->post_ok( "//$userid:$password@/api/v1/auth/password/validation" => json => $json ) - ->status_is(204, 'Validating using the `userid` attribute works') - ->content_is(q{}); + ->status_is( 204, 'Validating using the `userid` attribute works' )->content_is(q{}); $json = { identifier => $userid, @@ -191,8 +187,8 @@ subtest 'Password validation - authorized requests tests' => sub { }; $t->post_ok( "//$userid:$password@/api/v1/auth/password/validation" => json => $json ) - ->status_is(400, 'Passing both parameters forbidden') - ->json_is({ error => 'Bad request. Only one identifier attribute can be passed.' }); + ->status_is( 400, 'Passing both parameters forbidden' ) + ->json_is( { error => 'Bad request. Only one identifier attribute can be passed.' } ); $schema->storage->txn_rollback; }; --