-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #241 from DentallApp/patch-16
Add validation rule to check if the password is secure
- Loading branch information
Showing
10 changed files
with
188 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
namespace DentallApp.Shared.ValidationRules; | ||
|
||
public static class PasswordValidator | ||
{ | ||
public static IRuleBuilderOptions<T, string> MustBeSecurePassword<T>( | ||
this IRuleBuilder<T, string> ruleBuilder) | ||
{ | ||
return ruleBuilder.Must((rootObject, password, context) => | ||
{ | ||
if (string.IsNullOrWhiteSpace(password)) | ||
{ | ||
context.AddFailure(Messages.PasswordIsEmpty); | ||
return false; | ||
} | ||
Result result = IsPasswordSecure(password); | ||
if (result.IsSuccess) | ||
return true; | ||
foreach(string error in result.Errors) | ||
context.AddFailure(error); | ||
return false; | ||
}); | ||
} | ||
|
||
private static Result IsPasswordSecure(string password) | ||
{ | ||
var errors = new List<string>(); | ||
if (password.Length < 5) | ||
errors.Add(Messages.PasswordMinimumCharacters); | ||
|
||
if (HasNotUpperCaseLetters(password)) | ||
errors.Add(Messages.PasswordHasNotUpperCaseLetters); | ||
|
||
if (HasNotLowerCaseLetters(password)) | ||
errors.Add(Messages.PasswordHasNotLowerCaseLetters); | ||
|
||
if (HasNotNumbers(password)) | ||
errors.Add(Messages.PasswordHasNotNumbers); | ||
|
||
return errors.Count > 0 ? Result.Invalid(errors) : Result.Success(); | ||
} | ||
|
||
private static bool HasNotUpperCaseLetters(string password) | ||
=> !password.Where(c => c is >= 'A' and <= 'Z').Any(); | ||
|
||
private static bool HasNotLowerCaseLetters(string password) | ||
=> !password.Where(c => c is >= 'a' and <= 'z').Any(); | ||
|
||
private static bool HasNotNumbers(string password) | ||
=> !password.Where(c => c is >= '1' and <= '9').Any(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
66 changes: 66 additions & 0 deletions
66
tests/UnitTests/Shared/ValidationRules/PasswordValidatorTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
namespace UnitTests.Shared.ValidationRules; | ||
|
||
public class PasswordValidatorTests | ||
{ | ||
private class User | ||
{ | ||
public string Password { get; init; } | ||
} | ||
|
||
private class UserValidator : AbstractValidator<User> | ||
{ | ||
public UserValidator() | ||
{ | ||
RuleFor(user => user.Password) | ||
.MustBeSecurePassword(); | ||
} | ||
} | ||
|
||
[TestCase("1234")] | ||
[TestCase("D234")] | ||
[TestCase("DD34")] | ||
[TestCase("d234")] | ||
[TestCase("dd34")] | ||
[TestCase("Da34")] | ||
[TestCase("DaV4")] | ||
[TestCase("Dav4")] | ||
[TestCase("dAv4")] | ||
[TestCase("DAVE")] | ||
[TestCase("dave")] | ||
[TestCase("DAve")] | ||
[TestCase("123456789")] | ||
[TestCase("dave12354")] | ||
[TestCase("DAVE12354")] | ||
[TestCase("daveeclop")] | ||
[TestCase("DAVEECLOP")] | ||
[TestCase("DaVeecLop")] | ||
public void ShouldHaveErrorWhenPasswordIsInsecure(string password) | ||
{ | ||
var validator = new UserValidator(); | ||
var model = new User { Password = password }; | ||
var result = validator.TestValidate(model); | ||
result.ShouldHaveValidationErrorFor(user => user.Password); | ||
} | ||
|
||
[TestCase("Dsr2799")] | ||
[TestCase("Dsr27")] | ||
public void ShouldNotHaveErrorWhenPasswordIsSecure(string password) | ||
{ | ||
var validator = new UserValidator(); | ||
var model = new User { Password = password }; | ||
var result = validator.TestValidate(model); | ||
result.ShouldNotHaveValidationErrorFor(user => user.Password); | ||
} | ||
|
||
[TestCase("")] | ||
[TestCase(" ")] | ||
[TestCase(" ")] | ||
[TestCase(null)] | ||
public void ShouldHaveErrorWhenPasswordIsEmpty(string password) | ||
{ | ||
var validator = new UserValidator(); | ||
var model = new User { Password = password }; | ||
var result = validator.TestValidate(model); | ||
result.ShouldHaveValidationErrorFor(user => user.Password); | ||
} | ||
} |