Collections functions
General functions
Node functions
Render functions
Theme permission functions
User functions
Resource 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 the MD5 hash of the username and the secret scramble key, then allow a login 
    // using the MD5 password hash as the password. This is for the 'log in as this user' feature.
    
$impersonate_user = (getval('userkey''') === md5($username $scramble_key));

    
// 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);
        }

    
// User logs in
    
if($found_user_record && rs_password_verify($password$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;
        }
    
// An admin logs in as this user
    
elseif(
        
$found_user_record
        
&& $impersonate_user
        
&& rs_password_verify($password$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""");
        
ps_query("
            UPDATE user
               SET session=?,
                   last_active = NOW(),
                   login_tries = 0,
                   lang = ?
             WHERE ref = ?
        "
, array("s",$session_hash,"s",$language,"i",$userref));

        
// 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 19th March 2024 02:05 Europe/London time based on the source file dated 20th February 2024 17:10 Europe/London time.