View | Details | Raw Unified | Return to bug 14843
Collapse All | Expand All

(-)a/Koha/REST/V1/Auth.pm (+16 lines)
Lines 28-33 use C4::Auth qw( check_cookie_auth get_session haspermission ); Link Here
28
use Koha::Account::Lines;
28
use Koha::Account::Lines;
29
use Koha::Checkouts;
29
use Koha::Checkouts;
30
use Koha::Holds;
30
use Koha::Holds;
31
use Koha::Notice::Messages;
31
use Koha::Old::Checkouts;
32
use Koha::Old::Checkouts;
32
use Koha::Patrons;
33
use Koha::Patrons;
33
34
Lines 335-340 sub check_object_ownership { Link Here
335
        borrowernumber  => \&_object_ownership_by_borrowernumber,
336
        borrowernumber  => \&_object_ownership_by_borrowernumber,
336
        checkout_id     => \&_object_ownership_by_checkout_id,
337
        checkout_id     => \&_object_ownership_by_checkout_id,
337
        reserve_id      => \&_object_ownership_by_reserve_id,
338
        reserve_id      => \&_object_ownership_by_reserve_id,
339
        message_id      => \&_object_ownership_by_message_id,
338
    };
340
    };
339
341
340
    foreach my $param ( keys %{ $parameters } ) {
342
    foreach my $param ( keys %{ $parameters } ) {
Lines 398-403 sub _object_ownership_by_checkout_id { Link Here
398
            && $user->borrowernumber == $issue->borrowernumber;
400
            && $user->borrowernumber == $issue->borrowernumber;
399
}
401
}
400
402
403
=head3 _object_ownership_by_message_id
404
405
Finds a Koha::Notice::Message-object by C<$message_id> and checks if it
406
belongs to C<$user>.
407
408
=cut
409
410
sub _object_ownership_by_message_id {
411
    my ($c, $user, $message_id) = @_;
412
413
    my $message = Koha::Notice::Messages->find($message_id);
414
    return $message && $user->borrowernumber == $message->borrowernumber;
415
}
416
401
=head3 _object_ownership_by_reserve_id
417
=head3 _object_ownership_by_reserve_id
402
418
403
Finds a Koha::Hold-object by C<$reserve_id> and checks if it
419
Finds a Koha::Hold-object by C<$reserve_id> and checks if it
(-)a/Koha/REST/V1/Notice.pm (+176 lines)
Line 0 Link Here
1
package Koha::REST::V1::Notice;
2
3
# This file is part of Koha.
4
#
5
# Koha is free software; you can redistribute it and/or modify it under the
6
# terms of the GNU General Public License as published by the Free Software
7
# Foundation; either version 3 of the License, or (at your option) any later
8
# version.
9
#
10
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
11
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License along
15
# with Koha; if not, write to the Free Software Foundation, Inc.,
16
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
18
use Modern::Perl;
19
20
use Mojo::Base 'Mojolicious::Controller';
21
22
use Koha::Notice::Messages;
23
24
use Try::Tiny;
25
26
sub list {
27
    my $c = shift->openapi->valid_input or return;
28
29
    return try {
30
        my $params = $c->req->query_params->to_hash;
31
            $params = _between_time_queued($params); # Construct 'time_queued'
32
        my $notices;
33
        if (keys %$params) {
34
            my @valid_params = Koha::Notice::Messages->columns;
35
            foreach my $key (keys %$params) {
36
                delete $params->{$key} unless grep { $key eq $_ } @valid_params;
37
            }
38
            $notices = Koha::Notice::Messages->search($params);
39
        } else {
40
            $notices = Koha::Notice::Messages->search;
41
        }
42
43
        return $c->render(status => 200, openapi => $notices);
44
    }
45
    catch {
46
        Koha::Exceptions::rethrow_exception($_);
47
    };
48
}
49
50
sub get {
51
    my $c = shift->openapi->valid_input or return;
52
53
    my $message_id = $c->validation->param('message_id');
54
    my $notice;
55
    return try {
56
        $notice = Koha::Notice::Messages->find($message_id);
57
58
        unless ($notice) {
59
            return $c->render( status  => 404,
60
                               openapi => { error => "Notice not found" } );
61
        }
62
63
        return $c->render(status => 200, openapi => $notice);
64
    }
65
    catch {
66
        Koha::Exceptions::rethrow_exception($_);
67
    };
68
}
69
70
sub add {
71
    my $c = shift->openapi->valid_input or return;
72
73
    return try {
74
        my $body = $c->req->json;
75
76
        my $notice = Koha::Notice::Message->new($body)->store;
77
           $notice = Koha::Notice::Messages->find($notice->message_id);
78
        return $c->render(status => 201, openapi => $notice);
79
    }
80
    catch {
81
        Koha::Exceptions::rethrow_exception($_);
82
    };
83
}
84
85
sub edit {
86
    my $c = shift->openapi->valid_input or return;
87
88
    my $notice;
89
    return try {
90
        my $message_id = $c->validation->param('message_id');
91
        $notice = Koha::Notice::Messages->find($message_id);
92
        my $body = $c->req->json;
93
94
        $notice->set($body);
95
        return $c->render( status => 204, openapi => {}) unless $notice->is_changed;
96
        $notice->store;
97
        return $c->render( status => 200, openapi => $notice);
98
    }
99
    catch {
100
        unless ($notice) {
101
            return $c->render( status  => 404,
102
                               openapi => { error => "Notice not found" } );
103
        }
104
        Koha::Exceptions::rethrow_exception($_);
105
    };
106
}
107
108
sub patch {
109
    return edit(@_);
110
}
111
112
sub delete {
113
    my $c = shift->openapi->valid_input or return;
114
115
    my $notice = Koha::Notice::Messages->find($c->validation->param('message_id'));
116
    unless ($notice) {
117
        return $c->render( status  => 404,
118
                           openapi => { error => "Notice not found" } );
119
    }
120
121
    my $res = $notice->delete;
122
123
    if ($res eq '1') {
124
        return $c->render( status => 204, openapi => {});
125
    } elsif ($res eq '-1') {
126
        return $c->render( status => 404, openapi => {});
127
    } else {
128
        return $c->render( status => 400, openapi => {});
129
    }
130
}
131
132
sub resend {
133
    my $c = shift->openapi->valid_input or return;
134
135
    my $notice;
136
    return try {
137
        my $message_id = $c->validation->param('message_id');
138
        $notice = Koha::Notice::Messages->find($message_id);
139
        $notice->status('pending')->store;
140
        return $c->render( status => 204, openapi => {});
141
    }
142
    catch {
143
        unless ($notice) {
144
            return $c->render( status  => 404,
145
                               openapi => { error => "Notice not found" } );
146
        }
147
        Koha::Exceptions::rethrow_exception($_);
148
    };
149
}
150
151
sub _between_time_queued {
152
    my ($params) = @_;
153
154
    return $params if      $params->{'time_queued'};
155
    return $params if (   !$params->{'time_queued_start'}
156
                       && !$params->{'time_queued_end'} );
157
158
    my $start = $params->{'time_queued_start'};
159
    my $end   = $params->{'time_queued_end'};
160
161
    if ($start && !$end) {
162
        $params->{'time_queued'} = { '>=', $start };
163
    }
164
    elsif (!$start && $end) {
165
        $params->{'time_queued'} = { '<=', $end };
166
    }
167
    else {
168
        $params->{'time_queued'} = { '-between', [$start, $end] };
169
    }
170
171
    delete $params->{'time_queued_start'};
172
    delete $params->{'time_queued_end'};
173
    return $params;
174
}
175
176
1;
(-)a/api/v1/swagger/definitions.json (+3 lines)
Lines 50-55 Link Here
50
  "library": {
50
  "library": {
51
    "$ref": "definitions/library.json"
51
    "$ref": "definitions/library.json"
52
  },
52
  },
53
  "notice": {
54
    "$ref": "definitions/notice.json"
55
  },
53
  "error": {
56
  "error": {
54
    "$ref": "definitions/error.json"
57
    "$ref": "definitions/error.json"
55
  },
58
  },
(-)a/api/v1/swagger/definitions/notice.json (+59 lines)
Line 0 Link Here
1
{
2
  "type": "object",
3
  "properties": {
4
    "message_id": {
5
      "description": "Message internal identifier",
6
      "type": "integer",
7
      "readOnly": true
8
    },
9
    "borrowernumber": {
10
      "$ref": "../x-primitives.json#/borrowernumber"
11
    },
12
    "subject": {
13
      "description": "Subject of the message",
14
      "type": ["string", "null"]
15
    },
16
    "content": {
17
      "description": "Content of the message",
18
      "type": ["string", "null"]
19
    },
20
    "metadata": {
21
      "description": "",
22
      "type": ["string", "null"]
23
    },
24
    "letter_code": {
25
      "description": "",
26
      "type": ["string", "null"]
27
    },
28
    "message_transport_type": {
29
      "description": "Transport method. Values accepted by default are 'email', 'sms', 'phone' and 'print'",
30
      "type": "string"
31
    },
32
    "status": {
33
      "description": "Delivery status",
34
      "type": "string"
35
    },
36
    "time_queued": {
37
      "description": "Date and time of when message was placed in queue",
38
      "type": "string",
39
      "format": "date-time"
40
    },
41
    "to_address": {
42
      "description": "Destination email address",
43
      "type": ["string", "null"]
44
    },
45
    "from_address": {
46
      "description": "Source address of email",
47
      "type": ["string", "null"]
48
    },
49
    "content_type": {
50
      "description": "Content type",
51
      "type": ["string", "null"]
52
    },
53
    "delivery_note": {
54
      "description": "Additional delivery notes",
55
      "type": ["string", "null"]
56
    }
57
  },
58
  "additionalProperties": false
59
}
(-)a/api/v1/swagger/parameters.json (+3 lines)
Lines 38-43 Link Here
38
  "itemnumbersQueryParam": {
38
  "itemnumbersQueryParam": {
39
    "$ref": "parameters/item.json#/itemnumbersQueryParam"
39
    "$ref": "parameters/item.json#/itemnumbersQueryParam"
40
  },
40
  },
41
  "message_idPathParam": {
42
    "$ref": "parameters/notice.json#/message_idPathParam"
43
  },
41
  "passwordPostParam": {
44
  "passwordPostParam": {
42
   "$ref": "parameters/auth.json#/passwordPostParam"
45
   "$ref": "parameters/auth.json#/passwordPostParam"
43
  },
46
  },
(-)a/api/v1/swagger/parameters/notice.json (+9 lines)
Line 0 Link Here
1
{
2
  "message_idPathParam": {
3
    "name": "message_id",
4
    "in": "path",
5
    "description": "Message internal identifier",
6
    "required": true,
7
    "type": "integer"
8
  }
9
}
(-)a/api/v1/swagger/paths.json (+9 lines)
Lines 77-82 Link Here
77
  "/libraries/{branchcode}": {
77
  "/libraries/{branchcode}": {
78
    "$ref": "paths/libraries.json#/~1libraries~1{branchcode}"
78
    "$ref": "paths/libraries.json#/~1libraries~1{branchcode}"
79
  },
79
  },
80
  "/notices": {
81
    "$ref": "paths/notices.json#/~1notices"
82
  },
83
  "/notices/{message_id}": {
84
    "$ref": "paths/notices.json#/~1notices~1{message_id}"
85
  },
86
  "/notices/{message_id}/resend": {
87
    "$ref": "paths/notices.json#/~1notices~1{message_id}~1resend"
88
  },
80
  "/patrons": {
89
  "/patrons": {
81
    "$ref": "paths/patrons.json#/~1patrons"
90
    "$ref": "paths/patrons.json#/~1patrons"
82
  },
91
  },
(-)a/api/v1/swagger/paths/notices.json (+493 lines)
Line 0 Link Here
1
{
2
  "/notices": {
3
    "get": {
4
      "x-mojo-to": "Notice#list",
5
      "operationId": "listNotices",
6
      "x-koha-authorization": {
7
        "permissions": {
8
          "messages": "get_message"
9
        },
10
        "allow-owner": true,
11
        "allow-guarantor": true
12
      },
13
      "tags": ["notices"],
14
      "parameters": [{
15
        "name": "borrowernumber",
16
        "in": "query",
17
        "description": "Patron's borrowernumber",
18
        "required": false,
19
        "type": "integer"
20
      }, {
21
        "name": "subject",
22
        "in": "query",
23
        "description": "Case insensative 'starts-with' search on subject",
24
        "required": false,
25
        "type": "string"
26
      }, {
27
        "name": "content",
28
        "in": "query",
29
        "description": "Case insensative 'starts_with' search on content",
30
        "required": false,
31
        "type": "string"
32
      }, {
33
        "name": "metadata",
34
        "in": "query",
35
        "description": "Case insensative 'starts_with' search on metadata",
36
        "required": false,
37
        "type": "string"
38
      }, {
39
        "name": "message_transport_type",
40
        "in": "query",
41
        "description": "Case insensative 'starts_with' search on message transport type",
42
        "required": false,
43
        "type": "string"
44
      }, {
45
        "name": "time_queued_start",
46
        "in": "query",
47
        "description": "Search notices after given time",
48
        "required": false,
49
        "type": "string",
50
        "format": "date-time"
51
      }, {
52
        "name": "time_queued_end",
53
        "in": "query",
54
        "description": "Search notices before given time",
55
        "required": false,
56
        "type": "string"
57
      }, {
58
        "name": "to_address",
59
        "in": "query",
60
        "description": "Case insensative 'starts_with' search on to address",
61
        "required": false,
62
        "type": "string"
63
      }, {
64
        "name": "from_address",
65
        "in": "query",
66
        "description": "Case insensative 'starts_with' search on from address",
67
        "required": false,
68
        "type": "string"
69
      }, {
70
        "name": "content_type",
71
        "in": "query",
72
        "description": "Case insensative 'starts_with' search on content type",
73
        "required": false,
74
        "type": "string"
75
      }, {
76
        "name": "delivery_note",
77
        "in": "query",
78
        "description": "Case insensative 'starts_with' search on delivery note",
79
        "required": false,
80
        "type": "string"
81
      }],
82
      "produces": [
83
        "application/json"
84
      ],
85
      "responses": {
86
        "200": {
87
          "description": "A list of notices",
88
          "schema": {
89
            "type": "array",
90
            "items": {
91
              "$ref" : "../definitions.json#/notice"
92
            }
93
          }
94
        },
95
        "401": {
96
          "description": "Authentication required",
97
          "schema": {
98
            "$ref": "../definitions.json#/error"
99
          }
100
        },
101
        "403": {
102
          "description": "Access forbidden",
103
          "schema": {
104
            "$ref": "../definitions.json#/error"
105
          }
106
        },
107
        "404": {
108
          "description": "Notice not found",
109
          "schema": {
110
            "$ref": "../definitions.json#/error"
111
          }
112
        },
113
        "500": {
114
          "description": "Internal error",
115
          "schema": {
116
            "$ref": "../definitions.json#/error"
117
          }
118
        },
119
        "503": {
120
          "description": "Under maintenance",
121
          "schema": {
122
            "$ref": "../definitions.json#/error"
123
          }
124
        }
125
      }
126
    },
127
    "post": {
128
      "x-mojo-to": "Notice#add",
129
      "operationId": "addNotice",
130
      "x-koha-authorization": {
131
        "permissions": {
132
          "messages": "create_message"
133
        }
134
      },
135
      "tags": ["notices"],
136
      "parameters": [
137
        {
138
          "name": "body",
139
          "in": "body",
140
          "description": "A JSON object containing informations about the new notice",
141
          "required": true,
142
          "schema": { "$ref" : "../definitions.json#/notice" }
143
        }
144
      ],
145
      "produces": [
146
        "application/json"
147
      ],
148
      "responses": {
149
        "201": {
150
          "description": "A notice",
151
          "schema": {
152
              "$ref" : "../definitions.json#/notice"
153
          }
154
        },
155
        "400": {
156
          "description": "Missing or wrong parameters",
157
          "schema": { "$ref": "../definitions.json#/error" }
158
        },
159
        "401": {
160
          "description": "Authentication required",
161
          "schema": {
162
            "$ref": "../definitions.json#/error"
163
          }
164
        },
165
        "403": {
166
          "description": "Access forbidden",
167
          "schema": {
168
            "$ref": "../definitions.json#/error"
169
          }
170
        },
171
        "500": {
172
          "description": "Internal error",
173
          "schema": {
174
            "$ref": "../definitions.json#/error"
175
          }
176
        },
177
        "503": {
178
          "description": "Under maintenance",
179
          "schema": {
180
            "$ref": "../definitions.json#/error"
181
          }
182
        }
183
      }
184
    }
185
  },
186
  "/notices/{message_id}": {
187
    "put": {
188
      "x-mojo-to": "Notice#edit",
189
      "operationId": "editNotice",
190
      "x-koha-authorization": {
191
        "permissions": {
192
          "messages": "update_message"
193
        }
194
      },
195
      "tags": ["notices"],
196
      "parameters": [
197
        {
198
          "name": "body",
199
          "in": "body",
200
          "description": "A JSON object containing informations about the new notice",
201
          "required": false,
202
          "schema": { "$ref": "../definitions.json#/notice" }
203
        },
204
        {
205
          "$ref": "../parameters.json#/message_idPathParam"
206
        }
207
      ],
208
      "produces": [
209
        "application/json"
210
      ],
211
      "responses": {
212
        "200": {
213
          "description": "A notice",
214
          "schema": {
215
            "$ref" : "../definitions.json#/notice"
216
          }
217
        },
218
        "400": {
219
          "description": "Missing or wrong parameters",
220
          "schema": { "$ref": "../definitions.json#/error" }
221
        },
222
        "401": {
223
          "description": "Authentication required",
224
          "schema": {
225
            "$ref": "../definitions.json#/error"
226
          }
227
        },
228
        "403": {
229
          "description": "Access forbidden",
230
          "schema": {
231
            "$ref": "../definitions.json#/error"
232
          }
233
        },
234
        "404": {
235
          "description": "Notice not found",
236
          "schema": {
237
            "$ref": "../definitions.json#/error"
238
          }
239
        },
240
        "500": {
241
          "description": "Internal error",
242
          "schema": {
243
            "$ref": "../definitions.json#/error"
244
          }
245
        },
246
        "503": {
247
          "description": "Under maintenance",
248
          "schema": {
249
            "$ref": "../definitions.json#/error"
250
          }
251
        }
252
      }
253
    },
254
    "patch": {
255
      "x-mojo-to": "Notice#patch",
256
      "operationId": "patchNotice",
257
      "x-koha-authorization": {
258
        "permissions": {
259
          "messages": "update_message"
260
        }
261
      },
262
      "tags": ["notices"],
263
      "parameters": [
264
        {
265
          "name": "body",
266
          "in": "body",
267
          "description": "A JSON object containing informations about the new notice",
268
          "schema": { "$ref": "../definitions.json#/notice" }
269
        },
270
        {
271
          "$ref": "../parameters.json#/message_idPathParam"
272
        }
273
      ],
274
      "produces": [
275
        "application/json"
276
      ],
277
      "responses": {
278
        "200": {
279
          "description": "A notice",
280
          "schema": {
281
            "$ref" : "../definitions.json#/notice"
282
          }
283
        },
284
        "400": {
285
          "description": "Missing or wrong parameters",
286
          "schema": { "$ref": "../definitions.json#/error" }
287
        },
288
        "401": {
289
          "description": "Authentication required",
290
          "schema": {
291
            "$ref": "../definitions.json#/error"
292
          }
293
        },
294
        "403": {
295
          "description": "Access forbidden",
296
          "schema": {
297
            "$ref": "../definitions.json#/error"
298
          }
299
        },
300
        "404": {
301
          "description": "Notice not found",
302
          "schema": {
303
            "$ref": "../definitions.json#/error"
304
          }
305
        },
306
        "500": {
307
          "description": "Internal error",
308
          "schema": {
309
            "$ref": "../definitions.json#/error"
310
          }
311
        },
312
        "503": {
313
          "description": "Under maintenance",
314
          "schema": {
315
            "$ref": "../definitions.json#/error"
316
          }
317
        }
318
      }
319
    },
320
    "delete": {
321
      "x-mojo-to": "Notice#delete",
322
      "operationId": "deleteNotice",
323
      "x-koha-authorization": {
324
        "permissions": {
325
          "messages": "delete_message"
326
        }
327
      },
328
      "tags": ["notices"],
329
      "parameters": [
330
        {
331
          "$ref": "../parameters.json#/message_idPathParam"
332
        }
333
      ],
334
      "produces": [
335
        "application/json"
336
      ],
337
      "responses": {
338
        "204": {
339
          "description": "Deleting the notice succeeded.",
340
          "schema": {
341
            "type": "object"
342
          }
343
        },
344
        "401": {
345
          "description": "Authentication required",
346
          "schema": {
347
            "$ref": "../definitions.json#/error"
348
          }
349
        },
350
        "403": {
351
          "description": "Access forbidden",
352
          "schema": {
353
            "$ref": "../definitions.json#/error"
354
          }
355
        },
356
        "404": {
357
          "description": "Notice not found.",
358
          "schema": {
359
            "$ref": "../definitions.json#/error"
360
          }
361
        },
362
        "500": {
363
          "description": "Internal error",
364
          "schema": {
365
            "$ref": "../definitions.json#/error"
366
          }
367
        },
368
        "503": {
369
          "description": "Under maintenance",
370
          "schema": {
371
            "$ref": "../definitions.json#/error"
372
          }
373
        }
374
      }
375
    },
376
    "get": {
377
      "x-mojo-to": "Notice#get",
378
      "operationId": "getNotice",
379
      "x-koha-authorization": {
380
        "permissions": {
381
          "messages": "get_message"
382
        },
383
        "allow-owner": true,
384
        "allow-guarantor": true
385
      },
386
      "tags": ["notices"],
387
      "parameters": [
388
        {
389
          "$ref": "../parameters.json#/message_idPathParam"
390
        }
391
      ],
392
      "produces": [
393
        "application/json"
394
      ],
395
      "responses": {
396
        "200": {
397
          "description": "A notice",
398
          "schema": {
399
            "$ref" : "../definitions.json#/notice"
400
          }
401
        },
402
        "401": {
403
          "description": "Authentication required",
404
          "schema": {
405
            "$ref": "../definitions.json#/error"
406
          }
407
        },
408
        "403": {
409
          "description": "Access forbidden",
410
          "schema": {
411
            "$ref": "../definitions.json#/error"
412
          }
413
        },
414
        "404": {
415
          "description": "Notice not found",
416
          "schema": {
417
            "$ref": "../definitions.json#/error"
418
          }
419
        },
420
        "500": {
421
          "description": "Internal error",
422
          "schema": {
423
            "$ref": "../definitions.json#/error"
424
          }
425
        },
426
        "503": {
427
          "description": "Under maintenance",
428
          "schema": {
429
            "$ref": "../definitions.json#/error"
430
          }
431
        }
432
      }
433
    }
434
  },
435
  "/notices/{message_id}/resend": {
436
    "post": {
437
      "x-mojo-to": "Notice#resend",
438
      "operationId": "resendNotice",
439
      "x-koha-authorization": {
440
        "permissions": {
441
          "messages": "resend_message"
442
        }
443
      },
444
      "tags": ["notices"],
445
      "parameters": [
446
        {
447
          "$ref": "../parameters.json#/message_idPathParam"
448
        }
449
      ],
450
      "produces": [
451
        "application/json"
452
      ],
453
      "responses": {
454
        "204": {
455
          "description": "Resending the notice succeeded.",
456
          "schema": {
457
            "type": "object"
458
          }
459
        },
460
        "401": {
461
          "description": "Authentication required",
462
          "schema": {
463
            "$ref": "../definitions.json#/error"
464
          }
465
        },
466
        "403": {
467
          "description": "Access forbidden",
468
          "schema": {
469
            "$ref": "../definitions.json#/error"
470
          }
471
        },
472
        "404": {
473
          "description": "Notice not found",
474
          "schema": {
475
            "$ref": "../definitions.json#/error"
476
          }
477
        },
478
        "500": {
479
          "description": "Internal error",
480
          "schema": {
481
            "$ref": "../definitions.json#/error"
482
          }
483
        },
484
        "503": {
485
          "description": "Under maintenance",
486
          "schema": {
487
            "$ref": "../definitions.json#/error"
488
          }
489
        }
490
      }
491
    }
492
  }
493
}
(-)a/installer/data/mysql/atomicupdate/Bug-14843-Add_Permissions_for_message_queue-REST_operations.pl (+35 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# Copyright Koha-Suomi Oy 2017
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it under the
8
# terms of the GNU General Public License as published by the Free Software
9
# Foundation; either version 3 of the License, or (at your option) any later
10
# version.
11
#
12
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License along
17
# with Koha; if not, write to the Free Software Foundation, Inc.,
18
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20
use C4::Context;
21
use Koha::AtomicUpdater;
22
23
my $dbh = C4::Context->dbh();
24
my $atomicUpdater = Koha::AtomicUpdater->new();
25
26
use Koha::Auth::PermissionManager;
27
my $pm = Koha::Auth::PermissionManager->new();
28
$pm->addPermissionModule({module => 'messages', description => 'Permission regarding notifications and messages in message queue.'});
29
$pm->addPermission({module => 'messages', code => 'get_message', description => "Allows to get the messages in message queue."});
30
$pm->addPermission({module => 'messages', code => 'create_message', description => "Allows to create a new message and queue it."});
31
$pm->addPermission({module => 'messages', code => 'update_message', description => "Allows to update messages in message queue."});
32
$pm->addPermission({module => 'messages', code => 'delete_message', description => "Allows to delete a message and queue it."});
33
$pm->addPermission({module => 'messages', code => 'resend_message', description => "Allows to resend messages in message queue."});
34
35
print "Upgrade done (Bug 14843: Add Pemissions for message queue REST operations)\n";
(-)a/t/db_dependent/api/v1/notices.t (-1 / +411 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/env perl
2
3
# This file is part of Koha.
4
#
5
# Koha is free software; you can redistribute it and/or modify it under the
6
# terms of the GNU General Public License as published by the Free Software
7
# Foundation; either version 3 of the License, or (at your option) any later
8
# version.
9
#
10
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
11
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License along
15
# with Koha; if not, write to the Free Software Foundation, Inc.,
16
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
18
use Modern::Perl;
19
20
21
use Test::More tests => 7;
22
use Test::Mojo;
23
use t::lib::Mocks;
24
use t::lib::TestBuilder;
25
26
use C4::Auth;
27
use C4::Context;
28
29
use Koha::Database;
30
use Koha::Notice::Messages;
31
32
my $schema  = Koha::Database->new->schema;
33
my $builder = t::lib::TestBuilder->new;
34
35
# FIXME: sessionStorage defaults to mysql, but it seems to break transaction handling
36
# this affects the other REST api tests
37
t::lib::Mocks::mock_preference( 'SessionStorage', 'tmp' );
38
39
my $remote_address = '127.0.0.1';
40
my $t              = Test::Mojo->new('Koha::REST::V1');
41
42
subtest 'list() tests' => sub {
43
    plan tests => 24;
44
45
    $schema->storage->txn_begin;
46
47
    Koha::Notice::Messages->delete;
48
49
    my ($patron, $session) = create_user_and_session();
50
    my ($another_patron, undef) = create_user_and_session();
51
    my ($librarian, $librarian_session) = create_user_and_session({
52
        "messages" => "get_message"
53
    });
54
55
    my $notice = $builder->build({
56
        source => 'MessageQueue',
57
        value => {
58
            borrowernumber => $patron->borrowernumber,
59
            time_queued => '2016-01-01 13:00:00'
60
        }
61
    });
62
    my $another_notice = $builder->build({
63
        source => 'MessageQueue',
64
        value => {
65
            borrowernumber => $another_patron->borrowernumber,
66
            time_queued => '2017-01-01 13:00:00'
67
        }
68
    });
69
    my $message_id = $notice->{'message_id'};
70
    my $another_message_id = $another_notice->{'message_id'};
71
72
    my $tx = $t->ua->build_tx(GET => "/api/v1/notices?borrowernumber="
73
                              .$patron->borrowernumber);
74
    $tx->req->cookies({name => 'CGISESSID', value => $session->id});
75
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
76
    $t->request_ok($tx)
77
      ->status_is(200)
78
      ->json_is('/0/subject' => $notice->{'subject'});
79
80
    $tx = $t->ua->build_tx(GET => "/api/v1/notices?borrowernumber="
81
                              .$another_patron->borrowernumber);
82
    $tx->req->cookies({name => 'CGISESSID', value => $session->id});
83
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
84
    $t->request_ok($tx)
85
      ->status_is(403);
86
87
    $tx = $t->ua->build_tx(GET => "/api/v1/notices?borrowernumber=-1");
88
    $tx->req->cookies({name => 'CGISESSID', value => $librarian_session->id});
89
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
90
    $t->request_ok($tx)
91
      ->status_is(200)
92
      ->json_is('/0' => undef);
93
94
    $tx = $t->ua->build_tx(GET => "/api/v1/notices?borrowernumber="
95
                           .$patron->borrowernumber);
96
    $tx->req->cookies({name => 'CGISESSID', value => $librarian_session->id});
97
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
98
    $t->request_ok($tx)
99
      ->status_is(200)
100
      ->json_is('/0/subject' => $notice->{'subject'});
101
102
    $tx = $t->ua->build_tx(GET => '/api/v1/notices?'
103
                        .'time_queued_start=2016-12-12 12:00:00');
104
    $tx->req->cookies({name => 'CGISESSID', value => $librarian_session->id});
105
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
106
    $t->request_ok($tx)
107
      ->status_is(200)
108
      ->json_is('/0/subject' => $another_notice->{'subject'})
109
      ->json_hasnt('/1');
110
111
    $tx = $t->ua->build_tx(GET => '/api/v1/notices?'
112
                           .'time_queued_end=2016-12-12 12:00:00');
113
    $tx->req->cookies({name => 'CGISESSID', value => $librarian_session->id});
114
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
115
    $t->request_ok($tx)
116
      ->status_is(200)
117
      ->json_is('/0/subject' => $notice->{'subject'})
118
      ->json_hasnt('/1');
119
120
    $tx = $t->ua->build_tx(GET => '/api/v1/notices?'
121
    .'time_queued_start=2014-12-12 12:00:00&time_queued_end=2018-01-01 12:00:00');
122
    $tx->req->cookies({name => 'CGISESSID', value => $librarian_session->id});
123
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
124
    $t->request_ok($tx)
125
      ->status_is(200)
126
      ->json_is('/0/subject' => $notice->{'subject'})
127
      ->json_is('/1/subject' => $another_notice->{'subject'})
128
      ->json_hasnt('/2');
129
130
    $schema->storage->txn_rollback;
131
};
132
133
subtest 'get() tests' => sub {
134
    plan tests => 8;
135
136
    $schema->storage->txn_begin;
137
138
    my ($patron, $session) = create_user_and_session();
139
    my ($another_patron, undef) = create_user_and_session();
140
    my ($librarian, $librarian_session) = create_user_and_session({
141
        "messages" => "get_message"
142
    });
143
144
    my $notice = $builder->build({
145
        source => 'MessageQueue',
146
        value => {
147
            borrowernumber => $patron->borrowernumber,
148
        }
149
    });
150
    my $another_notice = $builder->build({
151
        source => 'MessageQueue',
152
        value => {
153
            borrowernumber => $another_patron->borrowernumber,
154
        }
155
    });
156
    my $message_id = $notice->{'message_id'};
157
    my $another_message_id = $another_notice->{'message_id'};
158
159
    my $tx = $t->ua->build_tx(GET => "/api/v1/notices/$message_id");
160
    $tx->req->cookies({name => 'CGISESSID', value => $session->id});
161
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
162
    $t->request_ok($tx)
163
      ->status_is(200)
164
      ->json_is('/subject' => $notice->{'subject'});
165
166
    $tx = $t->ua->build_tx(GET => "/api/v1/notices/$another_message_id");
167
    $tx->req->cookies({name => 'CGISESSID', value => $session->id});
168
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
169
    $t->request_ok($tx)
170
      ->status_is(403);
171
172
    $tx = $t->ua->build_tx(GET => "/api/v1/notices/$message_id");
173
    $tx->req->cookies({name => 'CGISESSID', value => $librarian_session->id});
174
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
175
    $t->request_ok($tx)
176
      ->status_is(200)
177
      ->json_is('/subject' => $notice->{'subject'});
178
179
    $schema->storage->txn_rollback;
180
};
181
182
subtest 'post() tests' => sub {
183
    plan tests => 6;
184
185
    $schema->storage->txn_begin;
186
187
    my ($patron, $session) = create_user_and_session();
188
    my ($librarian, $librarian_session) = create_user_and_session({
189
        "messages" => "create_message"
190
    });
191
192
    my $notice = {
193
        borrowernumber => 0+$patron->borrowernumber,
194
        subject => 'Bring milk from the store, please!',
195
        content => 'Title says it all',
196
        message_transport_type => 'email',
197
        status => 'failed',
198
    };
199
200
    my $tx = $t->ua->build_tx(POST => "/api/v1/notices" => json => $notice);
201
    $tx->req->cookies({name => 'CGISESSID', value => $session->id});
202
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
203
    $t->request_ok($tx)
204
      ->status_is(403);
205
206
    $tx = $t->ua->build_tx(POST => "/api/v1/notices" => json => $notice);
207
    $tx->req->cookies({name => 'CGISESSID', value => $librarian_session->id});
208
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
209
    $t->request_ok($tx)
210
      ->status_is(201)
211
      ->json_is('/subject' => $notice->{'subject'});
212
213
    my $msg = Koha::Notice::Messages->search({}, {
214
        order_by => { '-desc' => 'message_id' }
215
    })->next;
216
    is($msg->subject, $notice->{subject}, 'The notice was really added!');
217
218
    $schema->storage->txn_rollback;
219
};
220
221
subtest 'edit() tests' => sub {
222
    plan tests => 5;
223
224
    $schema->storage->txn_begin;
225
226
    my ($patron, $session) = create_user_and_session();
227
    my ($librarian, $librarian_session) = create_user_and_session({
228
        "messages" => "update_message"
229
    });
230
231
    my $notice = $builder->build({
232
        source => 'MessageQueue',
233
        value => {
234
            borrowernumber => $patron->borrowernumber,
235
        }
236
    });
237
238
    my $new_notice = {
239
        subject => 'Bring milk from the store, please!',
240
        content => 'Title says it all',
241
        message_transport_type => 'email',
242
        status => 'failed',
243
    };
244
245
    my $message_id = $notice->{'message_id'};
246
247
    my $tx = $t->ua->build_tx(PUT => "/api/v1/notices/$message_id" =>
248
                           json => $new_notice);
249
    $tx->req->cookies({name => 'CGISESSID', value => $session->id});
250
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
251
    $t->request_ok($tx)
252
      ->status_is(403);
253
254
    $tx = $t->ua->build_tx(PUT => "/api/v1/notices/$message_id" =>
255
                           json => $new_notice);
256
    $tx->req->cookies({name => 'CGISESSID', value => $librarian_session->id});
257
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
258
    $t->request_ok($tx)
259
      ->status_is(200)
260
      ->json_is('/subject' => $new_notice->{'subject'});
261
262
    $schema->storage->txn_rollback;
263
};
264
265
subtest 'put() tests' => sub {
266
    plan tests => 6;
267
268
    $schema->storage->txn_begin;
269
270
    my ($patron, $session) = create_user_and_session();
271
    my ($librarian, $librarian_session) = create_user_and_session({
272
        "messages" => "update_message"
273
    });
274
275
    my $notice = $builder->build({
276
        source => 'MessageQueue',
277
        value => {
278
            borrowernumber => $patron->borrowernumber,
279
        }
280
    });
281
282
    my $new_notice = {
283
        status => 'pending',
284
    };
285
286
    my $message_id = $notice->{'message_id'};
287
288
    my $tx = $t->ua->build_tx(PATCH => "/api/v1/notices/$message_id" =>
289
                           json => $new_notice);
290
    $tx->req->cookies({name => 'CGISESSID', value => $session->id});
291
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
292
    $t->request_ok($tx)
293
      ->status_is(403);
294
295
    $tx = $t->ua->build_tx(PATCH => "/api/v1/notices/$message_id" =>
296
                           json => $new_notice);
297
    $tx->req->cookies({name => 'CGISESSID', value => $librarian_session->id});
298
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
299
    $t->request_ok($tx)
300
      ->status_is(200)
301
      ->json_is('/subject' => $notice->{'subject'})
302
      ->json_is('/status' => $new_notice->{'status'});
303
304
    $schema->storage->txn_rollback;
305
};
306
307
subtest 'resend() tests' => sub {
308
    plan tests => 6;
309
310
    $schema->storage->txn_begin;
311
312
    my ($patron, $session) = create_user_and_session();
313
    my ($librarian, $librarian_session) = create_user_and_session({
314
        "messages" => "resend_message"
315
    });
316
317
    my $notice = $builder->build({
318
        source => 'MessageQueue',
319
        value => {
320
            borrowernumber => $patron->borrowernumber,
321
            status => 'failed'
322
        }
323
    });
324
325
    my $message_id = $notice->{'message_id'};
326
327
    my $msg = Koha::Notice::Messages->find($message_id);
328
    is($msg->status, 'failed', 'The notice is in failed status.');
329
330
    my $tx = $t->ua->build_tx(POST => "/api/v1/notices/$message_id/resend");
331
    $tx->req->cookies({name => 'CGISESSID', value => $session->id});
332
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
333
    $t->request_ok($tx)
334
      ->status_is(403);
335
336
    $tx = $t->ua->build_tx(POST => "/api/v1/notices/$message_id/resend");
337
    $tx->req->cookies({name => 'CGISESSID', value => $librarian_session->id});
338
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
339
    $t->request_ok($tx)
340
      ->status_is(204);
341
342
    $msg = Koha::Notice::Messages->find($message_id);
343
    is($msg->status, 'pending', 'The notice has been set to pending!');
344
345
    $schema->storage->txn_rollback;
346
};
347
348
subtest 'delete() tests' => sub {
349
    plan tests => 5;
350
351
    $schema->storage->txn_begin;
352
353
    my ($patron, $session) = create_user_and_session();
354
    my ($librarian, $librarian_session) = create_user_and_session({
355
        "messages" => "delete_message"
356
    });
357
358
    my $notice = $builder->build({
359
        source => 'MessageQueue',
360
        value => {
361
            borrowernumber => $patron->borrowernumber,
362
        }
363
    });
364
365
    my $message_id = $notice->{'message_id'};
366
367
    my $tx = $t->ua->build_tx(DELETE => "/api/v1/notices/$message_id");
368
    $tx->req->cookies({name => 'CGISESSID', value => $session->id});
369
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
370
    $t->request_ok($tx)
371
      ->status_is(403);
372
373
    $tx = $t->ua->build_tx(DELETE => "/api/v1/notices/$message_id");
374
    $tx->req->cookies({name => 'CGISESSID', value => $librarian_session->id});
375
    $tx->req->env({REMOTE_ADDR => '127.0.0.1'});
376
    $t->request_ok($tx)
377
      ->status_is(204);
378
379
    my $msg = Koha::Notice::Messages->find($message_id);
380
    is($msg, undef, 'The notice was really deleted!');
381
382
    $schema->storage->txn_rollback;
383
};
384
385
sub create_user_and_session {
386
    my ($flags) = @_;
387
388
    my $categorycode = $builder->build({ source => 'Category' })->{categorycode};
389
    my $branchcode = $builder->build({ source => 'Branch' })->{ branchcode };
390
391
    my $borrower = $builder->build({
392
        source => 'Borrower',
393
        value => {
394
            branchcode   => $branchcode,
395
            categorycode => $categorycode,
396
        }
397
    });
398
399
    my $session = C4::Auth::get_session('');
400
    $session->param('number', $borrower->{ borrowernumber });
401
    $session->param('id', $borrower->{ userid });
402
    $session->param('ip', '127.0.0.1');
403
    $session->param('lasttime', time());
404
    $session->flush;
405
    my $patron = Koha::Patrons->find($borrower->{borrowernumber});
406
    if ( $flags ) {
407
        Koha::Auth::PermissionManager->grantPermissions($patron, $flags);
408
    }
409
410
    return ($patron, $session);
411
}

Return to bug 14843