Bugzilla – Attachment 62791 Details for
Bug 14843
Notifications and messages via REST API
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 14843: REST API for message queue - /api/v1/notices
Bug-14843-REST-API-for-message-queue---apiv1notice.patch (text/plain), 41.00 KB, created by
Lari Taskula
on 2017-04-27 16:12:18 UTC
(
hide
)
Description:
Bug 14843: REST API for message queue - /api/v1/notices
Filename:
MIME Type:
Creator:
Lari Taskula
Created:
2017-04-27 16:12:18 UTC
Size:
41.00 KB
patch
obsolete
>From c7266d8a9c8f9372d8a6cc79f4a8c6de11882912 Mon Sep 17 00:00:00 2001 >From: Lari Taskula <lari.taskula@jns.fi> >Date: Thu, 27 Apr 2017 13:02:11 +0000 >Subject: [PATCH] Bug 14843: REST API for message queue - /api/v1/notices > >GET /api/v1/notices >POST /api/v1/notices >GET /api/v1/notices/{message_id} >PUT /api/v1/notices/{message_id} >PATCH /api/v1/notices/{message_id} >DELETE /api/v1/notices/{message_id} >POST /api/v1/notices/{message_id}/resend > >New permissions: >- Module > * messages >- Sub-permissions > * get_message > * create_message > * update_message > * delete_message > * resend_message > >To test: >1. prove t/db_dependent/api/v1/notices.t >--- > Koha/REST/V1/Auth.pm | 16 + > Koha/REST/V1/Notice.pm | 176 ++++++++ > api/v1/swagger/definitions.json | 3 + > api/v1/swagger/definitions/notice.json | 59 +++ > api/v1/swagger/parameters.json | 3 + > api/v1/swagger/parameters/notice.json | 9 + > api/v1/swagger/paths.json | 9 + > api/v1/swagger/paths/notices.json | 493 +++++++++++++++++++++ > ...ermissions_for_message_queue-REST_operations.pl | 35 ++ > t/db_dependent/api/v1/notices.t | 411 +++++++++++++++++ > 10 files changed, 1214 insertions(+) > create mode 100644 Koha/REST/V1/Notice.pm > create mode 100644 api/v1/swagger/definitions/notice.json > create mode 100644 api/v1/swagger/parameters/notice.json > create mode 100644 api/v1/swagger/paths/notices.json > create mode 100644 installer/data/mysql/atomicupdate/Bug-14843-Add_Permissions_for_message_queue-REST_operations.pl > create mode 100644 t/db_dependent/api/v1/notices.t > >diff --git a/Koha/REST/V1/Auth.pm b/Koha/REST/V1/Auth.pm >index 3b47f77..d094545 100644 >--- a/Koha/REST/V1/Auth.pm >+++ b/Koha/REST/V1/Auth.pm >@@ -28,6 +28,7 @@ use C4::Auth qw( check_cookie_auth get_session haspermission ); > use Koha::Account::Lines; > use Koha::Checkouts; > use Koha::Holds; >+use Koha::Notice::Messages; > use Koha::Old::Checkouts; > use Koha::Patrons; > >@@ -335,6 +336,7 @@ sub check_object_ownership { > borrowernumber => \&_object_ownership_by_borrowernumber, > checkout_id => \&_object_ownership_by_checkout_id, > reserve_id => \&_object_ownership_by_reserve_id, >+ message_id => \&_object_ownership_by_message_id, > }; > > foreach my $param ( keys %{ $parameters } ) { >@@ -398,6 +400,20 @@ sub _object_ownership_by_checkout_id { > && $user->borrowernumber == $issue->borrowernumber; > } > >+=head3 _object_ownership_by_message_id >+ >+Finds a Koha::Notice::Message-object by C<$message_id> and checks if it >+belongs to C<$user>. >+ >+=cut >+ >+sub _object_ownership_by_message_id { >+ my ($c, $user, $message_id) = @_; >+ >+ my $message = Koha::Notice::Messages->find($message_id); >+ return $message && $user->borrowernumber == $message->borrowernumber; >+} >+ > =head3 _object_ownership_by_reserve_id > > Finds a Koha::Hold-object by C<$reserve_id> and checks if it >diff --git a/Koha/REST/V1/Notice.pm b/Koha/REST/V1/Notice.pm >new file mode 100644 >index 0000000..f910e01 >--- /dev/null >+++ b/Koha/REST/V1/Notice.pm >@@ -0,0 +1,176 @@ >+package Koha::REST::V1::Notice; >+ >+# 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::Notice::Messages; >+ >+use Try::Tiny; >+ >+sub list { >+ my $c = shift->openapi->valid_input or return; >+ >+ return try { >+ my $params = $c->req->query_params->to_hash; >+ $params = _between_time_queued($params); # Construct 'time_queued' >+ my $notices; >+ if (keys %$params) { >+ my @valid_params = Koha::Notice::Messages->columns; >+ foreach my $key (keys %$params) { >+ delete $params->{$key} unless grep { $key eq $_ } @valid_params; >+ } >+ $notices = Koha::Notice::Messages->search($params); >+ } else { >+ $notices = Koha::Notice::Messages->search; >+ } >+ >+ return $c->render(status => 200, openapi => $notices); >+ } >+ catch { >+ Koha::Exceptions::rethrow_exception($_); >+ }; >+} >+ >+sub get { >+ my $c = shift->openapi->valid_input or return; >+ >+ my $message_id = $c->validation->param('message_id'); >+ my $notice; >+ return try { >+ $notice = Koha::Notice::Messages->find($message_id); >+ >+ unless ($notice) { >+ return $c->render( status => 404, >+ openapi => { error => "Notice not found" } ); >+ } >+ >+ return $c->render(status => 200, openapi => $notice); >+ } >+ catch { >+ Koha::Exceptions::rethrow_exception($_); >+ }; >+} >+ >+sub add { >+ my $c = shift->openapi->valid_input or return; >+ >+ return try { >+ my $body = $c->req->json; >+ >+ my $notice = Koha::Notice::Message->new($body)->store; >+ $notice = Koha::Notice::Messages->find($notice->message_id); >+ return $c->render(status => 201, openapi => $notice); >+ } >+ catch { >+ Koha::Exceptions::rethrow_exception($_); >+ }; >+} >+ >+sub edit { >+ my $c = shift->openapi->valid_input or return; >+ >+ my $notice; >+ return try { >+ my $message_id = $c->validation->param('message_id'); >+ $notice = Koha::Notice::Messages->find($message_id); >+ my $body = $c->req->json; >+ >+ $notice->set($body); >+ return $c->render( status => 204, openapi => {}) unless $notice->is_changed; >+ $notice->store; >+ return $c->render( status => 200, openapi => $notice); >+ } >+ catch { >+ unless ($notice) { >+ return $c->render( status => 404, >+ openapi => { error => "Notice not found" } ); >+ } >+ Koha::Exceptions::rethrow_exception($_); >+ }; >+} >+ >+sub patch { >+ return edit(@_); >+} >+ >+sub delete { >+ my $c = shift->openapi->valid_input or return; >+ >+ my $notice = Koha::Notice::Messages->find($c->validation->param('message_id')); >+ unless ($notice) { >+ return $c->render( status => 404, >+ openapi => { error => "Notice not found" } ); >+ } >+ >+ my $res = $notice->delete; >+ >+ if ($res eq '1') { >+ return $c->render( status => 204, openapi => {}); >+ } elsif ($res eq '-1') { >+ return $c->render( status => 404, openapi => {}); >+ } else { >+ return $c->render( status => 400, openapi => {}); >+ } >+} >+ >+sub resend { >+ my $c = shift->openapi->valid_input or return; >+ >+ my $notice; >+ return try { >+ my $message_id = $c->validation->param('message_id'); >+ $notice = Koha::Notice::Messages->find($message_id); >+ $notice->status('pending')->store; >+ return $c->render( status => 204, openapi => {}); >+ } >+ catch { >+ unless ($notice) { >+ return $c->render( status => 404, >+ openapi => { error => "Notice not found" } ); >+ } >+ Koha::Exceptions::rethrow_exception($_); >+ }; >+} >+ >+sub _between_time_queued { >+ my ($params) = @_; >+ >+ return $params if $params->{'time_queued'}; >+ return $params if ( !$params->{'time_queued_start'} >+ && !$params->{'time_queued_end'} ); >+ >+ my $start = $params->{'time_queued_start'}; >+ my $end = $params->{'time_queued_end'}; >+ >+ if ($start && !$end) { >+ $params->{'time_queued'} = { '>=', $start }; >+ } >+ elsif (!$start && $end) { >+ $params->{'time_queued'} = { '<=', $end }; >+ } >+ else { >+ $params->{'time_queued'} = { '-between', [$start, $end] }; >+ } >+ >+ delete $params->{'time_queued_start'}; >+ delete $params->{'time_queued_end'}; >+ return $params; >+} >+ >+1; >diff --git a/api/v1/swagger/definitions.json b/api/v1/swagger/definitions.json >index 4dd6d33..5a5a406 100644 >--- a/api/v1/swagger/definitions.json >+++ b/api/v1/swagger/definitions.json >@@ -50,6 +50,9 @@ > "library": { > "$ref": "definitions/library.json" > }, >+ "notice": { >+ "$ref": "definitions/notice.json" >+ }, > "error": { > "$ref": "definitions/error.json" > }, >diff --git a/api/v1/swagger/definitions/notice.json b/api/v1/swagger/definitions/notice.json >new file mode 100644 >index 0000000..1f02944 >--- /dev/null >+++ b/api/v1/swagger/definitions/notice.json >@@ -0,0 +1,59 @@ >+{ >+ "type": "object", >+ "properties": { >+ "message_id": { >+ "description": "Message internal identifier", >+ "type": "integer", >+ "readOnly": true >+ }, >+ "borrowernumber": { >+ "$ref": "../x-primitives.json#/borrowernumber" >+ }, >+ "subject": { >+ "description": "Subject of the message", >+ "type": ["string", "null"] >+ }, >+ "content": { >+ "description": "Content of the message", >+ "type": ["string", "null"] >+ }, >+ "metadata": { >+ "description": "", >+ "type": ["string", "null"] >+ }, >+ "letter_code": { >+ "description": "", >+ "type": ["string", "null"] >+ }, >+ "message_transport_type": { >+ "description": "Transport method. Values accepted by default are 'email', 'sms', 'phone' and 'print'", >+ "type": "string" >+ }, >+ "status": { >+ "description": "Delivery status", >+ "type": "string" >+ }, >+ "time_queued": { >+ "description": "Date and time of when message was placed in queue", >+ "type": "string", >+ "format": "date-time" >+ }, >+ "to_address": { >+ "description": "Destination email address", >+ "type": ["string", "null"] >+ }, >+ "from_address": { >+ "description": "Source address of email", >+ "type": ["string", "null"] >+ }, >+ "content_type": { >+ "description": "Content type", >+ "type": ["string", "null"] >+ }, >+ "delivery_note": { >+ "description": "Additional delivery notes", >+ "type": ["string", "null"] >+ } >+ }, >+ "additionalProperties": false >+} >diff --git a/api/v1/swagger/parameters.json b/api/v1/swagger/parameters.json >index f8fd864..24d1ca0 100644 >--- a/api/v1/swagger/parameters.json >+++ b/api/v1/swagger/parameters.json >@@ -38,6 +38,9 @@ > "itemnumbersQueryParam": { > "$ref": "parameters/item.json#/itemnumbersQueryParam" > }, >+ "message_idPathParam": { >+ "$ref": "parameters/notice.json#/message_idPathParam" >+ }, > "passwordPostParam": { > "$ref": "parameters/auth.json#/passwordPostParam" > }, >diff --git a/api/v1/swagger/parameters/notice.json b/api/v1/swagger/parameters/notice.json >new file mode 100644 >index 0000000..5788419 >--- /dev/null >+++ b/api/v1/swagger/parameters/notice.json >@@ -0,0 +1,9 @@ >+{ >+ "message_idPathParam": { >+ "name": "message_id", >+ "in": "path", >+ "description": "Message internal identifier", >+ "required": true, >+ "type": "integer" >+ } >+} >diff --git a/api/v1/swagger/paths.json b/api/v1/swagger/paths.json >index db50edc..a398805 100644 >--- a/api/v1/swagger/paths.json >+++ b/api/v1/swagger/paths.json >@@ -77,6 +77,15 @@ > "/libraries/{branchcode}": { > "$ref": "paths/libraries.json#/~1libraries~1{branchcode}" > }, >+ "/notices": { >+ "$ref": "paths/notices.json#/~1notices" >+ }, >+ "/notices/{message_id}": { >+ "$ref": "paths/notices.json#/~1notices~1{message_id}" >+ }, >+ "/notices/{message_id}/resend": { >+ "$ref": "paths/notices.json#/~1notices~1{message_id}~1resend" >+ }, > "/patrons": { > "$ref": "paths/patrons.json#/~1patrons" > }, >diff --git a/api/v1/swagger/paths/notices.json b/api/v1/swagger/paths/notices.json >new file mode 100644 >index 0000000..6351f5c >--- /dev/null >+++ b/api/v1/swagger/paths/notices.json >@@ -0,0 +1,493 @@ >+{ >+ "/notices": { >+ "get": { >+ "x-mojo-to": "Notice#list", >+ "operationId": "listNotices", >+ "x-koha-authorization": { >+ "permissions": { >+ "messages": "get_message" >+ }, >+ "allow-owner": true, >+ "allow-guarantor": true >+ }, >+ "tags": ["notices"], >+ "parameters": [{ >+ "name": "borrowernumber", >+ "in": "query", >+ "description": "Patron's borrowernumber", >+ "required": false, >+ "type": "integer" >+ }, { >+ "name": "subject", >+ "in": "query", >+ "description": "Case insensative 'starts-with' search on subject", >+ "required": false, >+ "type": "string" >+ }, { >+ "name": "content", >+ "in": "query", >+ "description": "Case insensative 'starts_with' search on content", >+ "required": false, >+ "type": "string" >+ }, { >+ "name": "metadata", >+ "in": "query", >+ "description": "Case insensative 'starts_with' search on metadata", >+ "required": false, >+ "type": "string" >+ }, { >+ "name": "message_transport_type", >+ "in": "query", >+ "description": "Case insensative 'starts_with' search on message transport type", >+ "required": false, >+ "type": "string" >+ }, { >+ "name": "time_queued_start", >+ "in": "query", >+ "description": "Search notices after given time", >+ "required": false, >+ "type": "string", >+ "format": "date-time" >+ }, { >+ "name": "time_queued_end", >+ "in": "query", >+ "description": "Search notices before given time", >+ "required": false, >+ "type": "string" >+ }, { >+ "name": "to_address", >+ "in": "query", >+ "description": "Case insensative 'starts_with' search on to address", >+ "required": false, >+ "type": "string" >+ }, { >+ "name": "from_address", >+ "in": "query", >+ "description": "Case insensative 'starts_with' search on from address", >+ "required": false, >+ "type": "string" >+ }, { >+ "name": "content_type", >+ "in": "query", >+ "description": "Case insensative 'starts_with' search on content type", >+ "required": false, >+ "type": "string" >+ }, { >+ "name": "delivery_note", >+ "in": "query", >+ "description": "Case insensative 'starts_with' search on delivery note", >+ "required": false, >+ "type": "string" >+ }], >+ "produces": [ >+ "application/json" >+ ], >+ "responses": { >+ "200": { >+ "description": "A list of notices", >+ "schema": { >+ "type": "array", >+ "items": { >+ "$ref" : "../definitions.json#/notice" >+ } >+ } >+ }, >+ "401": { >+ "description": "Authentication required", >+ "schema": { >+ "$ref": "../definitions.json#/error" >+ } >+ }, >+ "403": { >+ "description": "Access forbidden", >+ "schema": { >+ "$ref": "../definitions.json#/error" >+ } >+ }, >+ "404": { >+ "description": "Notice 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" >+ } >+ } >+ } >+ }, >+ "post": { >+ "x-mojo-to": "Notice#add", >+ "operationId": "addNotice", >+ "x-koha-authorization": { >+ "permissions": { >+ "messages": "create_message" >+ } >+ }, >+ "tags": ["notices"], >+ "parameters": [ >+ { >+ "name": "body", >+ "in": "body", >+ "description": "A JSON object containing informations about the new notice", >+ "required": true, >+ "schema": { "$ref" : "../definitions.json#/notice" } >+ } >+ ], >+ "produces": [ >+ "application/json" >+ ], >+ "responses": { >+ "201": { >+ "description": "A notice", >+ "schema": { >+ "$ref" : "../definitions.json#/notice" >+ } >+ }, >+ "400": { >+ "description": "Missing or wrong parameters", >+ "schema": { "$ref": "../definitions.json#/error" } >+ }, >+ "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" >+ } >+ } >+ } >+ } >+ }, >+ "/notices/{message_id}": { >+ "put": { >+ "x-mojo-to": "Notice#edit", >+ "operationId": "editNotice", >+ "x-koha-authorization": { >+ "permissions": { >+ "messages": "update_message" >+ } >+ }, >+ "tags": ["notices"], >+ "parameters": [ >+ { >+ "name": "body", >+ "in": "body", >+ "description": "A JSON object containing informations about the new notice", >+ "required": false, >+ "schema": { "$ref": "../definitions.json#/notice" } >+ }, >+ { >+ "$ref": "../parameters.json#/message_idPathParam" >+ } >+ ], >+ "produces": [ >+ "application/json" >+ ], >+ "responses": { >+ "200": { >+ "description": "A notice", >+ "schema": { >+ "$ref" : "../definitions.json#/notice" >+ } >+ }, >+ "400": { >+ "description": "Missing or wrong parameters", >+ "schema": { "$ref": "../definitions.json#/error" } >+ }, >+ "401": { >+ "description": "Authentication required", >+ "schema": { >+ "$ref": "../definitions.json#/error" >+ } >+ }, >+ "403": { >+ "description": "Access forbidden", >+ "schema": { >+ "$ref": "../definitions.json#/error" >+ } >+ }, >+ "404": { >+ "description": "Notice 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" >+ } >+ } >+ } >+ }, >+ "patch": { >+ "x-mojo-to": "Notice#patch", >+ "operationId": "patchNotice", >+ "x-koha-authorization": { >+ "permissions": { >+ "messages": "update_message" >+ } >+ }, >+ "tags": ["notices"], >+ "parameters": [ >+ { >+ "name": "body", >+ "in": "body", >+ "description": "A JSON object containing informations about the new notice", >+ "schema": { "$ref": "../definitions.json#/notice" } >+ }, >+ { >+ "$ref": "../parameters.json#/message_idPathParam" >+ } >+ ], >+ "produces": [ >+ "application/json" >+ ], >+ "responses": { >+ "200": { >+ "description": "A notice", >+ "schema": { >+ "$ref" : "../definitions.json#/notice" >+ } >+ }, >+ "400": { >+ "description": "Missing or wrong parameters", >+ "schema": { "$ref": "../definitions.json#/error" } >+ }, >+ "401": { >+ "description": "Authentication required", >+ "schema": { >+ "$ref": "../definitions.json#/error" >+ } >+ }, >+ "403": { >+ "description": "Access forbidden", >+ "schema": { >+ "$ref": "../definitions.json#/error" >+ } >+ }, >+ "404": { >+ "description": "Notice 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" >+ } >+ } >+ } >+ }, >+ "delete": { >+ "x-mojo-to": "Notice#delete", >+ "operationId": "deleteNotice", >+ "x-koha-authorization": { >+ "permissions": { >+ "messages": "delete_message" >+ } >+ }, >+ "tags": ["notices"], >+ "parameters": [ >+ { >+ "$ref": "../parameters.json#/message_idPathParam" >+ } >+ ], >+ "produces": [ >+ "application/json" >+ ], >+ "responses": { >+ "204": { >+ "description": "Deleting the notice succeeded.", >+ "schema": { >+ "type": "object" >+ } >+ }, >+ "401": { >+ "description": "Authentication required", >+ "schema": { >+ "$ref": "../definitions.json#/error" >+ } >+ }, >+ "403": { >+ "description": "Access forbidden", >+ "schema": { >+ "$ref": "../definitions.json#/error" >+ } >+ }, >+ "404": { >+ "description": "Notice 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" >+ } >+ } >+ } >+ }, >+ "get": { >+ "x-mojo-to": "Notice#get", >+ "operationId": "getNotice", >+ "x-koha-authorization": { >+ "permissions": { >+ "messages": "get_message" >+ }, >+ "allow-owner": true, >+ "allow-guarantor": true >+ }, >+ "tags": ["notices"], >+ "parameters": [ >+ { >+ "$ref": "../parameters.json#/message_idPathParam" >+ } >+ ], >+ "produces": [ >+ "application/json" >+ ], >+ "responses": { >+ "200": { >+ "description": "A notice", >+ "schema": { >+ "$ref" : "../definitions.json#/notice" >+ } >+ }, >+ "401": { >+ "description": "Authentication required", >+ "schema": { >+ "$ref": "../definitions.json#/error" >+ } >+ }, >+ "403": { >+ "description": "Access forbidden", >+ "schema": { >+ "$ref": "../definitions.json#/error" >+ } >+ }, >+ "404": { >+ "description": "Notice 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" >+ } >+ } >+ } >+ } >+ }, >+ "/notices/{message_id}/resend": { >+ "post": { >+ "x-mojo-to": "Notice#resend", >+ "operationId": "resendNotice", >+ "x-koha-authorization": { >+ "permissions": { >+ "messages": "resend_message" >+ } >+ }, >+ "tags": ["notices"], >+ "parameters": [ >+ { >+ "$ref": "../parameters.json#/message_idPathParam" >+ } >+ ], >+ "produces": [ >+ "application/json" >+ ], >+ "responses": { >+ "204": { >+ "description": "Resending the notice succeeded.", >+ "schema": { >+ "type": "object" >+ } >+ }, >+ "401": { >+ "description": "Authentication required", >+ "schema": { >+ "$ref": "../definitions.json#/error" >+ } >+ }, >+ "403": { >+ "description": "Access forbidden", >+ "schema": { >+ "$ref": "../definitions.json#/error" >+ } >+ }, >+ "404": { >+ "description": "Notice 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" >+ } >+ } >+ } >+ } >+ } >+} >diff --git a/installer/data/mysql/atomicupdate/Bug-14843-Add_Permissions_for_message_queue-REST_operations.pl b/installer/data/mysql/atomicupdate/Bug-14843-Add_Permissions_for_message_queue-REST_operations.pl >new file mode 100644 >index 0000000..4418ce4 >--- /dev/null >+++ b/installer/data/mysql/atomicupdate/Bug-14843-Add_Permissions_for_message_queue-REST_operations.pl >@@ -0,0 +1,35 @@ >+#!/usr/bin/perl >+ >+# Copyright Koha-Suomi Oy 2017 >+# >+# 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 C4::Context; >+use Koha::AtomicUpdater; >+ >+my $dbh = C4::Context->dbh(); >+my $atomicUpdater = Koha::AtomicUpdater->new(); >+ >+use Koha::Auth::PermissionManager; >+my $pm = Koha::Auth::PermissionManager->new(); >+$pm->addPermissionModule({module => 'messages', description => 'Permission regarding notifications and messages in message queue.'}); >+$pm->addPermission({module => 'messages', code => 'get_message', description => "Allows to get the messages in message queue."}); >+$pm->addPermission({module => 'messages', code => 'create_message', description => "Allows to create a new message and queue it."}); >+$pm->addPermission({module => 'messages', code => 'update_message', description => "Allows to update messages in message queue."}); >+$pm->addPermission({module => 'messages', code => 'delete_message', description => "Allows to delete a message and queue it."}); >+$pm->addPermission({module => 'messages', code => 'resend_message', description => "Allows to resend messages in message queue."}); >+ >+print "Upgrade done (Bug 14843: Add Pemissions for message queue REST operations)\n"; >diff --git a/t/db_dependent/api/v1/notices.t b/t/db_dependent/api/v1/notices.t >new file mode 100644 >index 0000000..88f34fb >--- /dev/null >+++ b/t/db_dependent/api/v1/notices.t >@@ -0,0 +1,411 @@ >+#!/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 => 7; >+use Test::Mojo; >+use t::lib::Mocks; >+use t::lib::TestBuilder; >+ >+use C4::Auth; >+use C4::Context; >+ >+use Koha::Database; >+use Koha::Notice::Messages; >+ >+my $schema = Koha::Database->new->schema; >+my $builder = t::lib::TestBuilder->new; >+ >+# FIXME: sessionStorage defaults to mysql, but it seems to break transaction handling >+# this affects the other REST api tests >+t::lib::Mocks::mock_preference( 'SessionStorage', 'tmp' ); >+ >+my $remote_address = '127.0.0.1'; >+my $t = Test::Mojo->new('Koha::REST::V1'); >+ >+subtest 'list() tests' => sub { >+ plan tests => 24; >+ >+ $schema->storage->txn_begin; >+ >+ Koha::Notice::Messages->delete; >+ >+ my ($patron, $session) = create_user_and_session(); >+ my ($another_patron, undef) = create_user_and_session(); >+ my ($librarian, $librarian_session) = create_user_and_session({ >+ "messages" => "get_message" >+ }); >+ >+ my $notice = $builder->build({ >+ source => 'MessageQueue', >+ value => { >+ borrowernumber => $patron->borrowernumber, >+ time_queued => '2016-01-01 13:00:00' >+ } >+ }); >+ my $another_notice = $builder->build({ >+ source => 'MessageQueue', >+ value => { >+ borrowernumber => $another_patron->borrowernumber, >+ time_queued => '2017-01-01 13:00:00' >+ } >+ }); >+ my $message_id = $notice->{'message_id'}; >+ my $another_message_id = $another_notice->{'message_id'}; >+ >+ my $tx = $t->ua->build_tx(GET => "/api/v1/notices?borrowernumber=" >+ .$patron->borrowernumber); >+ $tx->req->cookies({name => 'CGISESSID', value => $session->id}); >+ $tx->req->env({REMOTE_ADDR => '127.0.0.1'}); >+ $t->request_ok($tx) >+ ->status_is(200) >+ ->json_is('/0/subject' => $notice->{'subject'}); >+ >+ $tx = $t->ua->build_tx(GET => "/api/v1/notices?borrowernumber=" >+ .$another_patron->borrowernumber); >+ $tx->req->cookies({name => 'CGISESSID', value => $session->id}); >+ $tx->req->env({REMOTE_ADDR => '127.0.0.1'}); >+ $t->request_ok($tx) >+ ->status_is(403); >+ >+ $tx = $t->ua->build_tx(GET => "/api/v1/notices?borrowernumber=-1"); >+ $tx->req->cookies({name => 'CGISESSID', value => $librarian_session->id}); >+ $tx->req->env({REMOTE_ADDR => '127.0.0.1'}); >+ $t->request_ok($tx) >+ ->status_is(200) >+ ->json_is('/0' => undef); >+ >+ $tx = $t->ua->build_tx(GET => "/api/v1/notices?borrowernumber=" >+ .$patron->borrowernumber); >+ $tx->req->cookies({name => 'CGISESSID', value => $librarian_session->id}); >+ $tx->req->env({REMOTE_ADDR => '127.0.0.1'}); >+ $t->request_ok($tx) >+ ->status_is(200) >+ ->json_is('/0/subject' => $notice->{'subject'}); >+ >+ $tx = $t->ua->build_tx(GET => '/api/v1/notices?' >+ .'time_queued_start=2016-12-12 12:00:00'); >+ $tx->req->cookies({name => 'CGISESSID', value => $librarian_session->id}); >+ $tx->req->env({REMOTE_ADDR => '127.0.0.1'}); >+ $t->request_ok($tx) >+ ->status_is(200) >+ ->json_is('/0/subject' => $another_notice->{'subject'}) >+ ->json_hasnt('/1'); >+ >+ $tx = $t->ua->build_tx(GET => '/api/v1/notices?' >+ .'time_queued_end=2016-12-12 12:00:00'); >+ $tx->req->cookies({name => 'CGISESSID', value => $librarian_session->id}); >+ $tx->req->env({REMOTE_ADDR => '127.0.0.1'}); >+ $t->request_ok($tx) >+ ->status_is(200) >+ ->json_is('/0/subject' => $notice->{'subject'}) >+ ->json_hasnt('/1'); >+ >+ $tx = $t->ua->build_tx(GET => '/api/v1/notices?' >+ .'time_queued_start=2014-12-12 12:00:00&time_queued_end=2018-01-01 12:00:00'); >+ $tx->req->cookies({name => 'CGISESSID', value => $librarian_session->id}); >+ $tx->req->env({REMOTE_ADDR => '127.0.0.1'}); >+ $t->request_ok($tx) >+ ->status_is(200) >+ ->json_is('/0/subject' => $notice->{'subject'}) >+ ->json_is('/1/subject' => $another_notice->{'subject'}) >+ ->json_hasnt('/2'); >+ >+ $schema->storage->txn_rollback; >+}; >+ >+subtest 'get() tests' => sub { >+ plan tests => 8; >+ >+ $schema->storage->txn_begin; >+ >+ my ($patron, $session) = create_user_and_session(); >+ my ($another_patron, undef) = create_user_and_session(); >+ my ($librarian, $librarian_session) = create_user_and_session({ >+ "messages" => "get_message" >+ }); >+ >+ my $notice = $builder->build({ >+ source => 'MessageQueue', >+ value => { >+ borrowernumber => $patron->borrowernumber, >+ } >+ }); >+ my $another_notice = $builder->build({ >+ source => 'MessageQueue', >+ value => { >+ borrowernumber => $another_patron->borrowernumber, >+ } >+ }); >+ my $message_id = $notice->{'message_id'}; >+ my $another_message_id = $another_notice->{'message_id'}; >+ >+ my $tx = $t->ua->build_tx(GET => "/api/v1/notices/$message_id"); >+ $tx->req->cookies({name => 'CGISESSID', value => $session->id}); >+ $tx->req->env({REMOTE_ADDR => '127.0.0.1'}); >+ $t->request_ok($tx) >+ ->status_is(200) >+ ->json_is('/subject' => $notice->{'subject'}); >+ >+ $tx = $t->ua->build_tx(GET => "/api/v1/notices/$another_message_id"); >+ $tx->req->cookies({name => 'CGISESSID', value => $session->id}); >+ $tx->req->env({REMOTE_ADDR => '127.0.0.1'}); >+ $t->request_ok($tx) >+ ->status_is(403); >+ >+ $tx = $t->ua->build_tx(GET => "/api/v1/notices/$message_id"); >+ $tx->req->cookies({name => 'CGISESSID', value => $librarian_session->id}); >+ $tx->req->env({REMOTE_ADDR => '127.0.0.1'}); >+ $t->request_ok($tx) >+ ->status_is(200) >+ ->json_is('/subject' => $notice->{'subject'}); >+ >+ $schema->storage->txn_rollback; >+}; >+ >+subtest 'post() tests' => sub { >+ plan tests => 6; >+ >+ $schema->storage->txn_begin; >+ >+ my ($patron, $session) = create_user_and_session(); >+ my ($librarian, $librarian_session) = create_user_and_session({ >+ "messages" => "create_message" >+ }); >+ >+ my $notice = { >+ borrowernumber => 0+$patron->borrowernumber, >+ subject => 'Bring milk from the store, please!', >+ content => 'Title says it all', >+ message_transport_type => 'email', >+ status => 'failed', >+ }; >+ >+ my $tx = $t->ua->build_tx(POST => "/api/v1/notices" => json => $notice); >+ $tx->req->cookies({name => 'CGISESSID', value => $session->id}); >+ $tx->req->env({REMOTE_ADDR => '127.0.0.1'}); >+ $t->request_ok($tx) >+ ->status_is(403); >+ >+ $tx = $t->ua->build_tx(POST => "/api/v1/notices" => json => $notice); >+ $tx->req->cookies({name => 'CGISESSID', value => $librarian_session->id}); >+ $tx->req->env({REMOTE_ADDR => '127.0.0.1'}); >+ $t->request_ok($tx) >+ ->status_is(201) >+ ->json_is('/subject' => $notice->{'subject'}); >+ >+ my $msg = Koha::Notice::Messages->search({}, { >+ order_by => { '-desc' => 'message_id' } >+ })->next; >+ is($msg->subject, $notice->{subject}, 'The notice was really added!'); >+ >+ $schema->storage->txn_rollback; >+}; >+ >+subtest 'edit() tests' => sub { >+ plan tests => 5; >+ >+ $schema->storage->txn_begin; >+ >+ my ($patron, $session) = create_user_and_session(); >+ my ($librarian, $librarian_session) = create_user_and_session({ >+ "messages" => "update_message" >+ }); >+ >+ my $notice = $builder->build({ >+ source => 'MessageQueue', >+ value => { >+ borrowernumber => $patron->borrowernumber, >+ } >+ }); >+ >+ my $new_notice = { >+ subject => 'Bring milk from the store, please!', >+ content => 'Title says it all', >+ message_transport_type => 'email', >+ status => 'failed', >+ }; >+ >+ my $message_id = $notice->{'message_id'}; >+ >+ my $tx = $t->ua->build_tx(PUT => "/api/v1/notices/$message_id" => >+ json => $new_notice); >+ $tx->req->cookies({name => 'CGISESSID', value => $session->id}); >+ $tx->req->env({REMOTE_ADDR => '127.0.0.1'}); >+ $t->request_ok($tx) >+ ->status_is(403); >+ >+ $tx = $t->ua->build_tx(PUT => "/api/v1/notices/$message_id" => >+ json => $new_notice); >+ $tx->req->cookies({name => 'CGISESSID', value => $librarian_session->id}); >+ $tx->req->env({REMOTE_ADDR => '127.0.0.1'}); >+ $t->request_ok($tx) >+ ->status_is(200) >+ ->json_is('/subject' => $new_notice->{'subject'}); >+ >+ $schema->storage->txn_rollback; >+}; >+ >+subtest 'put() tests' => sub { >+ plan tests => 6; >+ >+ $schema->storage->txn_begin; >+ >+ my ($patron, $session) = create_user_and_session(); >+ my ($librarian, $librarian_session) = create_user_and_session({ >+ "messages" => "update_message" >+ }); >+ >+ my $notice = $builder->build({ >+ source => 'MessageQueue', >+ value => { >+ borrowernumber => $patron->borrowernumber, >+ } >+ }); >+ >+ my $new_notice = { >+ status => 'pending', >+ }; >+ >+ my $message_id = $notice->{'message_id'}; >+ >+ my $tx = $t->ua->build_tx(PATCH => "/api/v1/notices/$message_id" => >+ json => $new_notice); >+ $tx->req->cookies({name => 'CGISESSID', value => $session->id}); >+ $tx->req->env({REMOTE_ADDR => '127.0.0.1'}); >+ $t->request_ok($tx) >+ ->status_is(403); >+ >+ $tx = $t->ua->build_tx(PATCH => "/api/v1/notices/$message_id" => >+ json => $new_notice); >+ $tx->req->cookies({name => 'CGISESSID', value => $librarian_session->id}); >+ $tx->req->env({REMOTE_ADDR => '127.0.0.1'}); >+ $t->request_ok($tx) >+ ->status_is(200) >+ ->json_is('/subject' => $notice->{'subject'}) >+ ->json_is('/status' => $new_notice->{'status'}); >+ >+ $schema->storage->txn_rollback; >+}; >+ >+subtest 'resend() tests' => sub { >+ plan tests => 6; >+ >+ $schema->storage->txn_begin; >+ >+ my ($patron, $session) = create_user_and_session(); >+ my ($librarian, $librarian_session) = create_user_and_session({ >+ "messages" => "resend_message" >+ }); >+ >+ my $notice = $builder->build({ >+ source => 'MessageQueue', >+ value => { >+ borrowernumber => $patron->borrowernumber, >+ status => 'failed' >+ } >+ }); >+ >+ my $message_id = $notice->{'message_id'}; >+ >+ my $msg = Koha::Notice::Messages->find($message_id); >+ is($msg->status, 'failed', 'The notice is in failed status.'); >+ >+ my $tx = $t->ua->build_tx(POST => "/api/v1/notices/$message_id/resend"); >+ $tx->req->cookies({name => 'CGISESSID', value => $session->id}); >+ $tx->req->env({REMOTE_ADDR => '127.0.0.1'}); >+ $t->request_ok($tx) >+ ->status_is(403); >+ >+ $tx = $t->ua->build_tx(POST => "/api/v1/notices/$message_id/resend"); >+ $tx->req->cookies({name => 'CGISESSID', value => $librarian_session->id}); >+ $tx->req->env({REMOTE_ADDR => '127.0.0.1'}); >+ $t->request_ok($tx) >+ ->status_is(204); >+ >+ $msg = Koha::Notice::Messages->find($message_id); >+ is($msg->status, 'pending', 'The notice has been set to pending!'); >+ >+ $schema->storage->txn_rollback; >+}; >+ >+subtest 'delete() tests' => sub { >+ plan tests => 5; >+ >+ $schema->storage->txn_begin; >+ >+ my ($patron, $session) = create_user_and_session(); >+ my ($librarian, $librarian_session) = create_user_and_session({ >+ "messages" => "delete_message" >+ }); >+ >+ my $notice = $builder->build({ >+ source => 'MessageQueue', >+ value => { >+ borrowernumber => $patron->borrowernumber, >+ } >+ }); >+ >+ my $message_id = $notice->{'message_id'}; >+ >+ my $tx = $t->ua->build_tx(DELETE => "/api/v1/notices/$message_id"); >+ $tx->req->cookies({name => 'CGISESSID', value => $session->id}); >+ $tx->req->env({REMOTE_ADDR => '127.0.0.1'}); >+ $t->request_ok($tx) >+ ->status_is(403); >+ >+ $tx = $t->ua->build_tx(DELETE => "/api/v1/notices/$message_id"); >+ $tx->req->cookies({name => 'CGISESSID', value => $librarian_session->id}); >+ $tx->req->env({REMOTE_ADDR => '127.0.0.1'}); >+ $t->request_ok($tx) >+ ->status_is(204); >+ >+ my $msg = Koha::Notice::Messages->find($message_id); >+ is($msg, undef, 'The notice was really deleted!'); >+ >+ $schema->storage->txn_rollback; >+}; >+ >+sub create_user_and_session { >+ my ($flags) = @_; >+ >+ my $categorycode = $builder->build({ source => 'Category' })->{categorycode}; >+ my $branchcode = $builder->build({ source => 'Branch' })->{ branchcode }; >+ >+ my $borrower = $builder->build({ >+ source => 'Borrower', >+ value => { >+ branchcode => $branchcode, >+ categorycode => $categorycode, >+ } >+ }); >+ >+ my $session = C4::Auth::get_session(''); >+ $session->param('number', $borrower->{ borrowernumber }); >+ $session->param('id', $borrower->{ userid }); >+ $session->param('ip', '127.0.0.1'); >+ $session->param('lasttime', time()); >+ $session->flush; >+ my $patron = Koha::Patrons->find($borrower->{borrowernumber}); >+ if ( $flags ) { >+ Koha::Auth::PermissionManager->grantPermissions($patron, $flags); >+ } >+ >+ return ($patron, $session); >+} >-- >2.7.4
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 14843
:
42645
|
42693
|
42694
|
42719
| 62791