working SAML
authorDobrica Pavlinusic <dpavlin@rot13.org>
Wed, 11 Sep 2019 11:16:44 +0000 (13:16 +0200)
committerDobrica Pavlinusic <dpavlin@rot13.org>
Wed, 11 Sep 2019 11:16:44 +0000 (13:16 +0200)
lib/C4/Auth.pm

index 7483417..aa47f6e 100644 (file)
@@ -57,7 +57,7 @@ BEGIN {
         else            { exit }
     }
 
         else            { exit }
     }
 
-    $debug     = $ENV{DEBUG};
+    $debug     = 1 || $ENV{DEBUG};
     @ISA       = qw(Exporter);
     @EXPORT    = qw(&checkauth &get_template_and_user &haspermission &get_user_subpermissions);
     @EXPORT_OK = qw(&check_api_auth &get_session &check_cookie_auth &checkpw &checkpw_internal &checkpw_hash
     @ISA       = qw(Exporter);
     @EXPORT    = qw(&checkauth &get_template_and_user &haspermission &get_user_subpermissions);
     @EXPORT_OK = qw(&check_api_auth &get_session &check_cookie_auth &checkpw &checkpw_internal &checkpw_hash
@@ -834,34 +834,37 @@ sub checkauth {
 =cut
 
 
 =cut
 
 
-use Data::Dump qw(dump);
+       use Data::Dump qw(dump);
 warn "YYY ENV = ",dump( \%ENV );
 
     $userid = $ENV{'HTTP_ATTR_CODE'};
 warn "YYY ENV = ",dump( \%ENV );
 
     $userid = $ENV{'HTTP_ATTR_CODE'};
-warn "XXX userid = [$userid] ";
     $sessionID = $query->cookie("CGISESSID");
     $sessionID = $query->cookie("CGISESSID");
+warn "XXX userid = [$userid] sessionID = $sessionID";
 
 
+=for xxx
     if ( $sessionID && $userid ) {
                my $s = get_session($sessionID);
                if ( $s->param('sessiontype') eq 'anon' ) {
                        undef $sessionID; # remove anonymous session if we have SAML user
     if ( $sessionID && $userid ) {
                my $s = get_session($sessionID);
                if ( $s->param('sessiontype') eq 'anon' ) {
                        undef $sessionID; # remove anonymous session if we have SAML user
+                       warn "XXX remote anonymous session";
                }
     }
 
 #    ($userid,$sessionID) = () if $userid eq '_everyone';
                }
     }
 
 #    ($userid,$sessionID) = () if $userid eq '_everyone';
-       return clear_saml($query) if $userid && $userid eq '_everyone';
+#      return clear_saml($query) if $userid && $userid eq '_everyone';
 
 
-    if ( ! $sessionID && $userid ) { # anonymous SAML user
-       warn "# userid: $userid";
+=cut
 
        # create new user from SAML data
 
        # create new user from SAML data
-       if ( my $token = $query->cookie('AuthMemCookie') ) {
-
+       my $token = $query->cookie('AuthMemCookie');
+       if ( defined($token) ) {
 
                use Cache::Memcached;
                my $memd = new Cache::Memcached { 'servers' => [ '127.0.0.1:11211' ], 'compress_threshold' => 10_000 };
                if ( my $data = $memd->get($token) ) {
 
 
                use Cache::Memcached;
                my $memd = new Cache::Memcached { 'servers' => [ '127.0.0.1:11211' ], 'compress_threshold' => 10_000 };
                if ( my $data = $memd->get($token) ) {
 
+warn "XXX AuthMemCookie $token = $data";
+
                        my $saml;
                        foreach ( split(/[\n\r]+/,$data) ) {
                                my ($n,$v) = split /=/, $_;
                        my $saml;
                        foreach ( split(/[\n\r]+/,$data) ) {
                                my ($n,$v) = split /=/, $_;
@@ -877,6 +880,7 @@ warn "XXX userid = [$userid] ";
 
                        if ( my $borrowernumber = getborrowernumber($saml->{ATTR_nick}) ) {
                                warn "SAML login OK $borrowernumber using ATTR_nick: ", $saml->{ATTR_nick};
 
                        if ( my $borrowernumber = getborrowernumber($saml->{ATTR_nick}) ) {
                                warn "SAML login OK $borrowernumber using ATTR_nick: ", $saml->{ATTR_nick};
+                               $userid = $saml->{ATTR_nick};
                        } elsif ( $borrowernumber = getborrowernumber( $cardnumber ) ) {
                                warn "SAML login OK $borrowernumber using cardnumber: $cardnumber update userid: $userid";
                                my $sth = $dbh->prepare(qq{ update borrowers set userid = ? where userid = cardnumber and cardnumber = ? });
                        } elsif ( $borrowernumber = getborrowernumber( $cardnumber ) ) {
                                warn "SAML login OK $borrowernumber using cardnumber: $cardnumber update userid: $userid";
                                my $sth = $dbh->prepare(qq{ update borrowers set userid = ? where userid = cardnumber and cardnumber = ? });
@@ -923,29 +927,59 @@ warn "XXX userid = [$userid] ";
                        $sth->execute( $userid );
                        die "can't find $userid" unless $sth->rows;
 
                        $sth->execute( $userid );
                        die "can't find $userid" unless $sth->rows;
 
-                       my $session = get_session('') or die "can't create session";
-                       my $sessionID = $session->id;
-                       C4::Context->_new_userenv($sessionID);
-                       $cookie = $query->cookie(CGISESSID => $sessionID);
+                       if ( $sessionID = $query->cookie("CGISESSID") ) {
+                                       warn "AAA updateing existing session $sessionID";
+                                       $session = get_session($sessionID);
+                                       C4::Context->_new_userenv($sessionID);
+                       }
+                       if ( ! $session ) {
+                               $session = get_session('') or die "can't create session";
+                               $sessionID = $session->id;
+                               C4::Context->_new_userenv($sessionID);
+                               warn "AAA created new session $sessionID";
+                       }
+                       
+                       $cookie = $query->cookie(
+                               -name     => 'CGISESSID',
+                               -value    => $session->id,
+                               -HttpOnly => 1
+                       );
+
+                       if ( $flags = haspermission( $userid, $flagsrequired ) ) {
+                               $loggedin = 1;
+                       } else {
+                               warn "ERROR: haspermission $userid ",dump($flagsrequired);
+                       }
 
                        my $row = $sth->fetchrow_hashref;
 
                        my $row = $sth->fetchrow_hashref;
+                       warn "XXX row = ",dump( $row );
 
 
-                       $session->param( $_ => $row->{$_} ) foreach keys %$row;
+                       $session->param( $_ => defined $row->{$_} ? $row->{$_} : '' ) foreach keys %$row;
 
 
-                       $session->param('ip', $ENV{'REMOTE_ADDR'});
+                       $session->param('flags', $flags);
+                       $session->param('ip', $session->remote_addr);
                        $session->param('lasttime',time());
                        $session->param('lasttime',time());
+                       $session->param( 'interface', $type);
+                       $session->param( 'shibboleth', 1 );
+                       $session->param( 'sessiontype', '' ); # XXX not 'anon'
 
 
-                       $session->param('AuthMemCookie', $token);
 
 
-                       C4::Context::set_userenv(
-                               $session->param('number'),       $session->param('id'),
+                       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('cardnumber'),   $session->param('firstname'),
                                $session->param('surname'),      $session->param('branch'),
                                $session->param('branchname'),   $session->param('flags'),
-                               $session->param('emailaddress'), $session->param('branchprinter')
+                               $session->param('emailaddress'), $session->param('branchprinter'),
+                $session->param('shibboleth')
                        );
 
                        );
 
-=for removed
+            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') );
+
+warn "DEBUG ",dump( $C4::Context::context->{userenv} );
+
+=for old-and-unsupported
                        my $row_count = 10; # FIXME:This probably should be a syspref
                        my ($total, $totshelves, $barshelves, $pubshelves);
                        ($barshelves, $totshelves) = C4::VirtualShelves::GetRecentShelves(1, $row_count, $session->param('number'));
                        my $row_count = 10; # FIXME:This probably should be a syspref
                        my ($total, $totshelves, $barshelves, $pubshelves);
                        ($barshelves, $totshelves) = C4::VirtualShelves::GetRecentShelves(1, $row_count, $session->param('number'));
@@ -959,27 +993,26 @@ warn "XXX userid = [$userid] ";
                        C4::Context::set_shelves_userenv('bar',$barshelves);
                        C4::Context::set_shelves_userenv('pub',$pubshelves);
                        C4::Context::set_shelves_userenv('tot',$total);
                        C4::Context::set_shelves_userenv('bar',$barshelves);
                        C4::Context::set_shelves_userenv('pub',$pubshelves);
                        C4::Context::set_shelves_userenv('tot',$total);
-=cut
 
                        $loggedin = 1;
 
                        if ( $type eq 'opac' ) {
 
                        $loggedin = 1;
 
                        if ( $type eq 'opac' ) {
-                                       my $to = 'https://' . $query->virtual_host . '/' . $query->path_info;
+                                       # TODO path_info isn't correct under plack
+                                       my $to = 'https://' . $query->virtual_host . '/' . $query->path_info . '?ferweb_login='.time();
                                        warn "XXX redirect $userid to $to";
                                        warn "XXX redirect $userid to $to";
-                                       ## FIXME 2011-12-20 dpavlin -- redirect logged in users to http
                                        print $query->redirect( -uri => $to, -status => 302, -cookie => $cookie );
                                        print $query->redirect( -uri => $to, -status => 302, -cookie => $cookie );
-#                                      exit;
+                                       safe_exit;
+                                       warn "FAKE, FALLING THROUGH";
                        }
 
                        }
 
+=cut
                } else {
                } else {
-                       die "Can't find SAML token $token for user $userid\n";
+                       warn "ERROR: Can't find SAML token $token for user $userid\n";
                }
                }
-       } else {
-               die "Can't find SAML token for user $userid\n";
-       }
-
-       } # XXX SAML anon user
 
 
+               warn "XXX-11 userid = $userid sessionID = $sessionID";
+       }
+       #XXX END OF SAML MODIFICATIONS -- next line is elsif!
 
     elsif ( $emailaddress) {
         # the Google OpenID Connect passes an email address
 
     elsif ( $emailaddress) {
         # the Google OpenID Connect passes an email address
@@ -987,6 +1020,7 @@ warn "XXX userid = [$userid] ";
     elsif ( $sessionID = $query->cookie("CGISESSID") )
     {    # assignment, not comparison
         $session = get_session($sessionID);
     elsif ( $sessionID = $query->cookie("CGISESSID") )
     {    # assignment, not comparison
         $session = get_session($sessionID);
+warn "XXX-9001 sessionID = $sessionID session =", dump( $session );
         C4::Context->_new_userenv($sessionID);
         my ( $ip, $lasttime, $sessiontype );
         my $s_userid = '';
         C4::Context->_new_userenv($sessionID);
         my ( $ip, $lasttime, $sessiontype );
         my $s_userid = '';
@@ -1023,6 +1057,7 @@ warn "XXX userid = [$userid] ";
             C4::Context->_unset_userenv($sessionID);
             $sessionID = undef;
             $userid    = undef;
             C4::Context->_unset_userenv($sessionID);
             $sessionID = undef;
             $userid    = undef;
+                       warn "FLUSH session query id = $q_userid but session id = $s_userid";
         }
         elsif ($logout) {
 
         }
         elsif ($logout) {
 
@@ -1032,6 +1067,7 @@ warn "XXX userid = [$userid] ";
             $session->delete();
             $session->flush;
             C4::Context->_unset_userenv($sessionID);
             $session->delete();
             $session->flush;
             C4::Context->_unset_userenv($sessionID);
+                       warn "FLUSH session logout $sessionID";
 
             #_session_log(sprintf "%20s from %16s logged out at %30s (manually).\n", $userid,$ip,(strftime "%c",localtime));
             $sessionID = undef;
 
             #_session_log(sprintf "%20s from %16s logged out at %30s (manually).\n", $userid,$ip,(strftime "%c",localtime));
             $sessionID = undef;
@@ -1059,6 +1095,7 @@ warn "XXX userid = [$userid] ";
             #_session_log(sprintf "%20s from %16s logged out at %30s (inactivity).\n", $userid,$ip,(strftime "%c",localtime));
             $userid    = undef;
             $sessionID = undef;
             #_session_log(sprintf "%20s from %16s logged out at %30s (inactivity).\n", $userid,$ip,(strftime "%c",localtime));
             $userid    = undef;
             $sessionID = undef;
+                       warn "XXX-LOGOUT lasttime $lasttime";
         }
         elsif ( C4::Context->preference('SessionRestrictionByIP') && $ip ne $ENV{'REMOTE_ADDR'} ) {
 
         }
         elsif ( C4::Context->preference('SessionRestrictionByIP') && $ip ne $ENV{'REMOTE_ADDR'} ) {
 
@@ -1073,8 +1110,10 @@ warn "XXX userid = [$userid] ";
             #_session_log(sprintf "%20s from %16s logged out at %30s (ip changed to %16s).\n", $userid,$ip,(strftime "%c",localtime), $info{'newip'});
             $sessionID = undef;
             $userid    = undef;
             #_session_log(sprintf "%20s from %16s logged out at %30s (ip changed to %16s).\n", $userid,$ip,(strftime "%c",localtime), $info{'newip'});
             $sessionID = undef;
             $userid    = undef;
+                       warn "XXX-LOGOUT ip $ip";
         }
         else {
         }
         else {
+                       warn "XXX-new-cookie";
             $cookie = $query->cookie(
                 -name     => 'CGISESSID',
                 -value    => $session->id,
             $cookie = $query->cookie(
                 -name     => 'CGISESSID',
                 -value    => $session->id,
@@ -1083,6 +1122,7 @@ warn "XXX userid = [$userid] ";
             $session->param( 'lasttime', time() );
             unless ( $sessiontype && $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 );
             $session->param( 'lasttime', time() );
             unless ( $sessiontype && $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 );
+                               warn "XXX flags = ",dump( $flags );
                 if ($flags) {
                     $loggedin = 1;
                 } else {
                 if ($flags) {
                     $loggedin = 1;
                 } else {
@@ -1091,7 +1131,10 @@ warn "XXX userid = [$userid] ";
             }
         }
     }
             }
         }
     }
+       warn "XXX-11 userid = $userid sessionID = $sessionID ", defined $session ? $session->id : '';
+
     unless ( $userid || $sessionID ) {
     unless ( $userid || $sessionID ) {
+               warn "XXX-30 userid = $userid sessionID = $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()";
 
         #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()";
 
@@ -1347,6 +1390,7 @@ warn "XXX userid = [$userid] ";
         }
     }    # END unless ($userid)
 
         }
     }    # END unless ($userid)
 
+       warn "XXX-44 userid = $userid cookie = ",dump( $cookie ), " sessionID = $sessionID loggedin = $loggedin flags = $flags";
     # finished authentification, now respond
     if ( $loggedin || $authnotrequired )
     {
     # finished authentification, now respond
     if ( $loggedin || $authnotrequired )
     {
@@ -1357,10 +1401,13 @@ warn "XXX userid = [$userid] ";
                 -value    => '',
                 -HttpOnly => 1
             );
                 -value    => '',
                 -HttpOnly => 1
             );
+                       warn "nuke cookie";
         }
 
         track_login_daily( $userid );
         }
 
         track_login_daily( $userid );
-
+warn "XXX session = ",dump($session);
+warn "XXX userenv = ",dump( C4::Context->userenv );
+        warn "RETURN = ", dump( $userid, $cookie, $sessionID, $flags );
         return ( $userid, $cookie, $sessionID, $flags );
     }
 
         return ( $userid, $cookie, $sessionID, $flags );
     }