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

(-)a/Koha/AdvancedEditorMacro.pm (+61 lines)
Line 0 Link Here
1
package Koha::AdvancedEditorMacro;
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 Carp;
21
22
use Koha::Database;
23
24
use base qw(Koha::Object);
25
26
=head1 NAME
27
28
Koha::AdvancedEditorMacro - Koha Advanced Editor Macro Object class
29
30
=head1 API
31
32
=head2 Class methods
33
34
=head3 to_api_mapping
35
36
This method returns the mapping for representing a Koha::AdvancedEditorMacro object
37
on the API.
38
39
=cut
40
41
sub to_api_mapping {
42
    return {
43
        id              => 'macro_id',
44
        name            => 'name',
45
        macro           => 'macro_text',
46
        borrowernumber  => 'patron_id',
47
        public          => 'public',
48
    };
49
}
50
51
=head2 Internal methods
52
53
=head3 _type
54
55
=cut
56
57
sub _type {
58
    return 'AdvancedEditorMacro';
59
}
60
61
1;
(-)a/Koha/AdvancedEditorMacros.pm (+50 lines)
Line 0 Link Here
1
package Koha::AdvancedEditorMacros;
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 Carp;
21
22
use Koha::Database;
23
24
use Koha::AdvancedEditorMacro;
25
26
use base qw(Koha::Objects);
27
28
=head1 NAME
29
30
Koha::AdvancedEditorMacros - Koha Advanced Editor Macro Object set class
31
32
=head1 API
33
34
=head2 Class Methods
35
36
=cut
37
38
=head3 type
39
40
=cut
41
42
sub _type {
43
    return 'AdvancedEditorMacro';
44
}
45
46
sub object_class {
47
    return 'Koha::AdvancedEditorMacro';
48
}
49
50
1;
(-)a/Koha/REST/V1/AdvancedEditorMacro.pm (+303 lines)
Line 0 Link Here
1
package Koha::REST::V1::AdvancedEditorMacro;
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
use Koha::AdvancedEditorMacros;
22
23
use Try::Tiny;
24
25
=head1 API
26
27
=head2 Class Methods
28
29
=cut
30
31
=head3 list
32
33
Controller function that handles listing Koha::AdvancedEditorMacro objects
34
35
=cut
36
37
sub list {
38
    my $c = shift->openapi->valid_input or return;
39
    my $patron = $c->stash('koha.user');
40
    return try {
41
        my $macros_set = Koha::AdvancedEditorMacros->search({ -or => { public => 1, borrowernumber => $patron->borrowernumber } });
42
        my $macros = $c->objects->search( $macros_set, \&_to_model, \&_to_api );
43
        return $c->render( status => 200, openapi => $macros );
44
    }
45
    catch {
46
        if ( $_->isa('DBIx::Class::Exception') ) {
47
            return $c->render( status  => 500,
48
                               openapi => { error => $_->{msg} } );
49
        }
50
        else {
51
            return $c->render( status => 500,
52
                openapi => { error => "Something went wrong, check the logs. $_"} );
53
        }
54
    };
55
56
}
57
58
=head3 get
59
60
Controller function that handles retrieving a single Koha::AdvancedEditorMacro
61
62
=cut
63
64
sub get {
65
    my $c = shift->openapi->valid_input or return;
66
    my $patron = $c->stash('koha.user');
67
    my $macro = Koha::AdvancedEditorMacros->find( $c->validation->param('advancededitormacro_id') );
68
    unless ($macro) {
69
        return $c->render( status  => 404,
70
                           openapi => { error => "Macro not found" } );
71
    }
72
    unless ( $macro->public || $macro->borrowernumber == $patron->borrowernumber ){
73
        return $c->render( status  => 403,
74
                           openapi => { error => "You do not have permission to access this macro" } );
75
    }
76
77
    return $c->render( status => 200, openapi => $macro->to_api );
78
}
79
80
=head3 add
81
82
Controller function that handles adding a new Koha::AdvancedEditorMacro object
83
84
=cut
85
86
sub add {
87
    my $c = shift->openapi->valid_input or return;
88
89
    if( defined $c->validation->param('body')->{public} && $c->validation->param('body')->{public} == 1 ){
90
        my $patron = $c->stash('koha.user');
91
        unless ( $patron->has_permission({ editcatalogue => 'create_public_macros' }) ){
92
            return $c->render( status  => 403,
93
                               openapi => { error => "You do not have permission to create public macros" } );
94
        }
95
    }
96
97
    return try {
98
        my $macro = Koha::AdvancedEditorMacro->new( _to_model( $c->validation->param('body') ) );
99
        $macro->store;
100
        $c->res->headers->location( $c->req->url->to_string . '/' . $macro->id );
101
        return $c->render(
102
            status  => 201,
103
            openapi => $macro->to_api
104
        );
105
    }
106
    catch {
107
        if ( $_->isa('DBIx::Class::Exception') ) {
108
            return $c->render(
109
                status  => 500,
110
                openapi => { error => $_->{msg} }
111
            );
112
        }
113
        else {
114
            return $c->render(
115
                status  => 500,
116
                openapi => { error => "Something went wrong, check the logs." }
117
            );
118
        }
119
    };
120
}
121
122
=head3 update
123
124
Controller function that handles updating a Koha::Library object
125
126
=cut
127
128
sub update {
129
    my $c = shift->openapi->valid_input or return;
130
131
    my $macro = Koha::AdvancedEditorMacros->find( $c->validation->param('advancededitormacro_id') );
132
133
    if ( not defined $macro ) {
134
        return $c->render( status  => 404,
135
                           openapi => { error => "Object not found" } );
136
    }
137
138
    my $patron = $c->stash('koha.user');
139
    if( $macro->public == 1 || defined $c->validation->param('body')->{public} && $c->validation->param('body')->{public} == 1 && $macro->borrowernumber == $patron->borrowernumber ){
140
        unless ( $patron->has_permission({ editcatalogue => 'create_public_macros' }) ){
141
            return $c->render( status  => 403,
142
                               openapi => { error => "You do not have permission to create/edit public macros" } );
143
        }
144
    } else {
145
        unless ( $macro->borrowernumber == $patron->borrowernumber ){
146
            return $c->render( status  => 403,
147
                               openapi => { error => "You can only edit macros you own or public macros (with permission) " } );
148
        }
149
    }
150
151
    return try {
152
        my $params = $c->req->json;
153
        $macro->set( _to_model($params) );
154
        $macro->store();
155
        return $c->render( status => 200, openapi => $macro->to_api );
156
    }
157
    catch {
158
        if ( $_->isa('Koha::Exceptions::Object') ) {
159
            return $c->render( status  => 500,
160
                               openapi => { error => $_->message } );
161
        }
162
        else {
163
            return $c->render( status => 500,
164
                openapi => { error => "Something went wrong, check the logs."} );
165
        }
166
    };
167
}
168
169
=head3 delete
170
171
Controller function that handles deleting a Koha::AdvancedEditoracro object
172
173
=cut
174
175
sub delete {
176
    my $c = shift->openapi->valid_input or return;
177
178
    my $macro = Koha::AdvancedEditorMacros->find( $c->validation->param('advancededitormacro_id') );
179
    if ( not defined $macro ) {
180
        return $c->render( status  => 404,
181
                           openapi => { error => "Object not found" } );
182
    }
183
184
    my $patron = $c->stash('koha.user');
185
    if( $macro->public == 1 && $macro->borrowernumber != $patron->borrowernumber ){
186
        unless ( $patron->has_permission({ editcatalogue => 'delete_public_macros' }) ){
187
            return $c->render( status  => 403,
188
                               openapi => { error => "You do not have permission to create public macros" } );
189
        }
190
    } else {
191
        unless ( $macro->borrowernumber == $patron->borrowernumber ){
192
            return $c->render( status  => 403,
193
                               openapi => { error => "You can only delete macros you own or public macros (with permission) " } );
194
        }
195
    }
196
197
    return try {
198
        $macro->delete;
199
        return $c->render( status => 200, openapi => "" );
200
    }
201
    catch {
202
        if ( $_->isa('DBIx::Class::Exception') ) {
203
            return $c->render( status  => 500,
204
                               openapi => { error => $_->{msg} } );
205
        }
206
        else {
207
            return $c->render( status => 500,
208
                openapi => { error => "Something went wrong, check the logs. line 159"} );
209
        }
210
    };
211
}
212
213
=head3 _to_api
214
215
Helper function that maps a hashref of Koha::AdvancedEditorMacro attributes into REST api
216
attribute names.
217
218
=cut
219
220
sub _to_api {
221
    my $macro = shift;
222
223
    # Rename attributes
224
    foreach my $column ( keys %{ $Koha::REST::V1::AdvancedEditorMacro::to_api_mapping } ) {
225
        my $mapped_column = $Koha::REST::V1::AdvancedEditorMacro::to_api_mapping->{$column};
226
        if (    exists $macro->{ $column }
227
             && defined $mapped_column )
228
        {
229
            # key /= undef
230
            $macro->{ $mapped_column } = delete $macro->{ $column };
231
        }
232
        elsif (    exists $macro->{ $column }
233
                && !defined $mapped_column )
234
        {
235
            # key == undef => to be deleted
236
            delete $macro->{ $column };
237
        }
238
    }
239
240
    return $macro;
241
}
242
243
=head3 _to_model
244
245
Helper function that maps REST api objects into Koha::AdvancedEditorMacros
246
attribute names.
247
248
=cut
249
250
sub _to_model {
251
    my $macro = shift;
252
253
    foreach my $attribute ( keys %{ $Koha::REST::V1::AdvancedEditorMacro::to_model_mapping } ) {
254
        my $mapped_attribute = $Koha::REST::V1::AdvancedEditorMacro::to_model_mapping->{$attribute};
255
        if (    exists $macro->{ $attribute }
256
             && defined $mapped_attribute )
257
        {
258
            # key /= undef
259
            $macro->{ $mapped_attribute } = delete $macro->{ $attribute };
260
        }
261
        elsif (    exists $macro->{ $attribute }
262
                && !defined $mapped_attribute )
263
        {
264
            # key == undef => to be deleted
265
            delete $macro->{ $attribute };
266
        }
267
    }
268
269
    if ( exists $macro->{public} ) {
270
        $macro->{public} = ($macro->{public}) ? 1 : 0;
271
    }
272
273
274
    return $macro;
275
}
276
277
=head2 Global variables
278
279
=head3 $to_api_mapping
280
281
=cut
282
283
our $to_api_mapping = {
284
    id                  => 'macro_id',
285
    name                => 'name',
286
    macro               => 'macro_text',
287
    borrowernumber      => 'patron_id',
288
    public              => 'public',
289
};
290
291
=head3 $to_model_mapping
292
293
=cut
294
295
our $to_model_mapping = {
296
    macro_id         => 'id',
297
    name             => 'name',
298
    macro_text       => 'macro',
299
    patron_id        => 'borrowernumber',
300
    public           => 'public',
301
};
302
303
1;
(-)a/api/v1/swagger/definitions.json (+3 lines)
Lines 41-46 Link Here
41
  "order": {
41
  "order": {
42
    "$ref": "definitions/order.json"
42
    "$ref": "definitions/order.json"
43
  },
43
  },
