Apache-SiteControl

 view release on metacpan or  search on metacpan

lib/Apache/SiteControl/UserFactory.pm  view on Meta::CPAN

   my $lockdir = $r->dir_config("SiteControlLocks") || "/tmp";
   my %session;

   if(!$userobj->isa("Apache::SiteControl::User") || !defined($userobj->{sessionid})) {
      $r->log_error("Invalid user object passed to saveAttribute. Attribute not saved.");
      return 0;
   }

   eval {
      tie %session, 'Apache::Session::File', $userobj->{sessionid}, {
         Directory => $sessiondir,
         LockDirectory => $lockdir
         };

      $r->log_error("Saving attribute $name = " .
         $userobj->getAttribute($name) . 
         "using Apache::Session::File.") if $debug;
      $session{"attr_$name"} = $userobj->getAttribute($name);
      untie %session;
   };
   if($@) {
      $r->log_error("Failed to save user attribute: $@");
      return 0;
   }
}

# Internal method for this implementation (using session files)
# in: Apache request object
sub _getUsermap
{
   my $this = shift;
   my $r = shift;
   my $sessiondir = $r->dir_config("SiteControlSessions") || "/tmp";
   my $lockdir = $r->dir_config("SiteControlLocks") || "/tmp";
   my $debug = $r->dir_config("SiteControlDebug") || 0;
   my %usermap;

   eval {
   my %session;

   my @files = <$sessiondir/[0-9a-f]*>;
   my @sessions = grep { s#^.*/([^/]*)$#$1# } @files;
   my $username;

   $r->log_error("Current sessions: @sessions") if $debug;
   for my $id (@sessions)
   {
      next if $id !~ /^[0-9a-f]{20,}/;
      tie %session, 'Apache::Session::File', $id, {
         Directory => $sessiondir,
         LockDirectory => $lockdir
         };
      $username = $session{username};
      if(!defined($username)) {
         $r->log_error("Session $session{_session_id} does not have a username...deleting");
         tied(%session)->delete;
         next;
      }
      if(defined($usermap{$username})) {
         # last modify time of session we saw
         my $timea = (stat("$sessiondir/$usermap{$username}{_session_id}"))[9];
         # last modify time of this session
         my $timeb = (stat("$sessiondir/$id"))[9];
         $r->log_error("User $username has duplicate session! Expiring old session");
         if($timea < $timeb) {
            # The one we saw earlier is older. Delete it.
            untie %session;
            tie %session, 'Apache::Session::File', 
               $usermap{$username}{_session_id}, {
               Directory => $sessiondir,
               LockDirectory => $lockdir
               };
            tied(%session)->delete;
            redo; # redo this loop so we record the more better one ;)
         } else {
            # The one we are looking at is older...delete it and go on.
            tied(%session)->delete;
            next;
         }
      }
      $usermap{$username} = {};
      # Copy the session into our usermap
      for my $key (keys %session) {
         $usermap{$username}{$key} = $session{$key};
      }
      untie %session;
   }
   $r->log_error("Current user map : " .  Dumper(\%usermap)) if $debug;

   };
   if($@) {
      $r->log_error("Failure in _getUsermap: $@");
      return undef;
   }

   return { %usermap };
}

1;

__END__

=head1 NAME

Apache::SiteControl::UserFactory - User factory/persistence

=head1 DESCRIPTION

This class is responsible for creating user objects (see
Apache::SiteControl::User) and managing the interfacing of those objects with a
persistent session store.  The default implementation uses
Apache::Session::File to store the various attributes of the user to disk.

If you want to do your own user management, then you should leave the User
class alone, and subclass only this factory. The following methods are
required:

=over 3

=item makeUser($$) 

This method is called with the Apache Request object, username, password, and
all other credential_# fields from the login form.  It must create and return



( run in 1.273 second using v1.01-cache-2.11-cpan-39bf76dae61 )