Bug 31796: Add REST endpoint to modify an authority

To test:
1. Apply patch
2. Set RESTBasicAuth preference to true
3. Pick an authority to modify, and modify it's marc record
4. Make a PUT request to /api/v1/authorities/:authid with one of the following content type header
  - application/json
  - application/marcxml+xml
  - application/marc-in-json
  - application/marc
5. If content type is other than 'application/json' place the following header in the request 'x-authority-type: <auth type>'
5. Check that the authority was modified
6. Sign off

Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
This commit is contained in:
Agustin Moyano 2022-12-20 15:28:04 -03:00 committed by Tomas Cohen Arazi
parent 88000fbccb
commit b2801da206
No known key found for this signature in database
GPG Key ID: 0A272EA1B2F3C15F
3 changed files with 199 additions and 2 deletions

View File

@ -20,7 +20,7 @@ use Modern::Perl;
use Mojo::Base 'Mojolicious::Controller';
use Koha::Authorities;
use C4::AuthoritiesMarc qw( DelAuthority AddAuthority FindDuplicateAuthority);
use C4::AuthoritiesMarc qw( DelAuthority AddAuthority FindDuplicateAuthority ModAuthority);
use List::MoreUtils qw( any );
use MARC::Record::MiJ;
@ -193,4 +193,64 @@ sub add {
};
}
=head3 update
Controller function that handles modifying an authority object
=cut
sub update {
my $c = shift->openapi->valid_input or return;
my $authid = $c->validation->param('authority_id');
my $authority = Koha::Authorities->find( { authid => $authid } );
if ( not defined $authority ) {
return $c->render(
status => 404,
openapi => { error => "Object not found" }
);
}
try {
my $headers = $c->req->headers;
my $flavour =
C4::Context->preference('marcflavour') eq 'UNIMARC'
? 'UNIMARCAUTH'
: 'MARC21';
my $record;
my $authtypecode = $headers->header('x-authority-type') || $authority->authtypecode;
if ( $c->req->headers->content_type =~ m/application\/marcxml\+xml/ ) {
$record = MARC::Record->new_from_xml( $c->req->body, 'UTF-8', $flavour );
} elsif ( $c->req->headers->content_type =~ m/application\/marc-in-json/ ) {
$record = MARC::Record->new_from_mij_structure( $c->req->json );
} elsif ( $c->req->headers->content_type =~ m/application\/marc/ ) {
$record = MARC::Record->new_from_usmarc( $c->req->body );
} else {
return $c->render(
status => 406,
openapi => [
"application/json",
"application/marcxml+xml",
"application/marc-in-json",
"application/marc"
]
);
}
my $authid = ModAuthority( $authid, $record, $authtypecode );
$c->render(
status => 200,
openapi => { id => $authid }
);
}
catch {
$c->unhandled_exception($_);
};
}
1;

View File

@ -163,3 +163,54 @@
x-koha-authorization:
permissions:
editauthorities: "1"
put:
x-mojo-to: Authorities#update
operationId: updateAuthority
tags:
- authorities
summary: Update authority
parameters:
- $ref: "../swagger.yaml#/parameters/authority_id_pp"
- $ref: "../swagger.yaml#/parameters/authority_type_header"
produces:
- application/json
responses:
"200":
description: An authority id
"400":
description: Bad request
schema:
$ref: "../swagger.yaml#/definitions/error"
"401":
description: Authentication required
schema:
$ref: "../swagger.yaml#/definitions/error"
"403":
description: Access forbidden
schema:
$ref: "../swagger.yaml#/definitions/error"
"404":
description: Authority not found
schema:
$ref: "../swagger.yaml#/definitions/error"
"406":
description: Not acceptable
schema:
type: array
description: Accepted content-types
items:
type: string
"500":
description: |
Internal server error. Possible `error_code` attribute values:
* `internal_server_error`
schema:
$ref: "../swagger.yaml#/definitions/error"
"503":
description: Under maintenance
schema:
$ref: "../swagger.yaml#/definitions/error"
x-koha-authorization:
permissions:
editauthorities: "1"

88
t/db_dependent/api/v1/authorities.t Executable file → Normal file
View File

@ -20,7 +20,7 @@ use Modern::Perl;
use utf8;
use Encode;
use Test::More tests => 3;
use Test::More tests => 4;
use Test::MockModule;
use Test::Mojo;
use Test::Warn;
@ -228,3 +228,89 @@ subtest 'post() tests' => sub {
$schema->storage->txn_rollback;
};
subtest 'put() tests' => sub {
plan tests => 14;
$schema->storage->txn_begin;
Koha::Authorities->delete;
my $record;
my $subfield_a;
my $patron = $builder->build_object(
{
class => 'Koha::Patrons',
value => { flags => 0 } # no permissions
}
);
my $password = 'thePassword123';
$patron->set_password( { password => $password, skip_validation => 1 } );
my $userid = $patron->userid;
my $authority = $builder->build_object({ 'class' => 'Koha::Authorities', value => {
marcxml => q|<?xml version="1.0" encoding="UTF-8"?>
<record xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.loc.gov/MARC21/slim" xsi:schemaLocation="http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd">
<controlfield tag="001">1001</controlfield>
<datafield tag="110" ind1=" " ind2=" ">
<subfield code="9">102</subfield>
<subfield code="a">My Corporation</subfield>
</datafield>
</record>|
} });
my $authid = $authority->authid;
my $authtypecode = $authority->authtypecode;
my $marcxml = q|<?xml version="1.0" encoding="UTF-8"?>
<record xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.loc.gov/MARC21/slim" xsi:schemaLocation="http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd">
<controlfield tag="001">1001</controlfield>
<datafield tag="110" ind1=" " ind2=" ">
<subfield code="9">102</subfield>
<subfield code="a">MARCXML</subfield>
</datafield>
</record>|;
my $mij = '{"fields":[{"001":"1001"},{"110":{"subfields":[{"9":"102"},{"a":"MIJ"}],"ind1":" ","ind2":" "}}],"leader":" "}';
my $marc = '00079 2200049 45000010005000001100024000051001 9102aUSMARCFormated';
$t->put_ok("//$userid:$password@/api/v1/authorities/$authid")
->status_is(403, 'Not enough permissions makes it return the right code');
# Add permissions
$patron->flags( 2 ** 14 )->store; # 14 => editauthorities userflag
$t->put_ok("//$userid:$password@/api/v1/authorities/$authid" => {'Content-Type' => 'application/marcxml+xml', 'x-authority-type' => $authtypecode} => $marcxml)
->status_is(200)
->json_has('/id');
$authority = Koha::Authorities->find($authid);
$record = $authority->record;
$subfield_a = $record->subfield('110', 'a');
is($subfield_a, 'MARCXML');
$t->put_ok("//$userid:$password@/api/v1/authorities/$authid" => {'Content-Type' => 'application/marc-in-json', 'x-authority-type' => $authtypecode} => $mij)
->status_is(200)
->json_has('/id');
$authority = Koha::Authorities->find($authid);
$record = $authority->record;
$subfield_a = $record->subfield('110', 'a');
is($subfield_a, 'MIJ');
$t->put_ok("//$userid:$password@/api/v1/authorities/$authid" => {'Content-Type' => 'application/marc', 'x-authority-type' => $authtypecode} => $marc)
->status_is(200)
->json_has('/id');
$authority = Koha::Authorities->find($authid);
$record = $authority->record;
$subfield_a = $record->subfield('110', 'a');
is($subfield_a, 'USMARCFormated');
$schema->storage->txn_rollback;
};