44
  "advancededitormacro": {
45
    "$ref": "definitions/advancededitormacro.json"
46
  },
44
  "patron": {
47
  "patron": {
45
    "$ref": "definitions/patron.json"
48
    "$ref": "definitions/patron.json"
46
  },
49
  },
(-)a/api/v1/swagger/definitions/advancededitormacro.json (+26 lines)
Line 0 Link Here
1
{
2
  "type": "object",
3
  "properties": {
4
    "macro_id": {
5
      "$ref": "../x-primitives.json#/advancededitormacro_id"
6
    },
7
    "name": {
8
      "description": "macro name",
9
      "type": "string"
10
    },
11
    "macro_text": {
12
      "description": "macro text",
13
      "type": ["string", "null"]
14
    },
15
    "patron_id": {
16
      "description": "borrower number",
17
      "type": ["integer", "null"]
18
    },
19
    "public": {
20
        "description": "is macro public",
21
        "type": ["string", "null"]
22
    }
23
  },
24
  "additionalProperties": false,
25
  "required": ["name", "macro_text", "patron_id", "public"]
26
}
(-)a/api/v1/swagger/parameters.json (+3 lines)
Lines 2-7 Link Here
2
  "biblio_id_pp": {
2
  "biblio_id_pp": {
3
    "$ref": "parameters/biblio.json#/biblio_id_pp"
3
    "$ref": "parameters/biblio.json#/biblio_id_pp"
4
  },
4
  },
