private async Task <ResultWithError <ErrorData> > Process(
            ResetPasswordCommand request, CancellationToken cancellationToken)
        {
            var whenHappened = this._clock.GetCurrentInstant().ToDateTimeUtc();
            var userMaybe    =
                await this._userRepository.FindByUserBySecurityToken(request.Token, whenHappened, cancellationToken);

            if (userMaybe.HasNoValue)
            {
                return(ResultWithError.Fail(new ErrorData(ErrorCodes.UserNotFound)));
            }

            if (!this._passwordValidator.IsValid(request.NewPassword))
            {
                return(ResultWithError.Fail(new ErrorData(ErrorCodes.PasswordTooWeak, "Password is to weak")));
            }

            var user = userMaybe.Value;

            if (this._identitySettings.ValidatePasswordAgainstHistory && user.IsPasswordInHistory(
                    this._identitySettings.PreviousPasswordCheck,
                    s => this._passwordHasher.ValidatePassword(request.NewPassword, s)))
            {
                return(ResultWithError.Fail(new ErrorData(ErrorCodes.PasswordInHistory)));
            }

            user.ChangePasswordAndAddToHistory(
                this._passwordHasher.HashPassword(request.NewPassword),
                whenHappened);
            user.CompleteTokenLifecycle(request.Token, whenHappened);
            this._userRepository.Update(user);
            return(ResultWithError.Ok <ErrorData>());
        }
Example #2
0
        public void From_if_predicate_is_true_returns_ok_ResultWithError()
        {
            var error  = "error";
            var result = ResultWithError.From(() => true, error);

            result.IsSuccess.ShouldBeTrue();
        }
        private async Task <ResultWithError <ErrorData> > Process(GenerateRemoteMultiFactorAuthCodeCommand request, CancellationToken cancellationToken)
        {
            var currentUserMaybe = this._currentUserService.CurrentUser;

            if (currentUserMaybe.HasNoValue)
            {
                return(ResultWithError.Fail(new ErrorData(ErrorCodes.UserNotFound)));
            }

            var userMaybe =
                await this._userRepository.Find(this._currentUserService.CurrentUser.Value.UserId, cancellationToken);

            if (userMaybe.HasNoValue)
            {
                return(ResultWithError.Fail(new ErrorData(ErrorCodes.UserNotFound)));
            }

            var user = userMaybe.Value;
            var totp = new Totp(user.SecurityStamp.ToByteArray());

            var generated = totp.ComputeTotp();

            user.AddDomainEvent(new MfaTokenGeneratedEvent(
                                    request.TwoFactorProvider,
                                    user.Id,
                                    generated));

            return(ResultWithError.Ok <ErrorData>());
        }
        private async Task <ResultWithError <ErrorData> > Process(
            RevokeAuthenticatorDeviceCommand request, CancellationToken cancellationToken)
        {
            var currentUser = this._currentAuthenticatedUserProvider.CurrentAuthenticatedUser;

            if (currentUser.HasNoValue)
            {
                return(ResultWithError.Fail(new ErrorData(ErrorCodes.UserNotFound)));
            }

            var userMaybe = await this._userRepository.Find(currentUser.Value.UserId, cancellationToken);

            if (userMaybe.HasNoValue)
            {
                return(ResultWithError.Fail(new ErrorData(ErrorCodes.UserNotFound)));
            }

            var user = userMaybe.Value;

            if (!BCrypt.Net.BCrypt.Verify(request.Password, user.PasswordHash))
            {
                return(ResultWithError.Fail(new ErrorData(ErrorCodes.PasswordNotCorrect)));
            }

            if (user.AuthenticatorDevices.All(x => x.Id != request.DeviceId))
            {
                return(ResultWithError.Fail(new ErrorData(ErrorCodes.DeviceNotFound)));
            }

            user.RevokeAuthenticatorDevice(request.DeviceId, this._clock.GetCurrentInstant().ToDateTimeUtc());
            this._userRepository.Update(user);
            return(ResultWithError.Ok <ErrorData>());
        }
