Coding standards
Security in ResourceSpace
Developer reference
Database
Action functions
Admin functions
Ajax functions
Annotation functions
API functions
Collections functions
Comment functions
Config functions
CSV export functions
Dash functions
Debug functions
Encryption functions
Facial recognition functions
File functions
General functions
Language functions
Log functions
Login functions
Message functions
Migration functions
Node functions
PDF functions
Plugin functions
Render functions
Reporting functions
Request functions
Research functions
Slideshow functions
Theme permission functions
User functions
Video functions
Database functions
Metadata functions
Resource functions
Search functions
Map functions
Job functions
Tab functions
Test functions

perform_login()

Parameters

ColumnTypeDefaultDescription
$loginuser ""
$loginpass ""

Location

include/login_functions.php lines 8 to 213

Definition

 
function perform_login($loginuser="",$loginpass="")
    {
    global 
$scramble_key$lang$max_login_attempts_wait_minutes$max_login_attempts_per_ip$max_login_attempts_per_username,
    
$username$password$password_hash$session_hash$usergroup;

    
$result = [];
    
$result['valid'] = $valid false;

    if (
trim($loginpass) != "") {
        
$password trim($loginpass);
    }
    if(
trim($loginuser) != "") {
        
$username trim($loginuser);
    }

    
// If a special key is sent, which is a hash based on the username and scramble key, then allow a login
    // using this hash as the password. This is for the 'log in as this user' feature.
    
$impersonate_user hash_equals(getval('userkey'''),hash_hmac("sha256""login_as_user" $loginuser date("Ymd"), $scramble_keytrue));

    
// Get user record
    
$user_ref get_user_by_username($username);
    
$found_user_record = ($user_ref !== false);
    if (
$found_user_record) {
        
$user_data get_user($user_ref);
        
// Did the user log in using their email address? If so update username variable
        
if (
            
mb_strtolower($user_data['username']) !== mb_strtolower($username)
            && 
mb_strtolower($user_data['email']) === mb_strtolower($username)
        ) {
            
$username $user_data['username'];
        }
    }

    
// User logs in
    
if ($found_user_record
        
&& rs_password_verify($password, (string) $user_data['password'], ['username' => $username])
        && 
$password != ""
    
) {
        
$password_hash_info get_password_hash_info();
        
$algo $password_hash_info['algo'];
        
$options $password_hash_info['options'];

        if (
password_needs_rehash($user_data['password'], $algo$options)) {
            
$password_hash rs_password_hash("RS{$username}{$password}");
            if (
$password_hash === false) {
                
trigger_error('Failed to rehash password!');
            }

            
ps_query("UPDATE user SET `password` = ? WHERE ref = ?", array("s",$password_hash,"i",$user_ref));
        } else {
            
$password_hash $user_data['password'];
        }
        
$valid true;
    } elseif (
        
// An admin logs in as this user
        
$found_user_record
        
&& $impersonate_user
        
&& rs_password_verify($password, (string) $user_data['password'], ['username' => $username'impersonate_user' => true])
    ) {
        
$password_hash $user_data['password'];
        
$valid true;
    }

    
$ip get_ip();

    
# This may change the $username, $password, and $password_hash
    
$externalresult=hook("externalauth","",array($username$password)); #Attempt external auth if configured
    
if($externalresult)
        {
        
// Get user data as per old method
        
$user_ref get_user_by_username($username);
        
$found_user_record = ($user_ref !== false);
        if(
$found_user_record)
            {
            
$user_data get_user($user_ref);
            
$valid true;
            }
        }

    if(
$valid)
        {
        
$userref $user_data['ref'];
        
$usergroup $user_data['usergroup'];
        
$expires $user_data['account_expires'];
        
$approved $user_data['approved'];

        if (
$approved == 2)
            {
            
$result['error']=$lang["accountdisabled"];
            
log_activity('Account Disabled',LOG_CODE_FAILED_LOGIN_ATTEMPT,$ip,"user","last_ip",$userref,null,null,$user_ref);
            return 
$result;
            }

        if (
$expires!="" && $expires!="0000-00-00 00:00:00" && strtotime($expires)<=time())
            {
            
$result['error']=$lang["accountexpired"];
            
log_activity('Account Expired',LOG_CODE_FAILED_LOGIN_ATTEMPT,$ip,"user","last_ip",$userref,null,null,$user_ref);
            return 
$result;
            }

        
$session_hash generate_session_hash($password_hash);

        
$result['valid'] = true;
        
$result['session_hash'] = $session_hash;
        
$result['password_hash'] = $password_hash;
        
$result['ref'] = $userref;

        
        
$language getval("language""");

        
update_user_access($userref,
            [
            
"session" => $session_hash,
            
"lang" => $language,
            
"login_tries" => 0,
            
"last_ip" => $ip,
            ]
        );
        
        
// Update user local time zone (if provided)
        
$get_user_local_timezone getval('user_local_timezone'null);
        
set_config_option($userref'user_local_timezone'$get_user_local_timezone);

        
# Log this
        
daily_stat("User session"$userref);
        
log_activity(null,LOG_CODE_LOGGED_IN,$ip,"user","last_ip",($userref!="" $userref :"null"),null,'',($userref!="" $userref :"null"));

        
# Blank the IP address lockout counter for this IP
        
ps_query("DELETE FROM ip_lockout WHERE ip = ?",array("s",$ip));

        return 
$result;
        }

    
# Invalid login
    
if(isset($externalresult["error"])){$result['error']=$externalresult["error"];} // We may have been given a better error to display
        
else {$result['error']=$lang["loginincorrect"];}

  
hook("loginincorrect");

    
# Add / increment a lockout value for this IP
    
$lockouts=ps_value("select count(*) value from ip_lockout where ip=? and tries<?",array("s",$ip,"i",$max_login_attempts_per_ip),"");

    if (
$lockouts>0)
        {
        
# Existing row with room to move
        
$tries=ps_value("select tries value from ip_lockout where ip=?",array("s",$ip),0);
        
$tries++;
        if (
$tries==$max_login_attempts_per_ip)
            {
            
# Show locked out message.
            
$result['error']=str_replace("?",$max_login_attempts_wait_minutes,$lang["max_login_attempts_exceeded"]);
            
$log_message 'Max login attempts from IP exceeded - IP: ' $ip;
            
log_activity($log_messageLOG_CODE_FAILED_LOGIN_ATTEMPT$tries'ip_lockout''ip'$ip'ip');
            }
        
# Increment
        
ps_query("update ip_lockout set last_try=now(),tries=tries+1 where ip=?",array("s",$ip));
        }
    else
        {
        
# New row
        
ps_query("delete from ip_lockout where ip=?",array("s",$ip));
        
ps_query("insert into ip_lockout (ip,tries,last_try) values (?,1,now())",array("s",$ip));
        }

    
# Increment a lockout value for any matching username.
    
$ulocks=ps_query("select ref,login_tries,login_last_try from user where username=?",array("s",$username));
    if (
count($ulocks)>0)
        {
        
$tries=$ulocks[0]["login_tries"];
        if (
$tries=="") {$tries=1;} else {$tries++;}
        if (
$tries>$max_login_attempts_per_username) {$tries=1;}
        if (
$tries==$max_login_attempts_per_username)
            {
            
# Show locked out message.
            
$result['error']=str_replace("?",$max_login_attempts_wait_minutes,$lang["max_login_attempts_exceeded"]);
            
$log_message 'Max login attempts exceeded';
            
log_activity($log_message,LOG_CODE_FAILED_LOGIN_ATTEMPT,$ip,'user','ref',($user_ref != false $user_ref null),null,null,($user_ref != false $user_ref null));
            }
        
ps_query("update user set login_tries=?,login_last_try=now() where username=?",array("i",$tries,"s",$username));
        }
    
    if(
$valid !== true && !isset($log_message))
        {
        if(isset(
$result['error']) && $result['error'] != '')
            {
            
$log_message strip_tags($result['error']);
            }
        else
            {
            
$log_message 'Failed Login';
            }
        
log_activity(
            
$log_message,                           # Note
            
LOG_CODE_FAILED_LOGIN_ATTEMPT,          # Log Code
            
$ip,                                    # Value New
            
($user_ref != false 'user'    null),  # Remote Table
            
($user_ref != false 'last_ip' null),  # Remote Column
            
($user_ref != false $user_ref null),  # Remote Ref
            
null,                                   # Ref Column Override
            
null,                                   # Value Old
            
($user_ref != false $user_ref null)   # User Ref
        
);
        }
    
    return 
$result;
    }

This article was last updated 14th December 2024 20:35 Europe/London time based on the source file dated 25th November 2024 11:45 Europe/London time.