Bug 33197: Rename GDPR_Policy system preference

GDPR is a European Union (and, at time of writing, UK) law.
The GDPR_Policy system preference is about a patron
giving consent to their personal data being processed in
line with the library's privacy policy.

The name of the preference is vague: there could be
many policies implemented by libraries to comply with
GDPR. It also makes the preference look irrelevant for
libraries outside the areas where GDPR applies, while
it may be useful for libraries anywhere.

This renames GDPR_Policy to PrivacyPolicyConsent and
adjusts the system preference descriptions.

To test:
* Apply the patch
* Run database update
* Search for GDPR_Policy in the system preference
  - you should not find anything.
* Search for DataPrivacyConsent in the system preferences
  - you should find it and be able to activate it
* Verify the feature works as expected
  - If the preference is set to "enforced", you will be
    asked to give consent to the data privacy agreement
    in the OPAC when you log in
* Verify the page is now phrased neutrally using 'privacy policy'

Bonus: Consent date is now formatted according to DateFormat
       system preference.
Signed-off-by: David Nind <david@davidnind.com>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
This commit is contained in:
Katrin Fischer 2023-03-17 22:06:40 +00:00 committed by Tomas Cohen Arazi
parent 25b5428efd
commit bd75309933
Signed by: tomascohen
GPG key ID: 0A272EA1B2F3C15F
10 changed files with 32 additions and 19 deletions

View file