Example #5
0
        private async Task <ResultWithError <ErrorData> > Process(
            VerifyAccountAndSetPasswordCommand request, CancellationToken cancellationToken)
        {
            var whenHappened   = this._clock.GetCurrentInstant().ToDateTimeUtc();
            var convertedToken = new Guid(Convert.FromBase64String(request.Token));
            var userResult     =
                await this._userRepository.FindByUserBySecurityToken(convertedToken, whenHappened, cancellationToken);

            if (userResult.HasNoValue)
            {
                return(ResultWithError.Fail(new ErrorData(ErrorCodes.UserNotFound)));
            }

            var user = userResult.Value;

            if (user.IsVerified)
            {
                return(ResultWithError.Fail(new ErrorData(ErrorCodes.UserIsAlreadyVerified)));
            }

            user.VerifyAccount(whenHappened);

            user.ChangePassword(BCrypt.Net.BCrypt.HashPassword(request.NewPassword), whenHappened);

            user.CompleteTokenLifecycle(convertedToken, whenHappened);
            this._userRepository.Update(user);
            return(ResultWithError.Ok <ErrorData>());
        }
Example #6
0
        private async Task <ResultWithError <ErrorData> > Process(CancellationToken cancellationToken)
        {
            var currentUserMaybe = this._currentAuthenticatedUserProvider.CurrentAuthenticatedUser;

            if (currentUserMaybe.HasNoValue)
            {
                return(ResultWithError.Fail(new ErrorData(ErrorCodes.UserNotFound)));
            }

            var userMaybe = await this._userRepository.Find(currentUserMaybe.Value.UserId, cancellationToken);

            if (userMaybe.HasNoValue)
            {
                return(ResultWithError.Fail(new ErrorData(ErrorCodes.UserNotFound)));
            }

            var user = userMaybe.Value;

            var totp = new Totp(user.SecurityStamp.ToByteArray());

            var token = totp.ComputeTotp();

            user.AddDomainEvent(new EmailMfaTokenGeneratedEvent(
                                    user.EmailAddress,
                                    user.Profile.FirstName,
                                    user.Profile.LastName,
                                    token));

            user.ProcessPartialSuccessfulAuthenticationAttempt(
                this._clock.GetCurrentInstant().ToDateTimeUtc(),
                AuthenticationHistoryType.EmailMfaRequested);

            return(ResultWithError.Ok <ErrorData>());
        }
        public async Task Handle_GivenResponseIsResultWithErrorAndIsNotSuccessful_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 UnlockAccountCommand(TestVariables.UserId);

            var auditBehavior =
                new AuditBehavior <UnlockAccountCommand,
                                   ResultWithError <ErrorData> >(
                    auditLogger.Object, authenticatedUserProvider.Object);

            var requestHandlerDelegate =
                new Mock <RequestHandlerDelegate <ResultWithError <ErrorData> > >();

            requestHandlerDelegate.Setup(x => x())
            .ReturnsAsync(ResultWithError.Fail(
                              new ErrorData(ErrorCodes.SavingChanges)));

            await auditBehavior.Handle(request, CancellationToken.None, requestHandlerDelegate.Object);

            auditLogger.Verify(x => x.Error(It.IsAny <string>(), It.IsAny <string>(),
                                            It.IsAny <UnlockAccountCommand>(),
                                            It.Is <string>(x => x == TestVariables.UserId.ToString())));
        }
        public void Equals_betwwen_ResultWithError_and_null_is_false()
        {
            var result  = ResultWithError.Fail("abc");
            var isEqual = result.Equals(null);

            isEqual.ShouldBeFalse();
        }
Example #9
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));
        }
        private async Task <ResultWithError <ErrorData> > Process(
            UpdateUserCoreDetailsCommand request, CancellationToken cancellationToken)
        {
            var userMaybe = await this._userRepository.Find(request.UserId, cancellationToken);

            if (userMaybe.HasNoValue)
            {
                return(ResultWithError.Fail(new ErrorData(ErrorCodes.UserNotFound)));
            }

            var user = userMaybe.Value;

            if (!string.Equals(request.EmailAddress, user.EmailAddress, StringComparison.InvariantCultureIgnoreCase))
            {
                var statusCheck =
                    await this._userQueries.CheckForPresenceOfUserByEmailAddress(request.EmailAddress);

                if (statusCheck.IsPresent)
                {
                    return(ResultWithError.Fail(new ErrorData(ErrorCodes.UserAlreadyExists)));
                }
            }

            user.UpdateSystemAccessDetails(request.EmailAddress, request.IsLockable);
            user.UpdateProfile(request.FirstName, request.LastName);
            user.SetAdminStatus(request.IsAdmin);
            user.SetRoles(request.Roles);

            this._userRepository.Update(user);
            return(ResultWithError.Ok <ErrorData>());
        }
