Bugfixing interface issues. Also enabling contextual menu highlighting for catalogue...
[koha_gimpoz] / C4 / Auth.pm
old mode 100644 (file)
new mode 100755 (executable)
index 8d57a94..156ca97
@@ -1,3 +1,4 @@
+
 # -*- tab-width: 8 -*-
 # NOTE: This file uses 8-character tabs; do not change the tab size!
 
@@ -22,24 +23,23 @@ package C4::Auth;
 
 use strict;
 use Digest::MD5 qw(md5_base64);
+use CGI::Session;
 
 require Exporter;
 use C4::Context;
 use C4::Output;    # to get the template
-use C4::Interface::CGI::Output;
-use C4::Circulation::Circ2;    # getpatroninformation
+use C4::Members;
 use C4::Koha;
 use C4::Branch; # GetBranches
 
+# use utf8;
 # use Net::LDAP;
 # use Net::LDAP qw(:all);
 
 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
 
 # set the version for version checking
-$VERSION = do { my @v = '$Revision$' =~ /\d+/g;
-    shift(@v) . "." . join( "_", map { sprintf "%03d", $_ } @v );
-};
+$VERSION = 3.00;
 
 =head1 NAME
 
@@ -53,15 +53,18 @@ C4::Auth - Authenticates Koha users
   my $query = new CGI;
 
   my ($template, $borrowernumber, $cookie) 
-    = get_template_and_user({template_name   => "opac-main.tmpl",
-                             query           => $query,
-                            type            => "opac",
-                            authnotrequired => 1,
-                            flagsrequired   => {borrow => 1},
-                         });
+    = get_template_and_user(
+        {
+            template_name   => "opac-main.tmpl",
+            query           => $query,
+      type            => "opac",
+      authnotrequired => 1,
+      flagsrequired   => {borrow => 1},
+  }
+    );
 
   print $query->header(
-    -type => guesstype($template->output),
+    -type => 'utf-8',
     -cookie => $cookie
   ), $template->output;
 
@@ -84,16 +87,22 @@ C4::Auth - Authenticates Koha users
   &checkauth
   &get_template_and_user
 );
+@EXPORT_OK = qw(
+  &check_api_auth
+);
 
 =item get_template_and_user
 
   my ($template, $borrowernumber, $cookie)
-    = get_template_and_user({template_name   => "opac-main.tmpl",
-                             query           => $query,
-                            type            => "opac",
-                            authnotrequired => 1,
-                            flagsrequired   => {borrow => 1},
-                         });
+    = get_template_and_user(
+        {
+           template_name   => "opac-main.tmpl",
+           query           => $query,
+     type            => "opac",
+     authnotrequired => 1,
+     flagsrequired   => {borrow => 1},
+  }
+    );
 
     This call passes the C<query>, C<flagsrequired> and C<authnotrequired>
     to C<&checkauth> (in this module) to perform authentification.
