public async Task ValidadeUserPasswordForHistoryAsync_Invalid_False() { // Arrange var cxn = new SqlConnectionWrapperMock(); var repository = new SqlUserRepository(cxn.Object, cxn.Object); const int userId = 99; var userSalt = new Guid(); const string newPassword = "******"; var passwordHystory = new List <SqlUserRepository.HashedPassword> { new SqlUserRepository.HashedPassword { Password = HashingUtilities.GenerateSaltedHash(newPassword, userSalt), UserSALT = userSalt } }; cxn.SetupQueryAsync( "GetLastUserPasswords", new Dictionary <string, object> { { "@userId", userId } }, passwordHystory); // Act var result = await repository.ValidateUserPasswordForHistoryAsync(userId, newPassword); // Assert cxn.Verify(); Assert.AreEqual(false, result); }
public async Task UpdateUserPasswordAsync(string login, string password) { var userSalt = Guid.NewGuid(); var newPassword = HashingUtilities.GenerateSaltedHash(password, userSalt); var parameters = new DynamicParameters(); parameters.Add("@Login", login); parameters.Add("@UserSALT", userSalt); parameters.Add("@Password", newPassword); await _connectionWrapper.ExecuteAsync("UpdateUserOnPasswordResetAsync", parameters, commandType : CommandType.StoredProcedure); }
public async Task ResetPassword(AuthenticationUser user, string oldPassword, string newPassword) { if (string.IsNullOrEmpty(newPassword)) { throw new BadRequestException("Password reset failed, new password cannot be empty", ErrorCodes.EmptyPassword); } if (oldPassword != null && oldPassword == newPassword) { throw new BadRequestException("Password reset failed, new password cannot be equal to the old one", ErrorCodes.SamePassword); } if (newPassword.ToLower() == user.Login?.ToLower()) { throw new BadRequestException("Password reset failed, new password cannot be equal to login name", ErrorCodes.PasswordSameAsLogin); } if (newPassword.ToLower() == user.DisplayName?.ToLower()) { throw new BadRequestException("Password reset failed, new password cannot be equal to display name", ErrorCodes.PasswordSameAsDisplayName); } string errorMsg; if (!PasswordValidationHelper.ValidatePassword(newPassword, true, out errorMsg)) { throw new BadRequestException("Password reset failed, new password is invalid", ErrorCodes.TooSimplePassword); } if (await IsChangePasswordCooldownInEffect(user)) { throw new ConflictException("Password reset failed, password reset cooldown in effect", ErrorCodes.ChangePasswordCooldownInEffect); } if (!await _userRepository.ValidateUserPasswordForHistoryAsync(user.Id, newPassword)) { throw new BadRequestException("The new password matches a previously used password.", ErrorCodes.PasswordAlreadyUsedPreviously); } var newGuid = Guid.NewGuid(); user.UserSalt = newGuid; user.Password = HashingUtilities.GenerateSaltedHash(newPassword, user.UserSalt); await _userRepository.UpdateUserOnPasswordResetAsync(user); }
public async Task <bool> ValidateUserPasswordForHistoryAsync(int userId, string newPassword) { var prm = new DynamicParameters(); prm.Add("@userId", userId); var passwordHistory = await _connectionWrapper.QueryAsync <HashedPassword>("GetLastUserPasswords", prm, commandType : CommandType.StoredProcedure); foreach (var password in passwordHistory) { var newHashedPassword = HashingUtilities.GenerateSaltedHash(newPassword, password.UserSALT); if (string.Equals(newHashedPassword, password.Password)) { return(false); } } return(true); }
private AuthenticationStatus AuthenticateDatabaseUser(AuthenticationUser user, string password, int passwordExpirationInDays = 0) { var hashedPassword = HashingUtilities.GenerateSaltedHash(password, user.UserSalt); if (!string.Equals(user.Password, hashedPassword)) { return(AuthenticationStatus.InvalidCredentials); } if (!user.IsEnabled) { return(AuthenticationStatus.Locked); } if (HasExpiredPassword(user, passwordExpirationInDays)) { return(AuthenticationStatus.PasswordExpired); } return(AuthenticationStatus.Success); }
public async Task <IHttpActionResult> PostPasswordResetAsync([FromBody] ResetPasswordContent content) { // the deserializer creates a zero filled guid when none provided if (content.Token == Guid.Empty || content.Token.GetHashCode() == 0) { throw new BadRequestException("Password reset failed, token not provided", ErrorCodes.PasswordResetEmptyToken); } var tokens = (await _userRepository.GetPasswordRecoveryTokensAsync(content.Token)).ToList(); if (!tokens.Any()) { // user did not request password reset throw new ConflictException("Password reset failed, recovery token not found.", ErrorCodes.PasswordResetTokenNotFound); } if (tokens.First().RecoveryToken != content.Token) { // provided token doesn't match last requested throw new ConflictException("Password reset failed, a more recent recovery token exists.", ErrorCodes.PasswordResetTokenNotLatest); } var tokenLifespan = await _applicationSettingsRepository.GetValue(PasswordResetTokenExpirationInHoursKey, DefaultPasswordResetTokenExpirationInHours); if (tokens.First().CreationTime.AddHours(tokenLifespan) < DateTime.Now) { // token expired throw new ConflictException("Password reset failed, recovery token expired.", ErrorCodes.PasswordResetTokenExpired); } var userLogin = tokens.First().Login; var user = await _userRepository.GetUserByLoginAsync(userLogin); if (user == null) { // user does not exist throw new ConflictException("Password reset failed, the user does not exist.", ErrorCodes.PasswordResetUserNotFound); } if (!user.IsEnabled) { // user is disabled throw new ConflictException("Password reset failed, the login for this user is disabled.", ErrorCodes.PasswordResetUserDisabled); } string decodedNewPassword; try { decodedNewPassword = SystemEncryptions.Decode(content.Password); } catch (Exception) { throw new BadRequestException("Password reset failed, the provided password was not encoded correctly", ErrorCodes.PasswordDecodingError); } if (decodedNewPassword != null && user.Password == HashingUtilities.GenerateSaltedHash(decodedNewPassword, user.UserSalt)) { throw new BadRequestException("Password reset failed, new password cannot be equal to the old one", ErrorCodes.SamePassword); } // reset password await _authenticationRepository.ResetPassword(user, null, decodedNewPassword); // drop user session var uri = new Uri(WebApiConfig.AccessControl); var http = _httpClientProvider.Create(uri); var request = new HttpRequestMessage { RequestUri = new Uri(uri, $"sessions/{user.Id}"), Method = HttpMethod.Delete }; await http.SendAsync(request); return(Ok()); }