Bug 21336: Do not increase login_attempts after locking
[koha-equinox.git] / C4 / Auth.pm
index 8932066..5a0df07 100644 (file)
@@ -192,7 +192,7 @@ sub get_template_and_user {
         if (
 # If the user logged in is the SCO user and they try to go out of the SCO module,
 # log the user out removing the CGISESSID cookie
-               $in->{template_name} !~ m|sco/|
+            $in->{template_name} !~ m|sco/| && $in->{template_name} !~ m|errors/errorpage.tt|
             && C4::Context->preference('AutoSelfCheckID')
             && $user eq C4::Context->preference('AutoSelfCheckID')
           )
@@ -1155,6 +1155,7 @@ sub checkauth {
                     $session->param( 'emailaddress', $emailaddress );
                     $session->param( 'ip',           $session->remote_addr() );
                     $session->param( 'lasttime',     time() );
+                    $session->param( 'interface',    $type);
                     $session->param( 'shibboleth',   $shibSuccess );
                     $debug and printf STDERR "AUTH_4: (%s)\t%s %s - %s\n", map { $session->param($_) } qw(cardnumber firstname surname branch);
                 }
@@ -1180,6 +1181,7 @@ sub checkauth {
                 $session->param( 'lasttime', time() );
                 $session->param( 'ip',       $session->remote_addr() );
                 $session->param( 'sessiontype', 'anon' );
+                $session->param( 'interface', $type);
             }
         }    # END if ( $q_userid
         elsif ( $type eq "opac" ) {
@@ -1192,6 +1194,7 @@ sub checkauth {
             $session->param( 'ip',          $session->remote_addr() );
             $session->param( 'lasttime',    time() );
             $session->param( 'sessiontype', 'anon' );
+            $session->param( 'interface', $type);
         }
     }    # END unless ($userid)
 
@@ -1427,6 +1430,7 @@ sub check_api_auth {
         my $session = get_session($sessionID);
         C4::Context->_new_userenv($sessionID);
         if ($session) {
+            C4::Context->interface($session->param('interface'));
             C4::Context->set_userenv(
                 $session->param('number'),       $session->param('id'),
                 $session->param('cardnumber'),   $session->param('firstname'),
@@ -1585,6 +1589,7 @@ sub check_api_auth {
                 $session->param( 'emailaddress', $emailaddress );
                 $session->param( 'ip',           $session->remote_addr() );
                 $session->param( 'lasttime',     time() );
+                $session->param( 'interface',    'api'  );
             }
             $session->param( 'cas_ticket', $cas_ticket);
             C4::Context->set_userenv(
@@ -1606,7 +1611,11 @@ sub check_api_auth {
   ($status, $sessionId) = check_api_auth($cookie, $userflags);
 
 Given a CGISESSID cookie set during a previous login to Koha, determine
-if the user has the privileges specified by C<$userflags>.
+if the user has the privileges specified by C<$userflags>. C<$userflags>
+is passed unaltered into C<haspermission> and as such accepts all options
+avaiable to that routine with the one caveat that C<check_api_auth> will
+also allow 'undef' to be passed and in such a case the permissions check
+will be skipped altogether.
 
 C<check_cookie_auth> is meant for authenticating special services
 such as tools/upload-file.pl that are invoked by other pages that
@@ -1670,6 +1679,7 @@ sub check_cookie_auth {
     my $session   = get_session($sessionID);
     C4::Context->_new_userenv($sessionID);
     if ($session) {
+        C4::Context->interface($session->param('interface'));
         C4::Context->set_userenv(
             $session->param('number'),       $session->param('id'),
             $session->param('cardnumber'),   $session->param('firstname'),
@@ -1701,7 +1711,7 @@ sub check_cookie_auth {
             return ( "expired", undef );
         } else {
             $session->param( 'lasttime', time() );
-            my $flags = haspermission( $userid, $flagsrequired );
+            my $flags = defined($flagsrequired) ? haspermission( $userid, $flagsrequired ) : 1;
             if ($flags) {
                 return ( "ok", $sessionID );
             } else {
@@ -1841,7 +1851,7 @@ sub checkpw {
     if( $patron ) {
         if ( $passwd_ok ) {
             $patron->update({ login_attempts => 0 });
-        } else {
+        } elsif( !$patron->account_locked ) {
             $patron->update({ login_attempts => $patron->login_attempts + 1 });
         }
     }
@@ -2024,14 +2034,21 @@ sub get_all_subpermissions {
 
 =head2 haspermission
 
+  $flagsrequired = '*';                                 # Any permission at all
+  $flagsrequired = 'a_flag';                            # a_flag must be satisfied (all subpermissions)
+  $flagsrequired = [ 'a_flag', 'b_flag' ];              # a_flag OR b_flag must be satisfied
+  $flagsrequired = { 'a_flag => 1, 'b_flag' => 1 };     # a_flag AND b_flag must be satisfied
+  $flagsrequired = { 'a_flag' => 'sub_a' };             # sub_a of a_flag must be satisfied
+  $flagsrequired = { 'a_flag' => [ 'sub_a, 'sub_b' ] }; # sub_a OR sub_b of a_flag must be satisfied
+
   $flags = ($userid, $flagsrequired);
 
 C<$userid> the userid of the member
 C<$flags> is a query structure similar to that used by SQL::Abstract that
-denotes the combination of flags required.
+denotes the combination of flags required. It is a required parameter.
 
 The main logic of this method is that things in arrays are OR'ed, and things
-in hashes are AND'ed.
+in hashes are AND'ed. The `*` character can be used, at any depth, to denote `ANY`
 
 Returns member's flags or 0 if a permission is not met.
 
@@ -2072,11 +2089,17 @@ sub _dispatch {
 
 sub haspermission {
     my ( $userid, $flagsrequired ) = @_;
+
+
+    #Koha::Exceptions::WrongParameter->throw('$flagsrequired should not be undef')
+    #  unless defined($flagsrequired);
+
     my $sth = C4::Context->dbh->prepare("SELECT flags FROM borrowers WHERE userid=?");
     $sth->execute($userid);
     my $row = $sth->fetchrow();
     my $flags = getuserflags( $row, $userid );
 
+    return $flags unless defined($flagsrequired);
     return $flags if $flags->{superlibrarian};
     return _dispatch($flagsrequired, $flags);