From 84e89e1c4739507f733472804a0fc54616155ad2 Mon Sep 17 00:00:00 2001 From: TheXamlGuy Date: Sun, 9 Jun 2024 13:10:57 +0100 Subject: [PATCH] Added a password rule engine --- Bitvault.Avalonia/DropdownEntryView.axaml | 2 +- Bitvault.Avalonia/MaskedTextEntryView.axaml | 2 +- Bitvault.Avalonia/PasswordEntryView.axaml | 45 ++++++++++++++++- Bitvault.Avalonia/TextEntryView.axaml | 55 ++++++++++++++++++++- Bitvault/DigitRule.cs | 13 +++++ Bitvault/DiversityBonusRule.cs | 29 +++++++++++ Bitvault/IPasswordRule.cs | 6 +++ Bitvault/ItemConfiguration.cs | 4 ++ Bitvault/LengthRule.cs | 8 +++ Bitvault/LowercaseRule.cs | 14 ++++++ Bitvault/SpecialCharRule.cs | 12 +++++ Bitvault/UppercaseRule.cs | 13 +++++ 12 files changed, 199 insertions(+), 4 deletions(-) create mode 100644 Bitvault/DigitRule.cs create mode 100644 Bitvault/DiversityBonusRule.cs create mode 100644 Bitvault/IPasswordRule.cs create mode 100644 Bitvault/LengthRule.cs create mode 100644 Bitvault/LowercaseRule.cs create mode 100644 Bitvault/SpecialCharRule.cs create mode 100644 Bitvault/UppercaseRule.cs diff --git a/Bitvault.Avalonia/DropdownEntryView.axaml b/Bitvault.Avalonia/DropdownEntryView.axaml index 0107d14..7917c51 100644 --- a/Bitvault.Avalonia/DropdownEntryView.axaml +++ b/Bitvault.Avalonia/DropdownEntryView.axaml @@ -15,7 +15,7 @@ SelectedValueBinding="{ReflectionBinding Value}"> + + + + + + + + + + + + diff --git a/Bitvault.Avalonia/TextEntryView.axaml b/Bitvault.Avalonia/TextEntryView.axaml index 7e06de5..a32404f 100644 --- a/Bitvault.Avalonia/TextEntryView.axaml +++ b/Bitvault.Avalonia/TextEntryView.axaml @@ -6,6 +6,59 @@ x:DataType="vm:TextEntryViewModel" Header="{Binding Key}"> - + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Bitvault/DigitRule.cs b/Bitvault/DigitRule.cs new file mode 100644 index 0000000..ea32b19 --- /dev/null +++ b/Bitvault/DigitRule.cs @@ -0,0 +1,13 @@ +using System.Text.RegularExpressions; + +namespace Bitvault; + +public partial class DigitRule : + IPasswordRule +{ + public int CalculateScore(string password) => + Regex().IsMatch(password) ? 2 : 0; + + [GeneratedRegex(@"\d")] + private static partial Regex Regex(); +} diff --git a/Bitvault/DiversityBonusRule.cs b/Bitvault/DiversityBonusRule.cs new file mode 100644 index 0000000..88b088c --- /dev/null +++ b/Bitvault/DiversityBonusRule.cs @@ -0,0 +1,29 @@ +using System.Text.RegularExpressions; + +namespace Bitvault; + +public partial class DiversityBonusRule : + IPasswordRule +{ + public int CalculateScore(string password) + { + bool hasUppercase = UppercaseRegex().IsMatch(password); + bool hasLowercase = LowercaseRegex().IsMatch(password); + bool hasDigit = DigitRegex().IsMatch(password); + bool hasSpecialChar = SpecialCharRegex().IsMatch(password); + + return (hasUppercase && hasLowercase && hasDigit && hasSpecialChar) ? 2 : 0; + } + + [GeneratedRegex(@"[A-Z]")] + private static partial Regex UppercaseRegex(); + + [GeneratedRegex(@"[a-z]")] + private static partial Regex LowercaseRegex(); + + [GeneratedRegex(@"\d")] + private static partial Regex DigitRegex(); + + [GeneratedRegex(@"[^a-zA-Z0-9]")] + private static partial Regex SpecialCharRegex(); +} \ No newline at end of file diff --git a/Bitvault/IPasswordRule.cs b/Bitvault/IPasswordRule.cs new file mode 100644 index 0000000..dc7f87e --- /dev/null +++ b/Bitvault/IPasswordRule.cs @@ -0,0 +1,6 @@ +namespace Bitvault; + +public interface IPasswordRule +{ + int CalculateScore(string password); +} diff --git a/Bitvault/ItemConfiguration.cs b/Bitvault/ItemConfiguration.cs index db8cc1e..d99575e 100644 --- a/Bitvault/ItemConfiguration.cs +++ b/Bitvault/ItemConfiguration.cs @@ -719,6 +719,7 @@ public record ItemConfiguration { Label = "Type", Values = ["American Express", "Discover", "Maestro", "Mastercard", "Visa"], + Width = 120 }, new MaskedTextEntryConfiguration { @@ -731,18 +732,21 @@ public record ItemConfiguration Label = "Expiry Date", Pattern = "00/00", Value = "__/__", + Width = 120 }, new MaskedTextEntryConfiguration { Label = "Valid From", Pattern = "00/00", Value = "__/__", + Width = 120 }, new MaskedTextEntryConfiguration { Label = "Card verification code", Pattern = "000", Value = "___", + Width = 120 }, } }, diff --git a/Bitvault/LengthRule.cs b/Bitvault/LengthRule.cs new file mode 100644 index 0000000..f2680f5 --- /dev/null +++ b/Bitvault/LengthRule.cs @@ -0,0 +1,8 @@ +namespace Bitvault; + +public class LengthRule : + IPasswordRule +{ + public int CalculateScore(string password) => + password.Length >= 8 ? 5 : 0; +} diff --git a/Bitvault/LowercaseRule.cs b/Bitvault/LowercaseRule.cs new file mode 100644 index 0000000..fc696a4 --- /dev/null +++ b/Bitvault/LowercaseRule.cs @@ -0,0 +1,14 @@ +using System.Text.RegularExpressions; + +namespace Bitvault; + +public partial class LowercaseRule : + IPasswordRule +{ + public int CalculateScore(string password) => + Regex().IsMatch(password) ? 2 : 0; + + + [GeneratedRegex(@"[a-z]")] + private static partial Regex Regex(); +} diff --git a/Bitvault/SpecialCharRule.cs b/Bitvault/SpecialCharRule.cs new file mode 100644 index 0000000..ba2a10b --- /dev/null +++ b/Bitvault/SpecialCharRule.cs @@ -0,0 +1,12 @@ +using System.Text.RegularExpressions; + +namespace Bitvault; + +public partial class SpecialCharRule : IPasswordRule +{ + public int CalculateScore(string password) => + Regex().IsMatch(password) ? 2 : 0; + + [GeneratedRegex(@"[^a-zA-Z0-9]")] + private static partial Regex Regex(); +} \ No newline at end of file diff --git a/Bitvault/UppercaseRule.cs b/Bitvault/UppercaseRule.cs new file mode 100644 index 0000000..80ace89 --- /dev/null +++ b/Bitvault/UppercaseRule.cs @@ -0,0 +1,13 @@ +using System.Text.RegularExpressions; + +namespace Bitvault; + +public partial class UppercaseRule : + IPasswordRule +{ + public int CalculateScore(string password) => + Regex().IsMatch(password) ? 2 : 0; + + [GeneratedRegex(@"[A-Z]")] + private static partial Regex Regex(); +}