Example #11
0
        public void GetHasCode_between_two_ok_ResultWithError_of_different_types_is_not_equal()
        {
            var result1 = ResultWithError.Ok <int>();
            var result2 = ResultWithError.Ok <string>();

            result1.GetHashCode().ShouldNotBe(result2.GetHashCode());
        }
        private async Task <ResultWithError <ErrorData> > Process(PasswordResetCommand request, CancellationToken cancellationToken)
        {
            var whenHappened   = this._clock.GetCurrentInstant().ToDateTimeUtc();
            var convertedToken = new Guid(Convert.FromBase64String(request.Token));
            var userMaybe      =
                await this._userRepository.FindByUserBySecurityToken(convertedToken, whenHappened, cancellationToken);

            if (userMaybe.HasNoValue)
            {
                return(ResultWithError.Fail(new ErrorData(ErrorCodes.UserNotFound)));
            }

            var user = userMaybe.Value;

            if (user.PasswordHistories.OrderByDescending(x => x.WhenUsed).Take(this._securitySettings.HistoricalLimit)
                .Any(x => BCrypt.Net.BCrypt.Verify(request.NewPassword, x.Hash)))
            {
                return(ResultWithError.Fail(new ErrorData(
                                                ErrorCodes.PasswordInHistory)));
            }

            user.ChangePassword(BCrypt.Net.BCrypt.HashPassword(request.NewPassword), whenHappened);
            user.CompleteTokenLifecycle(convertedToken, whenHappened);
            user.AddDomainEvent(new PasswordChangedEvent(user.EmailAddress, user.Profile.FirstName, user.Profile.LastName));

            this._userRepository.Update(user);
            return(ResultWithError.Ok <ErrorData>());
        }
Example #13
0
        private async Task <ResultWithError <ErrorData> > Process(
            RequestAccountVerificationCommand request,
            CancellationToken cancellationToken)
        {
            var userMaybe = await this._userRepository.FindByEmailAddress(request.EmailAddress, cancellationToken);

            if (userMaybe.HasNoValue)
            {
                return(ResultWithError.Fail(new ErrorData(ErrorCodes.UserNotFound)));
            }

            var user = userMaybe.Value;

            if (user.IsVerified)
            {
                return(ResultWithError.Fail(new ErrorData(
                                                ErrorCodes.UserIsAlreadyVerified)));
            }

            var token = user.GenerateNewAccountConfirmationToken(
                this._clock.GetCurrentInstant().ToDateTimeUtc(),
                TimeSpan.FromHours(this._securitySettings.AccountVerificationTokenLifetime));

            user.AddDomainEvent(new AccountConfirmationTokenGeneratedEvent(user.EmailAddress, user.Profile.FirstName, user.Profile.LastName, token));

            this._userRepository.Update(user);
            return(ResultWithError.Ok <ErrorData>());
        }
Example #14
0
        private async Task <ResultWithError <ErrorData> > Process(
            VerifyAccountAndSetPasswordCommand request, CancellationToken cancellationToken)
        {
            var whenHappened = this._clock.GetCurrentInstant().ToDateTimeUtc();
            var userResult   =
                await this._userRepository.FindByUserBySecurityToken(request.Token, whenHappened, cancellationToken);

            if (userResult.HasNoValue)
            {
                return(ResultWithError.Fail(new ErrorData(ErrorCodes.UserNotFound)));
            }

            var user = userResult.Value;

            if (user.IsVerified)
            {
                return(ResultWithError.Fail(new ErrorData(ErrorCodes.UserIsAlreadyVerified)));
            }

            if (!this._passwordValidator.IsValid(request.Password))
            {
                return(ResultWithError.Fail(new ErrorData(ErrorCodes.PasswordTooWeak)));
            }

            user.VerifyAccount(whenHappened);

            user.ChangePasswordAndAddToHistory(this._passwordHasher.HashPassword(request.Password), whenHappened);

            user.CompleteTokenLifecycle(request.Token, whenHappened);
            this._userRepository.Update(user);
            return(ResultWithError.Ok <ErrorData>());
        }
