Preparing 3.0.3
[koha.git] / C4 / Auth.pm
old mode 100755 (executable)
new mode 100644 (file)
index 6545681..eb7a464
@@ -1,7 +1,3 @@
-
-# -*- tab-width: 8 -*-
-# NOTE: This file uses 8-character tabs; do not change the tab size!
-
 package C4::Auth;
 
 # Copyright 2000-2002 Katipo Communications
 package C4::Auth;
 
 # Copyright 2000-2002 Katipo Communications
@@ -31,7 +27,7 @@ use C4::Output;    # to get the template
 use C4::Members;
 use C4::Koha;
 use C4::Branch; # GetBranches
 use C4::Members;
 use C4::Koha;
 use C4::Branch; # GetBranches
-use C4::VirtualShelves 3.02 qw(GetShelvesSummary);
+use C4::VirtualShelves;
 
 # use utf8;
 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $debug $ldap);
 
 # use utf8;
 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $debug $ldap);
@@ -144,15 +140,23 @@ sub get_template_and_user {
         # user info
         $template->param( loggedinusername => $user );
         $template->param( sessionID        => $sessionID );
         # user info
         $template->param( loggedinusername => $user );
         $template->param( sessionID        => $sessionID );
-               my $shelves;
-               if ($shelves = C4::Context->get_shelves_userenv()) {
-               $template->param( barshelves     => scalar (@$shelves));
-               $template->param( barshelvesloop => $shelves);
+
+               my ($total, $pubshelves, $barshelves) = C4::Context->get_shelves_userenv();
+               if (defined($pubshelves)) {
+               $template->param(       pubshelves      => scalar (@$pubshelves),
+                                                       pubshelvesloop  => $pubshelves,
+                                                       );
+                       $template->param(       pubtotal                => $total->{'pubtotal'}, ) if ($total->{'pubtotal'} > scalar (@$pubshelves));
+               }
+               if (defined($barshelves)) {
+               $template->param(       barshelves      => scalar (@$barshelves),
+                                                       barshelvesloop  => $barshelves,
+                                                       );
+                       $template->param(       bartotal                => $total->{'bartotal'}, ) if ($total->{'bartotal'} > scalar (@$barshelves));
                }
 
         $borrowernumber = getborrowernumber($user);
                }
 
         $borrowernumber = getborrowernumber($user);
-        my ( $borr, $alternativeflags ) =
-          GetMemberDetails( $borrowernumber );
+        my ( $borr ) = GetMemberDetails( $borrowernumber );
         my @bordat;
         $bordat[0] = $borr;
         $template->param( "USER_INFO" => \@bordat );
         my @bordat;
         $bordat[0] = $borr;
         $template->param( "USER_INFO" => \@bordat );
@@ -221,42 +225,71 @@ sub get_template_and_user {
             }
         }
     }
             }
         }
     }