5
  "advancededitormacro_id_pp": {
6
    "$ref": "parameters/advancededitormacro.json#/advancededitormacro_id_pp"
7
  },
5
  "patron_id_pp": {
8
  "patron_id_pp": {
6
    "$ref": "parameters/patron.json#/patron_id_pp"
9
    "$ref": "parameters/patron.json#/patron_id_pp"
7
  },
10
  },
(-)a/api/v1/swagger/parameters/advancededitormacro.json (+9 lines)
Line 0 Link Here
1
{
2
    "advancededitormacro_id_pp": {
3
      "name": "advancededitormacro_id",
4
      "in": "path",
5
      "description": "Advanced Editor Macro internal identifier",
6
      "required": true,
7
      "type": "integer"
8
    }
9
}
(-)a/api/v1/swagger/paths.json (+6 lines)
Lines 68-73 Link Here
68
  "/checkouts/{checkout_id}/allows_renewal": {
68
  "/checkouts/{checkout_id}/allows_renewal": {
69
    "$ref": "paths/checkouts.json#/~1checkouts~1{checkout_id}~1allows_renewal"
69
    "$ref": "paths/checkouts.json#/~1checkouts~1{checkout_id}~1allows_renewal"
70
  },
70
  },
71
  "/advancededitormacros": {
72
    "$ref": "paths/advancededitormacros.json#/~1advancededitormacros"
73
  },
74
  "/advancededitormacros/{advancededitormacro_id}": {
75
    "$ref": "paths/advancededitormacros.json#/~1advancededitormacros~1{advancededitormacro_id}"
76
  },
71
  "/patrons": {
77
  "/patrons": {
72
    "$ref": "paths/patrons.json#/~1patrons"
78
    "$ref": "paths/patrons.json#/~1patrons"
73
  },
79
  },
