Bug 28606: Remove $DEBUG and $ENV{DEBUG}
[srvgit] / C4 / Auth.pm
index a5b1d2b..8e49f53 100644 (file)
@@ -32,12 +32,14 @@ use C4::Templates;    # to get the template
 use C4::Languages;
 use C4::Search::History;
 use Koha;
+use Koha::Logger;
 use Koha::Caches;
 use Koha::AuthUtils qw(get_script_name hash_password);
 use Koha::Checkouts;
 use Koha::DateUtils qw(dt_from_string);
 use Koha::Library::Groups;
 use Koha::Libraries;
+use Koha::Cash::Registers;
 use Koha::Desks;
 use Koha::Patrons;
 use Koha::Patron::Consents;
@@ -49,7 +51,7 @@ use Net::CIDR;
 use C4::Log qw/logaction/;
 
 # use utf8;
-use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $debug $ldap $cas $caslogout);
+use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $ldap $cas $caslogout);
 
 BEGIN {
     sub psgi_env { any { /^psgi\./ } keys %ENV }
@@ -61,7 +63,6 @@ BEGIN {
 
     C4::Context->set_remote_address;
 
-    $debug     = $ENV{DEBUG};
     @ISA       = qw(Exporter);
     @EXPORT    = qw(&checkauth &get_template_and_user &haspermission &get_user_subpermissions);
     @EXPORT_OK = qw(&check_api_auth &get_session &check_cookie_auth &checkpw &checkpw_internal &checkpw_hash
@@ -93,7 +94,7 @@ C4::Auth - Authenticates Koha users
   use C4::Auth;
   use C4::Output;
 
-  my $query = new CGI;
+  my $query = CGI->new;
 
   my ($template, $borrowernumber, $cookie)
     = get_template_and_user(
@@ -318,17 +319,20 @@ sub get_template_and_user {
             $template->param( CAN_user_editcatalogue    => 1 );
             $template->param( CAN_user_updatecharges    => 1 );
             $template->param( CAN_user_acquisition      => 1 );
+            $template->param( CAN_user_suggestions      => 1 );
             $template->param( CAN_user_tools            => 1 );
             $template->param( CAN_user_editauthorities  => 1 );
             $template->param( CAN_user_serials          => 1 );
             $template->param( CAN_user_reports          => 1 );
             $template->param( CAN_user_staffaccess      => 1 );
-            $template->param( CAN_user_plugins          => 1 );
             $template->param( CAN_user_coursereserves   => 1 );
+            $template->param( CAN_user_plugins          => 1 );
+            $template->param( CAN_user_lists            => 1 );
             $template->param( CAN_user_clubs            => 1 );
             $template->param( CAN_user_ill              => 1 );
             $template->param( CAN_user_stockrotation    => 1 );
-            $template->param( CAN_user_problem_reports   => 1 );
+            $template->param( CAN_user_cash_management  => 1 );
+            $template->param( CAN_user_problem_reports  => 1 );
 
             foreach my $module ( keys %$all_perms ) {
                 foreach my $subperm ( keys %{ $all_perms->{$module} } ) {
@@ -436,6 +440,25 @@ sub get_template_and_user {
         }
     }
 
+    # Sysprefs disabled via URL param
+    # Note that value must be defined in order to override via ENV
+    foreach my $syspref (
+        qw(
+            OPACUserCSS
+            OPACUserJS
+            IntranetUserCSS
+            IntranetUserJS
+            OpacAdditionalStylesheet
+            opaclayoutstylesheet
+            intranetcolorstylesheet
+            intranetstylesheet
+        )
+      )
+    {
+        $ENV{"OVERRIDE_SYSPREF_$syspref"} = q{}
+          if $in->{'query'}->param("DISABLE_SYSPREF_$syspref");
+    }
+
     # Anonymous opac search history
     # If opac search history is enabled and at least one search has already been performed
     if ( C4::Context->preference('EnableOpacSearchHistory') ) {
@@ -495,7 +518,6 @@ sub get_template_and_user {
             intranetstylesheet                                                         => C4::Context->preference("intranetstylesheet"),
             IntranetUserCSS                                                            => C4::Context->preference("IntranetUserCSS"),
             IntranetUserJS                                                             => C4::Context->preference("IntranetUserJS"),
-            intranetbookbag                                                            => C4::Context->preference("intranetbookbag"),
             suggestion                                                                 => C4::Context->preference("suggestion"),
             virtualshelves                                                             => C4::Context->preference("virtualshelves"),
             StaffSerialIssueDisplayCount                                               => C4::Context->preference("StaffSerialIssueDisplayCount"),
@@ -524,6 +546,7 @@ sub get_template_and_user {
             && $in->{'template_name'} =~ /opac-(.+)\.(?:tt|tmpl)$/ ) {
             my $pagename = $1;
             unless ( $pagename =~ /^(?:MARC|ISBD)?detail$/
+                or $pagename =~ /^showmarc$/
                 or $pagename =~ /^addbybiblionumber$/
                 or $pagename =~ /^review$/ ) {
                 my $sessionSearch = get_session( $sessionID || $in->{'query'}->cookie("CGISESSID") );
@@ -740,7 +763,7 @@ sub _version_check {
 
     # remove the 3 last . to have a Perl number
     $kohaversion =~ s/(.*\..*)\.(.*)\.(.*)/$1$2$3/;
-    $debug and print STDERR "kohaversion : $kohaversion\n";
+    Koha::Logger->get->debug("kohaversion : $kohaversion");
     if ( $version < $kohaversion ) {
         my $warning = "Database update needed, redirecting to %s. Database is $version and Koha is $kohaversion";
         if ( $type ne 'opac' ) {
@@ -762,18 +785,27 @@ sub _session_log {
 }
 
 sub _timeout_syspref {
-    my $timeout = C4::Context->preference('timeout') || 600;
+    my $default_timeout = 600;
+    my $timeout = C4::Context->preference('timeout') || $default_timeout;
 
     # value in days, convert in seconds
-    if ( $timeout =~ /(\d+)[dD]/ ) {
+    if ( $timeout =~ /^(\d+)[dD]$/ ) {
         $timeout = $1 * 86400;
     }
+    # value in hours, convert in seconds
+    elsif ( $timeout =~ /^(\d+)[hH]$/ ) {
+        $timeout = $1 * 3600;
+    }
+    elsif ( $timeout !~ m/^\d+$/ ) {
+        warn "The value of the system preference 'timeout' is not correct, defaulting to $default_timeout";
+        $timeout = $default_timeout;
+    }
+
     return $timeout;
 }
 
 sub checkauth {
     my $query = shift;
-    $debug and warn "Checking Auth";
 
     # Get shibboleth login attribute
     my $shib = C4::Context->config('useshibboleth') && shib_ok();
@@ -857,12 +889,10 @@ sub checkauth {
                 $session->param('surname'),      $session->param('branch'),
                 $session->param('branchname'),   $session->param('flags'),
                 $session->param('emailaddress'), $session->param('shibboleth'),
-                $session->param('desk_id'),      $session->param('desk_name')
+                $session->param('desk_id'),      $session->param('desk_name'),
+                $session->param('register_id'),  $session->param('register_name')
             );
-            C4::Context::set_shelves_userenv( 'bar', $session->param('barshelves') );
-            C4::Context::set_shelves_userenv( 'pub', $session->param('pubshelves') );
-            C4::Context::set_shelves_userenv( 'tot', $session->param('totshelves') );
-            $debug and printf STDERR "AUTH_SESSION: (%s)\t%s %s - %s\n", map { $session->param($_) } qw(cardnumber firstname surname branch);
+            Koha::Logger->get->debug(sprintf "AUTH_SESSION: (%s)\t%s %s - %s", map { $session->param($_) } qw(cardnumber firstname surname branch));
             $ip          = $session->param('ip');
             $lasttime    = $session->param('lasttime');
             $userid      = $s_userid;
@@ -875,7 +905,6 @@ sub checkauth {
 
             #if a user enters an id ne to the id in the current session, we need to log them in...
             #first we need to clear the anonymous session...
-            $debug and warn "query id = $q_userid but session id = $s_userid";
             $anon_search_history = $session->param('search_history');
             $session->delete();
             $session->flush;
@@ -1060,13 +1089,33 @@ sub checkauth {
                 }
                 else {
                     my $retuserid;
-                    ( $return, $cardnumber, $retuserid, $cas_ticket ) =
-                      checkpw( $dbh, $q_userid, $password, $query, $type );
-                    $userid = $retuserid if ($retuserid);
-                    $info{'invalid_username_or_password'} = 1 unless ($return);
+                    my $request_method = $query->request_method();
+                    if ($request_method eq 'POST'){
+                        ( $return, $cardnumber, $retuserid, $cas_ticket ) =
+                          checkpw( $dbh, $q_userid, $password, $query, $type );
+                        $userid = $retuserid if ($retuserid);
+                        $info{'invalid_username_or_password'} = 1 unless ($return);
+                    }
                 }
             }
 
+            # If shib configured and shibOnly enabled, we should ignore anything other than a shibboleth type login.
+            if (
+                   $shib
+                && !$shibSuccess
+                && (
+                    (
+                        ( $type eq 'opac' )
+                        && C4::Context->preference('OPACShibOnly')
+                    )
+                    || ( ( $type ne 'opac' )
+                        && C4::Context->preference('staffShibOnly') )
+                )
+              )
+            {
+                $return = 0;
+            }
+
             # $return: 1 = valid user
             if ($return) {
 
@@ -1079,7 +1128,8 @@ sub checkauth {
                     C4::Context->_unset_userenv($sessionID);
                 }
                 my ( $borrowernumber, $firstname, $surname, $userflags,
-                    $branchcode, $branchname, $emailaddress, $desk_id, $desk_name );
+                    $branchcode, $branchname, $emailaddress, $desk_id,
+                    $desk_name, $register_id, $register_name );
 
                 if ( $return == 1 ) {
                     my $select = "
@@ -1091,25 +1141,16 @@ sub checkauth {
                     my $sth = $dbh->prepare("$select where userid=?");
                     $sth->execute($userid);
                     unless ( $sth->rows ) {
-                        $debug and print STDERR "AUTH_1: no rows for userid='$userid'\n";
                         $sth = $dbh->prepare("$select where cardnumber=?");
                         $sth->execute($cardnumber);
 
                         unless ( $sth->rows ) {
-                            $debug and print STDERR "AUTH_2a: no rows for cardnumber='$cardnumber'\n";
                             $sth->execute($userid);
-                            unless ( $sth->rows ) {
-                                $debug and print STDERR "AUTH_2b: no rows for userid='$userid' AS cardnumber\n";
-                            }
                         }
                     }
                     if ( $sth->rows ) {
                         ( $borrowernumber, $firstname, $surname, $userflags,
                             $branchcode, $branchname, $emailaddress ) = $sth->fetchrow;
-                        $debug and print STDERR "AUTH_3 results: " .
-                          "$cardnumber,$borrowernumber,$userid,$firstname,$surname,$userflags,$branchcode,$emailaddress\n";
-                    } else {
-                        print STDERR "AUTH_3: no results for userid='$userid', cardnumber='$cardnumber'.\n";
                     }
 
                     # launch a sequence to check if we have a ip for the branch, i
@@ -1128,8 +1169,18 @@ sub checkauth {
                         my $desk = Koha::Desks->find($desk_id);
                         $desk_name = $desk ? $desk->desk_name : '';
                     }
+                    if ( C4::Context->preference('UseCashRegisters') ) {
+                        my $register =
+                          $query->param('register_id')
+                          ? Koha::Cash::Registers->find($query->param('register_id'))
+                          : Koha::Cash::Registers->search(
+                            { branch => $branchcode, branch_default => 1 },
+                            { rows   => 1 } )->single;
+                        $register_id   = $register->id   if ($register);
+                        $register_name = $register->name if ($register);
+                    }
                     my $branches = { map { $_->branchcode => $_->unblessed } Koha::Libraries->search };
-                    if ( $type ne 'opac' and C4::Context->boolean_preference('AutoLocation') ) {
+                    if ( $type ne 'opac' and C4::Context->preference('AutoLocation') ) {
 
                         # we have to check they are coming from the right ip range
                         my $domain = $branches->{$branchcode}->{'branchip'};
@@ -1172,7 +1223,8 @@ sub checkauth {
                     $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);
+                    $session->param( 'register_id',  $register_id );
+                    $session->param( 'register_name',  $register_name );
                 }
                 $session->param('cas_ticket', $cas_ticket) if $cas_ticket;
                 C4::Context->set_userenv(
@@ -1181,14 +1233,14 @@ sub checkauth {
                     $session->param('surname'),      $session->param('branch'),
                     $session->param('branchname'),   $session->param('flags'),
                     $session->param('emailaddress'), $session->param('shibboleth'),
-                    $session->param('desk_id'),      $session->param('desk_name')
+                    $session->param('desk_id'),      $session->param('desk_name'),
+                    $session->param('register_id'),  $session->param('register_name')
                 );
 
             }
             # $return: 0 = invalid user
             # reset to anonymous session
             else {
-                $debug and warn "Login failed, resetting anonymous session...";
                 if ($userid) {
                     $info{'invalid_username_or_password'} = 1;
                     C4::Context->_unset_userenv($sessionID);
@@ -1201,9 +1253,7 @@ sub checkauth {
         }    # END if ( $q_userid
         elsif ( $type eq "opac" ) {
 
-            # if we are here this is an anonymous session; add public lists to it and a few other items...
             # anonymous sessions are created only for the OPAC
-            $debug and warn "Initiating an anonymous session...";
 
             # setting a couple of other session vars...
             $session->param( 'ip',          $session->remote_addr() );
@@ -1292,7 +1342,6 @@ sub checkauth {
         OPACUserCSS                           => C4::Context->preference("OPACUserCSS"),
         intranetcolorstylesheet               => C4::Context->preference("intranetcolorstylesheet"),
         intranetstylesheet                    => C4::Context->preference("intranetstylesheet"),
-        intranetbookbag                       => C4::Context->preference("intranetbookbag"),
         IntranetNav                           => C4::Context->preference("IntranetNav"),
         IntranetFavicon                       => C4::Context->preference("IntranetFavicon"),
         IntranetUserCSS                       => C4::Context->preference("IntranetUserCSS"),
@@ -1347,6 +1396,13 @@ sub checkauth {
     }
 
     if ($shib) {
+        #If shibOnly is enabled just go ahead and redirect directly
+        if ( (($type eq 'opac') && C4::Context->preference('OPACShibOnly')) || (($type ne 'opac') && C4::Context->preference('staffShibOnly')) ) {
+            my $redirect_url = login_shib_url( $query );
+            print $query->redirect( -uri => "$redirect_url", -status => 303 );
+            safe_exit;
+        }
+
         $template->param(
             shibbolethAuthentication => $shib,
             shibbolethLoginUrl       => login_shib_url($query),
@@ -1460,7 +1516,8 @@ sub check_api_auth {
                 $session->param('surname'),      $session->param('branch'),
                 $session->param('branchname'),   $session->param('flags'),
                 $session->param('emailaddress'), $session->param('shibboleth'),
-                $session->param('desk_id'),      $session->param('desk_name')
+                $session->param('desk_id'),      $session->param('desk_name'),
+                $session->param('register_id'),  $session->param('register_name')
             );
 
             my $ip       = $session->param('ip');
@@ -1517,7 +1574,6 @@ sub check_api_auth {
         # Proxy CAS auth
         if ( $cas && $query->param('PT') ) {
             my $retuserid;
-            $debug and print STDERR "## check_api_auth - checking CAS\n";
 
             # In case of a CAS authentication, we use the ticket instead of the password
             my $PT = $query->param('PT');
@@ -1621,8 +1677,10 @@ sub check_api_auth {
                 $session->param('number'),       $session->param('id'),
                 $session->param('cardnumber'),   $session->param('firstname'),
                 $session->param('surname'),      $session->param('branch'),
+                $session->param('branchname'),   $session->param('flags'),
                 $session->param('emailaddress'), $session->param('shibboleth'),
-                $session->param('desk_id'),      $session->param('desk_name')
+                $session->param('desk_id'),      $session->param('desk_name'),
+                $session->param('register_id'),  $session->param('register_name')
             );
             return ( "ok", $cookie, $sessionID );
         } else {
@@ -1711,7 +1769,8 @@ sub check_cookie_auth {
             $session->param('surname'),      $session->param('branch'),
             $session->param('branchname'),   $session->param('flags'),
             $session->param('emailaddress'), $session->param('shibboleth'),
-            $session->param('desk_id'),      $session->param('desk_name')
+            $session->param('desk_id'),      $session->param('desk_name'),
+            $session->param('register_id'),  $session->param('register_name')
         );
 
         my $ip       = $session->param('ip');
@@ -1773,28 +1832,32 @@ sub _get_session_params {
     my $storage_method = C4::Context->preference('SessionStorage');
     if ( $storage_method eq 'mysql' ) {
         my $dbh = C4::Context->dbh;
-        return { dsn => "driver:MySQL;serializer:yaml;id:md5", dsn_args => { Handle => $dbh } };
+        return { dsn => "serializer:yamlxs;driver:MySQL;id:md5", dsn_args => { Handle => $dbh } };
     }
     elsif ( $storage_method eq 'Pg' ) {
         my $dbh = C4::Context->dbh;
-        return { dsn => "driver:PostgreSQL;serializer:yaml;id:md5", dsn_args => { Handle => $dbh } };
+        return { dsn => "serializer:yamlxs;driver:PostgreSQL;id:md5", dsn_args => { Handle => $dbh } };
     }
     elsif ( $storage_method eq 'memcached' && Koha::Caches->get_instance->memcached_cache ) {
         my $memcached = Koha::Caches->get_instance()->memcached_cache;
-        return { dsn => "driver:memcached;serializer:yaml;id:md5", dsn_args => { Memcached => $memcached } };
+        return { dsn => "serializer:yamlxs;driver:memcached;id:md5", dsn_args => { Memcached => $memcached } };
     }
     else {
         # catch all defaults to tmp should work on all systems
         my $dir = C4::Context::temporary_directory;
         my $instance = C4::Context->config( 'database' ); #actually for packages not exactly the instance name, but generally safer to leave it as it is
-        return { dsn => "driver:File;serializer:yaml;id:md5", dsn_args => { Directory => "$dir/cgisess_$instance" } };
+        return { dsn => "serializer:yamlxs;driver:File;id:md5", dsn_args => { Directory => "$dir/cgisess_$instance" } };
     }
 }
 
 sub get_session {
     my $sessionID      = shift;
     my $params = _get_session_params();
-    return new CGI::Session( $params->{dsn}, $sessionID, $params->{dsn_args} );
+    my $session = CGI::Session->new( $params->{dsn}, $sessionID, $params->{dsn_args} );
+    if ( ! $session ){
+        die CGI::Session->errstr();
+    }
+    return $session;
 }
 
 
@@ -1826,7 +1889,6 @@ sub checkpw {
     if ( $patron and $patron->account_locked ) {
         # Nothing to check, account is locked
     } elsif ($ldap && defined($password)) {
-        $debug and print STDERR "## checkpw - checking LDAP\n";
         my ( $retval, $retcard, $retuserid ) = checkpw_ldap(@_);    # EXTERNAL AUTH
         if ( $retval == 1 ) {
             @return = ( $retval, $retcard, $retuserid );
@@ -1835,7 +1897,6 @@ sub checkpw {
         $check_internal_as_fallback = 1 if $retval == 0;
 
     } elsif ( $cas && $query && $query->param('ticket') ) {
-        $debug and print STDERR "## checkpw - checking CAS\n";
 
         # In case of a CAS authentication, we use the ticket instead of the password
         my $ticket = $query->param('ticket');
@@ -1854,8 +1915,6 @@ sub checkpw {
     # time around.
     elsif ( $shib && $shib_login && !$password ) {
 
-        $debug and print STDERR "## checkpw - checking Shibboleth\n";
-
         # In case of a Shibboleth authentication, we expect a shibboleth user attribute
         # (defined under shibboleth mapping in koha-conf.xml) to contain the login of the
         # shibboleth-authenticated user
@@ -2161,7 +2220,7 @@ sub in_iprange {
     if (scalar @allowedipranges > 0) {
         my @rangelist;
         eval { @rangelist = Net::CIDR::range2cidr(@allowedipranges); }; return 0 if $@;
-        eval { $result = Net::CIDR::cidrlookup($ENV{'REMOTE_ADDR'}, @rangelist) } || ( $ENV{DEBUG} && warn 'cidrlookup failed for ' . join(' ',@rangelist) );
+        eval { $result = Net::CIDR::cidrlookup($ENV{'REMOTE_ADDR'}, @rangelist) } || Koha::Logger->get->warn('cidrlookup failed for ' . join(' ',@rangelist) );
      }
      return $result ? 1 : 0;
 }