public void AuthenticateCommand_PresentWrongPassword_ThrowsException() { // ---- Arrange ---- const string email = "*****@*****.**"; const string name = "Test user"; const string wrongPassword = "******"; const string password = "******"; var passwordHash = AuthUtils.GetMd5Hash(password); var testUser = new UserIdentityModel( Guid.NewGuid(), email, "Test user", name, passwordHash, Instant.MinValue); _authRepositoryMock.Setup(r => r.GetUserIdentity(email)) .ReturnsAsync(() => testUser); var command = new AuthenticateUserCommand(email, wrongPassword); var handler = new AuthenticateUserCommandHandler(_repositoryProviderMock.Object, _configuration); // ---- Act & Assert ---- Assert.ThrowsAsync <WrongPasswordException>( async() => await handler.Handle(command, CancellationToken.None)); _authRepositoryMock.Verify(r => r.GetUserIdentity(email), Times.Once); }
public async Task Handle_GivenSavingSucceeds_ExpectSuccessfulResult() { var user = new Mock <IUser>(); user.Setup(x => x.PasswordHash).Returns(BCrypt.Net.BCrypt.HashPassword("password")); user.Setup(x => x.Profile).Returns(new Profile(TestVariables.UserId, "first-name", "last-name")); user.Setup(x => x.AuthenticatorApps).Returns(new List <AuthenticatorApp>()); user.Setup(x => x.AuthenticatorDevices).Returns(new List <AuthenticatorDevice>()); user.Setup(x => x.IsVerified).Returns(true); 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.FindByEmailAddress(It.IsAny <string>(), It.IsAny <CancellationToken>())) .ReturnsAsync(() => Maybe.From(user.Object)); var clock = new Mock <IClock>(); var securitySettings = new Mock <IOptions <SecuritySettings> >(); securitySettings.Setup(x => x.Value).Returns(new SecuritySettings()); var fido = new Mock <IFido2>(); var handler = new AuthenticateUserCommandHandler(userRepository.Object, clock.Object, securitySettings.Object, fido.Object); var cmd = new AuthenticateUserCommand("email-address", "password"); var result = await handler.Handle(cmd, CancellationToken.None); Assert.True(result.IsSuccess); }
public async Task Handle_GivenUserDoesExistButPasswordDoesNotVerifyAndAccountsAreLockableAndAttemptsNotLess_ExpectFailedResultAndUnsuccessfulAttemptLoggedWithLockApplied() { var user = new Mock <IUser>(); user.Setup(x => x.PasswordHash).Returns(BCrypt.Net.BCrypt.HashPassword("password")); user.Setup(x => x.IsVerified).Returns(true); 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.FindByEmailAddress(It.IsAny <string>(), It.IsAny <CancellationToken>())) .ReturnsAsync(() => Maybe.From(user.Object)); var clock = new Mock <IClock>(); var securitySettings = new Mock <IOptions <SecuritySettings> >(); securitySettings.Setup(x => x.Value).Returns(() => new SecuritySettings { AllowedAttempts = 0 }); var fido = new Mock <IFido2>(); var handler = new AuthenticateUserCommandHandler(userRepository.Object, clock.Object, securitySettings.Object, fido.Object); var cmd = new AuthenticateUserCommand("email-address", "wrong-password"); var result = await handler.Handle(cmd, CancellationToken.None); Assert.True(result.IsFailure); Assert.Equal(ErrorCodes.AuthenticationFailed, result.Error.Code); user.Verify(x => x.ProcessUnsuccessfulAuthenticationAttempt(It.IsAny <DateTime>(), true)); }
public void Arrange() { _user = new User { Email = EmailAddress, Password = CorrectHashedPassword, Salt = CorrectSalt, PasswordProfileId = CorrectProfileId, FailedLoginAttempts = 1 }; _userRepository = new Mock <IUserRepository>(); _userRepository.Setup(r => r.GetByEmailAddress(EmailAddress)) .Returns(Task.FromResult(_user)); _passwordService = new Mock <IPasswordService>(); _passwordService.Setup(s => s.VerifyAsync(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>())) .Returns(Task.FromResult(false)); _passwordService.Setup(s => s.VerifyAsync(CorrectPassword, CorrectHashedPassword, CorrectSalt, CorrectProfileId)) .Returns(Task.FromResult(true)); _configuration = new EmployerUsersConfiguration { Account = new AccountConfiguration { AllowedFailedLoginAttempts = 2 } }; _configurationService = new Mock <IConfigurationService>(); _configurationService.Setup(s => s.GetAsync <EmployerUsersConfiguration>()).Returns(Task.FromResult(_configuration)); _mediator = new Mock <IMediator>(); _mediator.Setup(m => m.PublishAsync(It.IsAny <IAsyncNotification>())).Returns(Task.FromResult <object>(null)); _logger = new Mock <ILogger>(); _validator = new Mock <IValidator <AuthenticateUserCommand> >(); _validator.Setup(x => x.ValidateAsync(It.IsAny <AuthenticateUserCommand>())).ReturnsAsync(new ValidationResult { ValidationDictionary = new Dictionary <string, string>() }); _auditService = new Mock <IAuditService>(); _commandHandler = new AuthenticateUserCommandHandler( _userRepository.Object, _passwordService.Object, _configurationService.Object, _mediator.Object, _logger.Object, _validator.Object, _auditService.Object); _command = new AuthenticateUserCommand { EmailAddress = EmailAddress, Password = CorrectPassword }; }
public async Task Handle_GivenUserDoesExistAndPasswordDoesVerifyAndHasDeviceSetUp_ExpectSuccessfulResultWithAwaitingMfaDeviceAndAPartialAttemptLogged() { var user = new Mock <IUser>(); var userId = Guid.NewGuid(); user.Setup(x => x.Id).Returns(userId); user.Setup(x => x.EmailAddress).Returns("email-address"); user.Setup(x => x.PasswordHash).Returns(BCrypt.Net.BCrypt.HashPassword("password")); user.Setup(x => x.AuthenticatorApps).Returns(new List <AuthenticatorApp>()); user.Setup(x => x.AuthenticatorDevices).Returns(new List <AuthenticatorDevice> { new AuthenticatorDevice( TestVariables.AuthenticatorDeviceId, TestVariables.Now, TestVariables.AuthenticatorDevicePublicKey, TestVariables.AuthenticatorDeviceCredentialId, TestVariables.AuthenticatorDeviceAaguid, 1, "name", "cred-type"), }); user.Setup(x => x.IsVerified).Returns(true); 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.FindByEmailAddress(It.IsAny <string>(), It.IsAny <CancellationToken>())) .ReturnsAsync(() => Maybe.From(user.Object)); var clock = new Mock <IClock>(); var securitySettings = new Mock <IOptions <SecuritySettings> >(); securitySettings.Setup(x => x.Value).Returns(new SecuritySettings()); var fido = new Mock <IFido2>(); fido.Setup( x => x.GetAssertionOptions( It.IsAny <IEnumerable <PublicKeyCredentialDescriptor> >(), It.IsAny <UserVerificationRequirement>(), It.IsAny <AuthenticationExtensionsClientInputs>())) .Returns(new AssertionOptions()); var handler = new AuthenticateUserCommandHandler(userRepository.Object, clock.Object, securitySettings.Object, fido.Object); var cmd = new AuthenticateUserCommand("email-address", "password"); var result = await handler.Handle(cmd, CancellationToken.None); Assert.True(result.IsSuccess); Assert.Equal(userId, result.Value.UserId); Assert.True(result.Value.SetupMfaProviders.HasFlag(MfaProvider.Device)); Assert.True(result.Value.SetupMfaProviders.HasFlag(MfaProvider.Email)); Assert.Equal(BaseAuthenticationProcessCommandResult.AuthenticationState.AwaitingMfaDeviceCode, result.Value.AuthenticationStatus); user.Verify(x => x.ProcessPartialSuccessfulAuthenticationAttempt(It.IsAny <DateTime>(), AuthenticationHistoryType.DeviceMfaRequested)); }
public async Task ShouldFailAuthenticationIfWrongPassword() { var dbContext = InfrastructureFactory.GetInMemoryContext(nameof(ShouldFailAuthenticationIfWrongPassword)); var unitOfWork = InfrastructureFactory.GetEfUnitOfWork(dbContext); var user = EntityFactory.GetUser("johndoe", "Pass@123"); await unitOfWork.AddAndSaveAsync(user); var handler = new AuthenticateUserCommandHandler(unitOfWork, InfrastructureFactory.GetSha1Hasher(), InfrastructureFactory.GetMachineDateTime()); Assert.ThrowsAsync <UserAuthenticationFailedException>(() => handler.Handle(new AuthenticateUserCommand("johndoe", "Pass@13", UserAuthConstants.TokenExpirationTime), default)); }
private void SetData() { SQLServerAuthUserRepository repository = new SQLServerAuthUserRepository(); UserAuthenticator authenticator = new UserAuthenticator(repository); AuthenticateUserCommandHandler handler = new AuthenticateUserCommandHandler(authenticator); var data = new Dictionary <string, object>(); data.Add("handler", handler); login = new Login(data); }
public void AuthenticateCommand_AuthUser_SuccessAuth() { // ---- Arrange ---- const string email = "*****@*****.**"; const string name = "Test user"; const string password = "******"; var passwordHash = AuthUtils.GetMd5Hash(password); var clock = new FakeClock(SystemClock.Instance.GetCurrentInstant()); var testUser = new UserIdentityModel( Guid.NewGuid(), email, name, "user", passwordHash, clock.GetCurrentInstant()); _authRepositoryMock.Setup(r => r.GetUserIdentity(email)) .ReturnsAsync(() => testUser); var command = new AuthenticateUserCommand(email, password); var handler = new AuthenticateUserCommandHandler(_repositoryProviderMock.Object, _configuration) { Clock = clock }; AuthAccessModel result = null; var lifetime = DurationUtils.FromString( _configuration[$"{AuthUtils.Jwt.ConfigKeys.Section}:{AuthUtils.Jwt.ConfigKeys.LifetimeKey}"]); // ---- Act ---- Assert.DoesNotThrowAsync(async() => { result = await handler.Handle(command, CancellationToken.None); }); clock.Advance(lifetime); // for check expires token instant // ---- Assert ---- Assert.IsNotNull(result); Assert.AreEqual(testUser.Id, result.Id); Assert.AreEqual(testUser.Email, result.Email); Assert.AreEqual(clock.GetCurrentInstant(), result.ExpiresAt); Assert.AreEqual(clock.GetCurrentInstant(), result.ExpiresAt); Assert.AreEqual("user", testUser.Role); Assert.IsNotEmpty(result.Token); _authRepositoryMock.Verify(r => r.GetUserIdentity(email), Times.Once); }
public async Task ShouldReturnAuthenticatedUser() { var dbContext = InfrastructureFactory.GetInMemoryContext(nameof(ShouldReturnAuthenticatedUser)); var unitOfWork = InfrastructureFactory.GetEfUnitOfWork(dbContext); var user = EntityFactory.GetUser("johndoe", "Pass@123"); await unitOfWork.AddAndSaveAsync(user); var handler = new AuthenticateUserCommandHandler(unitOfWork, InfrastructureFactory.GetSha1Hasher(), InfrastructureFactory.GetMachineDateTime()); var authentication = await handler.Handle(new AuthenticateUserCommand("johndoe", "Pass@123", UserAuthConstants.TokenExpirationTime), default); Assert.AreEqual("johndoe", authentication.User.Nickname); Assert.IsFalse(string.IsNullOrEmpty(authentication.Token)); }
public AuthenticateUserCommandTests(QueryTestFixture fixture) { _merchantRepository = new Repository <Merchant>(_context); _merchantService = new MerchantService( _merchantRepository, fixture.EncryptionService, fixture.AppSettings, fixture.Mapper); _sut = new AuthenticateUserCommandHandler(_merchantService); _sutValidator = new AuthenticateUserCommandValidator(); }
public void Then_If_Error_A_HttpContextException_Is_Thrown( PostAuthenticateUserResult apiResponse, AuthenticateUserCommand command, [Frozen] Mock <IApimDeveloperApiClient <ApimDeveloperApiConfiguration> > apimDeveloperApiClient, AuthenticateUserCommandHandler handler) { apimDeveloperApiClient.Setup(x => x.PostWithResponseCode <PostAuthenticateUserResult>(It.Is <PostAuthenticateUserRequest>(c => ((PostAuthenticateUserRequestData)c.Data).Email.Equals(command.Email) && ((PostAuthenticateUserRequestData)c.Data).Password.Equals(command.Password)))) .ReturnsAsync(new ApiResponse <PostAuthenticateUserResult>(apiResponse, HttpStatusCode.BadRequest, "An Error")); Assert.ThrowsAsync <HttpRequestContentException>(() => handler.Handle(command, CancellationToken.None)); }
public async Task ShouldCreateTokenOnSucesfulAuth() { var dbContext = InfrastructureFactory.GetInMemoryContext(nameof(ShouldChangePasswordSaltAndReHashPasswordOnSuccesfulAuth)); var unitOfWork = InfrastructureFactory.GetEfUnitOfWork(dbContext); var user = EntityFactory.GetUser("johndoe", "Pass@123"); await unitOfWork.AddAndSaveAsync(user); var handler = new AuthenticateUserCommandHandler(unitOfWork, InfrastructureFactory.GetSha1Hasher(), InfrastructureFactory.GetMachineDateTime()); var authentication = await handler.Handle(new AuthenticateUserCommand("johndoe", "Pass@123", UserAuthConstants.TokenExpirationTime), default); var tokenCount = await dbContext.UserTokens.CountAsync(u => u.Nickname == "johndoe"); Assert.AreEqual(1, tokenCount); }
public void AuthenticateCommand_PresentInvalidEmail_ThrowsException() { // ---- Arrange ---- const string invalidEmail = "invalid_email"; const string password = "******"; var command = new AuthenticateUserCommand(invalidEmail, password); var handler = new AuthenticateUserCommandHandler(_repositoryProviderMock.Object, _configuration); // ---- Act & Assert ---- var exception = Assert.ThrowsAsync <InvalidEmailFormatException>( async() => await handler.Handle(command, CancellationToken.None)); Assert.AreEqual(invalidEmail, exception.Email); }
public async Task Then_The_Query_Is_Handled_And_User_Returned( PostAuthenticateUserResult apiResponse, AuthenticateUserCommand command, [Frozen] Mock <IApimDeveloperApiClient <ApimDeveloperApiConfiguration> > apimDeveloperApiClient, AuthenticateUserCommandHandler handler) { apimDeveloperApiClient.Setup(x => x.PostWithResponseCode <PostAuthenticateUserResult>(It.Is <PostAuthenticateUserRequest>(c => ((PostAuthenticateUserRequestData)c.Data).Email.Equals(command.Email) && ((PostAuthenticateUserRequestData)c.Data).Password.Equals(command.Password)))) .ReturnsAsync(new ApiResponse <PostAuthenticateUserResult>(apiResponse, HttpStatusCode.OK, "")); var actual = await handler.Handle(command, CancellationToken.None); actual.User.Should().BeEquivalentTo(apiResponse); }
public void AuthenticateCommand_PresentNewEmail_ThrowsException() { // ---- Arrange ---- const string email = "*****@*****.**"; const string password = "******"; var command = new AuthenticateUserCommand(email, password); var handler = new AuthenticateUserCommandHandler(_repositoryProviderMock.Object, _configuration); // ---- Act & Assert ---- var exception = Assert.ThrowsAsync <UserNotFoundByEmailException>( async() => await handler.Handle(command, CancellationToken.None)); _authRepositoryMock.Verify(r => r.GetUserIdentity(email), Times.Once); StringAssert.AreEqualIgnoringCase(email, exception.Email); }
public async Task ShouldChangePasswordSaltAndReHashPasswordOnSuccesfulAuth() { var dbContext = InfrastructureFactory.GetInMemoryContext(nameof(ShouldChangePasswordSaltAndReHashPasswordOnSuccesfulAuth)); var unitOfWork = InfrastructureFactory.GetEfUnitOfWork(dbContext); var user = EntityFactory.GetUser("johndoe", "Pass@123"); await unitOfWork.AddAndSaveAsync(user); var salt = user.PasswordSalt; var passwordHash = user.PasswordHash; var lastLoginDate = user.LastLoginDate; var handler = new AuthenticateUserCommandHandler(unitOfWork, InfrastructureFactory.GetSha1Hasher(), InfrastructureFactory.GetMachineDateTime()); var authentication = await handler.Handle(new AuthenticateUserCommand("johndoe", "Pass@123", UserAuthConstants.TokenExpirationTime), default); user = await unitOfWork.GetSingleAsync <UserEntity>(u => u.Nickname == "johndoe"); Assert.AreNotEqual(salt, user.PasswordSalt); Assert.AreNotEqual(passwordHash, user.PasswordSalt); Assert.AreNotEqual(lastLoginDate, user.LastLoginDate); }
public async Task Handle_GivenUserDoesExistAndPasswordDoesVerifyButHasNoAppSetUpAndNoDeviceSetUp_ExpectSuccessfulResultWithAwaitingMfaEmailCodeStateDomainEventRaisedAndAPartialAttemptLogged() { var user = new Mock <IUser>(); var userId = Guid.NewGuid(); user.Setup(x => x.Id).Returns(userId); user.Setup(x => x.EmailAddress).Returns("email-address"); user.Setup(x => x.PasswordHash).Returns(BCrypt.Net.BCrypt.HashPassword("password")); user.Setup(x => x.AuthenticatorApps).Returns(new List <AuthenticatorApp>()); user.Setup(x => x.AuthenticatorDevices).Returns(new List <AuthenticatorDevice>()); user.Setup(x => x.IsVerified).Returns(true); user.Setup(x => x.Profile).Returns(new Profile(Guid.NewGuid(), "first-name", "last-name")); 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.FindByEmailAddress(It.IsAny <string>(), It.IsAny <CancellationToken>())) .ReturnsAsync(() => Maybe.From(user.Object)); var clock = new Mock <IClock>(); var securitySettings = new Mock <IOptions <SecuritySettings> >(); securitySettings.Setup(x => x.Value).Returns(new SecuritySettings()); var fido = new Mock <IFido2>(); var handler = new AuthenticateUserCommandHandler(userRepository.Object, clock.Object, securitySettings.Object, fido.Object); var cmd = new AuthenticateUserCommand("email-address", "password"); var result = await handler.Handle(cmd, CancellationToken.None); Assert.True(result.IsSuccess); Assert.Equal(userId, result.Value.UserId); Assert.False(result.Value.SetupMfaProviders.HasFlag(MfaProvider.App)); Assert.True(result.Value.SetupMfaProviders.HasFlag(MfaProvider.Email)); Assert.Equal(BaseAuthenticationProcessCommandResult.AuthenticationState.AwaitingMfaEmailCode, result.Value.AuthenticationStatus); user.Verify(x => x.ProcessPartialSuccessfulAuthenticationAttempt(It.IsAny <DateTime>(), AuthenticationHistoryType.EmailMfaRequested)); user.Verify(x => x.AddDomainEvent(It.IsAny <EmailMfaTokenGeneratedEvent>())); }
public async Task Handle_GivenUserDoesNotExist_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); userRepository.Setup(x => x.FindByEmailAddress(It.IsAny <string>(), It.IsAny <CancellationToken>())) .ReturnsAsync(() => Maybe <IUser> .Nothing); var clock = new Mock <IClock>(); var securitySettings = new Mock <IOptions <SecuritySettings> >(); var fido = new Mock <IFido2>(); var handler = new AuthenticateUserCommandHandler(userRepository.Object, clock.Object, securitySettings.Object, fido.Object); var cmd = new AuthenticateUserCommand("email-address", "password"); var result = await handler.Handle(cmd, CancellationToken.None); Assert.True(result.IsFailure); Assert.Equal(ErrorCodes.UserNotFound, result.Error.Code); }
public AuthRespositoryTest() { repository = new SQLServerAuthUserRepository(); authenticator = new UserAuthenticator(repository); handler = new AuthenticateUserCommandHandler(authenticator); }
public Login(Dictionary <string, object> data) { InitializeComponent(); Handler = (AuthenticateUserCommandHandler)data["handler"]; }
public AuthenticateUserCommandHandlerTest() { dbContextMock = new Mock <IDocumentDbContext>(); authenticateUserCommandHandler = new AuthenticateUserCommandHandler(dbContextMock.Object); }