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

(-)a/Koha/REST/Plugin/Query.pm (+86 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
            my $THE_embed = {};
168
            foreach my $embed_req ( split /\s*,\s*/, $embed_header ) {
169
                my $matches = grep {lc $_ eq lc $embed_req} @{ $embed_spec };
170
171
                Koha::Exceptions::BadParameter->throw(
172
                    error => 'Embeding '.$embed_req. ' is not authorised. Check your x-koha-embed headers or remove it.'
173
                ) unless $matches;
174
175
                _merge_embed( _parse_embed($embed_req), $THE_embed);
176
            }
177
178
            $c->stash( 'koha.embed' => $THE_embed )
179
                if $THE_embed;
180
181
            return $c;
182
        }
183
    );
146
}
184
}
147
185
148
=head2 Internal methods
186
=head2 Internal methods
Lines 198-201 sub _build_order_atom { Link Here
198
    }
236
    }
199
}
237
}
200
238
239
=head3 _parse_embed
240
241
    my $embed = _parse_embed( $string );
242
243
Parses I<$string> and outputs data valid for passing to the Kohaa::Object(s)->to_api
244
method.
245
246
=cut
247
248
sub _parse_embed {
249
    my $string = shift;
250
251
    my $result;
252
    my ( $curr, $next ) = split /\s*\.\s*/, $string, 2;
253
254
    if ( $next ) {
255
        $result->{$curr} = { children => _parse_embed( $next ) };
256
    }
257
    else {
258
        $result->{$curr} = {};
259
    }
260
261
    return $result;
262
}
263
264
=head3 _merge_embed
265
266
    _merge_embed( $parsed_embed, $global_embed );
267
268
Merges the hash referenced by I<$parsed_embed> into I<$global_embed>.
269
270
=cut
271
272
sub _merge_embed {
273
    my ( $structure, $embed ) = @_;
274
275
    my ($root) = keys %{ $structure };
276
277
    if ( any { $root eq $_ } keys %{ $embed } ) {
278
        # Recurse
279
        _merge_embed( $structure->{$root}, $embed->{$root} );
280
    }
281
    else {
282
        # Embed
283
        $embed->{$root} = $structure->{$root};
284
    }
285
}
286
201
1;
287
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