Bugzilla – Attachment 131808 Details for
Bug 29957
Cookies not removed after logout
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 29957: Introduce Koha::CookieManager
Bug-29957-Introduce-KohaCookieManager.patch (text/plain), 8.79 KB, created by
Marcel de Rooy
on 2022-03-16 15:45:56 UTC
(
hide
)
Description:
Bug 29957: Introduce Koha::CookieManager
Filename:
MIME Type:
Creator:
Marcel de Rooy
Created:
2022-03-16 15:45:56 UTC
Size:
8.79 KB
patch
obsolete
>From bde5f5dcd9dcfca21d2389cc653eaa30d5b92e2e Mon Sep 17 00:00:00 2001 >From: Marcel de Rooy <m.de.rooy@rijksmuseum.nl> >Date: Fri, 11 Mar 2022 10:15:30 +0000 >Subject: [PATCH] Bug 29957: Introduce Koha::CookieManager >Content-Type: text/plain; charset=utf-8 > >Test plan: >Run t/CookieManager.t > >Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl> >--- > Koha/CookieManager.pm | 131 ++++++++++++++++++++++++++++++++++++++++++ > t/CookieManager.t | 120 ++++++++++++++++++++++++++++++++++++++ > 2 files changed, 251 insertions(+) > create mode 100644 Koha/CookieManager.pm > create mode 100755 t/CookieManager.t > >diff --git a/Koha/CookieManager.pm b/Koha/CookieManager.pm >new file mode 100644 >index 0000000000..898cfaa69b >--- /dev/null >+++ b/Koha/CookieManager.pm >@@ -0,0 +1,131 @@ >+package Koha::CookieManager; >+ >+# Copyright 2022 Rijksmuseum, Koha Development Team >+# >+# 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 <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+use CGI::Cookie; >+use Data::Dumper qw( Dumper ); >+use List::MoreUtils qw( uniq ); >+ >+use C4::Context; >+ >+use constant ALLOW_LIST_VAR => 'removable_cookie'; >+ >+our $cookies; >+ >+=head1 NAME >+ >+Koha::CookieManager - Object for handling cookies in Koha >+ >+=head1 SYNOPSIS >+ >+ use Koha::CookieManager; >+ >+=head1 DESCRIPTION >+ >+TODO Add a nice description >+ >+=head1 METHODS >+ >+=head2 new >+ >+=cut >+ >+sub new { >+ my ( $class, $params ) = @_; >+ my $self = bless $params//{}, $class; >+ my $allowed = C4::Context->config(ALLOW_LIST_VAR); # expecting scalar or arrayref >+ $allowed = [ $allowed ] if ref($allowed) eq q{}; >+ $self->{_remove_allowed} = { map { $_ => 1 } @$allowed }; >+ $self->{_secure} = C4::Context->https_enabled; >+ return $self; >+} >+ >+=head2 clear_if_allowed >+ >+ $cookies = $self->clear_if_allowed( $query->cookie, @$cookies ); >+ >+ Arguments: either cookie names or cookie objects (CGI::Cookie). >+ Note: in the example above $query->cookie is a list of cookie names. >+ >+ Returns an arrayref of cookie objects: empty, expired cookies for those passed >+ by name or object that are on the allow list, together with the remaining >+ (untouched) cookie objects not on that list. >+ >+=cut >+ >+sub clear_if_allowed { >+ my ( $self, @cookies ) = @_; >+ my @rv; >+ my $seen = {}; >+ foreach my $c ( @cookies ) { >+ my $name; >+ my $type = ref($c); >+ if( $type eq 'CGI::Cookie' ) { >+ $name = $c->name; >+ } elsif( $type ) { # not expected: ignore >+ next; >+ } else { >+ $name = $c; >+ } >+ >+ if( $self->{_remove_allowed}->{$name} ) { >+ next if $seen->{ $name }; >+ push @rv, CGI::Cookie->new( >+ # -expires explicitly omitted to create shortlived 'session' cookie >+ -name => $name, -value => q{}, -HttpOnly => 1, >+ $self->{_secure} ? ( -secure => 1 ) : (), >+ ); >+ $seen->{ $name } = 1; # prevent duplicates >+ } elsif( $type eq 'CGI::Cookie' ) { >+ push @rv, $c; >+ } >+ } >+ return \@rv; >+} >+ >+=head2 replace_in_list >+ >+ $list2 = $mgr->replace_in_list( $list1, $cookie ); >+ >+ Add $cookie to $list1, remove older occurrences in list1. >+ $list1 is a list of CGI::Cookie objects. >+ $cookie must be a CGI::Cookie object; if it is not, only >+ cookie objects in list1 are returned (filtering list1). >+ >+ Returns an arrayref of CGI::Cookie objects. >+ >+=cut >+ >+sub replace_in_list { >+ my ( $self, $list, $cookie ) = @_; >+ my $name = ref($cookie) eq 'CGI::Cookie' ? $cookie->name : q{}; >+ >+ my @result; >+ foreach my $c ( @$list ) { >+ next if ref($c) ne 'CGI::Cookie'; >+ push @result, $c if !$name or $c->name ne $name; >+ } >+ return $name ? [ @result, $cookie ] : \@result; >+} >+ >+=head1 INTERNAL ROUTINES >+ >+=cut >+ >+1; >diff --git a/t/CookieManager.t b/t/CookieManager.t >new file mode 100755 >index 0000000000..78a7d9e490 >--- /dev/null >+++ b/t/CookieManager.t >@@ -0,0 +1,120 @@ >+#!/usr/bin/perl >+# >+# Copyright 2022 Rijksmuseum, Koha Development Team >+# >+# 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 <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+use CGI; >+use Data::Dumper qw(Dumper); >+use Test::More tests => 3; >+ >+use t::lib::Mocks; >+ >+use C4::Context; >+use Koha::CookieManager; >+ >+subtest 'new' => sub { >+ plan tests => 3; >+ >+ t::lib::Mocks::mock_config( Koha::CookieManager::ALLOW_LIST_VAR, 'just_one' ); >+ my $cmgr = Koha::CookieManager->new; >+ is( scalar keys %{$cmgr->{_remove_allowed}}, 1, 'one entry' ); >+ is( exists $cmgr->{_secure}, 1, 'secure key found' ); >+ >+ t::lib::Mocks::mock_config( Koha::CookieManager::ALLOW_LIST_VAR, [ 'two', 'entries' ] ); >+ $cmgr = Koha::CookieManager->new; >+ is( scalar keys %{$cmgr->{_remove_allowed}}, 2, 'two entries' ); >+}; >+ >+subtest 'clear_if_allowed' => sub { >+ plan tests => 11; >+ >+ t::lib::Mocks::mock_config( Koha::CookieManager::ALLOW_LIST_VAR, [ 'aap', 'noot', 'mies' ] ); >+ >+ my $q = CGI->new; >+ my $cmgr = Koha::CookieManager->new; >+ >+ my $cookie1 = $q->cookie( >+ -name => 'aap', >+ -value => 'aap', >+ -expires => '+1d', >+ -HttpOnly => 1, >+ -secure => 1, >+ ); >+ my $cookie2 = $q->cookie( >+ -name => 'noot', >+ -value => 'noot', >+ -expires => '+1d', >+ -HttpOnly => 1, >+ -secure => 1, >+ ); >+ my $cookie3 = $q->cookie( -name => 'wim', -value => q{wim} ); >+ my $cookie4 = $q->cookie( -name => 'aap', -value => q{aap2} ); >+ my $list = [ $cookie1, $cookie2, $cookie3, $cookie4, 'mies', 'zus' ]; # 4 cookies, 2 names >+ >+ # No results expected >+ is( @{$cmgr->clear_if_allowed}, 0, 'Empty list' ); >+ is( @{$cmgr->clear_if_allowed( 'scalar', [], $q )}, 0, 'Empty list for invalid arguments' ); >+ >+ # Pass list, expect 4 cookies (3 cleared) >+ my @rv = @{$cmgr->clear_if_allowed( @$list )}; >+ is( @rv, 4, 'Four expected' ); >+ is( $rv[0]->name, 'aap', 'First cookie' ); >+ is( $rv[1]->name, 'noot', '2nd cookie' ); >+ is( $rv[2]->name, 'wim', '3rd cookie' ); >+ is( $rv[3]->name, 'mies', '4th cookie' ); >+ is( $rv[0]->value, q{}, 'aap should be empty' ); >+ is( $rv[1]->value, q{}, 'noot should be empty' ); >+ is( $rv[2]->value, 'wim', 'wim not empty' ); >+ is( $rv[3]->value, q{}, 'mies empty' ); >+}; >+ >+subtest 'replace_in_list' => sub { >+ plan tests => 13; >+ >+ my $q = CGI->new; >+ my $cmgr = Koha::CookieManager->new; >+ >+ my $cookie1 = $q->cookie( -name => 'c1', -value => q{c1} ); >+ my $cookie2 = $q->cookie( -name => 'c2', -value => q{c2} ); >+ my $cookie3 = $q->cookie( -name => 'c3', -value => q{c3} ); >+ my $cookie4 = $q->cookie( -name => 'c2', -value => q{c4} ); # name c2 ! >+ >+ # Unusual arguments (show that $cmgr handles the cookie mocks in Auth.t) >+ my $res = $cmgr->replace_in_list( [ 1, 2, 3 ], 4 ); >+ is( @$res, 0, 'No cookies' ); >+ $res = $cmgr->replace_in_list( [ 1, 2, 3 ], $cookie1 ); >+ is( @$res, 1, 'One cookie added' ); >+ is( $res->[0]->name, 'c1', '1st cookie' ); >+ $res = $cmgr->replace_in_list( [ $cookie2, 2, 3 ], 4 ); # filter 2,3 and ignore 4 >+ is( @$res, 1, 'One cookie found' ); >+ is( $res->[0]->name, 'c2', 'c2 found' ); >+ >+ # Pass c1 c2, add c3 >+ $res = $cmgr->replace_in_list( [ $cookie1, $cookie2 ], $cookie3 ); >+ is( @$res, 3, 'Returns three' ); >+ is( $res->[2]->name, 'c3', '3rd cookie' ); >+ is( $res->[2]->value, 'c3', 'value c3' ); >+ >+ # Pass c1 c2 c3 and replace c2 >+ $res = $cmgr->replace_in_list( [ $cookie1, $cookie2, $cookie3 ], $cookie4 ); >+ is( @$res, 3, 'Returns three' ); >+ is( $res->[0]->name, 'c1', '1st cookie' ); >+ is( $res->[1]->name, 'c3', '2nd cookie' ); >+ is( $res->[2]->name, 'c2', '3rd cookie' ); >+ is( $res->[2]->value, 'c4', 'value replaced' ); >+}; >-- >2.20.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 29957
:
129871
|
129872
|
130005
|
130006
|
131428
|
131750
|
131751
|
131752
|
131807
|
131808
|
131809
|
131810
|
131824
|
131825
|
131826
|
131827
|
131828
|
131840
|
131841
|
131842
|
131843
|
131856
|
132045
|
132046
|
132047
|
132105
|
132106
|
132107
|
132108
|
132109
|
132110
|
132111
|
132115
|
132210
|
132211
|
132231
|
132232
|
132233
|
132234
|
132235
|
132236
|
132237
|
132238
|
132239
|
132288
|
132289
|
132290
|
132291
|
132292
|
132293
|
132294
|
132295
|
132296