- Модуль: main
- Путь к файлу: ~/bitrix/modules/main/classes/general/user.php
- Класс: CAllUser
- Вызов: CAllUser::LoginInternal
static function LoginInternal(&$arParams, &$result_message = true, $context = null)
{
global $DB, $APPLICATION;
$user_id = 0;
$message = GetMessage("WRONG_LOGIN");
$errorType = "LOGIN";
$strSql =
"SELECT U.ID, U.LOGIN, U.ACTIVE, U.BLOCKED, U.PASSWORD, U.PASSWORD_EXPIRED, U.LOGIN_ATTEMPTS, U.CONFIRM_CODE, U.EMAIL " .
"FROM b_user U " .
"WHERE U.LOGIN='" . $DB->ForSQL($arParams["LOGIN"]) . "' ";
if (isset($arParams["EXTERNAL_AUTH_ID"]) && $arParams["EXTERNAL_AUTH_ID"] != '')
{
//external user
$strSql .= " AND EXTERNAL_AUTH_ID='" . $DB->ForSql($arParams["EXTERNAL_AUTH_ID"]) . "'";
}
else
{
//internal user (by default)
$strSql .= " AND (EXTERNAL_AUTH_ID IS NULL OR EXTERNAL_AUTH_ID='') ";
}
$result = $DB->Query($strSql);
if (($arUser = $result->Fetch()))
{
$passwordCorrect = false;
$policy = null;
$applicationId = null;
$original = isset($arParams["PASSWORD_ORIGINAL"]) && $arParams["PASSWORD_ORIGINAL"] === 'Y';
$loginAttempts = intval($arUser["LOGIN_ATTEMPTS"]) + 1;
if ($arUser["BLOCKED"] != 'Y')
{
$policy = static::getPolicy($arUser["ID"]);
//show captcha after a serial of incorrect login attempts
$correctCaptcha = true;
$policyLoginAttempts = (int)$policy->getLoginAttempts();
if ($policyLoginAttempts > 0 && $loginAttempts > $policyLoginAttempts)
{
$APPLICATION->SetNeedCAPTHA(true);
if (!$APPLICATION->CaptchaCheckCode($_REQUEST["captcha_word"] ?? '', $_REQUEST["captcha_sid"] ?? ''))
{
$correctCaptcha = false;
}
}
if ($correctCaptcha)
{
$passwordCorrect = Password::equals($arUser["PASSWORD"], $arParams["PASSWORD"], $original);
if (!$passwordCorrect)
{
if (isset($arParams["OTP"]) && $arParams["OTP"] != '' && $original)
{
// maybe we have OTP added to the password
$passwordWithoutOtp = mb_substr($arParams["PASSWORD"], 0, -6);
$passwordCorrect = Password::equals($arUser["PASSWORD"], $passwordWithoutOtp);
}
}
else
{
//this password has no added otp for sure
$arParams["OTP"] = '';
}
if (!$passwordCorrect)
{
//let's try to find application password
if (($appPassword = ApplicationPasswordTable::findPassword($arUser["ID"], $arParams["PASSWORD"], $original)) !== false)
{
$passwordCorrect = true;
$applicationId = $appPassword["APPLICATION_ID"];
if ($context instanceof AuthenticationContext)
{
$context
->setApplicationId($applicationId)
->setApplicationPasswordId($appPassword["ID"])
;
}
}
}
}
if (!$passwordCorrect)
{
//block the user after numerous incorrect login attempts
$policyBlockAttempts = (int)$policy->getBlockLoginAttempts();
$policyBlockTime = (int)$policy->getBlockTime();
if ($policyBlockAttempts > 0 && $policyBlockTime > 0 && $loginAttempts >= $policyBlockAttempts)
{
if ($arUser["ACTIVE"] == 'Y')
{
static::blockUser($arUser["ID"], $policyBlockTime, $loginAttempts);
}
}
}
}
if ($passwordCorrect)
{
//applied only to "human" passwords
if ($applicationId === null)
{
//only for original passwords
if ($original)
{
//update the old password hash to the new one with a salt
if (Password::needRehash($arUser["PASSWORD"]))
{
$newPassword = Password::hash($arParams["PASSWORD"]);
$DB->Query("UPDATE b_user SET PASSWORD='" . $DB->ForSQL($newPassword) . "', TIMESTAMP_X = TIMESTAMP_X WHERE ID = " . intval($arUser["ID"]));
}
//update digest hash for http digest authorization
if (Option::get('main', 'use_digest_auth', 'N') == 'Y')
{
static::UpdateDigest($arUser["ID"], $arParams["PASSWORD"]);
}
}
$passwordExpired = false;
if ($arUser['PASSWORD_EXPIRED'] == 'Y')
{
//require to change the password right now
$passwordExpired = true;
}
if (!$passwordExpired && $original && $policy->getPasswordCheckPolicy())
{
$passwordErrors = static::CheckPasswordAgainstPolicy($arParams["PASSWORD"], $policy->getValues());
if (!empty($passwordErrors))
{
//require to change the password because it doesn't match the group policy
$passwordExpired = true;
}
}
if (!$passwordExpired)
{
$policyChangeDays = (int)$policy->getPasswordChangeDays();
if ($policyChangeDays > 0)
{
//require to change the password after N days
if (UserPasswordTable::passwordExpired($arUser["ID"], $policyChangeDays))
{
$passwordExpired = true;
}
}
}
if ($passwordExpired)
{
$passwordCorrect = false;
$message = GetMessage("MAIN_LOGIN_CHANGE_PASSWORD");
$errorType = "CHANGE_PASSWORD";
}
}
if ($passwordCorrect)
{
if ($arUser["ACTIVE"] == 'Y')
{
//success
$user_id = $arUser["ID"];
}
else
{
//something wrong with the inactive user
if ($arUser["CONFIRM_CODE"] != '')
{
//unconfirmed email registration
$message = GetMessage("MAIN_LOGIN_EMAIL_CONFIRM", ["#EMAIL#" => $arUser["EMAIL"]]);
}
else
{
//user deactivated
$message = GetMessage("LOGIN_BLOCK");
//or possibly unconfirmed phone registration
if (Option::get('main', 'new_user_phone_auth', 'N') == 'Y')
{
$row = MainUserPhoneAuthTable::getRowById($arUser["ID"]);
if ($row && $row["CONFIRMED"] == 'N')
{
$message = GetMessage("main_login_need_phone_confirmation", ["#PHONE#" => $row["PHONE_NUMBER"]]);
}
}
}
}
}
}
else
{
//incorrect password
$DB->Query("UPDATE b_user SET LOGIN_ATTEMPTS = " . $loginAttempts . ", TIMESTAMP_X = TIMESTAMP_X WHERE ID = " . intval($arUser["ID"]));
}
}
if ($user_id == 0)
{
$APPLICATION->ThrowException($message);
$result_message = ["MESSAGE" => $message . "
", "TYPE" => "ERROR", "ERROR_TYPE" => $errorType];
}
return $user_id;
}