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());
        }
Пример #2
0
        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;
                }
            }
        }