Bug 21890: Allow restricting password resets by patron category
authorTomas Cohen Arazi <tomascohen@theke.io>
Thu, 31 Jan 2019 19:29:30 +0000 (16:29 -0300)
committerNick Clemens <nick@bywatersolutions.com>
Fri, 12 Apr 2019 02:32:03 +0000 (02:32 +0000)
This patch makes the templates relying on the OpacResetPassword syspref
use the introduced TT plugin method instead by changing:

[% IF Koha.Preference('OpacResetPassword') %]

=>

[% IF Categories.can_any_reset_password %]

To test:
- Verify that all the places in which the 'forgot password' link is
displayed in OPAC keep working, provided there's at least one category
that has the flag set
- Attempt to recover the password for a patron that belong to a valid
category (i.e. that has the flag set)
=> SUCCESS: You can go through the normal process
- Attempt to recover the password for a patron that belongs to a
category with the flag unset.
=> SUCCESS: Once Koha identifies your category, you are told you are not
allowed to do it
- Sign off :-D

Signed-off-by: Liz Rea <wizzyrea@gmail.com>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>

Signed-off-by: Nick Clemens <nick@bywatersolutions.com>

admin/categories.pl
koha-tmpl/intranet-tmpl/prog/en/modules/admin/categories.tt
koha-tmpl/intranet-tmpl/prog/en/modules/auth.tt
koha-tmpl/opac-tmpl/bootstrap/en/includes/masthead.inc
koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-auth.tt
koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-main.tt
koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-password-recovery.tt
opac/opac-password-recovery.pl

