public async Task <CommandHandlingResult> Handle(ValidateConfirmationCommand command, IEventPublisher publisher) { if (!await _google2FaService.ClientHasEnabledAsync(command.ClientId)) { publisher.PublishEvent(new ConfirmationValidationFailedEvent { Id = command.Id, ClientId = command.ClientId, Reason = ValidationFailReason.SecondFactorNotSetUp }); return(CommandHandlingResult.Ok()); } if (await _blacklistService.IsClientBlockedAsync(command.ClientId)) { publisher.PublishEvent(new ConfirmationValidationFailedEvent { Id = command.Id, ClientId = command.ClientId, Reason = ValidationFailReason.InvalidConfirmation }); } if (await _google2FaService.CheckCodeAsync(command.ClientId, command.Confirmation)) { await _blacklistService.ClientSucceededAsync(command.ClientId); publisher.PublishEvent(new ConfirmationValidationPassedEvent { Id = command.Id, ClientId = command.ClientId }); } else { await _blacklistService.ClientFailedAsync(command.ClientId); publisher.PublishEvent(new ConfirmationValidationFailedEvent { Id = command.Id, ClientId = command.ClientId, Reason = ValidationFailReason.InvalidConfirmation }); } return(CommandHandlingResult.Ok()); }
public async Task <IActionResult> VerifySetup([FromBody] VerifySetupGoogle2FaRequest model) { try { if (await _google2FaService.ClientHasEnabledAsync(model.ClientId)) { throw new Google2FaAlreadySetException(model.ClientId, "Cannot set up 2FA because it's already set up"); } if (!await _google2FaService.ClientHasPendingAsync(model.ClientId)) { throw new Google2FaNoSetupInProgressException(model.ClientId, "No 2FA setup is in progress"); } if (await _blacklistService.IsClientBlockedAsync(model.ClientId)) { throw new Google2FaTooManyAttemptsException(model.ClientId, "Client has exceeded maximum consecutive failed 2FA code verification attempts"); } var checkResult = await _confirmationCodesService.CheckSmsAsync(model.ClientId, model.Phone, model.SmsCode, ConfirmOperations.Google2FaSmsConfirm); if (checkResult.Status == CallLimitStatus.LimitExceed) { throw new Google2FaTooManyAttemptsException(model.ClientId, "Client has exceeded maximum consecutive failed sms verification attempts"); } if (checkResult.Status == CallLimitStatus.Allowed && checkResult.Result) { var codeIsValid = await _google2FaService.CheckCodeAsync(model.ClientId, model.GaCode, true); if (codeIsValid) { await _blacklistService.ClientSucceededAsync(model.ClientId); } else { await _blacklistService.ClientFailedAsync(model.ClientId); } if (checkResult.Result && codeIsValid) { await _google2FaService.ActivateAsync(model.ClientId); return(Ok(new VerifySetupGoogle2FaResponse { IsValid = true })); } } return(Ok(new VerifySetupGoogle2FaResponse { IsValid = false })); } catch (Exception exception) { _log.WriteError(nameof(VerifySetup), new { model.ClientId }, exception); switch (exception) { case Google2FaAlreadySetException alreadyEx: return(BadRequest(alreadyEx.Message)); case Google2FaNoSetupInProgressException inProgressEx: return(BadRequest(inProgressEx.Message)); case Google2FaTooManyAttemptsException _: return(StatusCode(403)); default: throw; } } }