From c12cc3753a3a21eae386c5a6c7af0c9327666bfc Mon Sep 17 00:00:00 2001 From: Marcel de Rooy Date: Fri, 10 Sep 2021 18:26:54 +0000 Subject: [PATCH] Bug 28999: Introduce Allowlist Content-Type: text/plain; charset=utf-8 Based on work of David Cook and Jonathan Druart. Removed the patron example here. --- Koha/Allowlist.pm | 116 +++++++++++++++++++++++++++++++++++++++++++++ t/Koha/Allowlist.t | 45 ++++++++++++++++++ 2 files changed, 161 insertions(+) create mode 100644 Koha/Allowlist.pm create mode 100755 t/Koha/Allowlist.t diff --git a/Koha/Allowlist.pm b/Koha/Allowlist.pm new file mode 100644 index 0000000000..e563dcf3f3 --- /dev/null +++ b/Koha/Allowlist.pm @@ -0,0 +1,116 @@ +package Koha::Allowlist; + +use Modern::Perl; + +=head1 NAME + +Koha::Allowlist - Allowlist implementation base class + +=head1 API + +=head2 Class Methods + +=head3 new + + my $allow_list = Koha::Allowlist->new({ interface => 'staff' }); + + Constructor. + + Interface must be 'staff' or 'opac' - defaults to 'opac' + +=cut + +sub new { + my ($class, $args) = @_; + $args = {} unless defined $args; + my $self = bless ($args, $class); + $self->{interface} = + ( $args->{interface} && $args->{interface} eq 'staff' ) + ? 'staff' + : 'opac'; + $self->{_entries} = {}; + return $self; +} + +=head3 add + + $list->add( 'column1', 'column2' ); + +=cut + +sub add { + my ( $self, @args ) = @_; + # TODO Could be extended by passing things like column3 => { staff => 1 } + foreach my $arg ( @args ) { + $self->{_entries}->{$arg} = 1; + } +} + +=head3 remove + + $list->remove( 'column3', 'column4' ); + +=cut + +sub remove { + my ( $self, @args ) = @_; + foreach my $arg ( @args ) { + delete $self->{_entries}->{$arg}; + } +} + +=head3 apply + + my $blocked = $allowlist->apply({ input => $hashref, verbose => 1 }); + + Apply an allowlist to input data. Note that we modify the $hashref argument! + The verbose flag controls the warn statement. + + Returns a hash of blocked entries. Might be useful for logging purposes? + +=cut + +sub apply { + my ( $self, $params ) = @_; + my $input = $params->{input} or return; + + my $blocked = {}; + foreach my $key ( keys %$input ){ + unless ( $self->{_entries}->{$key} ) { + $blocked->{$key} = delete $input->{ $key }; + } + } + warn 'Koha::Allowlist: apply blocked one or more keys' if keys %$blocked && $params->{verbose}; + return $blocked; +} + +=head3 load + + my $fields = $self->load; + + Loads default allow list entries. + + This routine should be overridden when subclassing. + +=cut + +sub load { + my ( $self ) = @_; + # You could do something here like: + # $self->add( 'myfield' ); +} + +=head3 unload + + $allowlist->unload; + + Clear all entries. + +=cut + +sub unload { + my ( $self ) = @_; + $self->{_entries} = {}; +} + +1; diff --git a/t/Koha/Allowlist.t b/t/Koha/Allowlist.t new file mode 100755 index 0000000000..e488ab063a --- /dev/null +++ b/t/Koha/Allowlist.t @@ -0,0 +1,45 @@ +#!/usr/bin/perl + +# 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 Test::More tests => 1; + +use Koha::Allowlist; + +subtest 'Allowlist' => sub { + plan tests => 7; + + my $allowlist = Koha::Allowlist->new; + $allowlist->load; + is( $allowlist->apply, undef, 'No input returns undef' ); + is( %{$allowlist->apply({ input => {} })}, 0, 'Empty hash returns nothing blocked' ); + + my @input = ( col1 => 1, col2 => 2, col3 => 3, col4 => 4 ); + my $blocked = $allowlist->apply({ input => { @input } }); + is( keys %$blocked, 4, 'Empty list blocks all' ); + $allowlist->add( 'col1' ); + $blocked = $allowlist->apply({ input => { @input } }); + is( keys %$blocked, 3, 'One field allowed' ); + is( $blocked->{col1}, undef, 'And that is col1' ); + $allowlist->remove( 'col1' ); + $blocked = $allowlist->apply({ input => { @input } }); + is( keys %$blocked, 4, 'Back to 4 after removing col1' ); + $allowlist->add( 'col2' ); + $allowlist->unload; + $blocked = $allowlist->apply({ input => { @input } }); + is( keys %$blocked, 4, 'Same after unloading' ); +}; -- 2.20.1