示例#1
0
 /**
  * Most complex method, can check everything:-)
  * ToDo: describe after refactoring
  *
  * @param array $params
  * @throws ArgumentTypeException
  * @return bool
  */
 public static function verifyUser(array $params)
 {
     /** @global \CMain $APPLICATION */
     global $APPLICATION;
     if (!static::isOtpEnabled()) {
         // OTP disabled in settings
         return true;
     }
     $isSuccess = false;
     // ToDo: review and refactoring needed
     $otp = static::getByUser($params['USER_ID']);
     if (!$otp->isActivated()) {
         // User does not use OTP
         $isSuccess = true;
         if (static::isMandatoryUsing() && !$otp->canSkipMandatory()) {
             // Grace full period ends. We must reject authorization and defer reject reason
             if (!$otp->isDbRecordExists() && static::getSkipMandatoryDays()) {
                 // If mandatory enabled and user never use OTP - let's deffer initialization
                 $otp->defer(static::getSkipMandatoryDays());
                 // We forgive the user for the first time
                 static::setDeferredParams(null);
                 return true;
             }
             // Save a flag which indicates that a OTP is required, but user doesn't use it :-(
             $params[static::REJECTED_KEY] = static::REJECT_BY_MANDATORY;
             static::setDeferredParams($params);
             return false;
         }
     }
     if (!$isSuccess) {
         // User skip OTP on this browser by cookie
         $isSuccess = $otp->canSkipByCookie();
     }
     if (!$isSuccess) {
         $isCaptchaChecked = !$otp->isAttemptsReached() || $APPLICATION->captchaCheckCode($params['CAPTCHA_WORD'], $params['CAPTCHA_SID']);
         $isRememberNeeded = $params['OTP_REMEMBER'] && Option::get('security', 'otp_allow_remember') === 'Y';
         if (!$isCaptchaChecked && !$_SESSION['BX_LOGIN_NEED_CAPTCHA']) {
             // Backward compatibility with old login page
             $_SESSION['BX_LOGIN_NEED_CAPTCHA'] = true;
         }
         $isOtpPassword = (bool) preg_match('/^\\d{6}$/D', $params['OTP']);
         $isRecoveryCode = static::isRecoveryCodesEnabled() && (bool) preg_match(RecoveryCodesTable::CODE_PATTERN, $params['OTP']);
         if ($isCaptchaChecked && ($isOtpPassword || $isRecoveryCode)) {
             if ($isOtpPassword) {
                 $isSuccess = $otp->verify($params['OTP'], true);
             } elseif ($isRecoveryCode) {
                 $isSuccess = RecoveryCodesTable::useCode($otp->getUserId(), $params['OTP']);
             } else {
                 $isSuccess = false;
             }
             if (!$isSuccess) {
                 $otp->setAttempts($otp->getAttempts() + 1)->save();
             } else {
                 if ($otp->getAttempts() > 0) {
                     // Clear OTP input attempts
                     $otp->setAttempts(0)->save();
                 }
                 if ($isRememberNeeded && $isOtpPassword) {
                     // If user provide otp password (not recovery codes)
                     // Sets cookie for bypass OTP checking
                     $otp->setSkipCookie();
                 }
             }
         }
     }
     if ($isSuccess) {
         static::setDeferredParams(null);
     } else {
         // Save a flag which indicates that a form for OTP is required
         $params[static::REJECTED_KEY] = static::REJECT_BY_CODE;
         static::setDeferredParams($params);
     }
     return $isSuccess;
 }