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);
        }
Exemple #3
0
        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));
        }
Exemple #4
0
        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");
        }
Exemple #7
0
        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);
        }