diff --git a/Koha/REST/V1/Authorities.pm b/Koha/REST/V1/Authorities.pm
index b46be125b7..2bbab6a6a3 100644
--- a/Koha/REST/V1/Authorities.pm
+++ b/Koha/REST/V1/Authorities.pm
@@ -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;
diff --git a/api/v1/swagger/paths/authorities.yaml b/api/v1/swagger/paths/authorities.yaml
index 45a18cc217..b2a3b7f334 100644
--- a/api/v1/swagger/paths/authorities.yaml
+++ b/api/v1/swagger/paths/authorities.yaml
@@ -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"
diff --git a/t/db_dependent/api/v1/authorities.t b/t/db_dependent/api/v1/authorities.t
old mode 100755
new mode 100644
index 8c8056323b..9524d53614
--- a/t/db_dependent/api/v1/authorities.t
+++ b/t/db_dependent/api/v1/authorities.t
@@ -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|
+
+ 1001
+
+ 102
+ My Corporation
+
+|
+ } });
+
+ my $authid = $authority->authid;
+ my $authtypecode = $authority->authtypecode;
+
+ my $marcxml = q|
+
+ 1001
+
+ 102
+ MARCXML
+
+|;
+
+ 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;
+};