diff --git a/src/App/Pages/Generator/GeneratorPage.xaml b/src/App/Pages/Generator/GeneratorPage.xaml
index e4630f1cf..200991294 100644
--- a/src/App/Pages/Generator/GeneratorPage.xaml
+++ b/src/App/Pages/Generator/GeneratorPage.xaml
@@ -132,6 +132,8 @@
HorizontalOptions="StartAndExpand" />
@@ -143,6 +145,8 @@
HorizontalOptions="StartAndExpand" />
diff --git a/src/App/Pages/Generator/GeneratorPageViewModel.cs b/src/App/Pages/Generator/GeneratorPageViewModel.cs
index b0af77a78..2b3db6f18 100644
--- a/src/App/Pages/Generator/GeneratorPageViewModel.cs
+++ b/src/App/Pages/Generator/GeneratorPageViewModel.cs
@@ -233,10 +233,7 @@ namespace Bit.App.Pages
});
}
- public bool IsPolicyInEffect => _enforcedPolicyOptions.MinLength > 0 || _enforcedPolicyOptions.UseUppercase ||
- _enforcedPolicyOptions.UseLowercase || _enforcedPolicyOptions.UseNumbers ||
- _enforcedPolicyOptions.NumberCount > 0 || _enforcedPolicyOptions.UseSpecial ||
- _enforcedPolicyOptions.SpecialCount > 0;
+ public bool IsPolicyInEffect => _enforcedPolicyOptions.InEffect();
public int TypeSelectedIndex
{
diff --git a/src/Core/Models/Domain/PasswordGeneratorPolicyOptions.cs b/src/Core/Models/Domain/PasswordGeneratorPolicyOptions.cs
index 62a78756e..b163f67a7 100644
--- a/src/Core/Models/Domain/PasswordGeneratorPolicyOptions.cs
+++ b/src/Core/Models/Domain/PasswordGeneratorPolicyOptions.cs
@@ -2,6 +2,7 @@
{
public class PasswordGeneratorPolicyOptions
{
+ public string DefaultType { get; set; }
public int MinLength { get; set; }
public bool UseUppercase { get; set; }
public bool UseLowercase { get; set; }
@@ -9,5 +10,23 @@
public int NumberCount { get; set; }
public bool UseSpecial { 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;
+ }
}
}
diff --git a/src/Core/Services/PasswordGenerationService.cs b/src/Core/Services/PasswordGenerationService.cs
index a3289b2cd..34854e6ab 100644
--- a/src/Core/Services/PasswordGenerationService.cs
+++ b/src/Core/Services/PasswordGenerationService.cs
@@ -312,6 +312,27 @@ namespace Bit.Core.Services
{
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
{
@@ -344,6 +365,12 @@ namespace Bit.Core.Services
enforcedOptions = new PasswordGeneratorPolicyOptions();
}
+ var defaultType = GetPolicyString(currentPolicy, "defaultType");
+ if(defaultType != null && enforcedOptions.DefaultType != "password")
+ {
+ enforcedOptions.DefaultType = defaultType;
+ }
+
var minLength = GetPolicyInt(currentPolicy, "minLength");
if(minLength != null && (int)(long)minLength > enforcedOptions.MinLength)
{
@@ -385,6 +412,24 @@ namespace Bit.Core.Services
{
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;
@@ -415,6 +460,19 @@ namespace Bit.Core.Services
}
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)
{
@@ -550,6 +608,11 @@ namespace Bit.Core.Services
options.NumWords = 20;
}
+ if(options.NumWords < enforcedPolicyOptions.MinNumberOfWords)
+ {
+ options.NumWords = enforcedPolicyOptions.MinNumberOfWords;
+ }
+
if(options.WordSeparator != null && options.WordSeparator.Length > 1)
{
options.WordSeparator = options.WordSeparator[0].ToString();