(-)a/api/v1/swagger/paths/advancededitormacros.json (+296 lines)
Line 0 Link Here
1
{
2
  "/advancededitormacros": {
3
    "get": {
4
      "x-mojo-to": "AdvancedEditorMacro#list",
5
      "operationId": "listMacro",
6
      "tags": ["advancededitormacro"],
7
      "produces": [
8
        "application/json"
9
      ],
10
      "parameters": [
11
        {
12
          "name": "name",
13
          "in": "query",
14
          "description": "Case insensative search on macro name",
15
          "required": false,
16
          "type": "string"
17
        },
18
        {
19
          "name": "macro_text",
20
          "in": "query",
21
          "description": "Case insensative search on macro text",
22
          "required": false,
23
          "type": "string"
24
        },
25
        {
26
          "name": "patron_id",
27
          "in": "query",
28
          "description": "Search on internal patron_id",
29
          "required": false,
30
          "type": "string"
31
        },
32
        {
33
          "name": "public",
34
          "in": "query",
35
          "description": "Search on public macros",
36
          "required": false,
37
          "type": "string"
38
        }
39
      ],
40
      "responses": {
41
        "200": {
42
          "description": "A list of macros",
43
          "schema": {
44
            "type": "array",
45
            "items": {
46
              "$ref": "../definitions.json#/advancededitormacro"
47
            }
48
          }
49
        },
50
        "403": {
51
          "description": "Access forbidden",
52
          "schema": {
53
            "$ref": "../definitions.json#/error"
54
          }
55
        },
56
        "500": {
57
          "description": "Internal error",
58
          "schema": {
59
            "$ref": "../definitions.json#/error"
60
          }
61
        },
62
        "503": {
63
          "description": "Under maintenance",
64
          "schema": {
65
            "$ref": "../definitions.json#/error"
66
          }
67
        }
68
      },
69
      "x-koha-authorization": {
70
        "permissions": {
71
            "editcatalogue": "advanced_editor"
72
        }
73
      }
74
    },
75
    "post": {
76
      "x-mojo-to": "AdvancedEditorMacro#add",
77
      "operationId": "addAdvancedEditorMacro",
78
      "tags": ["advancededitormacro"],
79
      "parameters": [{
80
        "name": "body",
81
        "in": "body",
82
        "description": "A JSON object containing informations about the new macro",
83
        "required": true,
84
        "schema": {
85
          "$ref": "../definitions.json#/advancededitormacro"
86
        }
87
      }],
88
      "produces": [
89
        "application/json"
90
      ],
91
      "responses": {
92
        "201": {
93
          "description": "Macro added",
94
          "schema": {
95
            "$ref": "../definitions.json#/advancededitormacro"
96
          }
97
        },
98
        "401": {
99
          "description": "Authentication required",
100
          "schema": {
101
            "$ref": "../definitions.json#/error"
102
          }
103
        },
104
        "403": {
105
          "description": "Access forbidden",
106
          "schema": {
107
            "$ref": "../definitions.json#/error"
108
          }
109
        },
110
        "500": {
111
          "description": "Internal error",
112
          "schema": {
113
            "$ref": "../definitions.json#/error"
114
          }
115
        },
116
        "503": {
117
          "description": "Under maintenance",
118
          "schema": {
119
            "$ref": "../definitions.json#/error"
120
          }
121
        }
122
      },
123
      "x-koha-authorization": {
124
        "permissions": {
125
          "editcatalogue": "advanced_editor"
126
        }
127
      }
128
    }
129
  },
130
  "/advancededitormacros/{advancededitormacro_id}": {
131
    "get": {
132
      "x-mojo-to": "AdvancedEditorMacro#get",
133
      "operationId": "getAdvancedEditorMacro",
134
      "tags": ["advancededitormacros"],
135
      "parameters": [{
136
        "$ref": "../parameters.json#/advancededitormacro_id_pp"
137
      }],
138
      "produces": [
139
        "application/json"
140
      ],
141
      "responses": {
142
        "200": {
143
          "description": "A macro",
144
          "schema": {
145
            "$ref": "../definitions.json#/advancededitormacro"
146
          }
147
        },
148
        "403": {
149
          "description": "Access forbidden",
150
          "schema": {
151
            "$ref": "../definitions.json#/error"
152
          }
153
        },
154
        "404": {
155
          "description": "AdvancedEditorMacro not found",
156
          "schema": {
157
            "$ref": "../definitions.json#/error"
158
          }
159
        },
160
        "500": {
161
          "description": "Internal error",
162
          "schema": {
163
            "$ref": "../definitions.json#/error"
164
          }
165
        },
166
        "503": {
167
          "description": "Under maintenance",
168
          "schema": {
169
            "$ref": "../definitions.json#/error"
170
          }
171
        }
172
      },
173
      "x-koha-authorization": {
174
        "permissions": {
175
            "editcatalogue": "advanced_editor"
176
        }
177
      }
178
    },
179
    "put": {
180
      "x-mojo-to": "AdvancedEditorMacro#update",
181
      "operationId": "updateAdvancedEditorMacro",
182
      "tags": ["advancededitormacros"],
183
      "parameters": [{
184
        "$ref": "../parameters.json#/advancededitormacro_id_pp"
185
      }, {
186
        "name": "body",
187
        "in": "body",
188
        "description": "An advanced editor macro object",
189
        "required": true,
190
        "schema": {
191
          "$ref": "../definitions.json#/advancededitormacro"
192
        }
193
      }],
194
      "produces": [
195
        "application/json"
196
      ],
197
      "responses": {
198
        "200": {
199
          "description": "An advanced editor macro",
200
          "schema": {
201
            "$ref": "../definitions.json#/advancededitormacro"
202
          }
203
        },
204
        "401": {
205
          "description": "Authentication required",
206
          "schema": {
207
            "$ref": "../definitions.json#/error"
208
          }
209
        },
210
        "403": {
211
          "description": "Access forbidden",
212
          "schema": {
213
            "$ref": "../definitions.json#/error"
214
          }
215
        },
216
        "404": {
217
          "description": "Macro not found",
218
          "schema": {
219
            "$ref": "../definitions.json#/error"
220
          }
221
        },
222
        "500": {
223
          "description": "Internal error",
224
          "schema": {
225
            "$ref": "../definitions.json#/error"
226
          }
227
        },
228
        "503": {
229
          "description": "Under maintenance",
230
          "schema": {
231
            "$ref": "../definitions.json#/error"
232
          }
233
        }
234
      },
235
      "x-koha-authorization": {
236
        "permissions": {
237
          "editcatalogue": "advanced_editor"
238
        }
239
      }
240
    },
241
    "delete": {
242
      "x-mojo-to": "AdvancedEditorMacro#delete",
243
      "operationId": "deleteAdvancedEditorMacro",
244
      "tags": ["advancededitormacros"],
245
      "parameters": [{
246
        "$ref": "../parameters.json#/advancededitormacro_id_pp"
247
      }],
248
      "produces": [
249
        "application/json"
250
      ],
251
      "responses": {
252
        "200": {
253
          "description": "Advanced editor macro deleted",
254
          "schema": {
255
            "type": "string"
256
          }
257
        },
258
        "401": {
259
          "description": "Authentication required",
260
          "schema": {
261
            "$ref": "../definitions.json#/error"
262
          }
263
        },
264
        "403": {
265
          "description": "Access forbidden",
266
          "schema": {
267
            "$ref": "../definitions.json#/error"
268
          }
269
        },
270
        "404": {
271
          "description": "Macro not found",
272
          "schema": {
273
            "$ref": "../definitions.json#/error"
274
          }
275
        },
276
        "500": {
277
          "description": "Internal error",
278
          "schema": {
279
            "$ref": "../definitions.json#/error"
280
          }
281
        },
282
        "503": {
283
          "description": "Under maintenance",
284
          "schema": {
285
            "$ref": "../definitions.json#/error"
286
          }
287
        }
288
      },
289
      "x-koha-authorization": {
290
        "permissions": {
291
          "editcatalogue": "advanced_editor"
292
        }
293
      }
294
    }
295
  }
296
}
(-)a/api/v1/swagger/x-primitives.json (+5 lines)
Lines 3-8 Link Here
3
    "type": "integer",
