public async Task <FailedSigninResultModel> RegisterFailedSigninAsync(string email) { if (string.IsNullOrEmpty(email)) { throw new ArgumentNullException(nameof(email)); } var(customerIdentity, sanitizedIdentity) = await GetCustomerIdentityAsync(email); if (await _locksService.DoesLockExistAsync(customerIdentity)) { _log.Warning($"The signin for [{sanitizedIdentity}] is already locked"); return(FailedSigninResultModel.SigninLocked((int)_config.AccountLockPeriod.TotalMinutes)); } var counter = await _expiringCountersService.IncrementCounterAsync(_config.ThresholdPeriod, nameof(SigninThrottlingService), customerIdentity); if (counter >= _config.LockThreshold) { var signinLocked = await _locksService.TryAcquireLockAsync( new { customerIdentity }.ToJson(), DateTime.UtcNow.Add(_config.AccountLockPeriod), customerIdentity); if (!signinLocked) { _log.Error(message: $"Couldn't lock signin for [{sanitizedIdentity}]"); throw new InvalidOperationException("Signin lock was unsuccessful"); } _log.Warning($"The account [{sanitizedIdentity}] has been locked for signin attempts for {_config.AccountLockPeriod}"); return(FailedSigninResultModel.SigninLocked((int)_config.AccountLockPeriod.TotalMinutes)); } var attemptsLeftBeforeLock = _config.LockThreshold - (int)counter; return(counter >= _config.WarningThreshold ? FailedSigninResultModel.Warning(attemptsLeftBeforeLock) : FailedSigninResultModel.NoImpact(attemptsLeftBeforeLock)); }