Browse Source
Signed-off-by: Andrew Fuerste-Henry <andrew@bywatersolutions.com> Signed-off-by: Heather Hernandez <Heather_Hernandez@nps.gov> Signed-off-by: Katrin Fischer <katrin.fischer.83@web.de> Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>20.05.x
11 changed files with 1558 additions and 0 deletions
@ -0,0 +1,57 @@ |
|||
package Koha::AdvancedEditorMacro; |
|||
|
|||
# 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, write to the Free Software Foundation, Inc., |
|||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
|||
|
|||
use Modern::Perl; |
|||
|
|||
use Carp; |
|||
|
|||
use Koha::Database; |
|||
|
|||
use base qw(Koha::Object); |
|||
|
|||
=head1 NAME |
|||
|
|||
Koha::AdvancedEditorMacro - Koha Advanced Editor Macro Object class |
|||
|
|||
=head1 API |
|||
|
|||
=head2 Class methods |
|||
|
|||
=head3 to_api_mapping |
|||
|
|||
=cut |
|||
|
|||
sub to_api_mapping { |
|||
return { |
|||
id => 'macro_id', |
|||
macro => 'macro_text', |
|||
borrowernumber => 'patron_id', |
|||
}; |
|||
} |
|||
|
|||
|
|||
=head2 Internal methods |
|||
|
|||
=head3 _type |
|||
|
|||
=cut |
|||
|
|||
sub _type { |
|||
return 'AdvancedEditorMacro'; |
|||
} |
|||
|
|||
1; |
@ -0,0 +1,50 @@ |
|||
package Koha::AdvancedEditorMacros; |
|||
|
|||
# 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, write to the Free Software Foundation, Inc., |
|||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
|||
|
|||
use Modern::Perl; |
|||
|
|||
use Carp; |
|||
|
|||
use Koha::Database; |
|||
|
|||
use Koha::AdvancedEditorMacro; |
|||
|
|||
use base qw(Koha::Objects); |
|||
|
|||
=head1 NAME |
|||
|
|||
Koha::AdvancedEditorMacros - Koha Advanced Editor Macro Object set class |
|||
|
|||
=head1 API |
|||
|
|||
=head2 Class Methods |
|||
|
|||
=cut |
|||
|
|||
=head3 type |
|||
|
|||
=cut |
|||
|
|||
sub _type { |
|||
return 'AdvancedEditorMacro'; |
|||
} |
|||
|
|||
sub object_class { |
|||
return 'Koha::AdvancedEditorMacro'; |
|||
} |
|||
|
|||
1; |
@ -0,0 +1,397 @@ |
|||
package Koha::REST::V1::AdvancedEditorMacro; |
|||
|
|||
# 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, write to the Free Software Foundation, Inc., |
|||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
|||
|
|||
use Modern::Perl; |
|||
|
|||
use Mojo::Base 'Mojolicious::Controller'; |
|||
use Koha::AdvancedEditorMacros; |
|||
|
|||
use Try::Tiny; |
|||
|
|||
=head1 API |
|||
|
|||
=head2 Class Methods |
|||
|
|||
=cut |
|||
|
|||
=head3 list |
|||
|
|||
Controller function that handles listing Koha::AdvancedEditorMacro objects |
|||
|
|||
=cut |
|||
|
|||
sub list { |
|||
my $c = shift->openapi->valid_input or return; |
|||
my $patron = $c->stash('koha.user'); |
|||
return try { |
|||
my $macros_set = Koha::AdvancedEditorMacros->search({ -or => { shared => 1, borrowernumber => $patron->borrowernumber } }); |
|||
my $macros = $c->objects->search( $macros_set, \&_to_model, \&_to_api ); |
|||
return $c->render( status => 200, openapi => $macros ); |
|||
} |
|||
catch { |
|||
if ( $_->isa('DBIx::Class::Exception') ) { |
|||
return $c->render( status => 500, |
|||
openapi => { error => $_->{msg} } ); |
|||
} |
|||
else { |
|||
return $c->render( status => 500, |
|||
openapi => { error => "Something went wrong, check the logs. $_"} ); |
|||
} |
|||
}; |
|||
|
|||
} |
|||
|
|||
=head3 get |
|||
|
|||
Controller function that handles retrieving a single Koha::AdvancedEditorMacro |
|||
|
|||
=cut |
|||
|
|||
sub get { |
|||
my $c = shift->openapi->valid_input or return; |
|||
my $patron = $c->stash('koha.user'); |
|||
my $macro = Koha::AdvancedEditorMacros->find({ |
|||
id => $c->validation->param('advancededitormacro_id'), |
|||
}); |
|||
unless ($macro) { |
|||
return $c->render( status => 404, |
|||
openapi => { error => "Macro not found" } ); |
|||
} |
|||
if( $macro->shared ){ |
|||
return $c->render( status => 403, openapi => { |
|||
error => "This macro is shared, you must access it via advancededitormacros/shared" |
|||
}); |
|||
} |
|||
warn $macro->borrowernumber; |
|||
warn $patron->borrowernumber; |
|||
if( $macro->borrowernumber != $patron->borrowernumber ){ |
|||
return $c->render( status => 403, openapi => { |
|||
error => "You do not have permission to access this macro" |
|||
}); |
|||
} |
|||
|
|||
return $c->render( status => 200, openapi => $macro->to_api ); |
|||
} |
|||
|
|||
=head3 get_shared |
|||
|
|||
Controller function that handles retrieving a single Koha::AdvancedEditorMacro |
|||
|
|||
=cut |
|||
|
|||
sub get_shared { |
|||
my $c = shift->openapi->valid_input or return; |
|||
my $patron = $c->stash('koha.user'); |
|||
my $macro = Koha::AdvancedEditorMacros->find({ |
|||
id => $c->validation->param('advancededitormacro_id'), |
|||
}); |
|||
unless ($macro) { |
|||
return $c->render( status => 404, |
|||
openapi => { error => "Macro not found" } ); |
|||
} |
|||
unless( $macro->shared ){ |
|||
return $c->render( status => 403, openapi => { |
|||
error => "This macro is not shared, you must access it via advancededitormacros" |
|||
}); |
|||
} |
|||
return $c->render( status => 200, openapi => $macro->to_api ); |
|||
} |
|||
|
|||
=head3 add |
|||
|
|||
Controller function that handles adding a new Koha::AdvancedEditorMacro object |
|||
|
|||
=cut |
|||
|
|||
sub add { |
|||
my $c = shift->openapi->valid_input or return; |
|||
|
|||
if( defined $c->validation->param('body')->{shared} && $c->validation->param('body')->{shared} == 1 ){ |
|||
return $c->render( status => 403, |
|||
openapi => { error => "To create shared macros you must use advancededitor/shared" } ); |
|||
} |
|||
|
|||
return try { |
|||
my $macro = Koha::AdvancedEditorMacro->new( _to_model( $c->validation->param('body') ) ); |
|||
$macro->store; |
|||
$c->res->headers->location( $c->req->url->to_string . '/' . $macro->id ); |
|||
return $c->render( |
|||
status => 201, |
|||
openapi => $macro->to_api |
|||
); |
|||
} |
|||
catch { handle_error($_) }; |
|||
} |
|||
|
|||
=head3 add_shared |
|||
|
|||
Controller function that handles adding a new shared Koha::AdvancedEditorMacro object |
|||
|
|||
=cut |
|||
|
|||
sub add_shared { |
|||
my $c = shift->openapi->valid_input or return; |
|||
|
|||
unless( defined $c->validation->param('body')->{shared} && $c->validation->param('body')->{shared} == 1 ){ |
|||
return $c->render( status => 403, |
|||
openapi => { error => "To create private macros you must use advancededitor" } ); |
|||
} |
|||
|
|||
return try { |
|||
my $macro = Koha::AdvancedEditorMacro->new( _to_model( $c->validation->param('body') ) ); |
|||
$macro->store; |
|||
$c->res->headers->location( $c->req->url->to_string . '/' . $macro->id ); |
|||
return $c->render( |
|||
status => 201, |
|||
openapi => $macro->to_api |
|||
); |
|||
} |
|||
catch { handle_error($_) }; |
|||
} |
|||
|
|||
=head3 update |
|||
|
|||
Controller function that handles updating a Koha::AdvancedEditorMacro object |
|||
|
|||
=cut |
|||
|
|||
sub update { |
|||
my $c = shift->openapi->valid_input or return; |
|||
|
|||
my $macro = Koha::AdvancedEditorMacros->find( $c->validation->param('advancededitormacro_id') ); |
|||
|
|||
if ( not defined $macro ) { |
|||
return $c->render( status => 404, |
|||
openapi => { error => "Object not found" } ); |
|||
} |
|||
my $patron = $c->stash('koha.user'); |
|||
|
|||
if( $macro->shared == 1 || defined $c->validation->param('body')->{shared} && $c->validation->param('body')->{shared} == 1 ){ |
|||
return $c->render( status => 403, |
|||
openapi => { error => "To update a macro as shared you must use the advancededitormacros/shared endpoint" } ); |
|||
} else { |
|||
unless ( $macro->borrowernumber == $patron->borrowernumber ){ |
|||
return $c->render( status => 403, |
|||
openapi => { error => "You can only edit macros you own" } ); |
|||
} |
|||
} |
|||
|
|||
return try { |
|||
my $params = $c->req->json; |
|||
$macro->set( _to_model($params) ); |
|||
$macro->store(); |
|||
return $c->render( status => 200, openapi => $macro->to_api ); |
|||
} |
|||
catch { handle_error($_) }; |
|||
} |
|||
|
|||
=head3 update_shared |
|||
|
|||
Controller function that handles updating a shared Koha::AdvancedEditorMacro object |
|||
|
|||
=cut |
|||
|
|||
sub update_shared { |
|||
my $c = shift->openapi->valid_input or return; |
|||
|
|||
my $macro = Koha::AdvancedEditorMacros->find( $c->validation->param('advancededitormacro_id') ); |
|||
|
|||
if ( not defined $macro ) { |
|||
return $c->render( status => 404, |
|||
openapi => { error => "Object not found" } ); |
|||
} |
|||
|
|||
unless( $macro->shared == 1 || defined $c->validation->param('body')->{shared} && $c->validation->param('body')->{shared} == 1 ){ |
|||
return $c->render( status => 403, |
|||
openapi => { error => "You can only update shared macros using this endpoint" } ); |
|||
} |
|||
|
|||
return try { |
|||
my $params = $c->req->json; |
|||
$macro->set( _to_model($params) ); |
|||
$macro->store(); |
|||
return $c->render( status => 200, openapi => $macro->to_api ); |
|||
} |
|||
catch { handle_error($_) }; |
|||
} |
|||
|
|||
=head3 delete |
|||
|
|||
Controller function that handles deleting a Koha::AdvancedEditorMacro object |
|||
|
|||
=cut |
|||
|
|||
sub delete { |
|||
my $c = shift->openapi->valid_input or return; |
|||
|
|||
my $macro = Koha::AdvancedEditorMacros->find( $c->validation->param('advancededitormacro_id') ); |
|||
if ( not defined $macro ) { |
|||
return $c->render( status => 404, |
|||
openapi => { error => "Object not found" } ); |
|||
} |
|||
|
|||
my $patron = $c->stash('koha.user'); |
|||
if( $macro->shared == 1 ){ |
|||
return $c->render( status => 403, |
|||
openapi => { error => "You cannot delete shared macros using this endpoint" } ); |
|||
} else { |
|||
unless ( $macro->borrowernumber == $patron->borrowernumber ){ |
|||
return $c->render( status => 403, |
|||
openapi => { error => "You can only delete macros you own" } ); |
|||
} |
|||
} |
|||
|
|||
return try { |
|||
$macro->delete; |
|||
return $c->render( status => 200, openapi => "" ); |
|||
} |
|||
catch { handle_error($_) }; |
|||
} |
|||
|
|||
=head3 delete_shared |
|||
|
|||
Controller function that handles deleting a shared Koha::AdvancedEditorMacro object |
|||
|
|||
=cut |
|||
|
|||
sub delete_shared { |
|||
my $c = shift->openapi->valid_input or return; |
|||
|
|||
my $macro = Koha::AdvancedEditorMacros->find( $c->validation->param('advancededitormacro_id') ); |
|||
if ( not defined $macro ) { |
|||
return $c->render( status => 404, |
|||
openapi => { error => "Object not found" } ); |
|||
} |
|||
|
|||
unless( $macro->shared == 1 ){ |
|||
return $c->render( status => 403, |
|||
openapi => { error => "You can only delete shared macros using this endpoint" } ); |
|||
} |
|||
|
|||
return try { |
|||
$macro->delete; |
|||
return $c->render( status => 200, openapi => "" ); |
|||
} |
|||
catch { handle_error($_,$c) }; |
|||
} |
|||
|
|||
=head3 _handle_error |
|||
|
|||
Helper function that passes exception or error |
|||
|
|||
=cut |
|||
|
|||
sub _handle_error { |
|||
my ($err,$c) = @_; |
|||
if ( $err->isa('DBIx::Class::Exception') ) { |
|||
return $c->render( status => 500, |
|||
openapi => { error => $err->{msg} } ); |
|||
} |
|||
else { |
|||
return $c->render( status => 500, |
|||
openapi => { error => "Something went wrong, check the logs."} ); |
|||
} |
|||
}; |
|||
|
|||
|
|||
=head3 _to_api |
|||
|
|||
Helper function that maps a hashref of Koha::AdvancedEditorMacro attributes into REST api |
|||
attribute names. |
|||
|
|||
=cut |
|||
|
|||
sub _to_api { |
|||
my $macro = shift; |
|||
|
|||
# Rename attributes |
|||
foreach my $column ( keys %{ $Koha::REST::V1::AdvancedEditorMacro::to_api_mapping } ) { |
|||
my $mapped_column = $Koha::REST::V1::AdvancedEditorMacro::to_api_mapping->{$column}; |
|||
if ( exists $macro->{ $column } |
|||
&& defined $mapped_column ) |
|||
{ |
|||
# key /= undef |
|||
$macro->{ $mapped_column } = delete $macro->{ $column }; |
|||
} |
|||
elsif ( exists $macro->{ $column } |
|||
&& !defined $mapped_column ) |
|||
{ |
|||
# key == undef => to be deleted |
|||
delete $macro->{ $column }; |
|||
} |
|||
} |
|||
|
|||
return $macro; |
|||
} |
|||
|
|||
=head3 _to_model |
|||
|
|||
Helper function that maps REST api objects into Koha::AdvancedEditorMacros |
|||
attribute names. |
|||
|
|||
=cut |
|||
|
|||
sub _to_model { |
|||
my $macro = shift; |
|||
|
|||
foreach my $attribute ( keys %{ $Koha::REST::V1::AdvancedEditorMacro::to_model_mapping } ) { |
|||
my $mapped_attribute = $Koha::REST::V1::AdvancedEditorMacro::to_model_mapping->{$attribute}; |
|||
if ( exists $macro->{ $attribute } |
|||
&& defined $mapped_attribute ) |
|||
{ |
|||
# key /= undef |
|||
$macro->{ $mapped_attribute } = delete $macro->{ $attribute }; |
|||
} |
|||
elsif ( exists $macro->{ $attribute } |
|||
&& !defined $mapped_attribute ) |
|||
{ |
|||
# key == undef => to be deleted |
|||
delete $macro->{ $attribute }; |
|||
} |
|||
} |
|||
|
|||
if ( exists $macro->{shared} ) { |
|||
$macro->{shared} = ($macro->{shared}) ? 1 : 0; |
|||
} |
|||
|
|||
|
|||
return $macro; |
|||
} |
|||
|
|||
=head2 Global variables |
|||
|
|||
=head3 $to_api_mapping |
|||
|
|||
=cut |
|||
|
|||
our $to_api_mapping = { |
|||
id => 'macro_id', |
|||
macro => 'macro_text', |
|||
borrowernumber => 'patron_id', |
|||
}; |
|||
|
|||
=head3 $to_model_mapping |
|||
|
|||
=cut |
|||
|
|||
our $to_model_mapping = { |
|||
macro_id => 'id', |
|||
macro_text => 'macro', |
|||
patron_id => 'borrowernumber', |
|||
}; |
|||
|
|||
1; |
@ -0,0 +1,26 @@ |
|||
{ |
|||
"type": "object", |
|||
"properties": { |
|||
"macro_id": { |
|||
"$ref": "../x-primitives.json#/advancededitormacro_id" |
|||
}, |
|||
"name": { |
|||
"description": "macro name", |
|||
"type": "string" |
|||
}, |
|||
"macro_text": { |
|||
"description": "macro text", |
|||
"type": ["string", "null"] |
|||
}, |
|||
"patron_id": { |
|||
"description": "borrower number", |
|||
"type": ["integer", "null"] |
|||
}, |
|||
"shared": { |
|||
"description": "is macro shared", |
|||
"type": ["boolean", "null"] |
|||
} |
|||
}, |
|||
"additionalProperties": false, |
|||
"required": ["name", "macro_text", "patron_id", "shared"] |
|||
} |
@ -0,0 +1,9 @@ |
|||
{ |
|||
"advancededitormacro_id_pp": { |
|||
"name": "advancededitormacro_id", |
|||
"in": "path", |
|||
"description": "Advanced Editor Macro internal identifier", |
|||
"required": true, |
|||
"type": "integer" |
|||
} |
|||
} |
@ -0,0 +1,521 @@ |
|||
{ |
|||
"/advancededitormacros": { |
|||
"get": { |
|||
"x-mojo-to": "AdvancedEditorMacro#list", |
|||
"operationId": "listMacro", |
|||
"tags": ["advancededitormacro"], |
|||
"produces": [ |
|||
"application/json" |
|||
], |
|||
"parameters": [ |
|||
{ |
|||
"name": "name", |
|||
"in": "query", |
|||
"description": "Case insensative search on macro name", |
|||
"required": false, |
|||
"type": "string" |
|||
}, |
|||
{ |
|||
"name": "macro_text", |
|||
"in": "query", |
|||
"description": "Case insensative search on macro text", |
|||
"required": false, |
|||
"type": "string" |
|||
}, |
|||
{ |
|||
"name": "patron_id", |
|||
"in": "query", |
|||
"description": "Search on internal patron_id", |
|||
"required": false, |
|||
"type": "string" |
|||
}, |
|||
{ |
|||
"name": "shared", |
|||
"in": "query", |
|||
"description": "Search on shared macros", |
|||
"required": false, |
|||
"type": "string" |
|||
} |
|||
], |
|||
"responses": { |
|||
"200": { |
|||
"description": "A list of macros", |
|||
"schema": { |
|||
"type": "array", |
|||
"items": { |
|||
"$ref": "../definitions.json#/advancededitormacro" |
|||
} |
|||
} |
|||
}, |
|||
"403": { |
|||
"description": "Access forbidden", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
}, |
|||
"500": { |
|||
"description": "Internal error", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
}, |
|||
"503": { |
|||
"description": "Under maintenance", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
} |
|||
}, |
|||
"x-koha-authorization": { |
|||
"permissions": { |
|||
"editcatalogue": "advanced_editor" |
|||
} |
|||
} |
|||
}, |
|||
"post": { |
|||
"x-mojo-to": "AdvancedEditorMacro#add", |
|||
"operationId": "addAdvancedEditorMacro", |
|||
"tags": ["advancededitormacro"], |
|||
"parameters": [{ |
|||
"name": "body", |
|||
"in": "body", |
|||
"description": "A JSON object containing informations about the new macro", |
|||
"required": true, |
|||
"schema": { |
|||
"$ref": "../definitions.json#/advancededitormacro" |
|||
} |
|||
}], |
|||
"produces": [ |
|||
"application/json" |
|||
], |
|||
"responses": { |
|||
"201": { |
|||
"description": "Macro added", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/advancededitormacro" |
|||
} |
|||
}, |
|||
"401": { |
|||
"description": "Authentication required", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
}, |
|||
"403": { |
|||
"description": "Access forbidden", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
}, |
|||
"500": { |
|||
"description": "Internal error", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
}, |
|||
"503": { |
|||
"description": "Under maintenance", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
} |
|||
}, |
|||
"x-koha-authorization": { |
|||
"permissions": { |
|||
"editcatalogue": "advanced_editor" |
|||
} |
|||
} |
|||
} |
|||
}, |
|||
"/advancededitormacros/shared": { |
|||
"post": { |
|||
"x-mojo-to": "AdvancedEditorMacro#add_shared", |
|||
"operationId": "addsharedAdvancedEditorMacro", |
|||
"tags": ["advancededitormacro"], |
|||
"parameters": [{ |
|||
"name": "body", |
|||
"in": "body", |
|||
"description": "A JSON object containing informations about the new macro", |
|||
"required": true, |
|||
"schema": { |
|||
"$ref": "../definitions.json#/advancededitormacro" |
|||
} |
|||
}], |
|||
"produces": [ |
|||
"application/json" |
|||
], |
|||
"responses": { |
|||
"201": { |
|||
"description": "Macro added", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/advancededitormacro" |
|||
} |
|||
}, |
|||
"401": { |
|||
"description": "Authentication required", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
}, |
|||
"403": { |
|||
"description": "Access forbidden", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
}, |
|||
"500": { |
|||
"description": "Internal error", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
}, |
|||
"503": { |
|||
"description": "Under maintenance", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
} |
|||
}, |
|||
"x-koha-authorization": { |
|||
"permissions": { |
|||
"editcatalogue": "advanced_editor", |
|||
"editcatalogue": "create_shared_macros" |
|||
} |
|||
} |
|||
} |
|||
}, |
|||
"/advancededitormacros/{advancededitormacro_id}": { |
|||
"get": { |
|||
"x-mojo-to": "AdvancedEditorMacro#get", |
|||
"operationId": "getAdvancedEditorMacro", |
|||
"tags": ["advancededitormacros"], |
|||
"parameters": [{ |
|||
"$ref": "../parameters.json#/advancededitormacro_id_pp" |
|||
}], |
|||
"produces": [ |
|||
"application/json" |
|||
], |
|||
"responses": { |
|||
"200": { |
|||
"description": "A macro", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/advancededitormacro" |
|||
} |
|||
}, |
|||
"403": { |
|||
"description": "Access forbidden", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
}, |
|||
"404": { |
|||
"description": "AdvancedEditorMacro not found", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
}, |
|||
"500": { |
|||
"description": "Internal error", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
}, |
|||
"503": { |
|||
"description": "Under maintenance", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
} |
|||
}, |
|||
"x-koha-authorization": { |
|||
"permissions": { |
|||
"editcatalogue": "advanced_editor" |
|||
} |
|||
} |
|||
}, |
|||
"put": { |
|||
"x-mojo-to": "AdvancedEditorMacro#update", |
|||
"operationId": "updateAdvancedEditorMacro", |
|||
"tags": ["advancededitormacros"], |
|||
"parameters": [{ |
|||
"$ref": "../parameters.json#/advancededitormacro_id_pp" |
|||
}, { |
|||
"name": "body", |
|||
"in": "body", |
|||
"description": "An advanced editor macro object", |
|||
"required": true, |
|||
"schema": { |
|||
"$ref": "../definitions.json#/advancededitormacro" |
|||
} |
|||
}], |
|||
"produces": [ |
|||
"application/json" |
|||
], |
|||
"responses": { |
|||
"200": { |
|||
"description": "An advanced editor macro", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/advancededitormacro" |
|||
} |
|||
}, |
|||
"401": { |
|||
"description": "Authentication required", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
}, |
|||
"403": { |
|||
"description": "Access forbidden", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
}, |
|||
"404": { |
|||
"description": "Macro not found", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
}, |
|||
"500": { |
|||
"description": "Internal error", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
}, |
|||
"503": { |
|||
"description": "Under maintenance", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
} |
|||
}, |
|||
"x-koha-authorization": { |
|||
"permissions": { |
|||
"editcatalogue": "advanced_editor" |
|||
} |
|||
} |
|||
}, |
|||
"delete": { |
|||
"x-mojo-to": "AdvancedEditorMacro#delete", |
|||
"operationId": "deleteAdvancedEditorMacro", |
|||
"tags": ["advancededitormacros"], |
|||
"parameters": [{ |
|||
"$ref": "../parameters.json#/advancededitormacro_id_pp" |
|||
}], |
|||
"produces": [ |
|||
"application/json" |
|||
], |
|||
"responses": { |
|||
"200": { |
|||
"description": "Advanced editor macro deleted", |
|||
"schema": { |
|||
"type": "string" |
|||
} |
|||
}, |
|||
"401": { |
|||
"description": "Authentication required", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
}, |
|||
"403": { |
|||
"description": "Access forbidden", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
}, |
|||
"404": { |
|||
"description": "Macro not found", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
}, |
|||
"500": { |
|||
"description": "Internal error", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
}, |
|||
"503": { |
|||
"description": "Under maintenance", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
} |
|||
}, |
|||
"x-koha-authorization": { |
|||
"permissions": { |
|||
"editcatalogue": "advanced_editor" |
|||
} |
|||
} |
|||
} |
|||
}, |
|||
"/advancededitormacros/shared/{advancededitormacro_id}": { |
|||
"get": { |
|||
"x-mojo-to": "AdvancedEditorMacro#get_shared", |
|||
"operationId": "getsharedAdvancedEditorMacro", |
|||
"tags": ["advancededitormacros"], |
|||
"parameters": [{ |
|||
"$ref": "../parameters.json#/advancededitormacro_id_pp" |
|||
}], |
|||
"produces": [ |
|||
"application/json" |
|||
], |
|||
"responses": { |
|||
"200": { |
|||
"description": "A macro", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/advancededitormacro" |
|||
} |
|||
}, |
|||
"403": { |
|||
"description": "Access forbidden", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
}, |
|||
"404": { |
|||
"description": "AdvancedEditorMacro not found", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
}, |
|||
"500": { |
|||
"description": "Internal error", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
}, |
|||
"503": { |
|||
"description": "Under maintenance", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
} |
|||
}, |
|||
"x-koha-authorization": { |
|||
"permissions": { |
|||
"editcatalogue": "advanced_editor" |
|||
} |
|||
} |
|||
}, |
|||
"put": { |
|||
"x-mojo-to": "AdvancedEditorMacro#update_shared", |
|||
"operationId": "updatesharedAdvancedEditorMacro", |
|||
"tags": ["advancededitormacros"], |
|||
"parameters": [{ |
|||
"$ref": "../parameters.json#/advancededitormacro_id_pp" |
|||
}, { |
|||
"name": "body", |
|||
"in": "body", |
|||
"description": "An advanced editor macro object", |
|||
"required": true, |
|||
"schema": { |
|||
"$ref": "../definitions.json#/advancededitormacro" |
|||
} |
|||
}], |
|||
"produces": [ |
|||
"application/json" |
|||
], |
|||
"responses": { |
|||
"200": { |
|||
"description": "An advanced editor macro", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/advancededitormacro" |
|||
} |
|||
}, |
|||
"401": { |
|||
"description": "Authentication required", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
}, |
|||
"403": { |
|||
"description": "Access forbidden", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
}, |
|||
"404": { |
|||
"description": "Macro not found", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
}, |
|||
"500": { |
|||
"description": "Internal error", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
}, |
|||
"503": { |
|||
"description": "Under maintenance", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
} |
|||
}, |
|||
"x-koha-authorization": { |
|||
"permissions": { |
|||
"editcatalogue": "advanced_editor", |
|||
"editcatalogue": "create_shared_macros" |
|||
} |
|||
} |
|||
}, |
|||
"delete": { |
|||
"x-mojo-to": "AdvancedEditorMacro#delete_shared", |
|||
"operationId": "deletesharedAdvancedEditorMacro", |
|||
"tags": ["advancededitormacros"], |
|||
"parameters": [{ |
|||
"$ref": "../parameters.json#/advancededitormacro_id_pp" |
|||
}], |
|||
"produces": [ |
|||
"application/json" |
|||
], |
|||
"responses": { |
|||
"200": { |
|||
"description": "Advanced editor macro deleted", |
|||
"schema": { |
|||
"type": "string" |
|||
} |
|||
}, |
|||
"401": { |
|||
"description": "Authentication required", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
}, |
|||
"403": { |
|||
"description": "Access forbidden", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
}, |
|||
"404": { |
|||
"description": "Macro not found", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
}, |
|||
"500": { |
|||
"description": "Internal error", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
}, |
|||
"503": { |
|||
"description": "Under maintenance", |
|||
"schema": { |
|||
"$ref": "../definitions.json#/error" |
|||
} |
|||
} |
|||
}, |
|||
"x-koha-authorization": { |
|||
"permissions": { |
|||
"editcatalogue": "advanced_editor", |
|||
"editcatalogue": "delete_shared_macros" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,475 @@ |
|||
#!/usr/bin/env 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, write to the Free Software Foundation, Inc., |
|||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
|||
|
|||
use Modern::Perl; |
|||
|
|||
use Test::More tests => 5; |
|||
use Test::Mojo; |
|||
use Test::Warn; |
|||
|
|||
use t::lib::TestBuilder; |
|||
use t::lib::Mocks; |
|||
|
|||
use Koha::AdvancedEditorMacros; |
|||
use Koha::Database; |
|||
|
|||
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'); |
|||
|
|||
$schema->storage->txn_begin; |
|||
|
|||
subtest 'list() tests' => sub { |
|||
plan tests => 8; |
|||
|
|||
|
|||
my $patron_1 = $builder->build_object({ |
|||
class => 'Koha::Patrons', |
|||
value => { flags => 9 } |
|||
}); |
|||
my $patron_2 = $builder->build_object({ |
|||
class => 'Koha::Patrons', |
|||
}); |
|||
my $password = 'thePassword123'; |
|||
$patron_1->set_password({ password => $password, skip_validation => 1 }); |
|||
my $userid = $patron_1->userid; |
|||
|
|||
# Create test context |
|||
my $macro_1 = $builder->build_object({ class => 'Koha::AdvancedEditorMacros', value => |
|||
{ |
|||
name => 'Test1', |
|||
macro => 'delete 100', |
|||
borrowernumber => $patron_1->borrowernumber, |
|||
} |
|||
}); |
|||
my $macro_2 = $builder->build_object({ class => 'Koha::AdvancedEditorMacros', value => |
|||
{ |
|||
name => 'Test2', |
|||
macro => 'delete 100', |
|||
borrowernumber => $patron_1->borrowernumber, |
|||
shared=> 1, |
|||
} |
|||
}); |
|||
my $macro_3 = $builder->build_object({ class => 'Koha::AdvancedEditorMacros', value => |
|||
{ |
|||
name => 'Test3', |
|||
macro => 'delete 100', |
|||
borrowernumber => $patron_2->borrowernumber, |
|||
} |
|||
}); |
|||
my $macro_4 = $builder->build_object({ class => 'Koha::AdvancedEditorMacros', value => |
|||
{ |
|||
name => 'Test4', |
|||
macro => 'delete 100', |
|||
borrowernumber => $patron_2->borrowernumber, |
|||
shared => 1, |
|||
} |
|||
}); |
|||
|
|||
my $macros_index = Koha::AdvancedEditorMacros->search({ -or => { shared => 1, borrowernumber => $patron_1->borrowernumber } })->count-1; |
|||
## Authorized user tests |
|||
# Make sure we are returned with the correct amount of macros |
|||
$t->get_ok( "//$userid:$password@/api/v1/advancededitormacros" ) |
|||
->status_is( 200, 'SWAGGER3.2.2' ) |
|||
->json_has('/' . $macros_index . '/macro_id') |
|||
->json_hasnt('/' . ($macros_index + 1) . '/macro_id'); |
|||
|
|||
subtest 'query parameters' => sub { |
|||
|
|||
plan tests => 15; |
|||
$t->get_ok("//$userid:$password@/api/v1/advancededitormacros?name=" . $macro_2->name) |
|||
->status_is(200) |
|||
->json_has( [ $macro_2 ] ); |
|||
$t->get_ok("//$userid:$password@/api/v1/advancededitormacros?name=" . $macro_3->name) |
|||
->status_is(200) |
|||
->json_has( [ ] ); |
|||
$t->get_ok("//$userid:$password@/api/v1/advancededitormacros?macro_text=delete 100") |
|||
->status_is(200) |
|||
->json_has( [ $macro_1, $macro_2, $macro_4 ] ); |
|||
$t->get_ok("//$userid:$password@/api/v1/advancededitormacros?patron_id=" . $patron_1->borrowernumber) |
|||
->status_is(200) |
|||
->json_has( [ $macro_1, $macro_2 ] ); |
|||
$t->get_ok("//$userid:$password@/api/v1/advancededitormacros?shared=1") |
|||
->status_is(200) |
|||
->json_has( [ $macro_2, $macro_4 ] ); |
|||
}; |
|||
|
|||
# Warn on unsupported query parameter |
|||
$t->get_ok( "//$userid:$password@/api/v1/advancededitormacros?macro_blah=blah" ) |
|||
->status_is(400) |
|||
->json_is( [{ path => '/query/macro_blah', message => 'Malformed query string'}] ); |
|||
|
|||
}; |
|||
|
|||
subtest 'get() tests' => sub { |
|||
|
|||
plan tests => 15; |
|||
|
|||
my $patron = $builder->build_object({ |
|||
class => 'Koha::Patrons', |
|||
value => { flags => 1 } |
|||
}); |
|||
my $password = 'thePassword123'; |
|||
$patron->set_password({ password => $password, skip_validation => 1 }); |
|||
my $userid = $patron->userid; |
|||
|
|||
my $macro_1 = $builder->build_object( { class => 'Koha::AdvancedEditorMacros', value => { |
|||
shared => 1, |
|||
} |
|||
}); |
|||
my $macro_2 = $builder->build_object( { class => 'Koha::AdvancedEditorMacros', value => { |
|||
shared => 0, |
|||
} |
|||
}); |
|||
my $macro_3 = $builder->build_object( { class => 'Koha::AdvancedEditorMacros', value => { |
|||
borrowernumber => $patron->borrowernumber, |
|||
shared => 0, |
|||
} |
|||
}); |
|||
|
|||
$t->get_ok( "//$userid:$password@/api/v1/advancededitormacros/" . $macro_1->id ) |
|||
->status_is( 403, 'Cannot get a shared macro via regular endpoint' ) |
|||
->json_is( '/error' => 'This macro is shared, you must access it via advancededitormacros/shared' ); |
|||
|
|||
$t->get_ok( "//$userid:$password@/api/v1/advancededitormacros/shared/" . $macro_1->id ) |
|||
->status_is( 200, 'Can get a shared macro via shared endpoint' ) |
|||
->json_is( '' => Koha::REST::V1::AdvancedEditorMacro::_to_api( $macro_1->TO_JSON ), 'Macro correctly retrieved' ); |
|||
|
|||
$t->get_ok( "//$userid:$password@/api/v1/advancededitormacros/" . $macro_2->id ) |
|||
->status_is( 403, 'Cannot access another users macro' ) |
|||
->json_is( '/error' => 'You do not have permission to access this macro' ); |
|||
|
|||
$t->get_ok( "//$userid:$password@/api/v1/advancededitormacros/" . $macro_3->id ) |
|||
->status_is( 200, 'Can get your own private macro' ) |
|||
->json_is( '' => Koha::REST::V1::AdvancedEditorMacro::_to_api( $macro_3->TO_JSON ), 'Macro correctly retrieved' ); |
|||
|
|||
my $non_existent_code = $macro_1->id; |
|||
$macro_1->delete; |
|||
|
|||
$t->get_ok( "//$userid:$password@/api/v1/advancededitormacros/" . $non_existent_code ) |
|||
->status_is(404) |
|||
->json_is( '/error' => 'Macro not found' ); |
|||
|
|||
}; |
|||
|
|||
subtest 'add() tests' => sub { |
|||
|
|||
plan tests => 24; |
|||
|
|||
my $authorized_patron = $builder->build_object({ |
|||
class => 'Koha::Patrons', |
|||
value => { flags => 0 } |
|||
}); |
|||
$builder->build({ |
|||
source => 'UserPermission', |
|||
value => { |
|||
borrowernumber => $authorized_patron->borrowernumber, |
|||
module_bit => 9, |
|||
code => 'advanced_editor', |
|||
}, |
|||
}); |
|||
|
|||
my $password = 'thePassword123'; |
|||
$authorized_patron->set_password({ password => $password, skip_validation => 1 }); |
|||
my $auth_userid = $authorized_patron->userid; |
|||
|
|||
my $unauthorized_patron = $builder->build_object({ |
|||
class => 'Koha::Patrons', |
|||
value => { flags => 0 } |
|||
}); |
|||
$unauthorized_patron->set_password({ password => $password, skip_validation => 1 }); |
|||
my $unauth_userid = $unauthorized_patron->userid; |
|||
|
|||
my $macro = $builder->build_object({ |
|||
class => 'Koha::AdvancedEditorMacros', |
|||
value => { shared => 0 } |
|||
}); |
|||
my $macro_values = Koha::REST::V1::AdvancedEditorMacro::_to_api( $macro->TO_JSON ); |
|||
delete $macro_values->{macro_id}; |
|||
$macro->delete; |
|||
|
|||
# Unauthorized attempt to write |
|||
$t->post_ok( "//$unauth_userid:$password@/api/v1/advancededitormacros" => json => $macro_values ) |
|||
->status_is(403); |
|||
|
|||
# Authorized attempt to write invalid data |
|||
my $macro_with_invalid_field = { %$macro_values }; |
|||
$macro_with_invalid_field->{'big_mac_ro'} = 'Mac attack'; |
|||
|
|||
$t->post_ok( "//$auth_userid:$password@/api/v1/advancededitormacros" => json => $macro_with_invalid_field ) |
|||
->status_is(400) |
|||
->json_is( |
|||
"/errors" => [ |
|||
{ |
|||
message => "Properties not allowed: big_mac_ro.", |
|||
path => "/body" |
|||
} |
|||
] |
|||
); |
|||
|
|||
# Authorized attempt to write |
|||
$t->post_ok( "//$auth_userid:$password@/api/v1/advancededitormacros" => json => $macro_values ) |
|||
->status_is( 201, 'SWAGGER3.2.1' ) |
|||
->json_has( '/macro_id', 'We generated a new id' ) |
|||
->json_is( '/name' => $macro_values->{name}, 'The name matches what we supplied' ) |
|||
->json_is( '/macro_text' => $macro_values->{macro_text}, 'The text matches what we supplied' ) |
|||
->json_is( '/patron_id' => $macro_values->{patron_id}, 'The borrower matches the borrower who submitted' ) |
|||
->json_is( '/shared' => 0, 'The macro is not shared' ) |
|||
->header_like( Location => qr|^\/api\/v1\/advancededitormacros\/d*|, 'Correct location' ); |
|||
|
|||
# save the library_id |
|||
my $macro_id = 999; |
|||
|
|||
# Authorized attempt to create with existing id |
|||
$macro_values->{macro_id} = $macro_id; |
|||
|
|||
$t->post_ok( "//$auth_userid:$password@/api/v1/advancededitormacros" => json => $macro_values ) |
|||
->status_is(400) |
|||
->json_is( '/errors' => [ |
|||
{ |
|||
message => "Read-only.", |
|||
path => "/body/macro_id" |
|||
} |
|||
] |
|||
); |
|||
|
|||
$macro_values->{shared} = 1; |
|||
delete $macro_values->{macro_id}; |
|||
|
|||
# Unauthorized attempt to write a shared macro on private endpoint |
|||
$t->post_ok( "//$auth_userid:$password@/api/v1/advancededitormacros" => json => $macro_values ) |
|||
->status_is(403); |
|||
# Unauthorized attempt to write a private macro on shared endpoint |
|||
$t->post_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/shared" => json => $macro_values ) |
|||
->status_is(403); |
|||
|
|||
$builder->build({ |
|||
source => 'UserPermission', |
|||
value => { |
|||
borrowernumber => $authorized_patron->borrowernumber, |
|||
module_bit => 9, |
|||
code => 'create_shared_macros', |
|||
}, |
|||
}); |
|||
|
|||
# Authorized attempt to write a shared macro on private endpoint |
|||
$t->post_ok( "//$auth_userid:$password@/api/v1/advancededitormacros" => json => $macro_values ) |
|||
->status_is(403); |
|||
|
|||
# Authorized attempt to write a shared macro on shared endpoint |
|||
$t->post_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/shared" => json => $macro_values ) |
|||
->status_is(201); |
|||
|
|||
}; |
|||
|
|||
subtest 'update() tests' => sub { |
|||
plan tests => 32; |
|||
|
|||
my $authorized_patron = $builder->build_object({ |
|||
class => 'Koha::Patrons', |
|||
value => { flags => 0 } |
|||
}); |
|||
$builder->build({ |
|||
source => 'UserPermission', |
|||
value => { |
|||
borrowernumber => $authorized_patron->borrowernumber, |
|||
module_bit => 9, |
|||
code => 'advanced_editor', |
|||
}, |
|||
}); |
|||
|
|||
my $password = 'thePassword123'; |
|||
$authorized_patron->set_password({ password => $password, skip_validation => 1 }); |
|||
my $auth_userid = $authorized_patron->userid; |
|||
|
|||
my $unauthorized_patron = $builder->build_object({ |
|||
class => 'Koha::Patrons', |
|||
value => { flags => 0 } |
|||
}); |
|||
$unauthorized_patron->set_password({ password => $password, skip_validation => 1 }); |
|||
my $unauth_userid = $unauthorized_patron->userid; |
|||
|
|||
my $macro = $builder->build_object({ |
|||
class => 'Koha::AdvancedEditorMacros', |
|||
value => { borrowernumber => $authorized_patron->borrowernumber, shared => 0 } |
|||
}); |
|||
my $macro_2 = $builder->build_object({ |
|||
class => 'Koha::AdvancedEditorMacros', |
|||
value => { borrowernumber => $unauthorized_patron->borrowernumber, shared => 0 } |
|||
}); |
|||
my $macro_id = $macro->id; |
|||
my $macro_2_id = $macro_2->id; |
|||
my $macro_values = Koha::REST::V1::AdvancedEditorMacro::_to_api( $macro->TO_JSON ); |
|||
delete $macro_values->{macro_id}; |
|||
|
|||
# Unauthorized attempt to update |
|||
$t->put_ok( "//$unauth_userid:$password@/api/v1/advancededitormacros/$macro_id" |
|||
=> json => { name => 'New unauthorized name change' } ) |
|||
->status_is(403); |
|||
|
|||
# Attempt partial update on a PUT |
|||
my $macro_with_missing_field = { |
|||
name => "Call it macro-roni", |
|||
}; |
|||
|
|||
$t->put_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/$macro_id" => json => $macro_with_missing_field ) |
|||
->status_is(400) |
|||
->json_has( "/errors" => |
|||
[ { message => "Missing property.", path => "/body/macro_text" } ] |
|||
); |
|||
|
|||
my $macro_update = { |
|||
name => "Macro-update", |
|||
macro_text => "delete 100", |
|||
patron_id => $authorized_patron->borrowernumber, |
|||
shared => 0, |
|||
}; |
|||
|
|||
my $test = $t->put_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/$macro_id" => json => $macro_update ) |
|||
->status_is(200, 'Authorized user can update a macro') |
|||
->json_is( '/macro_id' => $macro_id, 'We get the id back' ) |
|||
->json_is( '/name' => $macro_update->{name}, 'We get the name back' ) |
|||
->json_is( '/macro_text' => $macro_update->{macro_text}, 'We get the text back' ) |
|||
->json_is( '/patron_id' => $macro_update->{patron_id}, 'We get the patron_id back' ) |
|||
->json_is( '/shared' => $macro_update->{shared}, 'It should still not be shared' ); |
|||
|
|||
# Now try to make the macro shared |
|||
$macro_update->{shared} = 1; |
|||
|
|||
$t->put_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/shared/$macro_id" => json => $macro_update ) |
|||
->status_is(403, 'Cannot make your macro shared on private endpoint'); |
|||
$t->put_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/shared/$macro_id" => json => $macro_update ) |
|||
->status_is(403, 'Cannot make your macro shared without permission'); |
|||
|
|||
$builder->build({ |
|||
source => 'UserPermission', |
|||
value => { |
|||
borrowernumber => $authorized_patron->borrowernumber, |
|||
module_bit => 9, |
|||
code => 'create_shared_macros', |
|||
}, |
|||
}); |
|||
|
|||
$t->put_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/$macro_id" => json => $macro_update ) |
|||
->status_is(403, 'Cannot make your macro shared on the private endpoint'); |
|||
|
|||
$t->put_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/shared/$macro_id" => json => $macro_update ) |
|||
->status_is(200, 'Can update macro to shared with permission') |
|||
->json_is( '/macro_id' => $macro_id, 'We get back the id' ) |
|||
->json_is( '/name' => $macro_update->{name}, 'We get back the name' ) |
|||
->json_is( '/macro_text' => $macro_update->{macro_text}, 'We get back the text' ) |
|||
->json_is( '/patron_id' => $macro_update->{patron_id}, 'We get back our patron id' ) |
|||
->json_is( '/shared' => 1, 'It is shared' ); |
|||
|
|||
# Authorized attempt to write invalid data |
|||
my $macro_with_invalid_field = { %$macro_update }; |
|||
$macro_with_invalid_field->{'big_mac_ro'} = 'Mac attack'; |
|||
|
|||
$t->put_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/$macro_id" => json => $macro_with_invalid_field ) |
|||
->status_is(400) |
|||
->json_is( |
|||
"/errors" => [ |
|||
{ |
|||
message => "Properties not allowed: big_mac_ro.", |
|||
path => "/body" |
|||
} |
|||
] |
|||
); |
|||
|
|||
my $non_existent_macro = $builder->build_object({class => 'Koha::AdvancedEditorMacros'}); |
|||
my $non_existent_code = $non_existent_macro->id; |
|||
$non_existent_macro->delete; |
|||
|
|||
$t->put_ok("//$auth_userid:$password@/api/v1/advancededitormacros/$non_existent_code" => json => $macro_update) |
|||
->status_is(404); |
|||
|
|||
$t->put_ok("//$auth_userid:$password@/api/v1/advancededitormacros/$macro_2_id" => json => $macro_update) |
|||
->status_is(403, "Cannot update other borrowers private macro"); |
|||
}; |
|||
|
|||
subtest 'delete() tests' => sub { |
|||
plan tests => 12; |
|||
|
|||
my $authorized_patron = $builder->build_object({ |
|||
class => 'Koha::Patrons', |
|||
value => { flags => 0 } |
|||
}); |
|||
$builder->build({ |
|||
source => 'UserPermission', |
|||
value => { |
|||
borrowernumber => $authorized_patron->borrowernumber, |
|||
module_bit => 9, |
|||
code => 'advanced_editor', |
|||
}, |
|||
}); |
|||
|
|||
my $password = 'thePassword123'; |
|||
$authorized_patron->set_password({ password => $password, skip_validation => 1 }); |
|||
my $auth_userid = $authorized_patron->userid; |
|||
|
|||
my $unauthorized_patron = $builder->build_object({ |
|||
class => 'Koha::Patrons', |
|||
value => { flags => 0 } |
|||
}); |
|||
$unauthorized_patron->set_password({ password => $password, skip_validation => 1 }); |
|||
my $unauth_userid = $unauthorized_patron->userid; |
|||
|
|||
my $macro = $builder->build_object({ |
|||
class => 'Koha::AdvancedEditorMacros', |
|||
value => { borrowernumber => $authorized_patron->borrowernumber, shared => 0 } |
|||
}); |
|||
my $macro_2 = $builder->build_object({ |
|||
class => 'Koha::AdvancedEditorMacros', |
|||
value => { borrowernumber => $unauthorized_patron->borrowernumber, shared => 0 } |
|||
}); |
|||
my $macro_id = $macro->id; |
|||
my $macro_2_id = $macro_2->id; |
|||
|
|||
# Unauthorized attempt to delete |
|||
$t->delete_ok( "//$unauth_userid:$password@/api/v1/advancededitormacros/$macro_2_id") |
|||
->status_is(403, "Cannot delete macro without permission"); |
|||
|
|||
$t->delete_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/$macro_id") |
|||
->status_is(200, 'Can delete macro with permission'); |
|||
|
|||
$t->delete_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/$macro_2_id") |
|||
->status_is(403, 'Cannot delete other users macro with permission'); |
|||
|
|||
$macro_2->shared(1)->store(); |
|||
|
|||
$t->delete_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/shared/$macro_2_id") |
|||
->status_is(403, 'Cannot delete other users shared macro without permission'); |
|||
|
|||
$builder->build({ |
|||
source => 'UserPermission', |
|||
value => { |
|||
borrowernumber => $authorized_patron->borrowernumber, |
|||
module_bit => 9, |
|||
code => 'delete_shared_macros', |
|||
}, |
|||
}); |
|||
$t->delete_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/$macro_2_id") |
|||
->status_is(403, 'Cannot delete other users shared macro with permission on private endpoint'); |
|||
$t->delete_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/shared/$macro_2_id") |
|||
->status_is(200, 'Can delete other users shared macro with permission'); |
|||
|
|||
}; |
|||
|
|||
$schema->storage->txn_rollback; |
Loading…
Reference in new issue