@ -193,7 +193,7 @@ sub get_template_and_user {
# Exceptions for consent page itself and SCI/SCO system # Exceptions for consent page itself and SCI/SCO system
if( $in->{type} eq 'opac' && $user && if( $in->{type} eq 'opac' && $user &&
$in->{'template_name'} !~ /^(opac-page|opac-patron-consent|sc[io]\/)/ && $in->{'template_name'} !~ /^(opac-page|opac-patron-consent|sc[io]\/)/ &&
C4::Context->preference('GDPR_Policy') eq 'Enforced' ) C4::Context->preference('PrivacyPolicyConsent') eq 'Enforced' )
{ {
my $consent = Koha::Patron::Consents->search({ my $consent = Koha::Patron::Consents->search({
borrowernumber => getborrowernumber($user), borrowernumber => getborrowernumber($user),

View file

@ -0,0 +1,12 @@
use Modern::Perl;
return {
bug_number => "33197",
description => "Rename GDPR_Policy system preference",
up => sub {
my ($args) = @_;
my ($dbh, $out) = @$args{qw(dbh out)};
$dbh->do(q{UPDATE systempreferences set variable = "PrivacyPolicyConsent" WHERE variable = "GDPR_Policy"});
say $out "Rename system preference GDPR_Policy to PrivacyPolicyConsent";
},
};

View file

@ -254,7 +254,6 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `
('FinesLog','1',NULL,'If ON, log fines','YesNo'), ('FinesLog','1',NULL,'If ON, log fines','YesNo'),
('finesMode','off','off|production','Choose the fines mode, \'off\' (no charges), \'production\' (accrue overdue fines). Requires accruefines cronjob.','Choice'), ('finesMode','off','off|production','Choose the fines mode, \'off\' (no charges), \'production\' (accrue overdue fines). Requires accruefines cronjob.','Choice'),
('FRBRizeEditions','0','','If ON, Koha will query one or more ISBN web services for associated ISBNs and display an Editions tab on the details pages','YesNo'), ('FRBRizeEditions','0','','If ON, Koha will query one or more ISBN web services for associated ISBNs and display an Editions tab on the details pages','YesNo'),
('GDPR_Policy','','Enforced|Permissive|Disabled','General Data Protection Regulation - policy', 'Choice'),
('GenerateAuthorityField667', 'Machine generated authority record', NULL, 'When BiblioAddsAuthorities and AutoCreateAuthorities are enabled, use this as a default value for the 667$a field of MARC21 records', 'free'), ('GenerateAuthorityField667', 'Machine generated authority record', NULL, 'When BiblioAddsAuthorities and AutoCreateAuthorities are enabled, use this as a default value for the 667$a field of MARC21 records', 'free'),
('GenerateAuthorityField670', 'Work cat.', NULL, 'When BiblioAddsAuthorities and AutoCreateAuthorities are enabled, use this as a default value for the 670$a field of MARC21 records', 'free'), ('GenerateAuthorityField670', 'Work cat.', NULL, 'When BiblioAddsAuthorities and AutoCreateAuthorities are enabled, use this as a default value for the 670$a field of MARC21 records', 'free'),
('GoogleJackets','0',NULL,'if ON, displays jacket covers from Google Books API','YesNo'), ('GoogleJackets','0',NULL,'if ON, displays jacket covers from Google Books API','YesNo'),
@ -578,6 +577,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `
('PreserveSerialNotes','1','','When a new "Expected" issue is generated, should it be prefilled with last created issue notes?','YesNo'), ('PreserveSerialNotes','1','','When a new "Expected" issue is generated, should it be prefilled with last created issue notes?','YesNo'),
('previousIssuesDefaultSortOrder','asc','asc|desc','Specify the sort order of Previous Issues on the circulation page','Choice'), ('previousIssuesDefaultSortOrder','asc','asc|desc','Specify the sort order of Previous Issues on the circulation page','Choice'),
('PrintNoticesMaxLines','0','','If greater than 0, sets the maximum number of lines an overdue notice will print. If the number of items is greater than this number, the notice will end with a warning asking the borrower to check their online account for a full list of overdue items.','Integer'), ('PrintNoticesMaxLines','0','','If greater than 0, sets the maximum number of lines an overdue notice will print. If the number of items is greater than this number, the notice will end with a warning asking the borrower to check their online account for a full list of overdue items.','Integer'),
('PrivacyPolicyConsent','','Enforced|Permissive|Disabled','Data privacy policy consent in the OPAC', 'Choice'),
('PrivacyPolicyURL','',NULL,'This URL is used in messages about GDPR consents.', 'Free'), ('PrivacyPolicyURL','',NULL,'This URL is used in messages about GDPR consents.', 'Free'),
('ProcessingFeeNote', '', NULL, 'Set the text to be recorded in the column note, table accountlines when the processing fee (defined in item type) is applied', 'textarea'), ('ProcessingFeeNote', '', NULL, 'Set the text to be recorded in the column note, table accountlines when the processing fee (defined in item type) is applied', 'textarea'),
('ProtectSuperlibrarianPrivileges','1',NULL,'If enabled, non-superlibrarians cannot set superlibrarian privileges','YesNo'), ('ProtectSuperlibrarianPrivileges','1',NULL,'If enabled, non-superlibrarians cannot set superlibrarian privileges','YesNo'),

View file

@ -355,16 +355,16 @@ Patrons:
- Use the following URL - Use the following URL
- pref: PrivacyPolicyURL - pref: PrivacyPolicyURL
class: url class: url
- to refer to your local privacy policy in messages about privacy and data protection. (If you enforce GDPR policy, make sure that this page is not blocked.) - to refer to your local privacy policy in messages about privacy and data protection. (If you enforce a data privacy policy, make sure that this page is not blocked.)
- '<br><strong>NOTE:</strong> The URL will only be displayed if <a href="/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=GDPR_Policy">GDPR_Policy</a> is set.' - '<br><strong>NOTE:</strong> The URL will only be displayed if <a href="/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=PrivacyPolicyConsent">PrivacyPolicyConsent</a> is set.'
- -
- "Set GDPR policy to:" - "Set data privacy policy consent to:"
- pref: GDPR_Policy - pref: PrivacyPolicyConsent
choices: choices:
'': 'disabled' '': 'disabled'
Enforced: 'enforced' Enforced: 'enforced'
Permissive: 'permissive' Permissive: 'permissive'
- ". GDPR is the EU General Data Protection Regulation. When you enforce, patrons need to give consent before using the OPAC. If you set to permissive, Koha will warn but not enforce." - ". When you enforce a data privacy policy, patrons need to give consent before using the OPAC. If you set to permissive, Koha will warn but not enforce."
- '<br><strong>NOTE:</strong> If you enable this you will also have to set the URL of your public privacy policy with the <a href="/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=PrivacyPolicyURL">PrivacyPolicyURL</a> setting.' - '<br><strong>NOTE:</strong> If you enable this you will also have to set the URL of your public privacy policy with the <a href="/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=PrivacyPolicyURL">PrivacyPolicyURL</a> setting.'
- -
- Lock/expire patrons that submitted an unsubscribe request (refused consent) after - Lock/expire patrons that submitted an unsubscribe request (refused consent) after

View file

@ -24,7 +24,7 @@
[% END %] [% END %]
<a href="/cgi-bin/koha/opac-memberentry.pl">Personal details</a></li> <a href="/cgi-bin/koha/opac-memberentry.pl">Personal details</a></li>
[% IF Koha.Preference('GDPR_Policy') # remove when extending %] [% IF Koha.Preference('PrivacyPolicyConsent') # remove when extending %]
[% IF consentview %]<li class="active">[% ELSE %]<li>[% END %] [% IF consentview %]<li class="active">[% ELSE %]<li>[% END %]
<a href="/cgi-bin/koha/opac-patron-consent.pl">Consents</a> <a href="/cgi-bin/koha/opac-patron-consent.pl">Consents</a>
</li> </li>

View file

@ -1004,11 +1004,11 @@
</div> <!-- /.row --> </div> <!-- /.row -->
[% END %] [% END %]
[% IF Koha.Preference('GDPR_Policy') && action != 'edit' %] [% IF Koha.Preference('PrivacyPolicyConsent') && action != 'edit' %]
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<fieldset class="rows" id="memberentry_gdpr_consent"> <fieldset class="rows" id="memberentry_gdpr_consent">
<legend>GDPR consent</legend> <legend>Data privacy policy consent</legend>
<ol> <ol>
<li> <li>
<div class="label"></div> <div class="label"></div>

View file

@ -1,4 +1,5 @@
[% USE Koha %] [% USE Koha %]
[% USE KohaDates %]
[% USE AdditionalContents %] [% USE AdditionalContents %]
[% SET OpacNav = AdditionalContents.get( location => "OpacNav", lang => lang, library => logged_in_user.branchcode || default_branch, blocktitle => 0 ) %] [% SET OpacNav = AdditionalContents.get( location => "OpacNav", lang => lang, library => logged_in_user.branchcode || default_branch, blocktitle => 0 ) %]
[% SET OpacNavBottom = AdditionalContents.get( location => "OpacNavBottom", lang => lang, library => logged_in_user.branchcode || default_branch, blocktitle => 0 ) %] [% SET OpacNavBottom = AdditionalContents.get( location => "OpacNavBottom", lang => lang, library => logged_in_user.branchcode || default_branch, blocktitle => 0 ) %]
@ -36,9 +37,9 @@
<div class="col-lg-10 order-first order-md-first order-lg-2"> <div class="col-lg-10 order-first order-md-first order-lg-2">
<div id="patronconsents" class="maincontent"> <div id="patronconsents" class="maincontent">
[% IF Koha.Preference('GDPR_Policy') %] [% IF Koha.Preference('PrivacyPolicyConsent') %]
<div class="alert alert-warning"> <div class="alert alert-warning">
<p>In order to keep you logged in, we need your consent to process personal data as specified in the EU General Data Protection Regulation of May 25, 2018.</p> <p>In order to keep you logged in, we need your consent to process personal data as specified in the privacy policy linked below.</p>
<p>Please save your consent below or log out. Thank you!</p> <p>Please save your consent below or log out. Thank you!</p>
</div> </div>
[% END %] [% END %]
@ -46,8 +47,8 @@
<h1>Your consents</h1> <h1>Your consents</h1>
<form action="/cgi-bin/koha/opac-patron-consent.pl" method="post"> <form action="/cgi-bin/koha/opac-patron-consent.pl" method="post">
[% IF Koha.Preference('GDPR_Policy') %] [% IF Koha.Preference('PrivacyPolicyConsent') %]
<legend><h2 id="GDPR_consents">GDPR consents</h2></legend> <legend><h2 id="GDPR_consents">Privacy policy consents</h2></legend>
<input type="hidden" name="op" value="gdpr_proc_save"/> <input type="hidden" name="op" value="gdpr_proc_save"/>
<input type="hidden" name="borrowernumber" value="[% patron.borrowernumber | html %]"/> <input type="hidden" name="borrowernumber" value="[% patron.borrowernumber | html %]"/>
<fieldset> <fieldset>
@ -56,7 +57,7 @@
<p><input type="radio" name="gdpr_processing" value="agreed"> Yes, I agree.<br> <p><input type="radio" name="gdpr_processing" value="agreed"> Yes, I agree.<br>
<input type="radio" name="gdpr_processing" value="disagreed"> No, I do not agree. Please remove my account within a reasonable time.</p> <input type="radio" name="gdpr_processing" value="disagreed"> No, I do not agree. Please remove my account within a reasonable time.</p>
[% IF gdpr_proc_consent %] [% IF gdpr_proc_consent %]
<p>Your consent was registered on [% gdpr_proc_consent | html %].</p> <p>Your consent was registered on [% gdpr_proc_consent | $KohaDates with_hours => 1 %].</p>
[% ELSIF gdpr_proc_refusal %] [% ELSIF gdpr_proc_refusal %]
<p>You indicated recently that you do not consent, and we will process your request soon.</p> <p>You indicated recently that you do not consent, and we will process your request soon.</p>
[% END %] [% END %]

View file

@ -443,7 +443,7 @@ sub GetMandatoryFields {
C4::Context->preference("PatronSelfRegistrationBorrowerMandatoryField"); C4::Context->preference("PatronSelfRegistrationBorrowerMandatoryField");
my @fields = split( /\|/, $BorrowerMandatoryField ); my @fields = split( /\|/, $BorrowerMandatoryField );
push @fields, 'gdpr_proc_consent' if C4::Context->preference('GDPR_Policy') && $action eq 'create'; push @fields, 'gdpr_proc_consent' if C4::Context->preference('PrivacyPolicyConsent') && $action eq 'create';
foreach (@fields) { foreach (@fields) {
$mandatory_fields{$_} = 1; $mandatory_fields{$_} = 1;

View file

@ -40,7 +40,7 @@ my ( $template, $borrowernumber, $cookie ) = get_template_and_user({
my $patron = Koha::Patrons->find($borrowernumber); my $patron = Koha::Patrons->find($borrowernumber);
my $gdpr_proc_consent; my $gdpr_proc_consent;
if( C4::Context->preference('GDPR_Policy') ) { if( C4::Context->preference('PrivacyPolicyConsent') ) {
$gdpr_proc_consent = Koha::Patron::Consents->search({ $gdpr_proc_consent = Koha::Patron::Consents->search({
borrowernumber => $borrowernumber, borrowernumber => $borrowernumber,
type => GDPR_PROCESSING, type => GDPR_PROCESSING,
@ -64,7 +64,7 @@ if( $op eq 'gdpr_proc_save' && $gdpr_proc_consent ) {
} }
# If user refused GDPR consent and we enforce GDPR, logout (when saving) # If user refused GDPR consent and we enforce GDPR, logout (when saving)
if( $op =~ /save/ && C4::Context->preference('GDPR_Policy') eq 'Enforced' && $gdpr_proc_consent->refused_on ) if( $op =~ /save/ && C4::Context->preference('PrivacyPolicyConsent') eq 'Enforced' && $gdpr_proc_consent->refused_on )
{ {
print $query->redirect('/cgi-bin/koha/opac-main.pl?logout.x=1'); print $query->redirect('/cgi-bin/koha/opac-main.pl?logout.x=1');
exit; exit;

View file

@ -32,7 +32,7 @@ my $builder = t::lib::TestBuilder->new;
# FIXME: SessionStorage defaults to mysql, but it seems to break transaction # FIXME: SessionStorage defaults to mysql, but it seems to break transaction
# handling # handling
t::lib::Mocks::mock_preference( 'SessionStorage', 'tmp' ); t::lib::Mocks::mock_preference( 'SessionStorage', 'tmp' );
t::lib::Mocks::mock_preference( 'GDPR_Policy', '' ); # Disabled t::lib::Mocks::mock_preference( 'PrivacyPolicyConsent', '' ); # Disabled
# To silence useless warnings # To silence useless warnings
$ENV{REMOTE_ADDR} = '127.0.0.1'; $ENV{REMOTE_ADDR} = '127.0.0.1';