Bugzilla – Attachment 96543 Details for
Bug 24228
Add a parameter to recursively embed objects in Koha::Object(s)->to_api
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 24228: Add parameters to Koha::Object->to_api to automatically embed objects
Bug-24228-Add-parameters-to-KohaObject-toapi-to-au.patch (text/plain), 8.32 KB, created by
Agustín Moyano
on 2019-12-20 23:03:26 UTC
(
hide
)
Description:
Bug 24228: Add parameters to Koha::Object->to_api to automatically embed objects
Filename:
MIME Type:
Creator:
Agustín Moyano
Created:
2019-12-20 23:03:26 UTC
Size:
8.32 KB
patch
obsolete
>From 789338fd832a262ac834811a8850c37159152aa2 Mon Sep 17 00:00:00 2001 >From: Agustin Moyano <agustinmoyano@theke.io> >Date: Thu, 19 Dec 2019 15:50:49 -0300 >Subject: [PATCH] Bug 24228: Add parameters to Koha::Object->to_api to > automatically embed objects > >This patch adds the posibility to define 'x-koha-embed' parameter in swagger and in request headers. > >If 'x-koha-embed' header is present, in Koha::REST::V1::Auth it's compared with the whitelist defined in swagger through the 'x-koha-embed' parameter, placed at the same level of x-koha-authorization. > >Whitelist should be composed of DBIC relations (optinally chained by '.') that has the corresponding method in Koha::Object. > >To test: >1. Apply this patch >2. prove t/db_dependent/Koha/Object.t >--- > Koha/Exceptions/Authorization.pm | 5 ++++ > Koha/Object.pm | 35 ++++++++++++++++++++++++++-- > Koha/Objects.pm | 4 ++-- > Koha/REST/Plugin/Objects.pm | 7 +++--- > Koha/REST/V1/Auth.pm | 21 +++++++++++++++++ > t/db_dependent/Koha/Object.t | 40 +++++++++++++++++++++++++++++++- > 6 files changed, 104 insertions(+), 8 deletions(-) > >diff --git a/Koha/Exceptions/Authorization.pm b/Koha/Exceptions/Authorization.pm >index a3c625aca8..1474ffac20 100644 >--- a/Koha/Exceptions/Authorization.pm >+++ b/Koha/Exceptions/Authorization.pm >@@ -12,6 +12,11 @@ use Exception::Class ( > description => 'Unauthorized', > fields => ['required_permissions'] > }, >+ 'Koha::Exceptions::Authorization::Embedded' => { >+ isa => 'Koha::Exceptions::Authorization', >+ description => 'Embedded documents unauthorized', >+ fields => ['embedded_item'] >+ }, > > ); > >diff --git a/Koha/Object.pm b/Koha/Object.pm >index ce4c231591..553e53d28b 100644 >--- a/Koha/Object.pm >+++ b/Koha/Object.pm >@@ -380,12 +380,12 @@ Returns a representation of the object, suitable for API output. > =cut > > sub to_api { >- my ( $self ) = @_; >+ my ( $self, $embeds ) = @_; > my $json_object = $self->TO_JSON; > > # Rename attributes if there's a mapping > if ( $self->can('to_api_mapping') ) { >- foreach my $column ( keys %{$self->to_api_mapping} ) { >+ foreach my $column ( keys %{ $self->to_api_mapping } ) { > my $mapped_column = $self->to_api_mapping->{$column}; > if ( exists $json_object->{$column} > && defined $mapped_column ) >@@ -402,9 +402,40 @@ sub to_api { > } > } > >+ if ($embeds) { >+ foreach my $embed (@$embeds) { >+ my ( $curr, $next ) = split /\s*\.\s*/, $embed, 2; >+ my @nxembeds; >+ >+ @nxembeds = ($next) if $next; >+ >+ my $children = $self->$curr; >+ if ( ref $children eq 'ARRAY' ) { >+ my @list; >+ my $pos = 0; >+ foreach my $child (@$children) { >+ my $res = $child->to_api( \@nxembeds ); >+ $res = { $json_object->{$curr}->[$pos], $res } >+ if defined $json_object->{$curr} >+ && defined $json_object->{$curr}->[$pos]; >+ push @list, $res; >+ $pos++; >+ } >+ $json_object->{$curr} = \@list; >+ } >+ else { >+ my $res = $children->to_api( \@nxembeds ); >+ $res = { $json_object->{$curr}, $res } >+ if defined $json_object->{$curr}; >+ $json_object->{$curr} = $res; >+ } >+ } >+ } >+ > return $json_object; > } > >+ > =head3 $object->unblessed_all_relateds > > my $everything_into_one_hashref = $object->unblessed_all_relateds >diff --git a/Koha/Objects.pm b/Koha/Objects.pm >index 31387e1442..05b1de467d 100644 >--- a/Koha/Objects.pm >+++ b/Koha/Objects.pm >@@ -315,9 +315,9 @@ Returns a representation of the objects, suitable for API output . > =cut > > sub to_api { >- my ($self) = @_; >+ my ($self, $embeds) = @_; > >- return [ map { $_->to_api } $self->as_list ]; >+ return [ map { $_->to_api($embeds) } $self->as_list ]; > } > > =head3 Koha::Objects->_wrap >diff --git a/Koha/REST/Plugin/Objects.pm b/Koha/REST/Plugin/Objects.pm >index 3d314a784e..96a1a94819 100644 >--- a/Koha/REST/Plugin/Objects.pm >+++ b/Koha/REST/Plugin/Objects.pm >@@ -52,7 +52,6 @@ sub register { > > my $args = $c->validation->output; > my $attributes = {}; >- > # Extract reserved params > my ( $filtered_params, $reserved_params ) = $c->extract_reserved_params($args); > >@@ -82,6 +81,8 @@ sub register { > $filtered_params = $c->build_query_params( $filtered_params, $reserved_params ); > } > >+ my $embeds = $c->stash('koha.embed'); >+ > # Perform search > my $objects = $objects_set->search( $filtered_params, $attributes ); > >@@ -94,8 +95,8 @@ sub register { > > my @objects_list = map { > ( defined $to_api ) >- ? $to_api->( $_->TO_JSON ) >- : $_->TO_JSON >+ ? $to_api->( $_->TO_JSON, $embeds ) >+ : $_->to_api($embeds); > } $objects->as_list; > > return \@objects_list; >diff --git a/Koha/REST/V1/Auth.pm b/Koha/REST/V1/Auth.pm >index 8bffc977da..7c9d9bb929 100644 >--- a/Koha/REST/V1/Auth.pm >+++ b/Koha/REST/V1/Auth.pm >@@ -137,6 +137,27 @@ sub authenticate_api_request { > my $user; > > my $spec = $c->match->endpoint->pattern->defaults->{'openapi.op_spec'}; >+ >+ my $embed_header = $c->req->headers->header('x-koha-embed'); >+ >+ if($embed_header) { >+ my $embed = $spec->{'x-koha-embed'}; >+ >+ Koha::Exceptions::Authorization::Embedded->throw( >+ error => 'No embedded items are authorised for this endpoint. Remove your x-koha-embed headers.' >+ ) unless $embed; >+ >+ my @to_embed; >+ foreach my $eh (split /\s*,\s*/, $embed_header) { >+ my $matches = grep {lc $_ eq lc $eh} @$embed; >+ Koha::Exceptions::Authorization::Embedded->throw( >+ error => 'Embeding '.$eh. ' is not authorised. Check your x-koha-embed headers or remove it.' >+ ) unless $matches; >+ push @to_embed, $eh; >+ } >+ $c->stash('koha.embed' => \@to_embed); >+ } >+ > my $authorization = $spec->{'x-koha-authorization'}; > > my $authorization_header = $c->req->headers->authorization; >diff --git a/t/db_dependent/Koha/Object.t b/t/db_dependent/Koha/Object.t >index a37695bc1f..af97834a7d 100755 >--- a/t/db_dependent/Koha/Object.t >+++ b/t/db_dependent/Koha/Object.t >@@ -215,7 +215,7 @@ subtest 'TO_JSON tests' => sub { > > subtest "to_api() tests" => sub { > >- plan tests => 11; >+ plan tests => 18; > > $schema->storage->txn_begin; > >@@ -262,6 +262,44 @@ subtest "to_api() tests" => sub { > my $illrequest = $builder->build_object({ class => 'Koha::Illrequests' }); > is_deeply( $illrequest->to_api, $illrequest->TO_JSON, 'If no to_api_method present, return TO_JSON' ); > >+ my $item_class = Test::MockModule->new('Koha::Item'); >+ $item_class->mock( 'to_api_mapping', >+ sub { >+ return { >+ itemnumber => 'item_id' >+ }; >+ } >+ ); >+ >+ my $hold_class = Test::MockModule->new('Koha::Hold'); >+ $hold_class->mock( 'to_api_mapping', >+ sub { >+ return { >+ reserve_id => 'hold_id' >+ }; >+ } >+ ); >+ >+ my $biblio = $builder->build_sample_biblio(); >+ my $item = $builder->build_sample_item({ biblionumber => $biblio->biblionumber }); >+ my $hold = $builder->build_object({ class => 'Koha::Holds', value => { itemnumber => $item->itemnumber } }); >+ >+ my @embeds = ('items'); >+ >+ my $biblio_api = $biblio->to_api(\@embeds); >+ >+ ok(exists $biblio_api->{items}, 'Items where embedded in biblio results'); >+ is($biblio_api->{items}->[0]->{item_id}, $item->itemnumber, 'Item matches'); >+ ok(!exists $biblio_api->{items}->[0]->{holds}, 'No holds info should be embedded yet'); >+ >+ @embeds = ('items.holds'); >+ $biblio_api = $biblio->to_api(\@embeds); >+ >+ ok(exists $biblio_api->{items}, 'Items where embedded in biblio results'); >+ is($biblio_api->{items}->[0]->{item_id}, $item->itemnumber, 'Item still matches'); >+ ok(exists $biblio_api->{items}->[0]->{holds}, 'Holds info should be embedded'); >+ is($biblio_api->{items}->[0]->{holds}->[0]->{hold_id}, $hold->reserve_id, 'Hold matches'); >+ > $schema->storage->txn_rollback; > }; > >-- >2.17.1
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 24228
:
96543
|
96612
|
96613
|
96615
|
96622
|
96644
|
96645
|
96646
|
96685
|
96686
|
96687
|
96954
|
96955