Example #15
0
        public void GetHasCode_between_ok_ResultWithError_and_fail_ResultWithError_is_not_equal()
        {
            var result1 = ResultWithError.Ok <string>();
            var result2 = ResultWithError.Fail("abc");

            result1.GetHashCode().ShouldNotBe(result2.GetHashCode());
        }
Example #16
0
        public void GetHasCode_between_two_ok_ResultWithError_of_same_type_is_equal()
        {
            var result1 = ResultWithError.Ok <string>();
            var result2 = ResultWithError.Ok <string>();

            result1.GetHashCode().ShouldBe(result2.GetHashCode());
        }
Example #17
0
        private async Task <ResultWithError <ErrorData> > Process(ValidateAuthenticatorAppCommand request, CancellationToken cancellationToken)
        {
            var userMaybe = await this._userRepository.Find(this._currentUserService.CurrentUser.Value.UserId, cancellationToken);

            if (userMaybe.HasNoValue)
            {
                return(ResultWithError.Fail(new ErrorData(ErrorCodes.UserNotFound)));
            }

            var user = userMaybe.Value;

            var authApp = user.AuthenticatorApps.SingleOrDefault(x => x.WhenRevoked == null);

            if (authApp == null)
            {
                return(ResultWithError.Fail(new ErrorData(ErrorCodes.AuthenticatorAppAlreadyEnrolled)));
            }

            var secretBytes = Base32Encoding.ToBytes(authApp.Key);
            var topt        = new Totp(secretBytes);
            var isVerified  = topt.VerifyTotp(request.Token, out _);

            return(isVerified
                ? ResultWithError.Ok <ErrorData>()
                : ResultWithError.Fail(new ErrorData(ErrorCodes.FailedVerifyingAuthenticatorCode)));
        }
Example #18
0
        public void GetHasCode_between_two_fail_ResultWithError_is_not_equal_if_both_errors_are_not_equal()
        {
            var result1 = ResultWithError.Fail("abc");
            var result2 = ResultWithError.Fail("zzz");

            result1.GetHashCode().ShouldNotBe(result2.GetHashCode());
        }
        private async Task <ResultWithError <ErrorData> > Process(
            CreateUserCommand request, CancellationToken cancellationToken)
        {
            var whenHappened = this._clock.GetCurrentInstant().ToDateTimeUtc();

            var statusCheck = await this._userQueries.CheckForPresenceOfUserByEmailAddress(
                request.EmailAddress, cancellationToken);

            if (statusCheck.IsPresent)
            {
                return(ResultWithError.Fail(new ErrorData(ErrorCodes.UserIsAlreadyExists)));
            }



            var user = new User(Guid.NewGuid(), request.EmailAddress,
                                this._passwordHasher.HashPassword(this._passwordGenerator.Generate()), request.IsLockable, request.IsAdmin,
                                this._clock.GetCurrentInstant().ToDateTimeUtc());

            user.SetRoles(request.Roles);

            user.GenerateNewAccountConfirmationToken(
                whenHappened, whenHappened.AddHours(this._identitySettings.ConfirmationTokenLifetime));
            this._userRepository.Add(user);
            return(ResultWithError.Ok <ErrorData>());
        }
Example #20
0
        private async Task <ResultWithError <ErrorData> > Process(
            RequestAccountVerificationCommand request, CancellationToken cancellationToken)
        {
            var whenHappened = this._clock.GetCurrentInstant().ToDateTimeUtc();

            var userMaybe = await this._userRepository.FindByEmailAddress(request.EmailAddress, cancellationToken);


            if (userMaybe.HasNoValue)
            {
                return(ResultWithError.Fail(new ErrorData(ErrorCodes.UserNotFound)));
            }

            var user = userMaybe.Value;

            if (user.IsVerified)
            {
                return(ResultWithError.Fail(new ErrorData(
                                                ErrorCodes.UserIsAlreadyVerified)));
            }

            var token = user.GenerateNewAccountConfirmationToken(
                whenHappened,
                whenHappened.AddHours(this._identitySettings.ConfirmationTokenLifetime));

            this._userRepository.Update(user);
            return(ResultWithError.Ok <ErrorData>());
        }