+       else {  # if this is an anonymous session, setup to display public lists...
+
+        # load the template variables for stylesheets and JavaScript
+        $template->param( css_libs => $in->{'css_libs'} );
+        $template->param( css_module => $in->{'css_module'} );
+        $template->param( css_page => $in->{'css_page'} );
+        $template->param( css_widgets => $in->{'css_widgets'} );
+
+        $template->param( js_libs => $in->{'js_libs'} );
+        $template->param( js_module => $in->{'js_module'} );
+        $template->param( js_page => $in->{'js_page'} );
+        $template->param( js_widgets => $in->{'js_widgets'} );
+
+        $template->param( sessionID        => $sessionID );
+               
+               my ($total, $pubshelves) = C4::Context->get_shelves_userenv();  # an anonymous user has no 'barshelves'...
+               if (defined(($pubshelves))) {
+               $template->param(       pubshelves      => scalar (@$pubshelves),
+                                                       pubshelvesloop  => $pubshelves,
+                                                       );
+                       $template->param(       pubtotal                => $total->{'pubtotal'}, ) if ($total->{'pubtotal'} > scalar (@$pubshelves));
+               }
+
+       }
+
+    # these template parameters are set the same regardless of $in->{'type'}
+    $template->param(
+            "BiblioDefaultView".C4::Context->preference("BiblioDefaultView")         => 1,
+            EnhancedMessagingPreferences => C4::Context->preference('EnhancedMessagingPreferences'),
+            GoogleJackets                => C4::Context->preference("GoogleJackets"),
+            KohaAdminEmailAddress        => "" . C4::Context->preference("KohaAdminEmailAddress"),
+            LoginBranchcode              => (C4::Context->userenv?C4::Context->userenv->{"branch"}:"insecure"),
+            LoginFirstname               => (C4::Context->userenv?C4::Context->userenv->{"firstname"}:"Bel"),
+            LoginSurname                 => C4::Context->userenv?C4::Context->userenv->{"surname"}:"Inconnu",
+            TagsEnabled                  => C4::Context->preference("TagsEnabled"),
+            hide_marc                    => C4::Context->preference("hide_marc"),
+            dateformat                   => C4::Context->preference("dateformat"),
+            'item-level_itypes'          => C4::Context->preference('item-level_itypes'),
+            patronimages                 => C4::Context->preference("patronimages"),
+            singleBranchMode             => C4::Context->preference("singleBranchMode"),
+                 );
 
     if ( $in->{'type'} eq "intranet" ) {
         $template->param(
 
     if ( $in->{'type'} eq "intranet" ) {
         $template->param(
-            intranetcolorstylesheet => C4::Context->preference("intranetcolorstylesheet"),
-            intranetstylesheet => C4::Context->preference("intranetstylesheet"),
-            IntranetNav        => C4::Context->preference("IntranetNav"),
-            intranetuserjs     => C4::Context->preference("intranetuserjs"),
-            TemplateEncoding   => C4::Context->preference("TemplateEncoding"),
-            AmazonContent      => C4::Context->preference("AmazonContent"),
-            LibraryName        => C4::Context->preference("LibraryName"),
-            LoginBranchcode    => (C4::Context->userenv?C4::Context->userenv->{"branch"}:"insecure"),
-            LoginBranchname    => (C4::Context->userenv?C4::Context->userenv->{"branchname"}:"insecure"),
-            LoginFirstname     => (C4::Context->userenv?C4::Context->userenv->{"firstname"}:"Bel"),
-            LoginSurname       => C4::Context->userenv?C4::Context->userenv->{"surname"}:"Inconnu", 
-            AutoLocation       => C4::Context->preference("AutoLocation"),
-            hide_marc          => C4::Context->preference("hide_marc"),
-            patronimages       => C4::Context->preference("patronimages"),
+            AmazonContent               => C4::Context->preference("AmazonContent"),
+            AmazonSimilarItems          => C4::Context->preference("AmazonSimilarItems"),
+            AutoLocation                => C4::Context->preference("AutoLocation"),
             "BiblioDefaultView".C4::Context->preference("IntranetBiblioDefaultView") => 1,
             "BiblioDefaultView".C4::Context->preference("IntranetBiblioDefaultView") => 1,
-            advancedMARCEditor      => C4::Context->preference("advancedMARCEditor"),
-            suggestion              => C4::Context->preference("suggestion"),
-            virtualshelves          => C4::Context->preference("virtualshelves"),
-            LibraryName             => C4::Context->preference("LibraryName"),
-            KohaAdminEmailAddress   => "" . C4::Context->preference("KohaAdminEmailAddress"),
-            IntranetmainUserblock   => C4::Context->preference("IntranetmainUserblock"),
-            IndependantBranches     => C4::Context->preference("IndependantBranches"),
-                       CircAutocompl => C4::Context->preference("CircAutocompl"),
-                       FRBRizeEditions => C4::Context->preference("FRBRizeEditions"),
-                       AmazonSimilarItems => C4::Context->preference("AmazonSimilarItems"),
-                       'item-level_itypes' => C4::Context->preference('item-level_itypes'),
-                       canreservefromotherbranches => C4::Context->preference('canreservefromotherbranches'),
-                       intranetreadinghistory => C4::Context->preference("intranetreadinghistory"),
-                       noItemTypeImages => C4::Context->preference("noItemTypeImages"),
-            singleBranchMode => C4::Context->preference("singleBranchMode"),
-                       TagsEnabled => C4::Context->preference("TagsEnabled"),
-                       GoogleJackets => C4::Context->preference("GoogleJackets"),
-                       AuthorisedValueImages => C4::Context->preference("AuthorisedValueImages"),
+            CircAutocompl               => C4::Context->preference("CircAutocompl"),
+            FRBRizeEditions             => C4::Context->preference("FRBRizeEditions"),
+            IndependantBranches         => C4::Context->preference("IndependantBranches"),
+            IntranetNav                 => C4::Context->preference("IntranetNav"),
+            IntranetmainUserblock       => C4::Context->preference("IntranetmainUserblock"),
+            LibraryName                 => C4::Context->preference("LibraryName"),
+            LoginBranchname             => (C4::Context->userenv?C4::Context->userenv->{"branchname"}:"insecure"),
+            TemplateEncoding            => C4::Context->preference("TemplateEncoding"),
+            advancedMARCEditor          => C4::Context->preference("advancedMARCEditor"),
+            canreservefromotherbranches => C4::Context->preference('canreservefromotherbranches'),
+            intranetcolorstylesheet     => C4::Context->preference("intranetcolorstylesheet"),
+            intranetreadinghistory      => C4::Context->preference("intranetreadinghistory"),
+            intranetstylesheet          => C4::Context->preference("intranetstylesheet"),
+            intranetuserjs              => C4::Context->preference("intranetuserjs"),
+            noItemTypeImages            => C4::Context->preference("noItemTypeImages"),
+            suggestion                  => C4::Context->preference("suggestion"),
+            virtualshelves              => C4::Context->preference("virtualshelves"),
         );
     }
     else {
         );
     }
     else {
@@ -264,65 +297,52 @@ sub get_template_and_user {
         my $LibraryNameTitle = C4::Context->preference("LibraryName");
         $LibraryNameTitle =~ s/<(?:\/?)(?:br|p)\s*(?:\/?)>/ /sgi;
         $LibraryNameTitle =~ s/<(?:[^<>'"]|'(?:[^']*)'|"(?:[^"]*)")*>//sg;
         my $LibraryNameTitle = C4::Context->preference("LibraryName");
         $LibraryNameTitle =~ s/<(?:\/?)(?:br|p)\s*(?:\/?)>/ /sgi;
         $LibraryNameTitle =~ s/<(?:[^<>'"]|'(?:[^']*)'|"(?:[^"]*)")*>//sg;
-  $template->param(
-            KohaAdminEmailAddress  => "" . C4::Context->preference("KohaAdminEmailAddress"),
-            AnonSuggestions =>  "" . C4::Context->preference("AnonSuggestions"),
-            suggestion             => "" . C4::Context->preference("suggestion"),
-            OPACViewOthersSuggestions             => "" . C4::Context->preference("OPACViewOthersSuggestions"),
-            virtualshelves         => "" . C4::Context->preference("virtualshelves"),
-            OpacNav                => "" . C4::Context->preference("OpacNav"),
-            opacheader             => "" . C4::Context->preference("opacheader"),
-            opaccredits            => "" . C4::Context->preference("opaccredits"),
-            opacsmallimage         => "" . C4::Context->preference("opacsmallimage"),
-            opaclargeimage         => "" . C4::Context->preference("opaclargeimage"),
-            opaclayoutstylesheet   => "". C4::Context->preference("opaclayoutstylesheet"),
-            opaccolorstylesheet    => "". C4::Context->preference("opaccolorstylesheet"),
-            OPACUserCSS    => "". C4::Context->preference("OPACUserCSS"),
-            opaclanguagesdisplay   => "". C4::Context->preference("opaclanguagesdisplay"),
-            opacuserlogin          => "" . C4::Context->preference("opacuserlogin"),
-                       OpacMainUserBlock =>  "" . C4::Context->preference("OpacMainUserBlock"),
-                       OPACURLOpenInNewWindow =>  "" . C4::Context->preference("OPACURLOpenInNewWindow"),
-            opacbookbag            => "" . C4::Context->preference("opacbookbag"),
-            TemplateEncoding       => "". C4::Context->preference("TemplateEncoding"),
-            AmazonContent          => "" . C4::Context->preference("AmazonContent"),
-            OPACShelfBrowser       => "". C4::Context->preference("OPACShelfBrowser"),
-            OPACAmazonSimilarItems => "" . C4::Context->preference("OPACAmazonSimilarItems"),
-            LibraryName            => "" . C4::Context->preference("LibraryName"),
-            LibraryNameTitle       => "" . $LibraryNameTitle,
-            LoginBranchcode        => (C4::Context->userenv?C4::Context->userenv->{"branch"}:"insecure"),
-            LoginBranchname        => C4::Context->userenv?C4::Context->userenv->{"branchname"}:"", 
-            LoginFirstname        => (C4::Context->userenv?C4::Context->userenv->{"firstname"}:"Bel"),
-            LoginSurname        => C4::Context->userenv?C4::Context->userenv->{"surname"}:"Inconnu", 
-            OpacPasswordChange     => C4::Context->preference("OpacPasswordChange"),
-            opacreadinghistory     => C4::Context->preference("opacreadinghistory"),
-            opacuserjs             => C4::Context->preference("opacuserjs"),
-            OpacCloud              => C4::Context->preference("OpacCloud"),
-            OpacTopissue           => C4::Context->preference("OpacTopissue"),
-            OpacAuthorities        => C4::Context->preference("OpacAuthorities"),
-            OpacBrowser            => C4::Context->preference("OpacBrowser"),
-            RequestOnOpac          => C4::Context->preference("RequestOnOpac"),
-                       OPACItemHolds          => C4::Context->preference("OPACItemHolds"),
-            reviewson              => C4::Context->preference("reviewson"),
-            hide_marc              => C4::Context->preference("hide_marc"),
-            patronimages           => C4::Context->preference("patronimages"),
-            hidelostitems          => C4::Context->preference("hidelostitems"),
-            mylibraryfirst   => C4::Context->preference("SearchMyLibraryFirst"),
-            "BiblioDefaultView".C4::Context->preference("BiblioDefaultView") => 1,
-            OPACFRBRizeEditions => C4::Context->preference("OPACFRBRizeEditions"),
-            'item-level_itypes' => C4::Context->preference('item-level_itypes'),
-            'Version' => C4::Context->preference('Version'),
-            singleBranchMode => C4::Context->preference("singleBranchMode"),
-            XSLTResultsDisplay => C4::Context->preference("XSLTResultsDisplay"),
-            XSLTDetailsDisplay => C4::Context->preference("XSLTDetailsDisplay"),
-                       TagsEnabled => C4::Context->preference("TagsEnabled"),
-                       GoogleJackets => C4::Context->preference("GoogleJackets"),
-                       AuthorisedValueImages => C4::Context->preference("AuthorisedValueImages"),
-                       OPACBaseURL=> ($in->{'query'}->https() ? "https://" : "http://") .
-                          $ENV{'SERVER_NAME'} . 
-                          ($ENV{'SERVER_PORT'} eq "80" ? '' : ":$ENV{'SERVER_PORT'}"),
+        $template->param(
+            OPACAmazonContent             => "" . C4::Context->preference("OPACAmazonContent"),
+            AnonSuggestions           => "" . C4::Context->preference("AnonSuggestions"),
+            AuthorisedValueImages     => C4::Context->preference("AuthorisedValueImages"),
+            LibraryName               => "" . C4::Context->preference("LibraryName"),
+            LibraryNameTitle          => "" . $LibraryNameTitle,
+            LoginBranchname           => C4::Context->userenv?C4::Context->userenv->{"branchname"}:"",
+            OPACAmazonSimilarItems    => "" . C4::Context->preference("OPACAmazonSimilarItems"),
+            OPACFRBRizeEditions       => C4::Context->preference("OPACFRBRizeEditions"),
+            OPACItemHolds             => C4::Context->preference("OPACItemHolds"),
+            OPACShelfBrowser          => "". C4::Context->preference("OPACShelfBrowser"),
+            OPACURLOpenInNewWindow    => "" . C4::Context->preference("OPACURLOpenInNewWindow"),
+            OPACUserCSS               => "". C4::Context->preference("OPACUserCSS"),
+            OPACViewOthersSuggestions => "" . C4::Context->preference("OPACViewOthersSuggestions"),
+            OpacAuthorities           => C4::Context->preference("OpacAuthorities"),
+            OPACBaseURL               => ($in->{'query'}->https() ? "https://" : "http://") .
+                   $ENV{'SERVER_NAME'} .
+                   ($ENV{'SERVER_PORT'} eq ($in->{'query'}->https() ? "443" : "80") ? '' : ":$ENV{'SERVER_PORT'}"),
+            OpacBrowser               => C4::Context->preference("OpacBrowser"),
+            OpacCloud                 => C4::Context->preference("OpacCloud"),
+            OpacMainUserBlock         => "" . C4::Context->preference("OpacMainUserBlock"),
+            OpacNav                   => "" . C4::Context->preference("OpacNav"),
+            OpacPasswordChange        => C4::Context->preference("OpacPasswordChange"),
+            OpacTopissue              => C4::Context->preference("OpacTopissue"),
+            RequestOnOpac             => C4::Context->preference("RequestOnOpac"),
+            TemplateEncoding          => "". C4::Context->preference("TemplateEncoding"),
+            'Version'                 => C4::Context->preference('Version'),
+            XSLTDetailsDisplay        => C4::Context->preference("XSLTDetailsDisplay"),
+            XSLTResultsDisplay        => C4::Context->preference("XSLTResultsDisplay"),
+            hidelostitems             => C4::Context->preference("hidelostitems"),
+            mylibraryfirst            => C4::Context->preference("SearchMyLibraryFirst"),
+            opacbookbag               => "" . C4::Context->preference("opacbookbag"),
+            opaccolorstylesheet       => "". C4::Context->preference("opaccolorstylesheet"),
+            opaccredits               => "" . C4::Context->preference("opaccredits"),
+            opacheader                => "" . C4::Context->preference("opacheader"),
+            opaclanguagesdisplay      => "". C4::Context->preference("opaclanguagesdisplay"),
+            opaclayoutstylesheet      => "". C4::Context->preference("opaclayoutstylesheet"),
+            opacreadinghistory        => C4::Context->preference("opacreadinghistory"),
+            opacsmallimage            => "" . C4::Context->preference("opacsmallimage"),
+            opacuserjs                => C4::Context->preference("opacuserjs"),
+            opacuserlogin             => "" . C4::Context->preference("opacuserlogin"),
+            reviewson                 => C4::Context->preference("reviewson"),
+            suggestion                => "" . C4::Context->preference("suggestion"),
+            virtualshelves            => "" . C4::Context->preference("virtualshelves"),
         );
     }
         );
     }
-       $template->param(listloop=>[{shelfname=>"Freelist", shelfnumber=>110}]);
     return ( $template, $borrowernumber, $cookie, $flags);
 }
 
     return ( $template, $borrowernumber, $cookie, $flags);
 }
 
@@ -332,8 +352,8 @@ sub get_template_and_user {
 
 Verifies that the user is authorized to run this script.  If
 the user is authorized, a (userid, cookie, session-id, flags)
 
 Verifies that the user is authorized to run this script.  If
 the user is authorized, a (userid, cookie, session-id, flags)
-quadruple is returned.  If the user is not authorized but does
-not have the required privilege (see $flagsrequired below), it
+quadruple is returned.  If the user is not authorized due to
+insufficent privileges (see $flagsrequired below), it
 displays an error page and exits.  Otherwise, it displays the
 login page and exits.
 
 displays an error page and exits.  Otherwise, it displays the
 login page and exits.
 
@@ -409,7 +429,11 @@ sub _version_check ($$) {
     my $version;
     # If Version syspref is unavailable, it means Koha is beeing installed,
     # and so we must redirect to OPAC maintenance page or to the WebInstaller
     my $version;
     # If Version syspref is unavailable, it means Koha is beeing installed,
     # and so we must redirect to OPAC maintenance page or to the WebInstaller
-    #warn "about to check version";
+       # also, if OpacMaintenance is ON, OPAC should redirect to maintenance
+       if (C4::Context->preference('OpacMaintenance') && $type eq 'opac') {
+               warn "OPAC Install required, redirecting to maintenance";
+               print $query->redirect("/cgi-bin/koha/maintenance.pl");
+       }
     unless ($version = C4::Context->preference('Version')) {    # assignment, not comparison
       if ($type ne 'opac') {
         warn "Install required, redirecting to Installer";
     unless ($version = C4::Context->preference('Version')) {    # assignment, not comparison
       if ($type ne 'opac') {
         warn "Install required, redirecting to Installer";
@@ -471,8 +495,9 @@ sub checkauth {
     # state variables
     my $loggedin = 0;
     my %info;
     # state variables
     my $loggedin = 0;
     my %info;
-    my ( $userid, $cookie, $sessionID, $flags, $shelves );
+    my ( $userid, $cookie, $sessionID, $flags, $barshelves, $pubshelves );
     my $logout = $query->param('logout.x');
     my $logout = $query->param('logout.x');
+
     if ( $userid = $ENV{'REMOTE_USER'} ) {
         # Using Basic Authentication, no cookies required
         $cookie = $query->cookie(
     if ( $userid = $ENV{'REMOTE_USER'} ) {
         # Using Basic Authentication, no cookies required
         $cookie = $query->cookie(
@@ -485,7 +510,7 @@ sub checkauth {
     elsif ( $sessionID = $query->cookie("CGISESSID")) {     # assignment, not comparison 
         my $session = get_session($sessionID);
         C4::Context->_new_userenv($sessionID);
     elsif ( $sessionID = $query->cookie("CGISESSID")) {     # assignment, not comparison 
         my $session = get_session($sessionID);
         C4::Context->_new_userenv($sessionID);
-        my ($ip, $lasttime);
+        my ($ip, $lasttime, $sessiontype);
         if ($session){
             C4::Context::set_userenv(
                 $session->param('number'),       $session->param('id'),
         if ($session){
             C4::Context::set_userenv(
                 $session->param('number'),       $session->param('id'),
@@ -494,14 +519,27 @@ sub checkauth {
                 $session->param('branchname'),   $session->param('flags'),
                 $session->param('emailaddress'), $session->param('branchprinter')
             );
                 $session->param('branchname'),   $session->param('flags'),
                 $session->param('emailaddress'), $session->param('branchprinter')
             );
-            C4::Context::set_shelves_userenv($session->param('shelves'));
+            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) ;
             $ip       = $session->param('ip');
             $lasttime = $session->param('lasttime');
             $userid   = $session->param('id');
             $debug and printf STDERR "AUTH_SESSION: (%s)\t%s %s - %s\n", map {$session->param($_)} qw(cardnumber firstname surname branch) ;
             $ip       = $session->param('ip');
             $lasttime = $session->param('lasttime');
             $userid   = $session->param('id');
+                       $sessiontype = $session->param('sessiontype');
         }
         }
-    
-        if ($logout) {
+   
+               if ( ($query->param('koha_login_context')) && ($query->param('userid') ne $session->param('id')) ) {
+                       #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 = " . $query->param('userid') . " but session id = " . $session->param('id');
+            $session->flush;      
+            $session->delete();
+            C4::Context->_unset_userenv($sessionID);
+                       $sessionID = undef;
+                       $userid = undef;
+               }
+        elsif ($logout) {
             # voluntary logout the user
             $session->flush;      
             $session->delete();
             # voluntary logout the user
             $session->flush;      
             $session->delete();
@@ -510,167 +548,203 @@ sub checkauth {
             $sessionID = undef;
             $userid    = undef;
         }
             $sessionID = undef;
             $userid    = undef;
         }
-               elsif ( $lasttime < time() - $timeout ) {
-                       # timed logout
-                       $info{'timed_out'} = 1;
-                       $session->delete();
-                       C4::Context->_unset_userenv($sessionID);
-                       _session_log(sprintf "%20s from %16s logged out at %30s (inactivity).\n", $userid,$ip,localtime);
-                       $userid    = undef;
-                       $sessionID = undef;
-               }
-               elsif ( $ip ne $ENV{'REMOTE_ADDR'} ) {
-                       # Different ip than originally logged in from
-                       $info{'oldip'}        = $ip;
-                       $info{'newip'}        = $ENV{'REMOTE_ADDR'};
-                       $info{'different_ip'} = 1;
-                       $session->delete();
-                       C4::Context->_unset_userenv($sessionID);
-                       _session_log(sprintf "%20s from %16s logged out at %30s (ip changed to %16s).\n", $userid,$ip,localtime, $info{'newip'});
-                       $sessionID = undef;
-                       $userid    = undef;
-               }
-               else {
-                       $cookie = $query->cookie( CGISESSID => $session->id );
-                       $session->param('lasttime',time());
-                       $flags = haspermission( $dbh, $userid, $flagsrequired );
-                       if ($flags) {
-                               $loggedin = 1;
-                       } else {
-                               $info{'nopermission'} = 1;
-                       }
-               }
+        elsif ( $lasttime < time() - $timeout ) {
+            # timed logout
+            $info{'timed_out'} = 1;
+            $session->delete();
+            C4::Context->_unset_userenv($sessionID);
+            _session_log(sprintf "%20s from %16s logged out at %30s (inactivity).\n", $userid,$ip,localtime);
+            $userid    = undef;
+            $sessionID = undef;
+        }
+        elsif ( $ip ne $ENV{'REMOTE_ADDR'} ) {
+            # Different ip than originally logged in from
+            $info{'oldip'}        = $ip;
+            $info{'newip'}        = $ENV{'REMOTE_ADDR'};
+            $info{'different_ip'} = 1;
+            $session->delete();
+            C4::Context->_unset_userenv($sessionID);
+            _session_log(sprintf "%20s from %16s logged out at %30s (ip changed to %16s).\n", $userid,$ip,localtime, $info{'newip'});
+            $sessionID = undef;
+            $userid    = undef;
+        }
+        else {
+            $cookie = $query->cookie( CGISESSID => $session->id );
+            $session->param('lasttime',time());
+            unless ( $sessiontype eq 'anon' ) { #if this is an anonymous session, we want to update the session, but not behave as if they are logged in...
+                $flags = haspermission($userid, $flagsrequired);
+                if ($flags) {
+                    $loggedin = 1;
+                } else {
+                    $info{'nopermission'} = 1;
+                }
+            }
+        }
     }
     }
-    unless ($userid) {
-        my $session = get_session("") or die "Auth ERROR: Cannot get_session()";
+    unless ($userid || $sessionID) {
+        #we initiate a session prior to checking for a username to allow for anonymous sessions...
+               my $session = get_session("") or die "Auth ERROR: Cannot get_session()";
         my $sessionID = $session->id;
         my $sessionID = $session->id;
-        $userid    = $query->param('userid');
-        my $password = $query->param('password');
-        C4::Context->_new_userenv($sessionID);
-        my ( $return, $cardnumber ) = checkpw( $dbh, $userid, $password );
-        if ($return) {
-            _session_log(sprintf "%20s from %16s logged in  at %30s.\n", $userid,$ENV{'REMOTE_ADDR'},localtime);
-            $cookie = $query->cookie(CGISESSID => $sessionID);
-            if ( $flags = haspermission( $dbh, $userid, $flagsrequired ) ) {
-                               $loggedin = 1;
-            }
-            else {
-                $info{'nopermission'} = 1;
-                C4::Context->_unset_userenv($sessionID);
-            }
+               C4::Context->_new_userenv($sessionID);
+        $cookie = $query->cookie(CGISESSID => $sessionID);
+        if ( $userid    = $query->param('userid') ) {
+            my $password = $query->param('password');
+            my ( $return, $cardnumber ) = checkpw( $dbh, $userid, $password );
+            if ($return) {
+                _session_log(sprintf "%20s from %16s logged in  at %30s.\n", $userid,$ENV{'REMOTE_ADDR'},localtime);
+                if ( $flags = haspermission($userid, $flagsrequired) ) {
+                    $loggedin = 1;
+                }
+                else {
+                    $info{'nopermission'} = 1;
+                    C4::Context->_unset_userenv($sessionID);
+                }
 
 
-                       my ($borrowernumber, $firstname, $surname, $userflags,
-                               $branchcode, $branchname, $branchprinter, $emailaddress);
+                my ($borrowernumber, $firstname, $surname, $userflags,
+                    $branchcode, $branchname, $branchprinter, $emailaddress);
+
+                if ( $return == 1 ) {
+                    my $select = "
+                    SELECT borrowernumber, firstname, surname, flags, borrowers.branchcode, 
+                            branches.branchname    as branchname, 
+                            branches.branchprinter as branchprinter, 
+                            email 
+                    FROM borrowers 
+                    LEFT JOIN branches on borrowers.branchcode=branches.branchcode
+                    ";
+                    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, $branchprinter, $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
+# if we have one we replace the branchcode of the userenv by the branch bound in the ip.
 
 
-            if ( $return == 1 ) {
-                my $select = "
-                SELECT borrowernumber, firstname, surname, flags, borrowers.branchcode, 
-                        branches.branchname    as branchname, 
-                        branches.branchprinter as branchprinter, 
-                        email 
-                FROM borrowers 
-                LEFT JOIN branches on borrowers.branchcode=branches.branchcode
-                ";
-                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";
+                                       my $ip       = $ENV{'REMOTE_ADDR'};
+                                       # if they specify at login, use that
+                                       if ($query->param('branch')) {
+                                               $branchcode  = $query->param('branch');
+                                               $branchname = GetBranchName($branchcode);
+                                       }
+                                       my $branches = GetBranches();
+                                       if (C4::Context->boolean_preference('IndependantBranches') && C4::Context->boolean_preference('Autolocation')){
+                                               # we have to check they are coming from the right ip range
+                                               my $domain = $branches->{$branchcode}->{'branchip'};
+                                               if ($ip !~ /^$domain/){
+                                                       $loggedin=0;
+                                                       $info{'wrongip'} = 1;
                                                }
                                        }
                                                }
                                        }
-                               }
-                if ($sth->rows) {
-                    ($borrowernumber, $firstname, $surname, $userflags,
-                       $branchcode, $branchname, $branchprinter, $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
-# if we have one we replace the branchcode of the userenv by the branch bound in the ip.
+                                       my @branchesloop;
+                                       foreach my $br ( keys %$branches ) {
+                                               #     now we work with the treatment of ip
+                                               my $domain = $branches->{$br}->{'branchip'};
+                                               if ( $domain && $ip =~ /^$domain/ ) {
+                                                       $branchcode = $branches->{$br}->{'branchcode'};
 
 
-                my $ip       = $ENV{'REMOTE_ADDR'};
-                # if they specify at login, use that
-                if ($query->param('branch')) {
-                    $branchcode  = $query->param('branch');
-                    $branchname = GetBranchName($branchcode);
-                }
-                my $branches = GetBranches();
-                if (C4::Context->boolean_preference('IndependantBranches') && C4::Context->boolean_preference('Autolocation')){
-                                   # we have to check they are coming from the right ip range
-                                       my $domain = $branches->{$branchcode}->{'branchip'};
-                                       if ($ip !~ /^$domain/){
-                                               $loggedin=0;
-                                               $info{'wrongip'} = 1;
+                                                       # new op dev : add the branchprinter and branchname in the cookie
+                                                       $branchprinter = $branches->{$br}->{'branchprinter'};
+                                                       $branchname    = $branches->{$br}->{'branchname'};
+                                               }
                                        }
                                        }
+                                       $session->param('number',$borrowernumber);
+                                       $session->param('id',$userid);
+                                       $session->param('cardnumber',$cardnumber);
+                                       $session->param('firstname',$firstname);
+                                       $session->param('surname',$surname);
+                                       $session->param('branch',$branchcode);
+                                       $session->param('branchname',$branchname);
+                                       $session->param('flags',$userflags);
+                                       $session->param('emailaddress',$emailaddress);
+                                       $session->param('ip',$session->remote_addr());
+                                       $session->param('lasttime',time());
+                                       $debug and printf STDERR "AUTH_4: (%s)\t%s %s - %s\n", map {$session->param($_)} qw(cardnumber firstname surname branch) ;
                                }
                                }
-
-                my @branchesloop;
-                foreach my $br ( keys %$branches ) {
-                    #     now we work with the treatment of ip
-                    my $domain = $branches->{$br}->{'branchip'};
-                    if ( $domain && $ip =~ /^$domain/ ) {
-                        $branchcode = $branches->{$br}->{'branchcode'};
-
-                        # new op dev : add the branchprinter and branchname in the cookie
-                        $branchprinter = $branches->{$br}->{'branchprinter'};
-                        $branchname    = $branches->{$br}->{'branchname'};
-                    }
-                }
-                $session->param('number',$borrowernumber);
-                $session->param('id',$userid);
-                $session->param('cardnumber',$cardnumber);
-                $session->param('firstname',$firstname);
-                $session->param('surname',$surname);
-                $session->param('branch',$branchcode);
-                $session->param('branchname',$branchname);
-                $session->param('flags',$userflags);
-                $session->param('emailaddress',$emailaddress);
-                $session->param('ip',$session->remote_addr());
-                $session->param('lasttime',time());
-                $debug and printf STDERR "AUTH_4: (%s)\t%s %s - %s\n", map {$session->param($_)} qw(cardnumber firstname surname branch) ;
-            }
-            elsif ( $return == 2 ) {
-                #We suppose the user is the superlibrarian
-                               $borrowernumber = 0;
-                $session->param('number',0);
-                $session->param('id',C4::Context->config('user'));
-                $session->param('cardnumber',C4::Context->config('user'));
-                $session->param('firstname',C4::Context->config('user'));
-                $session->param('surname',C4::Context->config('user'));
-                $session->param('branch','NO_LIBRARY_SET');
-                $session->param('branchname','NO_LIBRARY_SET');
-                $session->param('flags',1);
-                $session->param('emailaddress', C4::Context->preference('KohaAdminEmailAddress'));
-                $session->param('ip',$session->remote_addr());
-                $session->param('lasttime',time());
-            }
-            C4::Context::set_userenv(
-                $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('branchprinter')
-            );
-                       $shelves = GetShelvesSummary($borrowernumber,2,10);
-                       $session->param('shelves', $shelves);
-                       C4::Context::set_shelves_userenv($shelves);
-        }
-        else {
-            if ($userid) {
-                $info{'invalid_username_or_password'} = 1;
-                C4::Context->_unset_userenv($sessionID);
-            }
-
-        }
+                               elsif ( $return == 2 ) {
+                                       #We suppose the user is the superlibrarian
+                                       $borrowernumber = 0;
+                                       $session->param('number',0);
+                                       $session->param('id',C4::Context->config('user'));
+                                       $session->param('cardnumber',C4::Context->config('user'));
+                                       $session->param('firstname',C4::Context->config('user'));
+                                       $session->param('surname',C4::Context->config('user'));
+                                       $session->param('branch','NO_LIBRARY_SET');
+                                       $session->param('branchname','NO_LIBRARY_SET');
+                                       $session->param('flags',1);
+                                       $session->param('emailaddress', C4::Context->preference('KohaAdminEmailAddress'));
+                                       $session->param('ip',$session->remote_addr());
+                                       $session->param('lasttime',time());
+                               }
+                               C4::Context::set_userenv(
+                                       $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('branchprinter')
+                               );
+
+                               # Grab borrower's shelves and public shelves and add them to the session
+                               # $row_count determines how many records are returned from the db query
+                               # and the number of lists to be displayed of each type in the 'Lists' button drop down
+                               my $row_count = 10; # FIXME:This probably should be a syspref
+                               my ($total, $totshelves, $barshelves, $pubshelves);
+                               ($barshelves, $totshelves) = C4::VirtualShelves::GetRecentShelves(1, $row_count, $borrowernumber);
+                               $total->{'bartotal'} = $totshelves;
+                               ($pubshelves, $totshelves) = C4::VirtualShelves::GetRecentShelves(2, $row_count, undef);
+                               $total->{'pubtotal'} = $totshelves;
+                               $session->param('barshelves', $barshelves->[0]);
+                               $session->param('pubshelves', $pubshelves->[0]);
+                               $session->param('totshelves', $total);
+                               
+                               C4::Context::set_shelves_userenv('bar',$barshelves->[0]);
+                               C4::Context::set_shelves_userenv('pub',$pubshelves->[0]);
+                               C4::Context::set_shelves_userenv('tot',$total);
+                       }
+               else {
+               if ($userid) {
+                       $info{'invalid_username_or_password'} = 1;
+                       C4::Context->_unset_userenv($sessionID);
+               }
+                       }
+        }      # END if ( $userid    = $query->param('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...";
+
+                       # Grab the public shelves and add to the session...
+                       my $row_count = 20; # FIXME:This probably should be a syspref
+                       my ($total, $totshelves, $pubshelves);
+                       ($pubshelves, $totshelves) = C4::VirtualShelves::GetRecentShelves(2, $row_count, undef);
+                       $total->{'pubtotal'} = $totshelves;
+                       $session->param('pubshelves', $pubshelves->[0]);
+                       $session->param('totshelves', $total);
+                       C4::Context::set_shelves_userenv('pub',$pubshelves->[0]);
+                       C4::Context::set_shelves_userenv('tot',$total);
+                       
+                       # setting a couple of other session vars...
+                       $session->param('ip',$session->remote_addr());
+                       $session->param('lasttime',time());
+                       $session->param('sessiontype','anon');
+               }
     }  # END unless ($userid)
     my $insecure = C4::Context->boolean_preference('insecure');
 
     }  # END unless ($userid)
     my $insecure = C4::Context->boolean_preference('insecure');
 
@@ -712,7 +786,6 @@ sub checkauth {
         INPUTS               => \@inputs,
         suggestion           => C4::Context->preference("suggestion"),
         virtualshelves       => C4::Context->preference("virtualshelves"),
         INPUTS               => \@inputs,
         suggestion           => C4::Context->preference("suggestion"),
         virtualshelves       => C4::Context->preference("virtualshelves"),
-        opaclargeimage       => C4::Context->preference("opaclargeimage"),
         LibraryName          => C4::Context->preference("LibraryName"),
         opacuserlogin        => C4::Context->preference("opacuserlogin"),
         OpacNav              => C4::Context->preference("OpacNav"),
         LibraryName          => C4::Context->preference("LibraryName"),
         opacuserlogin        => C4::Context->preference("opacuserlogin"),
         OpacNav              => C4::Context->preference("OpacNav"),
@@ -729,6 +802,7 @@ sub checkauth {
         OpacAuthorities      => C4::Context->preference("OpacAuthorities"),
         OpacBrowser          => C4::Context->preference("OpacBrowser"),
         opacheader           => C4::Context->preference("opacheader"),
         OpacAuthorities      => C4::Context->preference("OpacAuthorities"),
         OpacBrowser          => C4::Context->preference("OpacBrowser"),
         opacheader           => C4::Context->preference("opacheader"),
+        TagsEnabled                  => C4::Context->preference("TagsEnabled"),
         OPACUserCSS           => C4::Context->preference("OPACUserCSS"),
         intranetcolorstylesheet =>
                                                                C4::Context->preference("intranetcolorstylesheet"),
         OPACUserCSS           => C4::Context->preference("OPACUserCSS"),
         intranetcolorstylesheet =>
                                                                C4::Context->preference("intranetcolorstylesheet"),
@@ -738,7 +812,6 @@ sub checkauth {
         TemplateEncoding   => C4::Context->preference("TemplateEncoding"),
         IndependantBranches=> C4::Context->preference("IndependantBranches"),
         AutoLocation       => C4::Context->preference("AutoLocation"),
         TemplateEncoding   => C4::Context->preference("TemplateEncoding"),
         IndependantBranches=> C4::Context->preference("IndependantBranches"),
         AutoLocation       => C4::Context->preference("AutoLocation"),
-        yuipath            => C4::Context->preference("yuipath"),
                wrongip            => $info{'wrongip'}
     );
     
                wrongip            => $info{'wrongip'}
     );
     
@@ -863,7 +936,7 @@ sub check_api_auth {
             } else {
                 my $cookie = $query->cookie( CGISESSID => $session->id );
                 $session->param('lasttime',time());
             } else {
                 my $cookie = $query->cookie( CGISESSID => $session->id );
                 $session->param('lasttime',time());
-                my $flags = haspermission( $dbh, $userid, $flagsrequired );
+                my $flags = haspermission($userid, $flagsrequired);
                 if ($flags) {
                     return ("ok", $cookie, $sessionID);
                 } else {
                 if ($flags) {
                     return ("ok", $cookie, $sessionID);
                 } else {
@@ -886,7 +959,7 @@ sub check_api_auth {
             return ("failed", undef, undef);
         }
         my ( $return, $cardnumber ) = checkpw( $dbh, $userid, $password );
             return ("failed", undef, undef);
         }
         my ( $return, $cardnumber ) = checkpw( $dbh, $userid, $password );
-        if ($return and haspermission( $dbh, $userid, $flagsrequired)) {
+        if ($return and haspermission($userid, $flagsrequired)) {
             my $session = get_session("");
             return ("failed", undef, undef) unless $session;
 
             my $session = get_session("");
             return ("failed", undef, undef) unless $session;
 
@@ -1081,7 +1154,7 @@ sub check_cookie_auth {
             return ("expired", undef);
         } else {
             $session->param('lasttime',time());
             return ("expired", undef);
         } else {
             $session->param('lasttime',time());
-            my $flags = haspermission( $dbh, $userid, $flagsrequired );
+            my $flags = haspermission($userid, $flagsrequired);
             if ($flags) {
                 return ("ok", $sessionID);
             } else {
             if ($flags) {
                 return ("ok", $sessionID);
             } else {
@@ -1118,14 +1191,14 @@ sub get_session {
     my $dbh = C4::Context->dbh;
     my $session;
     if ($storage_method eq 'mysql'){
     my $dbh = C4::Context->dbh;
     my $session;
     if ($storage_method eq 'mysql'){
-        $session = new CGI::Session("driver:MySQL;serializer:yaml", $sessionID, {Handle=>$dbh});
+        $session = new CGI::Session("driver:MySQL;serializer:yaml;id:md5", $sessionID, {Handle=>$dbh});
     }
     elsif ($storage_method eq 'Pg') {
     }
     elsif ($storage_method eq 'Pg') {
-        $session = new CGI::Session("driver:PostgreSQL;serializer:yaml", $sessionID, {Handle=>$dbh});
+        $session = new CGI::Session("driver:PostgreSQL;serializer:yaml;id:md5", $sessionID, {Handle=>$dbh});
     }
     else {
         # catch all defaults to tmp should work on all systems
     }
     else {
         # catch all defaults to tmp should work on all systems
-        $session = new CGI::Session("driver:File;serializer:yaml", $sessionID, {Directory=>'/tmp'});
+        $session = new CGI::Session("driver:File;serializer:yaml;id:md5", $sessionID, {Directory=>'/tmp'});
     }
     return $session;
 }
     }
     return $session;
 }
@@ -1134,7 +1207,7 @@ sub checkpw {
 
     my ( $dbh, $userid, $password ) = @_;
     if ($ldap) {
 
     my ( $dbh, $userid, $password ) = @_;
     if ($ldap) {
-        $debug and print "## checkpw - checking LDAP\n";
+        $debug and print STDERR "## checkpw - checking LDAP\n";
         my ($retval,$retcard) = checkpw_ldap(@_);    # EXTERNAL AUTH
         ($retval) and return ($retval,$retcard);
     }
         my ($retval,$retcard) = checkpw_ldap(@_);    # EXTERNAL AUTH
         ($retval) and return ($retval,$retcard);
     }
@@ -1194,10 +1267,12 @@ sub checkpw {
 
 =item getuserflags
 
 
 =item getuserflags
 
- $authflags = getuserflags($flags,$dbh);
+    my $authflags = getuserflags($flags, $userid, [$dbh]);
+
 Translates integer flags into permissions strings hash.
 
 C<$flags> is the integer userflags value ( borrowers.userflags )
 Translates integer flags into permissions strings hash.
 
 C<$flags> is the integer userflags value ( borrowers.userflags )
+C<$userid> is the members.userid, used for building subpermissions
 C<$authflags> is a hashref of permissions
 
 =cut
 C<$authflags> is a hashref of permissions
 
 =cut
@@ -1205,7 +1280,7 @@ C<$authflags> is a hashref of permissions
 sub getuserflags {
     my $flags   = shift;
     my $userid  = shift;
 sub getuserflags {
     my $flags   = shift;
     my $userid  = shift;
-    my $dbh     = shift;
+    my $dbh     = @_ ? shift : C4::Context->dbh;
     my $userflags;
     $flags = 0 unless $flags;
     my $sth = $dbh->prepare("SELECT bit, flag, defaulton FROM userflags");
     my $userflags;
     $flags = 0 unless $flags;
     my $sth = $dbh->prepare("SELECT bit, flag, defaulton FROM userflags");
@@ -1263,11 +1338,11 @@ sub get_user_subpermissions {
     my $userid = shift;
 
     my $dbh = C4::Context->dbh;
     my $userid = shift;
 
     my $dbh = C4::Context->dbh;
-    my $sth = $dbh->prepare("SELECT flag, code
+    my $sth = $dbh->prepare("SELECT flag, user_permissions.code as code
                              FROM user_permissions
                              JOIN permissions USING (module_bit, code)
                              FROM user_permissions
                              JOIN permissions USING (module_bit, code)
-                             JOIN userflags ON (module_bit = bit)
-                             JOIN borrowers USING (borrowernumber)
+                             JOIN userflags ON (permissions.module_bit = userflags.bit)
+                             JOIN borrowers ON (user_permissions.borrowernumber=borrowers.borrowernumber)
                              WHERE userid = ?");
     $sth->execute($userid);
 
                              WHERE userid = ?");
     $sth->execute($userid);
 
@@ -1310,9 +1385,9 @@ sub get_all_subpermissions {
 
 =item haspermission 
 
 
 =item haspermission 
 
-  $flags = ($dbh,$member,$flagsrequired);
+  $flags = ($userid, $flagsrequired);
 
 
-C<$member> may be either userid or overloaded with $borrower hashref from GetMemberDetails.
+C<$userid> the userid of the member
 C<$flags> is a hashref of required flags like C<$borrower-&lt;{authflags}> 
 
 Returns member's flags or 0 if a permission is not met.
 C<$flags> is a hashref of required flags like C<$borrower-&lt;{authflags}> 
 
 Returns member's flags or 0 if a permission is not met.
@@ -1320,22 +1395,15 @@ Returns member's flags or 0 if a permission is not met.
 =cut
 
 sub haspermission {
 =cut
 
 sub haspermission {
-    my ( $dbh, $userid, $flagsrequired ) = @_;
-    my ($flags,$intflags);
-    $dbh=C4::Context->dbh unless($dbh);
-    if(ref($userid)) {
-        $intflags = $userid->{'flags'};  
-    } else {
-        my $sth = $dbh->prepare("SELECT flags FROM borrowers WHERE userid=?");
-        $sth->execute($userid);
-        my ($intflags) = $sth->fetchrow;
-        $flags = getuserflags( $intflags, $userid, $dbh );
-    }
+    my ($userid, $flagsrequired) = @_;
+    my $sth = C4::Context->dbh->prepare("SELECT flags FROM borrowers WHERE userid=?");
+    $sth->execute($userid);
+    my $flags = getuserflags( $sth->fetchrow(), $userid );
     if ( $userid eq C4::Context->config('user') ) {
         # Super User Account from /etc/koha.conf
         $flags->{'superlibrarian'} = 1;
     }
     if ( $userid eq C4::Context->config('user') ) {
         # Super User Account from /etc/koha.conf
         $flags->{'superlibrarian'} = 1;
     }
-    if ( $userid eq 'demo' && C4::Context->config('demo') ) {
+    elsif ( $userid eq 'demo' && C4::Context->config('demo') ) {
         # Demo user that can do "anything" (demo=1 in /etc/koha.conf)
         $flags->{'superlibrarian'} = 1;
     }
         # Demo user that can do "anything" (demo=1 in /etc/koha.conf)
         $flags->{'superlibrarian'} = 1;
     }