Added a password rule engine

This commit is contained in:
TheXamlGuy
2024-06-09 13:10:57 +01:00
parent e8372f875f
commit 84e89e1c47
12 changed files with 199 additions and 4 deletions
+1 -1
View File
@@ -15,7 +15,7 @@
SelectedValueBinding="{ReflectionBinding Value}"> SelectedValueBinding="{ReflectionBinding Value}">
<ComboBox.Styles> <ComboBox.Styles>
<Style Selector="ComboBox.Write"> <Style Selector="ComboBox.Write">
<Setter Property="MinWidth" Value="296" /> <Setter Property="MinWidth" Value="{Binding Width}" />
<Setter Property="IsVisible" Value="True" /> <Setter Property="IsVisible" Value="True" />
</Style> </Style>
<Style Selector="ComboBox.Read"> <Style Selector="ComboBox.Read">
+1 -1
View File
@@ -9,7 +9,7 @@
<MaskedTextBox Mask="{Binding Pattern}" Text="{Binding Value}"> <MaskedTextBox Mask="{Binding Pattern}" Text="{Binding Value}">
<TextBox.Styles> <TextBox.Styles>
<Style Selector="TextBox.Write"> <Style Selector="TextBox.Write">
<Setter Property="MinWidth" Value="296" /> <Setter Property="MinWidth" Value="{Binding Width}" />
</Style> </Style>
<Style Selector="TextBox.Read"> <Style Selector="TextBox.Read">
<Setter Property="MinWidth" Value="0" /> <Setter Property="MinWidth" Value="0" />
+44 -1
View File
@@ -7,15 +7,58 @@
Header="{Binding Key}"> Header="{Binding Key}">
<SettingsExpander.Footer> <SettingsExpander.Footer>
<TextBox <TextBox
MinWidth="264"
Classes="revealPasswordButton" Classes="revealPasswordButton"
PasswordChar="&#x25CF;" PasswordChar="&#x25CF;"
Text="{Binding Value}"> Text="{Binding Value}">
<TextBox.Styles>
<Style Selector="TextBox.Write">
<Setter Property="MinWidth" Value="{Binding Width}" />
</Style>
<Style Selector="TextBox.Read">
<Setter Property="MinWidth" Value="0" />
<Setter Property="IsReadOnly" Value="True" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground">
<Setter.Value>
<SolidColorBrush Opacity="0.7" Color="{DynamicResource TextFillColorPrimary}" />
</Setter.Value>
</Setter>
<Style Selector="^:pointerover">
<Setter Property="Foreground">
<Setter.Value>
<SolidColorBrush Opacity="0.7" Color="{DynamicResource TextFillColorPrimary}" />
</Setter.Value>
</Setter>
<Style Selector="^ /template/ Border#PART_BorderElement">
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Background" Value="Transparent" />
</Style>
</Style>
<Style Selector="^:focus">
<Setter Property="Foreground">
<Setter.Value>
<SolidColorBrush Opacity="0.7" Color="{DynamicResource TextFillColorPrimary}" />
</Setter.Value>
</Setter>
<Style Selector="^ /template/ Border#PART_BorderElement">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="Transparent" />
</Style>
</Style>
</Style>
</TextBox.Styles>
<Interaction.Behaviors> <Interaction.Behaviors>
<DataTriggerBehavior Binding="{Binding State}" Value="{x:Static vm:ItemState.Read}"> <DataTriggerBehavior Binding="{Binding State}" Value="{x:Static vm:ItemState.Read}">
<AddClassAction ClassName="Read" RemoveIfExists="True" /> <AddClassAction ClassName="Read" RemoveIfExists="True" />
<RemoveClassAction ClassName="Write" />
</DataTriggerBehavior>
<DataTriggerBehavior Binding="{Binding State}" Value="{x:Static vm:ItemState.New}">
<AddClassAction ClassName="Write" RemoveIfExists="True" />
<RemoveClassAction ClassName="Read" />
</DataTriggerBehavior> </DataTriggerBehavior>
<DataTriggerBehavior Binding="{Binding State}" Value="{x:Static vm:ItemState.Write}"> <DataTriggerBehavior Binding="{Binding State}" Value="{x:Static vm:ItemState.Write}">
<AddClassAction ClassName="Write" RemoveIfExists="True" />
<RemoveClassAction ClassName="Read" /> <RemoveClassAction ClassName="Read" />
</DataTriggerBehavior> </DataTriggerBehavior>
</Interaction.Behaviors> </Interaction.Behaviors>
+54 -1
View File
@@ -6,6 +6,59 @@
x:DataType="vm:TextEntryViewModel" x:DataType="vm:TextEntryViewModel"
Header="{Binding Key}"> Header="{Binding Key}">
<SettingsExpander.Footer> <SettingsExpander.Footer>
<DatePicker /> <TextBox Text="{Binding Value}">
<TextBox.Styles>
<Style Selector="TextBox.Write">
<Setter Property="MinWidth" Value="{Binding Width}" />
</Style>
<Style Selector="TextBox.Read">
<Setter Property="MinWidth" Value="0" />
<Setter Property="IsReadOnly" Value="True" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground">
<Setter.Value>
<SolidColorBrush Opacity="0.7" Color="{DynamicResource TextFillColorPrimary}" />
</Setter.Value>
</Setter>
<Style Selector="^:pointerover">
<Setter Property="Foreground">
<Setter.Value>
<SolidColorBrush Opacity="0.7" Color="{DynamicResource TextFillColorPrimary}" />
</Setter.Value>
</Setter>
<Style Selector="^ /template/ Border#PART_BorderElement">
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Background" Value="Transparent" />
</Style>
</Style>
<Style Selector="^:focus">
<Setter Property="Foreground">
<Setter.Value>
<SolidColorBrush Opacity="0.7" Color="{DynamicResource TextFillColorPrimary}" />
</Setter.Value>
</Setter>
<Style Selector="^ /template/ Border#PART_BorderElement">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="Transparent" />
</Style>
</Style>
</Style>
</TextBox.Styles>
<Interaction.Behaviors>
<DataTriggerBehavior Binding="{Binding State}" Value="{x:Static vm:ItemState.Read}">
<AddClassAction ClassName="Read" RemoveIfExists="True" />
<RemoveClassAction ClassName="Write" />
</DataTriggerBehavior>
<DataTriggerBehavior Binding="{Binding State}" Value="{x:Static vm:ItemState.New}">
<AddClassAction ClassName="Write" RemoveIfExists="True" />
<RemoveClassAction ClassName="Read" />
</DataTriggerBehavior>
<DataTriggerBehavior Binding="{Binding State}" Value="{x:Static vm:ItemState.Write}">
<AddClassAction ClassName="Write" RemoveIfExists="True" />
<RemoveClassAction ClassName="Read" />
</DataTriggerBehavior>
</Interaction.Behaviors>
</TextBox>
</SettingsExpander.Footer> </SettingsExpander.Footer>
</SettingsExpander> </SettingsExpander>
+13
View File
@@ -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();
}
+29
View File
@@ -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();
}
+6
View File
@@ -0,0 +1,6 @@
namespace Bitvault;
public interface IPasswordRule
{
int CalculateScore(string password);
}
+4
View File
@@ -719,6 +719,7 @@ public record ItemConfiguration
{ {
Label = "Type", Label = "Type",
Values = ["American Express", "Discover", "Maestro", "Mastercard", "Visa"], Values = ["American Express", "Discover", "Maestro", "Mastercard", "Visa"],
Width = 120
}, },
new MaskedTextEntryConfiguration new MaskedTextEntryConfiguration
{ {
@@ -731,18 +732,21 @@ public record ItemConfiguration
Label = "Expiry Date", Label = "Expiry Date",
Pattern = "00/00", Pattern = "00/00",
Value = "__/__", Value = "__/__",
Width = 120
}, },
new MaskedTextEntryConfiguration new MaskedTextEntryConfiguration
{ {
Label = "Valid From", Label = "Valid From",
Pattern = "00/00", Pattern = "00/00",
Value = "__/__", Value = "__/__",
Width = 120
}, },
new MaskedTextEntryConfiguration new MaskedTextEntryConfiguration
{ {
Label = "Card verification code", Label = "Card verification code",
Pattern = "000", Pattern = "000",
Value = "___", Value = "___",
Width = 120
}, },
} }
}, },
+8
View File
@@ -0,0 +1,8 @@
namespace Bitvault;
public class LengthRule :
IPasswordRule
{
public int CalculateScore(string password) =>
password.Length >= 8 ? 5 : 0;
}
+14
View File
@@ -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();
}
+12
View File
@@ -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();
}
+13
View File
@@ -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();
}