private async Task <Result <ValidateAppMfaCodeAgainstCurrentUserCommandResult, ErrorData> > Process( ValidateAppMfaCodeAgainstCurrentUserCommand request, CancellationToken cancellationToken) { var currentUserMaybe = this._currentAuthenticatedUserProvider.CurrentAuthenticatedUser; if (currentUserMaybe.HasNoValue) { return(Result.Fail <ValidateAppMfaCodeAgainstCurrentUserCommandResult, ErrorData>(new ErrorData(ErrorCodes.UserNotFound))); } var userMaybe = await this._userRepository.Find(currentUserMaybe.Value.UserId, cancellationToken); if (userMaybe.HasNoValue) { return(Result.Fail <ValidateAppMfaCodeAgainstCurrentUserCommandResult, ErrorData>(new ErrorData(ErrorCodes.UserNotFound))); } var user = userMaybe.Value; var authApp = user.AuthenticatorApps.SingleOrDefault(x => x.WhenRevoked == null); if (authApp == null) { return(Result.Fail <ValidateAppMfaCodeAgainstCurrentUserCommandResult, ErrorData>(new ErrorData(ErrorCodes.NoAuthenticatorAppEnrolled))); } var secretBytes = Base32Encoding.ToBytes(authApp.Key); var topt = new Totp(secretBytes); var isVerified = topt.VerifyTotp(request.Code, out _); return(isVerified ? Result.Ok <ValidateAppMfaCodeAgainstCurrentUserCommandResult, ErrorData>(new ValidateAppMfaCodeAgainstCurrentUserCommandResult(user.Id)) : Result.Fail <ValidateAppMfaCodeAgainstCurrentUserCommandResult, ErrorData>(new ErrorData(ErrorCodes.MfaCodeNotValid))); }
public async Task Handle_GivenSavingSucceeds_ExpectSuccessfulResult() { var user = new Mock <IUser>(); user.Setup(x => x.Profile).Returns(new Profile(TestVariables.UserId, "first-name", "last-name")); user.Setup(x => x.AuthenticatorApps).Returns(new List <AuthenticatorApp> { new AuthenticatorApp(Guid.NewGuid(), "key", DateTime.UtcNow), }); var userRepository = new Mock <IUserRepository>(); var unitOfWork = new Mock <IUnitOfWork>(); unitOfWork.Setup(x => x.SaveEntitiesAsync(It.IsAny <CancellationToken>())).ReturnsAsync(() => true); userRepository.Setup(x => x.UnitOfWork).Returns(unitOfWork.Object); userRepository.Setup(x => x.Find(It.IsAny <Guid>(), It.IsAny <CancellationToken>())) .ReturnsAsync(() => Maybe.From(user.Object)); var currentAuthenticatedUserProvider = new Mock <ICurrentAuthenticatedUserProvider>(); currentAuthenticatedUserProvider.Setup(x => x.CurrentAuthenticatedUser) .Returns(Maybe.From(new UnauthenticatedUser(TestVariables.UserId, MfaProvider.None) as ISystemUser)); var handler = new ValidateAppMfaCodeAgainstCurrentUserCommandHandler( userRepository.Object, currentAuthenticatedUserProvider.Object); var totp = new Totp(Base32Encoding.ToBytes("key")); var code = totp.ComputeTotp(); var cmd = new ValidateAppMfaCodeAgainstCurrentUserCommand(code); var result = await handler.Handle(cmd, CancellationToken.None); Assert.True(result.IsSuccess); }
public async Task Handle_GiveUserDoesExistButHasNoAuthApp_ExpectFailedResult() { var user = new Mock <IUser>(); var userId = Guid.NewGuid(); user.Setup(x => x.Id).Returns(userId); user.Setup(x => x.AuthenticatorApps).Returns(new List <AuthenticatorApp>()); var userRepository = new Mock <IUserRepository>(); var unitOfWork = new Mock <IUnitOfWork>(); unitOfWork.Setup(x => x.SaveEntitiesAsync(It.IsAny <CancellationToken>())).ReturnsAsync(() => true); userRepository.Setup(x => x.UnitOfWork).Returns(unitOfWork.Object); userRepository.Setup(x => x.Find(It.IsAny <Guid>(), It.IsAny <CancellationToken>())) .ReturnsAsync(() => Maybe.From(user.Object)); var currentAuthenticatedUserProvider = new Mock <ICurrentAuthenticatedUserProvider>(); currentAuthenticatedUserProvider.Setup(x => x.CurrentAuthenticatedUser) .Returns(Maybe.From(new UnauthenticatedUser(TestVariables.UserId, MfaProvider.None) as ISystemUser)); var handler = new ValidateAppMfaCodeAgainstCurrentUserCommandHandler( userRepository.Object, currentAuthenticatedUserProvider.Object); var totp = new Totp(Base32Encoding.ToBytes("key")); var code = totp.ComputeTotp(); var cmd = new ValidateAppMfaCodeAgainstCurrentUserCommand(code); var result = await handler.Handle(cmd, CancellationToken.None); Assert.True(result.IsFailure); Assert.Equal(ErrorCodes.NoAuthenticatorAppEnrolled, result.Error.Code); }
public async Task Handle_GivenResponseIsResultAndIsSuccessful_ExpectInformationLogged() { var auditLogger = new Mock <ILogger>(); var authenticatedUserProvider = new Mock <ICurrentAuthenticatedUserProvider>(); authenticatedUserProvider.Setup(x => x.CurrentAuthenticatedUser).Returns( Maybe.From <ISystemUser>(new UnauthenticatedUser(TestVariables.UserId, MfaProvider.None))); var request = new ValidateAppMfaCodeAgainstCurrentUserCommand("code"); var auditBehavior = new AuditBehavior <ValidateAppMfaCodeAgainstCurrentUserCommand, Result <ValidateAppMfaCodeAgainstCurrentUserCommandResult, ErrorData> >( auditLogger.Object, authenticatedUserProvider.Object); var requestHandlerDelegate = new Mock <RequestHandlerDelegate <Result <ValidateAppMfaCodeAgainstCurrentUserCommandResult, ErrorData> > >(); requestHandlerDelegate.Setup(x => x()) .ReturnsAsync(Result.Ok <ValidateAppMfaCodeAgainstCurrentUserCommandResult, ErrorData>( new ValidateAppMfaCodeAgainstCurrentUserCommandResult(TestVariables.UserId))); await auditBehavior.Handle(request, CancellationToken.None, requestHandlerDelegate.Object); auditLogger.Verify(x => x.Information(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <ValidateAppMfaCodeAgainstCurrentUserCommand>(), It.Is <string>(x => x == TestVariables.UserId.ToString()))); }
public void Validate_GivenAllPropertiesAreValid_ExpectValidationSuccess() { var cmd = new ValidateAppMfaCodeAgainstCurrentUserCommand("code"); var validator = new ValidateAppMfaCodeAgainstCurrentUserCommandValidator(); var result = validator.Validate(cmd); Assert.True(result.IsValid); }
public void Validate_GivenCodeIsEmpty_ExpectValidationFailure() { var cmd = new ValidateAppMfaCodeAgainstCurrentUserCommand(string.Empty); var validator = new ValidateAppMfaCodeAgainstCurrentUserCommandValidator(); var result = validator.Validate(cmd); Assert.False(result.IsValid); Assert.Contains( result.Errors, failure => failure.ErrorCode.Equals(ValidationCodes.FieldIsRequired) && failure.PropertyName == "Code"); }
public async Task <Result <ValidateAppMfaCodeAgainstCurrentUserCommandResult, ErrorData> > Handle( ValidateAppMfaCodeAgainstCurrentUserCommand request, CancellationToken cancellationToken) { var result = await this.Process(request, cancellationToken); var dbResult = await this._userRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken); if (!dbResult) { return(Result.Fail <ValidateAppMfaCodeAgainstCurrentUserCommandResult, ErrorData>(new ErrorData( ErrorCodes.SavingChanges, "Failed To Save Database"))); } return(result); }
public async Task Handle_GivenNoUserAppearsToBeAuthenticate_ExpectFailedResult() { var userRepository = new Mock <IUserRepository>(); var unitOfWork = new Mock <IUnitOfWork>(); unitOfWork.Setup(x => x.SaveEntitiesAsync(It.IsAny <CancellationToken>())).ReturnsAsync(() => true); userRepository.Setup(x => x.UnitOfWork).Returns(unitOfWork.Object); var currentAuthenticatedUserProvider = new Mock <ICurrentAuthenticatedUserProvider>(); currentAuthenticatedUserProvider.Setup(x => x.CurrentAuthenticatedUser) .Returns(Maybe <ISystemUser> .Nothing); var handler = new ValidateAppMfaCodeAgainstCurrentUserCommandHandler( userRepository.Object, currentAuthenticatedUserProvider.Object); var cmd = new ValidateAppMfaCodeAgainstCurrentUserCommand("code"); var result = await handler.Handle(cmd, CancellationToken.None); Assert.True(result.IsFailure); Assert.Equal(ErrorCodes.UserNotFound, result.Error.Code); }
public void Constructor_GiveValidArguments_PropertiesAreSet() { var command = new ValidateAppMfaCodeAgainstCurrentUserCommand("code"); Assert.Equal("code", command.Code); }