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 / +88 lines)
Lines 125-133 get '/build_query' => sub { Link Here
125
    };
125
    };
126
};
126
};
127
127
128
get '/stash_embed' => sub {
129
    my $c = shift;
130
131
    try {
132
        $c->stash_embed(
133
            {
134
                spec => {
135
                    'x-koha-embed' => [
136
                        'checkouts',
137
                        'checkouts.item',
138
                        'library'
139
                    ]
140
                }
141
            }
142
        );
143
144
        $c->render(
145
            status => 200,
146
            json   => $c->stash( 'koha.embed' )
147
        );
148
    }
149
    catch {
150
        $c->render(
151
            status => 400,
152
            json   => { error => "$_" }
153
        );
154
    };
155
};
156
157
get '/stash_embed_no_spec' => sub {
158
    my $c = shift;
159
160
    try {
161
        $c->stash_embed({ spec => {} });
162
163
        $c->render(
164
            status => 200,
165
            json   => $c->stash( 'koha.embed' )
166
        );
167
    }
168
    catch {
169
        $c->render(
170
            status => 400,
171
            json   => { error => "$_" }
172
        );
173
    };
174
};
175
176
sub to_model {
177
    my ($args) = @_;
178
    $args->{three} = delete $args->{tres}
179
        if exists $args->{tres};
180
    return $args;
181
}
182
128
# The tests
183
# The tests
129
184
130
use Test::More tests => 3;
185
use Test::More tests => 4;
131
use Test::Mojo;
186
use Test::Mojo;
132
187
133
subtest 'extract_reserved_params() tests' => sub {
188
subtest 'extract_reserved_params() tests' => sub {
Lines 228-230 subtest '_build_query_params_from_api' => sub { Link Here
228
      ->json_is( '/exception_type' => 'Koha::Exceptions::WrongParameter' );
283
      ->json_is( '/exception_type' => 'Koha::Exceptions::WrongParameter' );
229
284
230
};
285
};
231
- 
286
287
subtest 'stash_embed() tests' => sub {
288
289
    plan tests => 12;
290
291
    my $t = Test::Mojo->new;
292
293
    $t->get_ok( '/stash_embed' => { 'x-koha-embed' => 'checkouts,checkouts.item' } )
294
      ->status_is(200)
295
      ->json_is( { checkouts => { children => { item => {} } } } );
296
297
    $t->get_ok( '/stash_embed' => { 'x-koha-embed' => 'checkouts,checkouts.item,library' } )
298
      ->status_is(200)
299
      ->json_is( { checkouts => { children => { item => {} } }, library => {} } );
300
301
    $t->get_ok( '/stash_embed' => { 'x-koha-embed' => 'checkouts,checkouts.item,patron' } )
302
      ->status_is(400)
303
      ->json_is(
304
        {
305
            error => 'Embeding patron is not authorised. Check your x-koha-embed headers or remove it.'
306
        }
307
      );
308
309
    $t->get_ok( '/stash_embed_no_spec' => { 'x-koha-embed' => 'checkouts,checkouts.item,patron' } )
310
      ->status_is(400)
311
      ->json_is(
312
        {
313
            error => 'Embedding objects is not allowed on this endpoint.'
314
        }
315
      );
316
317
};

Return to bug 24302