@@ -120,17 +129,30 @@ sub get_template_and_user {
         $in->{'authnotrequired'},
         $in->{'flagsrequired'},
         $in->{'type'}
-    );
+    ) unless ($in->{'template_name'}=~/maintenance/);
 
     my $borrowernumber;
     my $insecure = C4::Context->preference('insecure');
     if ($user or $insecure) {
+
+               # 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'} );
+
+               # user info
         $template->param( loggedinusername => $user );
         $template->param( sessionID        => $sessionID );
 
         $borrowernumber = getborrowernumber($user);
         my ( $borr, $alternativeflags ) =
-          getpatroninformation( undef, $borrowernumber );
+          GetMemberDetails( $borrowernumber );
         my @bordat;
         $bordat[0] = $borr;
         $template->param( "USER_INFO" => \@bordat );
@@ -150,7 +172,7 @@ sub get_template_and_user {
             $template->param( CAN_user_updatecharge     => 1 );
             $template->param( CAN_user_acquisition      => 1 );
             $template->param( CAN_user_management       => 1 );
-            $template->param( CAN_user_tools            => 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 );
@@ -200,11 +222,11 @@ sub get_template_and_user {
         if ( $flags && $flags->{tools} == 1 ) {
             $template->param( CAN_user_tools => 1 );
         }
-       
+  
         if ( $flags && $flags->{editauthorities} == 1 ) {
             $template->param( CAN_user_editauthorities => 1 );
         }
-               
+    
         if ( $flags && $flags->{serials} == 1 ) {
             $template->param( CAN_user_serials => 1 );
         }
@@ -215,56 +237,71 @@ sub get_template_and_user {
     }
     if ( $in->{'type'} eq "intranet" ) {
         $template->param(
-            intranetcolorstylesheet =>
-              C4::Context->preference("intranetcolorstylesheet"),
+            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"),
-            "BiblioDefaultView".C4::Context->preference("BiblioDefaultView") => 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"),
+                       yuipath => C4::Context->preference("yuipath"),
         );
     }
     else {
-        warn "template type should be OPAC, here it is=[" . $in->{'type'} . "]"
-          unless ( $in->{'type'} eq 'opac' );
+        warn "template type should be OPAC, here it is=[" . $in->{'type'} . "]" unless ( $in->{'type'} eq 'opac' );
         my $LibraryNameTitle = C4::Context->preference("LibraryName");
         $LibraryNameTitle =~ s/<(?:\/?)(?:br|p)\s*(?:\/?)>/ /sgi;
         $LibraryNameTitle =~ s/<(?:[^<>'"]|'(?:[^']*)'|"(?:[^"]*)")*>//sg;
-       $template->param(
-            suggestion     => "" . C4::Context->preference("suggestion"),
-            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"),
-            opaclanguagesdisplay => "". C4::Context->preference("opaclanguagesdisplay"),
-            opacuserlogin    => "" . C4::Context->preference("opacuserlogin"),
-            opacbookbag      => "" . C4::Context->preference("opacbookbag"),
-            TemplateEncoding => "". C4::Context->preference("TemplateEncoding"),
-            AmazonContent => "" . C4::Context->preference("AmazonContent"),
-            LibraryName   => "" . C4::Context->preference("LibraryName"),
-            LibraryNameTitle   => "" . $LibraryNameTitle,
-            LoginBranchname    => C4::Context->userenv?C4::Context->userenv->{"branchname"}:"", 
-            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"),
-            reviewson          => C4::Context->preference("reviewson"),
-            hide_marc          => C4::Context->preference("hide_marc"),
-            patronimages       => C4::Context->preference("patronimages"),
+  $template->param(
+            KohaAdminEmailAddress  => "" . C4::Context->preference("KohaAdminEmailAddress"),
+            suggestion             => "" . C4::Context->preference("suggestion"),
+            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"),
+            opaclanguagesdisplay   => "". C4::Context->preference("opaclanguagesdisplay"),
+            opacuserlogin          => "" . C4::Context->preference("opacuserlogin"),
+            opacbookbag            => "" . C4::Context->preference("opacbookbag"),
+            TemplateEncoding       => "". C4::Context->preference("TemplateEncoding"),
+            AmazonContent          => "" . C4::Context->preference("AmazonContent"),
+            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"),
+            reviewson              => C4::Context->preference("reviewson"),
+            hide_marc              => C4::Context->preference("hide_marc"),
+            patronimages           => C4::Context->preference("patronimages"),
+            mylibraryfirst   => C4::Context->preference("SearchMyLibraryFirst"),
             "BiblioDefaultView".C4::Context->preference("BiblioDefaultView") => 1,
         );
     }
@@ -331,8 +368,8 @@ has authenticated.
 
 sub checkauth {
     my $query = shift;
-
-# $authnotrequired will be set for scripts which will run without authentication
+  # warn "Checking Auth";
+    # $authnotrequired will be set for scripts which will run without authentication
     my $authnotrequired = shift;
     my $flagsrequired   = shift;
     my $type            = shift;
@@ -342,51 +379,77 @@ sub checkauth {
     my $timeout = C4::Context->preference('timeout');
     $timeout = 600 unless $timeout;
 
-    my $template_name;
-    if ( $type eq 'opac' ) {
-        $template_name = "opac-auth.tmpl";
-    }
-    else {
-        $template_name = "auth.tmpl";
+
+    # 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";
+    unless (C4::Context->preference('Version')) {
+      if ($type ne 'opac') {
+        warn "Install required, redirecting to Installer";
+        print $query->redirect("/cgi-bin/koha/installer/install.pl");
+      } 
+      else {
+        warn "OPAC Install required, redirecting to maintenance";
+        print $query->redirect("/cgi-bin/koha/maintenance.pl");
+      }
+      exit;
     }
 
+
     # state variables
     my $loggedin = 0;
     my %info;
-    my ( $userid, $cookie, $sessionID, $flags, $envcookie );
+    my ( $userid, $cookie, $sessionID, $flags );
     my $logout = $query->param('logout.x');
     if ( $userid = $ENV{'REMOTE_USER'} ) {
-
         # Using Basic Authentication, no cookies required
         $cookie = $query->cookie(
-            -name    => 'sessionID',
+            -name    => 'CGISESSID',
             -value   => '',
             -expires => ''
         );
         $loggedin = 1;
     }
-    elsif ( $sessionID = $query->cookie('sessionID') ) {
+    elsif ( $sessionID = $query->cookie("CGISESSID")) {
+               my $storage_method = C4::Context->preference('SessionStorage');
+               my $session;
+               if ($storage_method eq 'mysql'){
+                   $session = new CGI::Session("driver:MySQL", $sessionID, {Handle=>$dbh});
+               }
+               elsif ($storage_method eq 'Pg') {
+                       $session = new CGI::Session("driver:PostgreSQL", $sessionID, {Handle=>$dbh});
+               }
+               else {
+                       # catch all defaults to tmp should work on all systems
+                       $session = new CGI::Session("driver:File", $sessionID, {Directory=>'/tmp'});
+               }
         C4::Context->_new_userenv($sessionID);
-        if ( my %hash = $query->cookie('userenv') ) {
+        if ($session){
             C4::Context::set_userenv(
-                $hash{number},       $hash{id},
-                $hash{cardnumber},   $hash{firstname},
-                $hash{surname},      $hash{branch},
-                $hash{branchname},   $hash{flags},
-                $hash{emailaddress}, $hash{branchprinter}
+                $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')
             );
+#             warn       "".$session->param('cardnumber').",   ".$session->param('firstname').",
+#                 ".$session->param('surname').",      ".$session->param('branch');
         }
-        my ( $ip, $lasttime );
-
-        ( $userid, $ip, $lasttime ) =
-          $dbh->selectrow_array(
-            "SELECT userid,ip,lasttime FROM sessions WHERE sessionid=?",
-            undef, $sessionID );
+        my $ip;
+        my $lasttime;
+        if ($session) {
+          $ip = $session->param('ip');
+          $lasttime = $session->param('lasttime');
+                $userid = $session->param('id');
+        }
+        
+    
         if ($logout) {
 
             # voluntary logout the user
-            $dbh->do( "DELETE FROM sessions WHERE sessionID=?",
-                undef, $sessionID );
+
+            $session->flush;      
+                       $session->delete();
             C4::Context->_unset_userenv($sessionID);
             $sessionID = undef;
             $userid    = undef;
@@ -398,11 +461,9 @@ sub checkauth {
         }
         if ($userid) {
             if ( $lasttime < time() - $timeout ) {
-
                 # timed logout
                 $info{'timed_out'} = 1;
-                $dbh->do( "DELETE FROM sessions WHERE sessionID=?",
-                    undef, $sessionID );
+                $session->delete();
                 C4::Context->_unset_userenv($sessionID);
                 $userid    = undef;
                 $sessionID = undef;
@@ -413,13 +474,11 @@ sub checkauth {
                 close L;
             }
             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;
-                $dbh->do( "DELETE FROM sessions WHERE sessionID=?",
-                    undef, $sessionID );
+        $session->delete();
                 C4::Context->_unset_userenv($sessionID);
                 $sessionID = undef;
                 $userid    = undef;
@@ -431,13 +490,8 @@ sub checkauth {
                 close L;
             }
             else {
-                $cookie = $query->cookie(
-                    -name    => 'sessionID',
-                    -value   => $sessionID,
-                    -expires => ''
-                );
-                $dbh->do( "UPDATE sessions SET lasttime=? WHERE sessionID=?",
-                    undef, ( time(), $sessionID ) );
+                $cookie = $query->cookie( CGISESSID => $session->id );
+                $session->param('lasttime',time());
                 $flags = haspermission( $dbh, $userid, $flagsrequired );
                 if ($flags) {
                     $loggedin = 1;
@@ -449,30 +503,35 @@ sub checkauth {
         }
     }
     unless ($userid) {
-        $sessionID = int( rand() * 100000 ) . '-' . time();
+               my $storage_method = C4::Context->preference('SessionStorage');
+               my $session;
+               if ($storage_method eq 'mysql'){
+                   $session = new CGI::Session("driver:MySQL", $sessionID, {Handle=>$dbh});
+               }
+               elsif ($storage_method eq 'Pg') {
+                       $session = new CGI::Session("driver:PostgreSQL", $sessionID, {Handle=>$dbh});
+               }
+               else {
+                       # catch all defaults to tmp should work on all systems
+                       $session = new CGI::Session("driver:File", $sessionID, {Directory=>'/tmp'});                    
+               }
+
+        my $sessionID;
+               if ($session) {
+                       $sessionID = $session->id;
+               }
         $userid    = $query->param('userid');
         C4::Context->_new_userenv($sessionID);
         my $password = $query->param('password');
         C4::Context->_new_userenv($sessionID);
         my ( $return, $cardnumber ) = checkpw( $dbh, $userid, $password );
         if ($return) {
-            $dbh->do( "DELETE FROM sessions WHERE sessionID=? AND userid=?",
-                undef, ( $sessionID, $userid ) );
-            $dbh->do(
-"INSERT INTO sessions (sessionID, userid, ip,lasttime) VALUES (?, ?, ?, ?)",
-                undef,
-                ( $sessionID, $userid, $ENV{'REMOTE_ADDR'}, time() )
-            );
             open L, ">>/tmp/sessionlog";
             my $time = localtime( time() );
             printf L "%20s from %16s logged in  at %30s.\n", $userid,
               $ENV{'REMOTE_ADDR'}, $time;
             close L;
-            $cookie = $query->cookie(
-                -name    => 'sessionID',
-                -value   => $sessionID,
-                -expires => ''
-            );
+            $cookie = $query->cookie(CGISESSID => $sessionID);
             if ( $flags = haspermission( $dbh, $userid, $flagsrequired ) ) {
                 $loggedin = 1;
             }
@@ -499,7 +558,7 @@ sub checkauth {
                   = $sth->fetchrow
                   if ( $sth->rows );
 
-#                              warn "$cardnumber,$borrowernumber,$userid,$firstname,$surname,$userflags,$branchcode,$emailaddress";
+#         warn "$cardnumber,$borrowernumber,$userid,$firstname,$surname,$userflags,$branchcode,$emailaddress";
                 unless ( $sth->rows ) {
                     my $sth =
                       $dbh->prepare(
@@ -514,7 +573,7 @@ sub checkauth {
                       = $sth->fetchrow
                       if ( $sth->rows );
 
-#                                      warn "$cardnumber,$borrowernumber,$userid,$firstname,$surname,$userflags,$branchcode,$emailaddress";
+#           warn "$cardnumber,$borrowernumber,$userid,$firstname,$surname,$userflags,$branchcode,$emailaddress";
                     unless ( $sth->rows ) {
                         $sth->execute($userid);
                         (
@@ -524,19 +583,19 @@ sub checkauth {
                           = $sth->fetchrow
                           if ( $sth->rows );
                     }
-
-#                                      warn "$cardnumber,$borrowernumber,$userid,$firstname,$surname,$userflags,$branchcode,$emailaddress";
                 }
 
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-#  new op dev :
 # launch a sequence to check if we have a ip for the branch, if we have one we replace the branchcode of the userenv by the branch bound in the ip.
                 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();
                 my @branchesloop;
                 foreach my $br ( keys %$branches ) {
-
-                    #          now we work with the treatment of ip
+                    #     now we work with the treatment of ip
                     my $domain = $branches->{$br}->{'branchip'};
                     if ( $domain && $ip =~ /^$domain/ ) {
                         $branchcode = $branches->{$br}->{'branchcode'};
@@ -546,40 +605,45 @@ sub checkauth {
                         $branchname    = $branches->{$br}->{'branchname'};
                     }
                 }
-                my $hash = C4::Context::set_userenv(
-                    $borrowernumber, $userid,    $cardnumber,
-                    $firstname,      $surname,   $branchcode,
-                    $branchname,     $userflags, $emailaddress,
-                    $branchprinter,
-                );
-
-                $envcookie = $query->cookie(
-                    -name    => 'userenv',
-                    -value   => $hash,
-                    -expires => ''
-                );
+                $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());
+#            warn       "".$session->param('cardnumber').",   ".$session->param('firstname').",
+#                 ".$session->param('surname').",      ".$session->param('branch');
             }
             elsif ( $return == 2 ) {
-
                 #We suppose the user is the superlibrarian
-                my $hash = C4::Context::set_userenv(
-                    0,
-                    0,
-                    C4::Context->config('user'),
-                    C4::Context->config('user'),
-                    C4::Context->config('user'),
-                    "",
-                    "SUPER",
-                    1,
-                    C4::Context->preference('KohaAdminEmailAddress')
-                );
-                $envcookie = $query->cookie(
-                    -name    => 'userenv',
-                    -value   => $hash,
-                    -expires => ''
-                );
-            }
+                        $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());
+                }
+                if ($session){
+                    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')
+                    );
+                }
         }
+
         else {
             if ($userid) {
                 $info{'invalid_username_or_password'} = 1;
@@ -592,24 +656,21 @@ sub checkauth {
     # finished authentification, now respond
     if ( $loggedin || $authnotrequired || ( defined($insecure) && $insecure ) )
     {
-
         # successful login
         unless ($cookie) {
-            $cookie = $query->cookie(
-                -name    => 'sessionID',
-                -value   => '',
-                -expires => ''
+            $cookie = $query->cookie( CGISESSID => ''
             );
         }
-        if ($envcookie) {
-            return ( $userid, [ $cookie, $envcookie ], $sessionID, $flags );
-        }
-        else {
-            return ( $userid, $cookie, $sessionID, $flags );
-        }
+    return ( $userid, $cookie, $sessionID, $flags );
+
     }
 
-    # else we have a problem...
+#
+#
+# AUTH rejected, show the login/password template, after checking the DB.
+#
+#
+    
     # get the inputs from the incoming query
     my @inputs = ();
     foreach my $name ( param $query) {
@@ -617,9 +678,42 @@ sub checkauth {
         my $value = $query->param($name);
         push @inputs, { name => $name, value => $value };
     }
+    # get the branchloop, which we need for authentication
+    my $branches = GetBranches();
+    my @branch_loop;
+    for my $branch_hash (keys %$branches) {
+                push @branch_loop, {branchcode => "$branch_hash", branchname => $branches->{$branch_hash}->{'branchname'}, };
+    }
 
+    # check that database and koha version are the same
+    # there is no DB version, it's a fresh install,
+    # go to web installer
+    # there is a DB version, compare it to the code version
+    my $kohaversion=C4::Context::KOHAVERSION;
+    # remove the 3 last . to have a Perl number
+    $kohaversion =~ s/(.*\..*)\.(.*)\.(.*)/$1$2$3/;
+#     warn "kohaversion : $kohaversion";
+    if (C4::Context->preference('Version') < $kohaversion){
+      if ($type ne 'opac'){
+      warn "Database update needed, redirecting to Installer. Database is ".C4::Context->preference('Version')." and Koha is : ".C4::Context->config("kohaversion");
+        print $query->redirect("/cgi-bin/koha/installer/install.pl?step=3");
+      } else {
+      warn "OPAC :Database update needed, redirecting to maintenance. Database is ".C4::Context->preference('Version')." and Koha is : ".C4::Context->config("kohaversion");
+        print $query->redirect("/cgi-bin/koha/maintenance.pl");
+      }       
+      exit;
+    }
+    my $template_name;
+    if ( $type eq 'opac' ) {
+        $template_name = "opac-auth.tmpl";
+    }
+    else {
+        $template_name = "auth.tmpl";
+    }
     my $template = gettemplate( $template_name, $type, $query );
+    $template->param(branchloop => \@branch_loop,);
     $template->param(
+    login        => 1,
         INPUTS               => \@inputs,
         suggestion           => C4::Context->preference("suggestion"),
         virtualshelves       => C4::Context->preference("virtualshelves"),
@@ -640,7 +734,8 @@ sub checkauth {
         IntranetNav        => C4::Context->preference("IntranetNav"),
         intranetuserjs     => C4::Context->preference("intranetuserjs"),
         TemplateEncoding   => C4::Context->preference("TemplateEncoding"),
-
+        IndependantBranches     => C4::Context->preference("IndependantBranches"),
+               AutoLocation       => C4::Context->preference("AutoLocation"),
     );
     $template->param( loginprompt => 1 ) unless $info{'nopermission'};
 
@@ -650,19 +745,264 @@ sub checkauth {
         LibraryName => => C4::Context->preference("LibraryName"),
     );
     $template->param( \%info );
-    $cookie = $query->cookie(
-        -name    => 'sessionID',
-        -value   => $sessionID,
-        -expires => ''
-    );
+#    $cookie = $query->cookie(CGISESSID => $session->id
+#   );
     print $query->header(
-        -type   => guesstype( $template->output ),
+               -type   => 'text/html',
+        -charset => 'utf-8',
         -cookie => $cookie
       ),
       $template->output;
     exit;
 }
 
+=item check_api_auth
+
+  ($status, $cookie, $sessionId) = check_api_auth($query, $userflags);
+
+Given a CGI query containing the parameters 'userid' and 'password' and/or a session
+cookie, determine if the user has the privileges specified by C<$userflags>.
+
+C<check_api_auth> is is meant for authenticating users of web services, and
+consequently will always return and will not attempt to redirect the user
+agent.
+
+If a valid session cookie is already present, check_api_auth will return a status
+of "ok", the cookie, and the Koha session ID.
+
+If no session cookie is present, check_api_auth will check the 'userid' and 'password
+parameters and create a session cookie and Koha session if the supplied credentials
+are OK.
+
+Possible return values in C<$status> are:
+
+=over 4
+
+=item "ok" -- user authenticated; C<$cookie> and C<$sessionid> have valid values.
+
+=item "failed" -- credentials are not correct; C<$cookie> and C<$sessionid> are undef
+
+=item "maintenance" -- DB is in maintenance mode; no login possible at the moment
+
+=item "expired -- session cookie has expired; API user should resubmit userid and password
+
+=back
+
+=cut
+
+sub check_api_auth {
+    my $query = shift;
+    my $flagsrequired = shift;
+
+    my $dbh     = C4::Context->dbh;
+    my $timeout = C4::Context->preference('timeout');
+    $timeout = 600 unless $timeout;
+
+    unless (C4::Context->preference('Version')) {
+        # database has not been installed yet
+        return ("maintenance", undef, undef);
+    }
+    my $kohaversion=C4::Context::KOHAVERSION;
+    $kohaversion =~ s/(.*\..*)\.(.*)\.(.*)/$1$2$3/;
+    if (C4::Context->preference('Version') < $kohaversion) {
+        # database in need of version update; assume that
+        # no API should be called while databsae is in
+        # this condition.
+        return ("maintenance", undef, undef);
+    }
+
+    # FIXME -- most of what follows is a copy-and-paste
+    # of code from checkauth.  There is an obvious need
+    # for refactoring to separate the various parts of
+    # the authentication code, but as of 2007-11-19 this
+    # is deferred so as to not introduce bugs into the
+    # regular authentication code for Koha 3.0.
+
+    # see if we have a valid session cookie already
+    # however, if a userid parameter is present (i.e., from
+    # a form submission, assume that any current cookie
+    # is to be ignored
+    my $sessionID = undef;
+    unless ($query->param('userid')) {
+        $sessionID = $query->cookie("CGISESSID");
+    }
+    if ($sessionID) {
+        my $storage_method = C4::Context->preference('SessionStorage');
+        my $session;
+        if ($storage_method eq 'mysql'){
+            $session = new CGI::Session("driver:MySQL", $sessionID, {Handle=>$dbh});
+        }
+        elsif ($storage_method eq 'Pg') {
+            $session = new CGI::Session("driver:PostgreSQL", $sessionID, {Handle=>$dbh});
+        }
+        else {
+            # catch all defaults to tmp should work on all systems
+            $session = new CGI::Session("driver:File", $sessionID, {Directory=>'/tmp'});
+        }
+        C4::Context->_new_userenv($sessionID);
+        if ($session) {
+            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')
+            );
+
+            my $ip = $session->param('ip');
+            my $lasttime = $session->param('lasttime');
+            my $userid = $session->param('id');
+            if ( $lasttime < time() - $timeout ) {
+                # time out
+                $session->delete();
+                C4::Context->_unset_userenv($sessionID);
+                $userid    = undef;
+                $sessionID = undef;
+                return ("expired", undef, undef);
+            } elsif ( $ip ne $ENV{'REMOTE_ADDR'} ) {
+                # IP address changed
+                $session->delete();
+                C4::Context->_unset_userenv($sessionID);
+                $userid    = undef;
+                $sessionID = undef;
+                return ("expired", undef, undef);
+            } else {
+                my $cookie = $query->cookie( CGISESSID => $session->id );
+                $session->param('lasttime',time());
+                my $flags = haspermission( $dbh, $userid, $flagsrequired );
+                if ($flags) {
+                    return ("ok", $cookie, $sessionID);
+                } else {
+                    $session->delete();
+                    C4::Context->_unset_userenv($sessionID);
+                    $userid    = undef;
+                    $sessionID = undef;
+                    return ("failed", undef, undef);
+                }
+            }
+        } else {
+            return ("expired", undef, undef);
+        }
+    } else {
+        # new login
+        my $userid = $query->param('userid');   
+        my $password = $query->param('password');   
+        unless ($userid and $password) {
+            # caller did something wrong, fail the authenticateion
+            return ("failed", undef, undef);
+        }
+        my ( $return, $cardnumber ) = checkpw( $dbh, $userid, $password );
+        if ($return and haspermission( $dbh, $userid, $flagsrequired)) {
+            my $storage_method = C4::Context->preference('SessionStorage');
+            my $session;
+            if ($storage_method eq 'mysql'){
+                $session = new CGI::Session("driver:MySQL", $sessionID, {Handle=>$dbh});
+            } elsif ($storage_method eq 'Pg') {
+                $session = new CGI::Session("driver:PostgreSQL", $sessionID, {Handle=>$dbh});
+            } else {
+                # catch all defaults to tmp should work on all systems
+                $session = new CGI::Session("driver:File", $sessionID, {Directory=>'/tmp'});
+            }
+            return ("failed", undef, undef) unless $session;
+
+            my $sessionID = $session->id;
+            C4::Context->_new_userenv($sessionID);
+            my $cookie = $query->cookie(CGISESSID => $sessionID);
+            if ( $return == 1 ) {
+                my (
+                    $borrowernumber, $firstname,  $surname,
+                    $userflags,      $branchcode, $branchname,
+                    $branchprinter,  $emailaddress
+                );
+                my $sth =
+                  $dbh->prepare(
+"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 where userid=?"
+                  );
+                $sth->execute($userid);
+                (
+                    $borrowernumber, $firstname,  $surname,
+                    $userflags,      $branchcode, $branchname,
+                    $branchprinter,  $emailaddress
+                ) = $sth->fetchrow if ( $sth->rows );
+
+                unless ($sth->rows ) {
+                    my $sth = $dbh->prepare(
+"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 where cardnumber=?"
+                      );
+                    $sth->execute($cardnumber);
+                    (
+                        $borrowernumber, $firstname,  $surname,
+                        $userflags,      $branchcode, $branchname,
+                        $branchprinter,  $emailaddress
+                    ) = $sth->fetchrow if ( $sth->rows );
+
+                    unless ( $sth->rows ) {
+                        $sth->execute($userid);
+                        (
+                            $borrowernumber, $firstname, $surname, $userflags,
+                            $branchcode, $branchname, $branchprinter, $emailaddress
+                        ) = $sth->fetchrow if ( $sth->rows );
+                    }
+                }
+
+                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();
+                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());
+            } elsif ( $return == 2 ) {
+                #We suppose the user is the superlibrarian
+                $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')
+            );
+            return ("ok", $cookie, $sessionID);
+        } else {
+            return ("failed", undef, undef);
+        }
+    } 
+}
+
 sub checkpw {
 
     my ( $dbh, $userid, $password ) = @_;
@@ -705,7 +1045,7 @@ sub checkpw {
     {
 
 # Koha superuser account
-#              C4::Context->set_userenv(0,0,C4::Context->config('user'),C4::Context->config('user'),C4::Context->config('user'),"",1);
+#     C4::Context->set_userenv(0,0,C4::Context->config('user'),C4::Context->config('user'),C4::Context->config('user'),"",1);
         return 2;
     }
     if (   $userid && $userid eq 'demo'