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

(-)a/Koha/REST/Plugin/Query.pm (+88 lines)
Lines 18-23 package Koha::REST::Plugin::Query; Link Here
18
use Modern::Perl;
18
use Modern::Perl;
19
19
20
use Mojo::Base 'Mojolicious::Plugin';
20
use Mojo::Base 'Mojolicious::Plugin';
21
use List::MoreUtils qw(any);
21
use Scalar::Util qw(reftype);
22
use Scalar::Util qw(reftype);
22
23
23
use Koha::Exceptions;
24
use Koha::Exceptions;
Lines 143-148 is raised. Link Here
143
            return $params;
144
            return $params;
144
        }
145
        }
145
    );
146
    );
147
148
=head3 stash_embed
149
150
    $c->stash_embed( $c->match->endpoint->pattern->defaults->{'openapi.op_spec'} );
151
152
=cut
153
154
    $app->helper(
155
        'stash_embed' => sub {
156
157
            my ( $c, $args ) = @_;
158
159
            my $spec = $args->{spec} // {};
160
161
            my $embed_spec   = $spec->{'x-koha-embed'};
162
            my $embed_header = $c->req->headers->header('x-koha-embed');
163
164
            Koha::Exceptions::BadParameter->throw("Embedding objects is not allowed on this endpoint.")
165
                if $embed_header and !defined $embed_spec;
166
167
            if ( $embed_header ) {
168
                my $THE_embed = {};
169
                foreach my $embed_req ( split /\s*,\s*/, $embed_header ) {
170
                    my $matches = grep {lc $_ eq lc $embed_req} @{ $embed_spec };
171
172
                    Koha::Exceptions::BadParameter->throw(
173
                        error => 'Embeding '.$embed_req. ' is not authorised. Check your x-koha-embed headers or remove it.'
174
                    ) unless $matches;
175
176
                    _merge_embed( _parse_embed($embed_req), $THE_embed);
177
                }
178
179
                $c->stash( 'koha.embed' => $THE_embed )
180
                    if $THE_embed;
181
            }
182
183
            return $c;
184
        }
185
    );
146
}
186
}
147
187
148
=head2 Internal methods
188
=head2 Internal methods
Lines 198-201 sub _build_order_atom { Link Here
198
    }
238
    }
199
}
239
}
200
240
241
=head3 _parse_embed
242
243
    my $embed = _parse_embed( $string );
244
245
Parses I<$string> and outputs data valid for passing to the Kohaa::Object(s)->to_api
246
method.
247
248
=cut
249
250
sub _parse_embed {
251
    my $string = shift;
252
253
    my $result;
254
    my ( $curr, $next ) = split /\s*\.\s*/, $string, 2;
255
256
    if ( $next ) {
257
        $result->{$curr} = { children => _parse_embed( $next ) };
258
    }
259
    else {
260
        $result->{$curr} = {};
261
    }
262
263
    return $result;
264
}
265
266
=head3 _merge_embed
267
268
    _merge_embed( $parsed_embed, $global_embed );
269
270
Merges the hash referenced by I<$parsed_embed> into I<$global_embed>.
271
272
=cut
273
274
sub _merge_embed {
275
    my ( $structure, $embed ) = @_;
276
277
    my ($root) = keys %{ $structure };
278
279
    if ( any { $root eq $_ } keys %{ $embed } ) {
280
        # Recurse
281
        _merge_embed( $structure->{$root}, $embed->{$root} );
282
    }
283
    else {
284
        # Embed
285
        $embed->{$root} = $structure->{$root};
286
    }
287
}
288
201
1;
289
1;
(-)a/t/Koha/REST/Plugin/Query.t (-2 / +81 lines)
Lines 122-127 get '/build_query' => sub { Link Here
122
    };
122
    };
123
};
123
};
124
124
125
get '/stash_embed' => sub {
126
    my $c = shift;
127
128
    try {
129
        $c->stash_embed(
130
            {
131
                spec => {
132
                    'x-koha-embed' => [
133
                        'checkouts',
134
                        'checkouts.item',
135
                        'library'
136
                    ]
137
                }
138
            }
139
        );
140
141
        $c->render(
142
            status => 200,
143
            json   => $c->stash( 'koha.embed' )
144
        );
145
    }
146
    catch {
147
        $c->render(
148
            status => 400,
149
            json   => { error => "$_" }
150
        );
151
    };
152
};
153
154
get '/stash_embed_no_spec' => sub {
155
    my $c = shift;
156
157
    try {
158
        $c->stash_embed({ spec => {} });
159
160
        $c->render(
161
            status => 200,
162
            json   => $c->stash( 'koha.embed' )
163
        );
164
    }
165
    catch {
166
        $c->render(
167
            status => 400,
168
            json   => { error => "$_" }
169
        );
170
    };
171
};
172
125
sub to_model {
173
sub to_model {
126
    my ($args) = @_;
174
    my ($args) = @_;
127
    $args->{three} = delete $args->{tres}
175
    $args->{three} = delete $args->{tres}
Lines 131-137 sub to_model { Link Here
131
179
132
# The tests
180
# The tests
133
181
134
use Test::More tests => 3;
182
use Test::More tests => 4;
135
use Test::Mojo;
183
use Test::Mojo;
136
184
137
subtest 'extract_reserved_params() tests' => sub {
185
subtest 'extract_reserved_params() tests' => sub {
Lines 232-234 subtest '_build_query_params_from_api' => sub { Link Here
232
      ->json_is( '/exception_type' => 'Koha::Exceptions::WrongParameter' );
280
      ->json_is( '/exception_type' => 'Koha::Exceptions::WrongParameter' );
233
281
234
};
282
};
235
- 
283
284
subtest 'stash_embed() tests' => sub {
285
286
    plan tests => 12;
287
288
    my $t = Test::Mojo->new;
289
290
    $t->get_ok( '/stash_embed' => { 'x-koha-embed' => 'checkouts,checkouts.item' } )
291
      ->status_is(200)
292
      ->json_is( { checkouts => { children => { item => {} } } } );
293
294
    $t->get_ok( '/stash_embed' => { 'x-koha-embed' => 'checkouts,checkouts.item,library' } )
295
      ->status_is(200)
296
      ->json_is( { checkouts => { children => { item => {} } }, library => {} } );
297
298
    $t->get_ok( '/stash_embed' => { 'x-koha-embed' => 'checkouts,checkouts.item,patron' } )
299
      ->status_is(400)
300
      ->json_is(
301
        {
302
            error => 'Embeding patron is not authorised. Check your x-koha-embed headers or remove it.'
303
        }
304
      );
305
306
    $t->get_ok( '/stash_embed_no_spec' => { 'x-koha-embed' => 'checkouts,checkouts.item,patron' } )
307
      ->status_is(400)
308
      ->json_is(
309
        {
310
            error => 'Embedding objects is not allowed on this endpoint.'
311
        }
312
      );
313
314
};

Return to bug 24302