From c6e5f79bfdce47e701176611a4b3ced280b4b111 Mon Sep 17 00:00:00 2001 From: Tomas Cohen Arazi Date: Tue, 29 Nov 2022 15:14:51 -0300 Subject: [PATCH] Bug 32370: Provide a generic set of tools for JSON fields This patch introduces a new class for extending Koha::Object-based classes so they have reusable ways to deal with JSON encoded fields. As documented in the POD, classes can now ```perl use base qw(Koha::Object Koha::Object::JSONFields); ``` and will have the following methods available: * decode_json_field * set_encoded_json_field For convenience, the Koha::Auth::Identity::Provider class is tweaked to make use of this, and also to prove the behavior is correct (expected results, exceptions, encoding, etc). To test: 1. Run: $ kshell k$ prove t/db_dependent/Koha/Auth/Identity/Provider.t \ t/db_dependent/api/v1/idp.t => SUCCESS: Identity provider related tests pass! 2. Apply this patches 3. Repeat 1 => SUCCESS: Tests still pass! 4. Run the specific tests: k$ prove t/db_dependent/Koha/Object/JSONField.t => SUCCESS: Tests pass! 5. Sign off :-D --- Koha/Auth/Identity/Provider.pm | 39 ++--------- Koha/Object/JSONFields.pm | 122 +++++++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+), 34 deletions(-) create mode 100644 Koha/Object/JSONFields.pm diff --git a/Koha/Auth/Identity/Provider.pm b/Koha/Auth/Identity/Provider.pm index e9dfc2fddbb..d01546754cb 100644 --- a/Koha/Auth/Identity/Provider.pm +++ b/Koha/Auth/Identity/Provider.pm @@ -19,14 +19,10 @@ package Koha::Auth::Identity::Provider; use Modern::Perl; -use base qw(Koha::Object); - -use JSON qw( decode_json encode_json ); -use Try::Tiny; +use base qw(Koha::Object Koha::Object::JSONFields); use Koha::Auth::Identity::Provider::Domains; use Koha::Exceptions; -use Koha::Exceptions::Object; =head1 NAME @@ -61,12 +57,7 @@ Returns a I containing the configuration parameters for the provider. sub get_config { my ($self) = @_; - return try { - return decode_json( $self->config ); - } - catch { - Koha::Exceptions::Object::BadValue->throw("Error reading JSON data: $_"); - }; + return $self->decode_json_field({ field => 'config' }); } =head3 set_config @@ -105,14 +96,7 @@ sub set_config { } } - try { - my $encoded_config = encode_json($config); - $self->config($encoded_config); - } catch { - Koha::Exceptions::Object::BadValue->throw("Error serializing data into JSON: $_"); - }; - - return $self; + return $self->set_encoded_json_field({ data => $config, field => 'config' }); } =head3 get_mapping @@ -126,12 +110,7 @@ Returns a I containing the attribute mapping for the provider. sub get_mapping { my ($self) = @_; - return try { - return decode_json( $self->mapping ); - } - catch { - Koha::Exceptions::Object::BadValue->throw("Error reading JSON data: $_"); - }; + return $self->decode_json_field({ field => 'mapping' }); } =head3 set_mapping @@ -145,15 +124,7 @@ This method stores the passed mappings in JSON format. sub set_mapping { my ($self, $mapping) = @_; - try { - my $encoded_mapping = encode_json( $mapping ); - $self->mapping( $encoded_mapping ); - } - catch { - Koha::Exceptions::Object::BadValue->throw("Error serializing data into JSON: $_"); - }; - - return $self; + return $self->set_encoded_json_field({ data => $mapping, field => 'mapping' }); } =head3 upgrade_class diff --git a/Koha/Object/JSONFields.pm b/Koha/Object/JSONFields.pm new file mode 100644 index 00000000000..5ccaa67cc08 --- /dev/null +++ b/Koha/Object/JSONFields.pm @@ -0,0 +1,122 @@ +package Koha::Object::JSONFields; + +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use JSON; +use Try::Tiny; + +use Koha::Exceptions; +use Koha::Exceptions::Object; + +=head1 NAME + +Koha::Object::JSONFields - Class that adds JSON field manipulation helper methods +for Koha::Object-derived classes + +=head1 SYNOPSIS + + use base qw(Koha::Object Koha::Object::JSONFields); + my $object = Koha::Object->new({ property1 => $property1, property2 => $property2, etc... } ); + my $field_name_hashref = $object->decode_json_field({ field => 'field_name' }); + $object->encode_json_field({ field => 'field_name', data => $data }); + +=head1 API + +=head2 Class methods + +=head3 decode_json_field + + my $hashref = $object->decode_json_field({ field => 'field_name' }); + +Returns a data structure representing the JSON-decoded value of field I. + +=cut + +sub decode_json_field { + my ( $self, $params ) = @_; + + Koha::Exceptions::MissingParameter->throw( parameter => 'field' ) + unless defined $params->{field}; + + my $field = $params->{field}; + + return try { + $self->$field ? $self->_json->decode( $self->$field ) : undef; + } + catch { + Koha::Exceptions::Object::BadValue->throw("Error reading JSON data: $_"); + }; +} + +=head3 set_encoded_json_field + + $object->set_encoded_json_field( + { data => $data, + field => 'field_name', + } + ); + +Sets a JSON string encoded representation of I<$data> into the object's I +attribute. + +=cut + +sub set_encoded_json_field { + my ( $self, $params ) = @_; + + Koha::Exceptions::MissingParameter->throw( parameter => 'field' ) + unless defined $params->{field}; + + Koha::Exceptions::MissingParameter->throw( parameter => 'data' ) + unless exists $params->{data}; + + my $field = $params->{field}; + my $data = $params->{data}; + + return try { + $self->$field( $data ? $self->_json->encode($data) : undef ); + } + catch { + Koha::Exceptions::Object::BadValue->throw("Error reading JSON data: $_"); + }; +} + +=head2 Internal methods + +=head3 _json + + my $JSON_object = $self->_json; + +Returns a JSON object with utf8 disabled. Encoding to UTF-8 should be +done later. + +=cut + +sub _json { + my ($self) = @_; + $self->{_json} //= JSON->new->utf8(0); + return $self->{_json}; +} + +=head1 AUTHOR + +Tomas Cohen Arazi, Etomascohen@theke.ioE + +=cut + +1; -- 2.34.1