Example #21
0
        private async Task <ResultWithError <ErrorData> > Process(UpdateRoleCommand request, CancellationToken cancellationToken)
        {
            var presenceResult = await this._roleQueries.CheckForPresenceOfRoleByNameWithIdExclusion(request.Name, request.RoleId, cancellationToken);

            if (presenceResult.IsPresent)
            {
                return(ResultWithError.Fail(new ErrorData(ErrorCodes.RoleAlreadyExists)));
            }

            var roleMaybe = await this._roleRepository.Find(request.RoleId, cancellationToken);

            if (roleMaybe.HasNoValue)
            {
                return(ResultWithError.Fail(new ErrorData(ErrorCodes.RoleNotFound)));
            }

            var role = roleMaybe.Value;

            role.UpdateName(request.Name);
            role.SetResources(request.Resources);

            this._roleRepository.Update(role);

            return(ResultWithError.Ok <ErrorData>());
        }
Example #22
0
 public static Task <HttpResultWithError <TError> > OnSuccessToHttpResultWithError <TError>(
     this ResultWithError <TError> resultWithError,
     Func <Task <HttpResultWithError <TError> > > onSuccessFunc)
 {
     return(resultWithError.IsFailure
         ? Task.FromResult(HttpResultWithError.Fail(resultWithError.Error, HttpState.Empty))
         : onSuccessFunc());
 }
        public void Inequality_operator_between_ok_ResultWithError_and_fail_ResultWithError_is_true()
        {
            var okResult    = ResultWithError.Ok <string>();
            var errorResult = ResultWithError.Fail("abc");
            var isDifferent = okResult != errorResult;

            isDifferent.ShouldBeTrue();
        }
        public void Inequality_operator_between_two_fail_ResultWithErrors_is_true_if_errors_are_not_equal()
        {
            var result1     = ResultWithError.Fail("abc");
            var result2     = ResultWithError.Fail("zzz");
            var isDifferent = result1 != result2;

            isDifferent.ShouldBeTrue();
        }
        public void OnSuccess_propagates_error_if_result_is_fail()
        {
            var error  = "error";
            var result = ResultWithError.Fail(error)
                         .OnSuccessToResultWithValueAndError(() => 1);

            result.Error.ShouldBe(error);
        }
        public void OnSuccess_new_result_contains_value_from_function_if_result_is_ok()
        {
            var newValue = 1;
            var result   = ResultWithError.Ok <string>()
                           .OnSuccessToResultWithValueAndError(() => newValue);

            result.Value.ShouldBe(newValue);
        }
        public void Inequality_operator_between_error_and_fail_ResultWithError_is_false_if_errors_are_equals()
        {
            var error       = "abc";
            var result      = ResultWithError.Fail(error);
            var isDifferent = result != error;

            isDifferent.ShouldBeFalse();
        }
Example #28
0
        public void GetHasCode_between_two_fail_ResultWithError_is_equal_if_both_errors_are_equal()
        {
            var error   = "abc";
            var result1 = ResultWithError.Fail(error);
            var result2 = ResultWithError.Fail(error);

            result1.GetHashCode().ShouldBe(result2.GetHashCode());
        }
        public void Inequality_operator_between_error_and_ok_ResultWithError_is_true()
        {
            var error       = "abc";
            var result      = ResultWithError.Ok <string>();
            var isDifferent = result != error;

            isDifferent.ShouldBeTrue();
        }
        public void Inequality_operator_between_two_ok_ResultWithErrors_is_false()
        {
            var result1     = ResultWithError.Ok <string>();
            var result2     = ResultWithError.Ok <string>();
            var isDifferent = result1 != result2;

            isDifferent.ShouldBeFalse();
        }