3
    "type": "integer",
4
    "description": "Internal biblio identifier"
4
    "description": "Internal biblio identifier"
5
  },
5
  },
6
  "advancededitormacro_id": {
7
    "type": "integer",
8
    "description": "Internal advanced editor macro identifier",
9
    "readOnly": true
10
  },
6
  "patron_id": {
11
  "patron_id": {
7
    "type": "integer",
12
    "type": "integer",
8
    "description": "Internal patron identifier"
13
    "description": "Internal patron identifier"
(-)a/t/db_dependent/api/v1/advanced_editor_macros.t (-1 / +456 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
use Test::More tests => 5;
21
use Test::Mojo;
22
use Test::Warn;
23
24
use t::lib::TestBuilder;
25
use t::lib::Mocks;
26
27
use Koha::AdvancedEditorMacros;
28
use Koha::Database;
29
30
my $schema  = Koha::Database->new->schema;
31
my $builder = t::lib::TestBuilder->new;
32
33
t::lib::Mocks::mock_preference( 'RESTBasicAuth', 1 );
34
35
my $t = Test::Mojo->new('Koha::REST::V1');
36
37
$schema->storage->txn_begin;
38
39
subtest 'list() tests' => sub {
40
    plan tests => 8;
41
42
43
    my $patron_1 = $builder->build_object({
44
        class => 'Koha::Patrons',
45
        value => { flags => 9 }
46
    });
47
    my $patron_2 = $builder->build_object({
48
        class => 'Koha::Patrons',
49
    });
50
    my $password = 'thePassword123';
51
    $patron_1->set_password({ password => $password, skip_validation => 1 });
52
    my $userid = $patron_1->userid;
53
54
    # Create test context
55
    my $macro_1 = $builder->build_object({ class => 'Koha::AdvancedEditorMacros', value =>
56
        {
57
            name => 'Test1',
58
            macro => 'delete 100',
59
            borrowernumber => $patron_1->borrowernumber,
60
        }
61
    });
62
    my $macro_2 = $builder->build_object({ class => 'Koha::AdvancedEditorMacros', value =>
63
        {
64
            name => 'Test2',
65
            macro => 'delete 100',
66
            borrowernumber => $patron_1->borrowernumber,
67
            public => 1,
68
        }
69
    });
70
    my $macro_3 = $builder->build_object({ class => 'Koha::AdvancedEditorMacros', value =>
71
        {
72
            name => 'Test3',
73
            macro => 'delete 100',
74
            borrowernumber => $patron_2->borrowernumber,
75
        }
76
    });
77
    my $macro_4 = $builder->build_object({ class => 'Koha::AdvancedEditorMacros', value =>
78
        {
79
            name => 'Test4',
80
            macro => 'delete 100',
81
            borrowernumber => $patron_2->borrowernumber,
82
            public => 1,
83
        }
84
    });
85
86
    my $macros_index = Koha::AdvancedEditorMacros->search({ -or => { public => 1, borrowernumber => $patron_1->borrowernumber } })->count-1;
87
    ## Authorized user tests
88
    # Make sure we are returned with the correct amount of macros
89
    $t->get_ok( "//$userid:$password@/api/v1/advancededitormacros" )
90
      ->status_is( 200, 'SWAGGER3.2.2' )
91
      ->json_has('/' . $macros_index . '/macro_id')
92
      ->json_hasnt('/' . ($macros_index + 1) . '/macro_id');
93
94
    subtest 'query parameters' => sub {
95
96
        plan tests => 15;
97
        $t->get_ok("//$userid:$password@/api/v1/advancededitormacros?name=" . $macro_2->name)
98
          ->status_is(200)
99
          ->json_has( [ $macro_2 ] );
100
        $t->get_ok("//$userid:$password@/api/v1/advancededitormacros?name=" . $macro_3->name)
101
          ->status_is(200)
102
          ->json_has( [ ] );
103
        $t->get_ok("//$userid:$password@/api/v1/advancededitormacros?macro_text=delete 100")
104
          ->status_is(200)
105
          ->json_has( [ $macro_1, $macro_2, $macro_4 ] );
106
        $t->get_ok("//$userid:$password@/api/v1/advancededitormacros?patron_id=" . $patron_1->borrowernumber)
107
          ->status_is(200)
108
          ->json_has( [ $macro_1, $macro_2 ] );
109
        $t->get_ok("//$userid:$password@/api/v1/advancededitormacros?public=1")
110
          ->status_is(200)
111
          ->json_has( [ $macro_2, $macro_4 ] );
112
    };
113
114
    # Warn on unsupported query parameter
115
    $t->get_ok( "//$userid:$password@/api/v1/advancededitormacros?macro_blah=blah" )
116
      ->status_is(400)
117
      ->json_is( [{ path => '/query/macro_blah', message => 'Malformed query string'}] );
118
119
};
120
121
subtest 'get() tests' => sub {
122
123
    plan tests => 12;
124
125
    my $patron = $builder->build_object({
126
        class => 'Koha::Patrons',
127
        value => { flags => 1 }
128
    });
129
    my $password = 'thePassword123';
130
    $patron->set_password({ password => $password, skip_validation => 1 });
131
    my $userid = $patron->userid;
132
133
    my $macro_1 = $builder->build_object( { class => 'Koha::AdvancedEditorMacros', value => {
134
            public => 1,
135
        }
136
    });
137
    my $macro_2 = $builder->build_object( { class => 'Koha::AdvancedEditorMacros', value => {
138
            public => 0,
139
        }
140
    });
141
    my $macro_3 = $builder->build_object( { class => 'Koha::AdvancedEditorMacros', value => {
142
            borrowernumber => $patron->borrowernumber,
143
        }
144
    });
145
146
    $t->get_ok( "//$userid:$password@/api/v1/advancededitormacros/" . $macro_1->id )
147
      ->status_is( 200, 'SWAGGER3.2.2' )
148
      ->json_is( '' => Koha::REST::V1::AdvancedEditorMacro::_to_api( $macro_1->TO_JSON ), 'SWAGGER3.3.2' );
149
150
    $t->get_ok( "//$userid:$password@/api/v1/advancededitormacros/" . $macro_2->id )
151
      ->status_is( 403, 'SWAGGER3.2.2' )
152
      ->json_is( '/error' => 'You do not have permission to access this macro' );
153
154
    $t->get_ok( "//$userid:$password@/api/v1/advancededitormacros/" . $macro_3->id )
155
      ->status_is( 200, 'SWAGGER3.2.2' )
156
      ->json_is( '' => Koha::REST::V1::AdvancedEditorMacro::_to_api( $macro_3->TO_JSON ), 'SWAGGER3.3.2' );
157
158
    my $non_existent_code = $macro_1->id;
159
    $macro_1->delete;
160
161
    $t->get_ok( "//$userid:$password@/api/v1/advancededitormacros/" . $non_existent_code )
162
      ->status_is(404)
163
      ->json_is( '/error' => 'Macro not found' );
164
165
};
166
167
subtest 'add() tests' => sub {
168
169
    plan tests => 20;
170
171
    my $authorized_patron = $builder->build_object({
172
        class => 'Koha::Patrons',
173
        value => { flags => 0 }
174
    });
175
    $builder->build({
176
        source => 'UserPermission',
177
        value  => {
178
            borrowernumber => $authorized_patron->borrowernumber,
179
            module_bit     => 9,
180
            code           => 'advanced_editor',
181
        },
182
    });
183
184
    my $password = 'thePassword123';
185
    $authorized_patron->set_password({ password => $password, skip_validation => 1 });
186
    my $auth_userid = $authorized_patron->userid;
187
188
    my $unauthorized_patron = $builder->build_object({
189
        class => 'Koha::Patrons',
190
        value => { flags => 0 }
191
    });
192
    $unauthorized_patron->set_password({ password => $password, skip_validation => 1 });
193
    my $unauth_userid = $unauthorized_patron->userid;
194
195
    my $macro = $builder->build_object({
196
        class => 'Koha::AdvancedEditorMacros',
197
        value => { public => 0 }
198
    });
199
    my $macro_values     = Koha::REST::V1::AdvancedEditorMacro::_to_api( $macro->TO_JSON );
200
    delete $macro_values->{macro_id};
201
    $macro->delete;
202
203
    # Unauthorized attempt to write
204
    $t->post_ok( "//$unauth_userid:$password@/api/v1/advancededitormacros" => json => $macro_values )
205
      ->status_is(403);
206
207
    # Authorized attempt to write invalid data
208
    my $macro_with_invalid_field = { %$macro_values };
209
    $macro_with_invalid_field->{'big_mac_ro'} = 'Mac attack';
210
211
    $t->post_ok( "//$auth_userid:$password@/api/v1/advancededitormacros" => json => $macro_with_invalid_field )
212
      ->status_is(400)
213
      ->json_is(
214
        "/errors" => [
215
            {
216
                message => "Properties not allowed: big_mac_ro.",
217
                path    => "/body"
218
            }
219
        ]
220
    );
221
222
    # Authorized attempt to write
223
    $t->post_ok( "//$auth_userid:$password@/api/v1/advancededitormacros" => json => $macro_values )
224
      ->status_is( 201, 'SWAGGER3.2.1' )
225
      ->json_has( '/macro_id', 'SWAGGER3.3.1' )
226
      ->json_is( '/name' => $macro_values->{name}, 'SWAGGER3.3.1' )
227
      ->json_is( '/macro_text' => $macro_values->{macro_text}, 'SWAGGER3.3.1' )
228
      ->json_is( '/patron_id' => $macro_values->{patron_id}, 'SWAGGER3.3.1' )
229
      ->json_is( '/public' => $macro_values->{public}, 'SWAGGER3.3.1' )
230
      ->header_like( Location => qr|^\/api\/v1\/advancededitormacros\/d*|, 'SWAGGER3.4.1' );
231
232
    # save the library_id
233
    my $macro_id = 999;
234
235
    # Authorized attempt to create with existing id
236
    $macro_values->{macro_id} = $macro_id;
237
238
    $t->post_ok( "//$auth_userid:$password@/api/v1/advancededitormacros" => json => $macro_values )
239
      ->status_is(400)
240
      ->json_is( '/errors' => [
241
            {
242
                message => "Read-only.",
243
                path   => "/body/macro_id"
244
            }
245
        ]
246
    );
247
248
    $macro_values->{public} = 1;
249
    delete $macro_values->{macro_id};
250
251
    # Unauthorized attempt to write a public macro
252
    $t->post_ok( "//$auth_userid:$password@/api/v1/advancededitormacros" => json => $macro_values )
253
      ->status_is(403);
254
255
    $builder->build({
256
        source => 'UserPermission',
257
        value  => {
258
            borrowernumber => $authorized_patron->borrowernumber,
259
            module_bit     => 9,
260
            code           => 'create_public_macros',
261
        },
262
    });
263
264
    # Authorized attempt to write a public macro
265
    $t->post_ok( "//$auth_userid:$password@/api/v1/advancededitormacros" => json => $macro_values )
266
      ->status_is(201);
267
268
};
269
270
subtest 'update() tests' => sub {
271
    plan tests => 28;
272
273
    my $authorized_patron = $builder->build_object({
274
        class => 'Koha::Patrons',
275
        value => { flags => 0 }
276
    });
277
    $builder->build({
278
        source => 'UserPermission',
279
        value  => {
280
            borrowernumber => $authorized_patron->borrowernumber,
281
            module_bit     => 9,
282
            code           => 'advanced_editor',
283
        },
284
    });
285
286
    my $password = 'thePassword123';
287
    $authorized_patron->set_password({ password => $password, skip_validation => 1 });
288
    my $auth_userid = $authorized_patron->userid;
289
290
    my $unauthorized_patron = $builder->build_object({
291
        class => 'Koha::Patrons',
292
        value => { flags => 0 }
293
    });
294
    $unauthorized_patron->set_password({ password => $password, skip_validation => 1 });
295
    my $unauth_userid = $unauthorized_patron->userid;
296
297
    my $macro = $builder->build_object({
298
        class => 'Koha::AdvancedEditorMacros',
299
        value => { borrowernumber => $authorized_patron->borrowernumber, public => 0 }
300
    });
301
    my $macro_2 = $builder->build_object({
302
        class => 'Koha::AdvancedEditorMacros',
303
        value => { borrowernumber => $unauthorized_patron->borrowernumber, public => 0 }
304
    });
305
    my $macro_id = $macro->id;
306
    my $macro_2_id = $macro_2->id;
307
    my $macro_values     = Koha::REST::V1::AdvancedEditorMacro::_to_api( $macro->TO_JSON );
308
    delete $macro_values->{macro_id};
309
310
    # Unauthorized attempt to update
311
    $t->put_ok( "//$unauth_userid:$password@/api/v1/advancededitormacros/$macro_id"
312
                    => json => { name => 'New unauthorized name change' } )
313
      ->status_is(403);
314
315
    # Attempt partial update on a PUT
316
    my $macro_with_missing_field = {
317
        name => "Call it macro-roni",
318
    };
319
320
    $t->put_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/$macro_id" => json => $macro_with_missing_field )
321
      ->status_is(400)
322
      ->json_has( "/errors" =>
323
          [ { message => "Missing property.", path => "/body/macro_text" } ]
324
      );
325
326
    my $macro_update = {
327
        name => "Macro-update",
328
        macro_text => "delete 100",
329
        patron_id => $authorized_patron->borrowernumber,
330
        public => 0,
331
    };
332
333
    my $test = $t->put_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/$macro_id" => json => $macro_update )
334
      ->status_is(200, 'SWAGGER3.2.1')
335
      ->json_has( '/macro_id', 'SWAGGER3.3.1' )
336
      ->json_is( '/name' => $macro_update->{name}, 'SWAGGER3.3.1' )
337
      ->json_is( '/macro_text' => $macro_update->{macro_text}, 'SWAGGER3.3.1' )
338
      ->json_is( '/patron_id' => $macro_update->{patron_id}, 'SWAGGER3.3.1' )
339
      ->json_is( '/public' => $macro_update->{public}, 'SWAGGER3.3.1' );
340
341
    # Now try to make the macro public
342
    $macro_update->{public} = 1;
343
344
    $t->put_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/$macro_id" => json => $macro_update )
345
      ->status_is(403, 'Cannot make your macro public without permission');
346
347
    $builder->build({
348
        source => 'UserPermission',
349
        value  => {
350
            borrowernumber => $authorized_patron->borrowernumber,
351
            module_bit     => 9,
352
            code           => 'create_public_macros',
353
        },
354
    });
355
356
    $t->put_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/$macro_id" => json => $macro_update )
357
      ->status_is(200, 'Can update macro to public with permission')
358
      ->json_has( '/macro_id', 'SWAGGER3.3.1' )
359
      ->json_is( '/name' => $macro_update->{name}, 'SWAGGER3.3.1' )
360
      ->json_is( '/macro_text' => $macro_update->{macro_text}, 'SWAGGER3.3.1' )
361
      ->json_is( '/patron_id' => $macro_update->{patron_id}, 'SWAGGER3.3.1' )
362
      ->json_is( '/public' => $macro_update->{public}, 'SWAGGER3.3.1' );
363
364
    # Authorized attempt to write invalid data
365
    my $macro_with_invalid_field = { %$macro_update };
366
    $macro_with_invalid_field->{'big_mac_ro'} = 'Mac attack';
367
368
    $t->put_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/$macro_id" => json => $macro_with_invalid_field )
369
      ->status_is(400)
370
      ->json_is(
371
        "/errors" => [
372
            {
373
                message => "Properties not allowed: big_mac_ro.",
374
                path    => "/body"
375
            }
376
        ]
377
    );
378
379
    my $non_existent_macro = $builder->build_object({class => 'Koha::AdvancedEditorMacros'});
380
    my $non_existent_code = $non_existent_macro->id;
381
    $non_existent_macro->delete;
382
383
    $t->put_ok("//$auth_userid:$password@/api/v1/advancededitormacros/$non_existent_code" => json => $macro_update)
384
      ->status_is(404);
385
386
    $t->put_ok("//$auth_userid:$password@/api/v1/advancededitormacros/$macro_2_id" => json => $macro_update)
387
      ->status_is(403, "Cannot update other borrowers non public macro");
388
};
389
390
subtest 'delete() tests' => sub {
391
    plan tests => 10;
392
393
    my $authorized_patron = $builder->build_object({
394
        class => 'Koha::Patrons',
395
        value => { flags => 0 }
396
    });
397
    $builder->build({
398
        source => 'UserPermission',
399
        value  => {
400
            borrowernumber => $authorized_patron->borrowernumber,
401
            module_bit     => 9,
402
            code           => 'advanced_editor',
403
        },
404
    });
405
406
    my $password = 'thePassword123';
407
    $authorized_patron->set_password({ password => $password, skip_validation => 1 });
408
    my $auth_userid = $authorized_patron->userid;
409
410
    my $unauthorized_patron = $builder->build_object({
411
        class => 'Koha::Patrons',
412
        value => { flags => 0 }
413
    });
414
    $unauthorized_patron->set_password({ password => $password, skip_validation => 1 });
415
    my $unauth_userid = $unauthorized_patron->userid;
416
417
    my $macro = $builder->build_object({
418
        class => 'Koha::AdvancedEditorMacros',
419
        value => { borrowernumber => $authorized_patron->borrowernumber, public => 0 }
420
    });
421
    my $macro_2 = $builder->build_object({
422
        class => 'Koha::AdvancedEditorMacros',
423
        value => { borrowernumber => $unauthorized_patron->borrowernumber, public => 0 }
424
    });
425
    my $macro_id = $macro->id;
426
    my $macro_2_id = $macro_2->id;
427
428
    # Unauthorized attempt to delete
429
    $t->delete_ok( "//$unauth_userid:$password@/api/v1/advancededitormacros/$macro_2_id")
430
      ->status_is(403, "Cannot delete macro without permission");
431
432
    $t->delete_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/$macro_id")
433
      ->status_is(200, 'Can delete macro with permission');
434
435
    $t->delete_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/$macro_2_id")
436
      ->status_is(403, 'Cannot delete other users macro with permission');
437
438
    $macro_2->public(1)->store();
439
440
    $t->delete_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/$macro_2_id")
441
      ->status_is(403, 'Cannot delete other users public macro without permission');
442
443
    $builder->build({
444
        source => 'UserPermission',
445
        value  => {
446
            borrowernumber => $authorized_patron->borrowernumber,
447
            module_bit     => 9,
448
            code           => 'delete_public_macros',
449
        },
450
    });
451
    $t->delete_ok( "//$auth_userid:$password@/api/v1/advancededitormacros/$macro_2_id")
452
      ->status_is(200, 'Can delete other users public macro with permission');
453
454
};
455
456
$schema->storage->txn_rollback;

Return to bug 17268