Enforce Passphrase Policy (#772)
* Enforce passphrase policy * Update multi-line conditional formatting * Updated formatting round 2 Co-authored-by: Vincent Salucci <vsalucci@bitwarden.com>
This commit is contained in:
parent
a4eff45534
commit
df8f44d77d
|
@ -132,6 +132,8 @@
|
||||||
HorizontalOptions="StartAndExpand" />
|
HorizontalOptions="StartAndExpand" />
|
||||||
<Switch
|
<Switch
|
||||||
IsToggled="{Binding Capitalize}"
|
IsToggled="{Binding Capitalize}"
|
||||||
|
IsEnabled="{Binding EnforcedPolicyOptions.Capitalize,
|
||||||
|
Converter={StaticResource inverseBool}}"
|
||||||
StyleClass="box-value"
|
StyleClass="box-value"
|
||||||
HorizontalOptions="End" />
|
HorizontalOptions="End" />
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
|
@ -143,6 +145,8 @@
|
||||||
HorizontalOptions="StartAndExpand" />
|
HorizontalOptions="StartAndExpand" />
|
||||||
<Switch
|
<Switch
|
||||||
IsToggled="{Binding IncludeNumber}"
|
IsToggled="{Binding IncludeNumber}"
|
||||||
|
IsEnabled="{Binding EnforcedPolicyOptions.IncludeNumber,
|
||||||
|
Converter={StaticResource inverseBool}}"
|
||||||
StyleClass="box-value"
|
StyleClass="box-value"
|
||||||
HorizontalOptions="End" />
|
HorizontalOptions="End" />
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
|
|
|
@ -233,10 +233,7 @@ namespace Bit.App.Pages
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsPolicyInEffect => _enforcedPolicyOptions.MinLength > 0 || _enforcedPolicyOptions.UseUppercase ||
|
public bool IsPolicyInEffect => _enforcedPolicyOptions.InEffect();
|
||||||
_enforcedPolicyOptions.UseLowercase || _enforcedPolicyOptions.UseNumbers ||
|
|
||||||
_enforcedPolicyOptions.NumberCount > 0 || _enforcedPolicyOptions.UseSpecial ||
|
|
||||||
_enforcedPolicyOptions.SpecialCount > 0;
|
|
||||||
|
|
||||||
public int TypeSelectedIndex
|
public int TypeSelectedIndex
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
{
|
{
|
||||||
public class PasswordGeneratorPolicyOptions
|
public class PasswordGeneratorPolicyOptions
|
||||||
{
|
{
|
||||||
|
public string DefaultType { get; set; }
|
||||||
public int MinLength { get; set; }
|
public int MinLength { get; set; }
|
||||||
public bool UseUppercase { get; set; }
|
public bool UseUppercase { get; set; }
|
||||||
public bool UseLowercase { get; set; }
|
public bool UseLowercase { get; set; }
|
||||||
|
@ -9,5 +10,23 @@
|
||||||
public int NumberCount { get; set; }
|
public int NumberCount { get; set; }
|
||||||
public bool UseSpecial { get; set; }
|
public bool UseSpecial { get; set; }
|
||||||
public int SpecialCount { get; set; }
|
public int SpecialCount { get; set; }
|
||||||
|
public int MinNumberOfWords { get; set; }
|
||||||
|
public bool Capitalize { get; set; }
|
||||||
|
public bool IncludeNumber { get; set; }
|
||||||
|
|
||||||
|
public bool InEffect()
|
||||||
|
{
|
||||||
|
return DefaultType != "" ||
|
||||||
|
MinLength > 0 ||
|
||||||
|
NumberCount > 0 ||
|
||||||
|
SpecialCount > 0 ||
|
||||||
|
UseUppercase ||
|
||||||
|
UseLowercase ||
|
||||||
|
UseNumbers ||
|
||||||
|
UseSpecial ||
|
||||||
|
MinNumberOfWords > 0 ||
|
||||||
|
Capitalize ||
|
||||||
|
IncludeNumber;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -312,6 +312,27 @@ namespace Bit.Core.Services
|
||||||
{
|
{
|
||||||
options.MinSpecial = options.Length - options.MinNumber;
|
options.MinSpecial = options.Length - options.MinNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(options.NumWords < enforcedPolicyOptions.MinNumberOfWords)
|
||||||
|
{
|
||||||
|
options.NumWords = enforcedPolicyOptions.MinNumberOfWords;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(enforcedPolicyOptions.Capitalize)
|
||||||
|
{
|
||||||
|
options.Capitalize = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(enforcedPolicyOptions.IncludeNumber)
|
||||||
|
{
|
||||||
|
options.IncludeNumber = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force default type if password/passphrase selected via policy
|
||||||
|
if(enforcedPolicyOptions.DefaultType == "password" || enforcedPolicyOptions.DefaultType == "passphrase")
|
||||||
|
{
|
||||||
|
options.Type = enforcedPolicyOptions.DefaultType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -344,6 +365,12 @@ namespace Bit.Core.Services
|
||||||
enforcedOptions = new PasswordGeneratorPolicyOptions();
|
enforcedOptions = new PasswordGeneratorPolicyOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var defaultType = GetPolicyString(currentPolicy, "defaultType");
|
||||||
|
if(defaultType != null && enforcedOptions.DefaultType != "password")
|
||||||
|
{
|
||||||
|
enforcedOptions.DefaultType = defaultType;
|
||||||
|
}
|
||||||
|
|
||||||
var minLength = GetPolicyInt(currentPolicy, "minLength");
|
var minLength = GetPolicyInt(currentPolicy, "minLength");
|
||||||
if(minLength != null && (int)(long)minLength > enforcedOptions.MinLength)
|
if(minLength != null && (int)(long)minLength > enforcedOptions.MinLength)
|
||||||
{
|
{
|
||||||
|
@ -385,6 +412,24 @@ namespace Bit.Core.Services
|
||||||
{
|
{
|
||||||
enforcedOptions.SpecialCount = (int)(long)minSpecial;
|
enforcedOptions.SpecialCount = (int)(long)minSpecial;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var minNumberWords = GetPolicyInt(currentPolicy, "minNumberWords");
|
||||||
|
if(minNumberWords != null && (int)(long)minNumberWords > enforcedOptions.MinNumberOfWords)
|
||||||
|
{
|
||||||
|
enforcedOptions.MinNumberOfWords = (int)(long)minNumberWords;
|
||||||
|
}
|
||||||
|
|
||||||
|
var capitalize = GetPolicyBool(currentPolicy, "capitalize");
|
||||||
|
if(capitalize != null && (bool)capitalize)
|
||||||
|
{
|
||||||
|
enforcedOptions.Capitalize = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var includeNumber = GetPolicyBool(currentPolicy, "includeNumber");
|
||||||
|
if(includeNumber != null && (bool)includeNumber)
|
||||||
|
{
|
||||||
|
enforcedOptions.IncludeNumber = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return enforcedOptions;
|
return enforcedOptions;
|
||||||
|
@ -416,6 +461,19 @@ namespace Bit.Core.Services
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string GetPolicyString(Policy policy, string key)
|
||||||
|
{
|
||||||
|
if(policy.Data.ContainsKey(key))
|
||||||
|
{
|
||||||
|
var value = policy.Data[key];
|
||||||
|
if(value != null)
|
||||||
|
{
|
||||||
|
return (string)value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public async Task SaveOptionsAsync(PasswordGenerationOptions options)
|
public async Task SaveOptionsAsync(PasswordGenerationOptions options)
|
||||||
{
|
{
|
||||||
await _storageService.SaveAsync(Keys_Options, options);
|
await _storageService.SaveAsync(Keys_Options, options);
|
||||||
|
@ -550,6 +608,11 @@ namespace Bit.Core.Services
|
||||||
options.NumWords = 20;
|
options.NumWords = 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(options.NumWords < enforcedPolicyOptions.MinNumberOfWords)
|
||||||
|
{
|
||||||
|
options.NumWords = enforcedPolicyOptions.MinNumberOfWords;
|
||||||
|
}
|
||||||
|
|
||||||
if(options.WordSeparator != null && options.WordSeparator.Length > 1)
|
if(options.WordSeparator != null && options.WordSeparator.Length > 1)
|
||||||
{
|
{
|
||||||
options.WordSeparator = options.WordSeparator[0].ToString();
|
options.WordSeparator = options.WordSeparator[0].ToString();
|
||||||
|
|
Loading…
Reference in New Issue