public async Task Handle_GivenSavingFails_ExpectFailedResult() { var user = new Mock <IUser>(); 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(() => false); 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 clock = new Mock <IClock>(); var currentAuthenticatedUserProvider = new Mock <ICurrentAuthenticatedUserProvider>(); currentAuthenticatedUserProvider.Setup(x => x.CurrentAuthenticatedUser) .Returns(Maybe.From(new AuthenticatedUser(TestVariables.UserId, "email-address", "first-name", "last-name") as ISystemUser)); var commandHandler = new EnrollAuthenticatorAppCommandHandler(userRepository.Object, clock.Object, currentAuthenticatedUserProvider.Object); var key = KeyGeneration.GenerateRandomKey(); var keyAsBase32String = Base32Encoding.ToString(key); var totp = new Totp(key); var code = totp.ComputeTotp(); var cmd = new EnrollAuthenticatorAppCommand(keyAsBase32String, code); var result = await commandHandler.Handle(cmd, CancellationToken.None); Assert.True(result.IsFailure); Assert.Equal(ErrorCodes.SavingChanges, result.Error.Code); }
public async Task Handle_GivenCodeDoesVerify_ExpectSuccessfulResultAndEnrollAttempted() { var user = new Mock <IUser>(); 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 clock = new Mock <IClock>(); var currentAuthenticatedUserProvider = new Mock <ICurrentAuthenticatedUserProvider>(); currentAuthenticatedUserProvider.Setup(x => x.CurrentAuthenticatedUser) .Returns(Maybe.From(new AuthenticatedUser(TestVariables.UserId, "email-address", "first-name", "last-name") as ISystemUser)); var commandHandler = new EnrollAuthenticatorAppCommandHandler(userRepository.Object, clock.Object, currentAuthenticatedUserProvider.Object); var key = KeyGeneration.GenerateRandomKey(); var keyAsBase32String = Base32Encoding.ToString(key); var totp = new Totp(key); var code = totp.ComputeTotp(); var cmd = new EnrollAuthenticatorAppCommand(keyAsBase32String, code); var result = await commandHandler.Handle(cmd, CancellationToken.None); Assert.True(result.IsSuccess); user.Verify( x => x.EnrollAuthenticatorApp(It.IsAny <Guid>(), It.IsAny <string>(), It.IsAny <DateTime>()), Times.Once); }
private async Task<ResultWithError<ErrorData>> Process( EnrollAuthenticatorAppCommand request, CancellationToken cancellationToken) { var currentUserMaybe = this._currentAuthenticatedUserProvider.CurrentAuthenticatedUser; if (currentUserMaybe.HasValue && currentUserMaybe.Value is AuthenticatedUser currentUser) { var userMaybe = await this._userRepository.Find(currentUser.UserId, cancellationToken); if (userMaybe.HasNoValue) { return ResultWithError.Fail(new ErrorData(ErrorCodes.UserNotFound)); } var user = userMaybe.Value; if (user.AuthenticatorApps.Any(x => x.WhenRevoked == null)) { return ResultWithError.Fail(new ErrorData(ErrorCodes.AuthenticatorAppAlreadyEnrolled)); } var secretBytes = Base32Encoding.ToBytes(request.Key); var topt = new Totp(secretBytes); var isVerified = topt.VerifyTotp(request.Code, out _); if (!isVerified) { return ResultWithError.Fail(new ErrorData(ErrorCodes.FailedVerifyingAuthenticatorCode)); } user.EnrollAuthenticatorApp(Guid.NewGuid(), request.Key, this._clock.GetCurrentInstant().ToDateTimeUtc()); return ResultWithError.Ok<ErrorData>(); } return ResultWithError.Fail(new ErrorData(ErrorCodes.UserNotFound)); }
public void Constructor_GiveValidArguments_PropertiesAreSet() { var command = new EnrollAuthenticatorAppCommand("key", "code"); Assert.Equal("code", command.Code); Assert.Equal("key", command.Key); }
public void Validate_GivenAllPropertiesAreValid_ExpectValidationSuccess() { var cmd = new EnrollAuthenticatorAppCommand("key", "code"); var validator = new EnrollAuthenticatorAppCommandValidator(); var result = validator.Validate(cmd); Assert.True(result.IsValid); }
public void Validate_GivenKeyIsNull_ExpectValidationFailure() { var cmd = new EnrollAuthenticatorAppCommand(null, "code"); var validator = new EnrollAuthenticatorAppCommandValidator(); var result = validator.Validate(cmd); Assert.False(result.IsValid); Assert.Contains( result.Errors, failure => failure.ErrorCode.Equals(ValidationCodes.FieldIsRequired) && failure.PropertyName == "Key"); }
public async Task<ResultWithError<ErrorData>> Handle( EnrollAuthenticatorAppCommand request, CancellationToken cancellationToken) { var result = await this.Process(request, cancellationToken); var dbResult = await this._userRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken); if (!dbResult) { return ResultWithError.Fail(new ErrorData( ErrorCodes.SavingChanges, "Failed To Save Database")); } return result; }
public async Task Handle_GivenNoUserAppearsToBeAuthenticate_ExpectFailedResultAndNoEnrollAttempted() { var user = new Mock <IUser>(); 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 clock = new Mock <IClock>(); var currentAuthenticatedUserProvider = new Mock <ICurrentAuthenticatedUserProvider>(); currentAuthenticatedUserProvider.Setup(x => x.CurrentAuthenticatedUser) .Returns(Maybe <ISystemUser> .Nothing); var commandHandler = new EnrollAuthenticatorAppCommandHandler(userRepository.Object, clock.Object, currentAuthenticatedUserProvider.Object); var key = KeyGeneration.GenerateRandomKey(); var keyAsBase32String = Base32Encoding.ToString(key); var totp = new Totp(key); var code = totp.ComputeTotp(); var cmd = new EnrollAuthenticatorAppCommand(keyAsBase32String, code); var result = await commandHandler.Handle(cmd, CancellationToken.None); Assert.True(result.IsFailure); Assert.Equal(ErrorCodes.UserNotFound, result.Error.Code); user.Verify( x => x.EnrollAuthenticatorApp(It.IsAny <Guid>(), It.IsAny <string>(), It.IsAny <DateTime>()), Times.Never); }