<%once>
my $loaded_user = 0;
</%once>
<%init>

use RT::Authen::ExternalAuth;

# Work around a bug in the RT 3.8.0 and 3.8.1 plugin system (fixed in 3.8.2)
# Temporarily force RT to reload RT::User, since it isn't being loaded
# correctly as a plugin.
unless ($loaded_user) {
    $RT::Logger->error("Working around bug in RT and reloading RT::User");
    $loaded_user++;
    delete $INC{'RT/User.pm'};
    delete $INC{'RT/User_Overlay.pm'};
    delete $INC{'RT/User_Vendor.pm'};
    require RT::User;
}
######################################################################################

# If the user is logging in, let's authenticate; if they can auth but don't load
# (e.g. they don't have an account but external auth succeeds), we'll autocreate
# their account.
unless ($session{'CurrentUser'}) {
    
    # Password has not been confirmed valid until we say so
    my $password_validated = 0;

    # If $user has been passed by login page, 
    # or any other custom code previous to this
    if (defined ($user)) {
        $session{'CurrentUser'} = RT::CurrentUser->new();
        
        # Does user exist internally?
        $session{'CurrentUser'}->Load($user);

        # Unless we have loaded a valid user with a UserID
        # check if user exists externally and autocreate if it does
        unless ($session{'CurrentUser'}->Id) {
            if(RT::Authen::ExternalAuth::UserExists($user)){
				my $UserObj = RT::User->new($RT::SystemUser);
            	my ($val, $msg) = 
                  $UserObj->Create(%{ref($RT::AutoCreate) ? $RT::AutoCreate : {}},
                                   Name   => $user,
                                   Gecos  => $user,
                                  );
                unless ($val) {
                    $RT::Logger->error( "Couldn't create user $user: $msg" );
                    return;
                }
                $RT::Logger->info(  "Autocreated external user",
                                    $UserObj->Name,
                                    "(",
                                    $UserObj->Id,
                                    ")");
                
                $RT::Logger->debug("Loading new user (",
                					$user,
                					") into current session");
                $session{'CurrentUser'}->Load($user);
            }
        } 
    }
    
    # If we now have a completely valid RT user to play with...
    if ($session{'CurrentUser'} && $session{'CurrentUser'}->Id) {
	    
	    # If a password was given on the login page, validate it
	    if (defined($pass)) {
	        $RT::Logger->debug("\$pass defined ($pass), Running IsPassword");
	        $password_validated = $session{'CurrentUser'}->UserObj->IsPassword($pass);
	    }
	        
	    unless($password_validated) {
	        $RT::Logger->debug("Password Incorrect");
	        delete $session{'CurrentUser'};
	    }
	}
	    
    # If we STILL have a completely valid RT user to play with...
    # and therefore password has been validated...
    if ($session{'CurrentUser'} && $session{'CurrentUser'}->Id) {
        
        # Even if we have JUST created the user in RT, we are going to
        # reload their information from an external source. This allows us
        # to be sure that the user the cookie gave us really does exist in
        # the database, but more importantly, UpdateFromExternal will check 
        # whether the user is disabled or not which we have not been able to 
        # do during auto-create
        my ($updated,$update_msg) = RT::Authen::ExternalAuth::UpdateUserInfo($session{'CurrentUser'}->Name);
                
        # Now that we definitely have up-to-date user information,
        # if the user is disabled, kick them out. Now!
        if ($session{'CurrentUser'}->UserObj->Disabled) {
            delete $session{'CurrentUser'};
        }
    }
    # Original thank to Walter Duncan for these session deletes.
    
    # If the user has already been authenticated successfully above
    # then all is well, log the successful user auth
    # Else, ensure the session dies.
    
    # We will not check the password here, because this will be
    # done by the autohandler this Callback is extending if
    # we delete the session.
    
    # If we **STILL** have a full user and the session hasn't already been deleted
    if ($session{'CurrentUser'} && $session{'CurrentUser'}->Id) {
    	# Sanity check
        if($password_validated) {
            
            $RT::Logger->info(  "Successful login for",
                                $user,
                                "from",
                                $ENV{'REMOTE_ADDR'});
            # Do not delete the session. User stays logged in and
            # autohandler will not check the password again
        } else {
            # Make SURE the session is deleted.
            delete $session{'CurrentUser'};
            # This will cause autohandler to request IsPassword 
            # which will in turn call IsExternalPassword
        }
    }
}
return;
</%init>

<%ARGS>
$user => undef
$pass => undef
$menu => undef
</%ARGS>