index ba0d11e..b824b9b 100755 (executable)
@@ -92,9 +92,11 @@ elsif ( $op eq 'add_validate' ) {
     my $BlockExpiredPatronOpacActions = $input->param('BlockExpiredPatronOpacActions');
     my $checkPrevCheckout = $input->param('checkprevcheckout');
     my $default_privacy = $input->param('default_privacy');
-    my $can_reset_password = $input->param('can_reset_password');
+    my $reset_password = $input->param('reset_password');
     my @branches = grep { $_ ne q{} } $input->multi_param('branches');
 
+    $reset_password = undef if $reset_password eq -1;
+
     my $is_a_modif = $input->param("is_a_modif");
 
     if ($enrolmentperioddate) {
@@ -123,7 +125,7 @@ elsif ( $op eq 'add_validate' ) {
         $category->BlockExpiredPatronOpacActions($BlockExpiredPatronOpacActions);
         $category->checkprevcheckout($checkPrevCheckout);
         $category->default_privacy($default_privacy);
-        $category->can_reset_password($can_reset_password);
+        $category->reset_password($reset_password);
         eval {
             $category->store;
             $category->replace_branch_limitations( \@branches );
@@ -150,7 +152,7 @@ elsif ( $op eq 'add_validate' ) {
             BlockExpiredPatronOpacActions => $BlockExpiredPatronOpacActions,
             checkprevcheckout => $checkPrevCheckout,
             default_privacy => $default_privacy,
-            can_reset_password => $can_reset_password,
+            reset_password => $reset_password,
         });
         eval {
             $category->store;
index ff48b74..5cc99d7 100644 (file)
                     </span>
                 </li>
                 <li>
-                    <label for="can_reset_password">Password reset in OPAC: </label>
-                    <select name="can_reset_password" id="can_reset_password">
-                        [% IF category.can_reset_password %]
-                            <option value="0">Allowed</option>
-                            <option value="1" selected="selected">Not allowed</option>
+                    <label for="reset_password">Password reset in OPAC: </label>
+                    <select name="reset_password" id="reset_password">
+                      [% IF category.reset_password.defined %]
+                        [% IF category.reset_password %]
+                          [% IF Koha.Preference('OpacResetPassword') %]
+                            <option value="-1">Follow system preference OpacResetPassword (enabled)</option>
+                          [% ELSE %]
+                            <option value="-1">Follow system preference OpacResetPassword (disabled)</option>
+                          [% END %]
+                            <option value="1" selected="selected">Allowed</option>
+                            <option value="0">Not allowed</option>
                         [% ELSE %]
-                            <option value="0" selected="selected">Allowed</option>
-                            <option value="1">Not allowed</option>
+                          [% IF Koha.Preference('OpacResetPassword') %]
+                            <option value="-1">Follow system preference OpacResetPassword (enabled)</option>
+                          [% ELSE %]
+                            <option value="-1">Follow system preference OpacResetPassword (disabled)</option>
+                          [% END %]
+                            <option value="1">Allowed</option>
+                            <option value="0" selected="selected">Not allowed</option>
                         [% END %]
+                      [% ELSE %]
+                          [% IF Koha.Preference('OpacResetPassword') %]
+                            <option value="-1" selected="selected">Follow system preference OpacResetPassword (enabled)</option>
+                          [% ELSE %]
+                            <option value="-1" selected="selected">Follow system preference OpacResetPassword (disabled)</option>
+                          [% END %]
+                            <option value="1">Allowed</option>
+                            <option value="0">Not allowed</option>
+                      [% END %]
                     </select>
                 </li>
                 <li><label for="block_expired">Block expired patrons:</label>
index 19548ca..7533b0c 100644 (file)
@@ -1,6 +1,7 @@
 [% USE raw %]
 [% USE Koha %]
 [% USE Branches %]
+[% USE Categories %]
 [% SET footerjs = 1 %]
 [% INCLUDE 'doc-head-open.inc' %]
 <title>Koha &rsaquo; 
@@ -42,7 +43,7 @@
 
 [% IF too_many_login_attempts %]
     <div id="login_error"><strong>Error: </strong>This account has been locked!</div>
-    [% IF Koha.Preference('OpacResetPassword') && Koha.Preference('OpacBaseURL') %]
+    [% IF Categories.can_any_reset_password && Koha.Preference('OpacBaseURL') %]
         <a href="[% Koha.Preference('OpacBaseURL') | url %]/cgi-bin/koha/opac-password-recovery.pl">You must reset your password</a>.
     [% END %]
 [% ELSIF invalid_username_or_password %]
index 9466c2d..3b5e9d9 100644 (file)
@@ -1,6 +1,7 @@
 [% USE raw %]
 [% USE Koha %]
 [% USE Branches %]
+[% USE Categories %]
 [% SET OpacLangSelectorMode = Koha.Preference('OpacLangSelectorMode') %]
 <div id="wrap">
     <div id="header-region" class="noprint">
                             [% Koha.Preference( 'OpacLoginInstructions' ) | $raw %]
                         </div>
                     [% END %]
-                    [% IF Koha.Preference('OpacPasswordChange') && Koha.Preference('OpacResetPassword') %]
+                    [% IF Koha.Preference('OpacPasswordChange') && Categories.can_any_reset_password %]
                         <div id="forgotpassword-modal" class="forgotpassword">
                             <a href="/cgi-bin/koha/opac-password-recovery.pl">Forgot your password?</a>
                         </div>
index d8aeabe..8bb82f5 100644 (file)
@@ -1,5 +1,6 @@
 [% USE raw %]
 [% USE Koha %]
+[% USE Categories %]
 [% INCLUDE 'doc-head-open.inc' %]
 <title>[% IF ( LibraryNameTitle ) %][% LibraryNameTitle | html %][% ELSE %]Koha online[% END %] catalog &rsaquo;
 [% IF Koha.Preference( 'opacuserlogin' ) == 1 %]
 
                             <input type="submit" value="Log in" class="btn" />
                             <p/>
-                            [% IF Koha.Preference('OpacPasswordChange') && Koha.Preference('OpacResetPassword') %]
+                            [% IF Koha.Preference('OpacPasswordChange') && Categories.can_any_reset_password %]
                                 <div id="forgotpassword">
                                     <a href="/cgi-bin/koha/opac-password-recovery.pl">Forgot your password?</a>
                                 </div>
index 46768ca..bd9fb86 100644 (file)
@@ -2,6 +2,7 @@
 [% USE Koha %]
 [% USE KohaDates %]
 [% USE Branches %]
+[% USE Categories %]
 [% USE Price %]
 [% INCLUDE 'doc-head-open.inc' %]
 <title>[% IF ( LibraryNameTitle ) %][% LibraryNameTitle | html %][% ELSE %]Koha online[% END %] catalog</title>
                                                 [% Koha.Preference( 'OpacLoginInstructions' ) | $raw %]
                                             </div>
                                         [% END %]
-                                        [% IF Koha.Preference('OpacPasswordChange') && Koha.Preference('OpacResetPassword') %]
+                                        [% IF Koha.Preference('OpacPasswordChange') && Categories.can_any_reset_password %]
                                             <div id="forgotpassword-main" class="forgotpassword">
                                                 <p><a href="/cgi-bin/koha/opac-password-recovery.pl">Forgot your password?</a></p>
                                             </div>
index c30309e..6ecaab0 100644 (file)
@@ -1,4 +1,5 @@
 [% USE Koha %]
+[% USE Categories %]
 [% INCLUDE 'doc-head-open.inc' %]
 <title>[% IF ( LibraryNameTitle ) %][% LibraryNameTitle | html %][% ELSE %]Koha online[% END %] catalog &rsaquo; Forgotten password recovery</title>
 [% INCLUDE 'doc-head-close.inc' %]
@@ -54,6 +55,8 @@
                         <br/>Please try again later.
                     [% ELSIF (errNoBorrowerFound) %]
                         No account was found with the provided information.
+                    [% ELSIF errResetForbidden %]
+                        You are not allowed to reset your password. Contact library staff for assistance.
                     [% ELSIF (errMultipleAccountsForEmail) %]
                         Account identification with this email address only is ambiguous.
                         <br />Please use the field 'Login' as well.
@@ -83,7 +86,7 @@
                 </div>
             [% END %]
                 <div id="password-recovery">
-[% IF (!Koha.Preference('OpacResetPassword')) %]
+[% IF (! Categories.can_any_reset_password ) %]
                     <div class="alert alert-info">You can't reset your password.</div>
 [% ELSIF (password_recovery) %]
                     <form action="/cgi-bin/koha/opac-password-recovery.pl" method="post" autocomplete="off">
index e4b5a91..8563e25 100755 (executable)
@@ -43,6 +43,7 @@ my $errMultipleAccountsForEmail;
 my $errAlreadyStartRecovery;
 my $errTooManyEmailFound;
 my $errBadEmail;
+my $errResetForbidden;
 
 #new password form error
 my $errLinkNotValid;
@@ -74,36 +75,45 @@ if ( $query->param('sendEmail') || $query->param('resendEmail') ) {
         $errMultipleAccountsForEmail = 1;
     }
     elsif ( $borrower = $search_results->next() ) {    # One matching borrower
-        my @emails = grep { $_ } ( $borrower->email, $borrower->emailpro, $borrower->B_email );
 
-        my $firstNonEmptyEmail;
-        $firstNonEmptyEmail = $emails[0] if @emails;
+        if ( $borrower->category->effective_reset_password ) {
 
-        # Is the given email one of the borrower's ?
-        if ( $email && !( grep /^$email$/i, @emails ) ) {
-            $hasError    = 1;
-            $errNoBorrowerFound = 1;
-        }
+            my @emails = grep { $_ } ( $borrower->email, $borrower->emailpro, $borrower->B_email );
 
-        # If there is no given email, and there is no email on record
-        elsif ( !$email && !$firstNonEmptyEmail ) {
-            $hasError           = 1;
-            $errNoBorrowerEmail = 1;
-        }
+            my $firstNonEmptyEmail;
+            $firstNonEmptyEmail = $emails[0] if @emails;
+
+            # Is the given email one of the borrower's ?
+            if ( $email && !( grep /^$email$/i, @emails ) ) {
+                $hasError    = 1;
+                $errNoBorrowerFound = 1;
+            }
+
+            # If there is no given email, and there is no email on record
+            elsif ( !$email && !$firstNonEmptyEmail ) {
+                $hasError           = 1;
+                $errNoBorrowerEmail = 1;
+            }
 
-# Check if a password reset already issued for this borrower AND we are not asking for a new email
-        elsif ( not $query->param('resendEmail') ) {
-            if ( ValidateBorrowernumber( $borrower->borrowernumber ) ) {
-                $hasError                = 1;
-                $errAlreadyStartRecovery = 1;
+            # Check if a password reset already issued for this
+            # borrower AND we are not asking for a new email
+            elsif ( not $query->param('resendEmail') ) {
+                if ( ValidateBorrowernumber( $borrower->borrowernumber ) ) {
+                    $hasError                = 1;
+                    $errAlreadyStartRecovery = 1;
+                }
+                else {
+                    DeleteExpiredPasswordRecovery( $borrower->borrowernumber );
+                }
             }
-            else {
-                DeleteExpiredPasswordRecovery( $borrower->borrowernumber );
+            # Set the $email, if we don't have one.
+            if ( !$hasError && !$email ) {
+                $email = $firstNonEmptyEmail;
             }
         }
-        # Set the $email, if we don't have one.
-        if ( !$hasError && !$email ) {
-            $email = $firstNonEmptyEmail;
+        else {
+            $hasError          = 1;
+            $errResetForbidden = 1;
         }
     }
     else {    # 0 matching borrower
@@ -119,6 +129,7 @@ if ( $query->param('sendEmail') || $query->param('resendEmail') ) {
             errBadEmail             => $errBadEmail,
             errNoBorrowerEmail      => $errNoBorrowerEmail,
             errMultipleAccountsForEmail => $errMultipleAccountsForEmail,
+            errResetForbidden       => $errResetForbidden,
             password_recovery       => 1,
             email                   => HTML::Entities::encode($email),
             username                => $username