From dcb585455714623e99a36390ac45aba28aaacd45 Mon Sep 17 00:00:00 2001 From: Jake Fink Date: Fri, 10 Mar 2023 12:55:48 -0500 Subject: [PATCH] [EC-1045] add vault timeout action to policy (#2372) * [EC-1045] lock action if policy and show message * [EC-1045] add text for policy message * [EC-1045] add consts to policy service * [EC-1045] missed a const * [AC-1045] fix build --- .../SettingsPage/SettingsPageViewModel.cs | 46 +++++++++++++++---- src/App/Resources/AppResources.Designer.cs | 20 +++++++- src/App/Resources/AppResources.resx | 8 +++- src/Core/Abstractions/IPolicyService.cs | 1 + src/Core/Services/PolicyService.cs | 22 ++++----- src/Core/Services/VaultTimeoutService.cs | 2 +- 6 files changed, 75 insertions(+), 24 deletions(-) diff --git a/src/App/Pages/Settings/SettingsPage/SettingsPageViewModel.cs b/src/App/Pages/Settings/SettingsPage/SettingsPageViewModel.cs index 2845401bf..7f27993ef 100644 --- a/src/App/Pages/Settings/SettingsPage/SettingsPageViewModel.cs +++ b/src/App/Pages/Settings/SettingsPage/SettingsPageViewModel.cs @@ -120,7 +120,7 @@ namespace Bit.App.Pages if (await _policyService.PolicyAppliesToUser(PolicyType.MaximumVaultTimeout)) { _vaultTimeoutPolicy = (await _policyService.GetAll(PolicyType.MaximumVaultTimeout)).First(); - var minutes = _policyService.GetPolicyInt(_vaultTimeoutPolicy, "minutes").GetValueOrDefault(); + var minutes = _policyService.GetPolicyInt(_vaultTimeoutPolicy, PolicyService.TIMEOUT_POLICY_MINUTES).GetValueOrDefault(); _vaultTimeouts = _vaultTimeouts.Where(t => t.Value <= minutes && (t.Value > 0 || t.Value == CustomVaultTimeoutValue) && @@ -295,7 +295,7 @@ namespace Bit.App.Pages if (_vaultTimeoutPolicy != null) { - var maximumTimeout = _policyService.GetPolicyInt(_vaultTimeoutPolicy, "minutes"); + var maximumTimeout = _policyService.GetPolicyInt(_vaultTimeoutPolicy, PolicyService.TIMEOUT_POLICY_MINUTES); if (newTimeout > maximumTimeout) { @@ -374,6 +374,10 @@ namespace Bit.App.Pages public async Task VaultTimeoutActionAsync() { + if (!string.IsNullOrEmpty(_policyService.GetPolicyString(_vaultTimeoutPolicy, PolicyService.TIMEOUT_POLICY_ACTION))) + { + return; + } var options = _vaultTimeoutActions.Select(o => o.Key == _vaultTimeoutActionDisplayValue ? $"✓ {o.Key}" : o.Key).ToArray(); var selection = await Page.DisplayActionSheet(AppResources.VaultTimeoutAction, @@ -597,14 +601,38 @@ namespace Bit.App.Pages } if (_vaultTimeoutPolicy != null) { - var maximumTimeout = _policyService.GetPolicyInt(_vaultTimeoutPolicy, "minutes").GetValueOrDefault(); - securityItems.Insert(0, new SettingsPageListItem + var maximumTimeout = _policyService.GetPolicyInt(_vaultTimeoutPolicy, PolicyService.TIMEOUT_POLICY_MINUTES).GetValueOrDefault(); + var timeoutAction = _policyService.GetPolicyString(_vaultTimeoutPolicy, PolicyService.TIMEOUT_POLICY_ACTION); + if (maximumTimeout != default && timeoutAction != default) { - Name = string.Format(AppResources.VaultTimeoutPolicyInEffect, - Math.Floor((float)maximumTimeout / 60), - maximumTimeout % 60), - UseFrame = true, - }); + securityItems.Insert(0, new SettingsPageListItem + { + Name = string.Format(AppResources.VaultTimeoutPolicyWithActionInEffect, + Math.Floor((float)maximumTimeout / 60), + maximumTimeout % 60, + timeoutAction == PolicyService.TIMEOUT_POLICY_ACTION_LOCK ? AppResources.Lock : AppResources.LogOut), + UseFrame = true, + }); + } + else if (maximumTimeout != default && timeoutAction == default) + { + securityItems.Insert(0, new SettingsPageListItem + { + Name = string.Format(AppResources.VaultTimeoutPolicyInEffect, + Math.Floor((float)maximumTimeout / 60), + maximumTimeout % 60), + UseFrame = true, + }); + } + else if (maximumTimeout == default && timeoutAction != default) + { + securityItems.Insert(0, new SettingsPageListItem + { + Name = string.Format(AppResources.VaultTimeoutActionPolicyInEffect, + timeoutAction == PolicyService.TIMEOUT_POLICY_ACTION_LOCK ? AppResources.Lock : AppResources.LogOut), + UseFrame = true, + }); + } } if (Device.RuntimePlatform == Device.Android) { diff --git a/src/App/Resources/AppResources.Designer.cs b/src/App/Resources/AppResources.Designer.cs index 16763104f..243501dac 100644 --- a/src/App/Resources/AppResources.Designer.cs +++ b/src/App/Resources/AppResources.Designer.cs @@ -6677,6 +6677,15 @@ namespace Bit.App.Resources { } } + /// + /// Looks up a localized string similar to Your organization policies have set your vault timeout action to {0}.. + /// + public static string VaultTimeoutActionPolicyInEffect { + get { + return ResourceManager.GetString("VaultTimeoutActionPolicyInEffect", resourceCulture); + } + } + /// /// Looks up a localized string similar to Logging out will remove all access to your vault and requires online authentication after the timeout period. Are you sure you want to use this setting?. /// @@ -6687,7 +6696,7 @@ namespace Bit.App.Resources { } /// - /// Looks up a localized string similar to Your organization policies are affecting your vault timeout. Maximum allowed vault timeout is {0} hour(s) and {1} minute(s). + /// Looks up a localized string similar to Your organization policies have set your maximum allowed vault timeout to {0} hour(s) and {1} minute(s).. /// public static string VaultTimeoutPolicyInEffect { get { @@ -6695,6 +6704,15 @@ namespace Bit.App.Resources { } } + /// + /// Looks up a localized string similar to Your organization policies are affecting your vault timeout. Maximum allowed vault timeout is {0} hour(s) and {1} minute(s). Your vault timeout action is set to {2}.. + /// + public static string VaultTimeoutPolicyWithActionInEffect { + get { + return ResourceManager.GetString("VaultTimeoutPolicyWithActionInEffect", resourceCulture); + } + } + /// /// Looks up a localized string similar to Your vault timeout exceeds the restrictions set by your organization.. /// diff --git a/src/App/Resources/AppResources.resx b/src/App/Resources/AppResources.resx index 61742c5f6..d7b15ae3f 100644 --- a/src/App/Resources/AppResources.resx +++ b/src/App/Resources/AppResources.resx @@ -2141,7 +2141,13 @@ Scanning will happen automatically. This organization has an enterprise policy that will automatically enroll you in password reset. Enrollment will allow organization administrators to change your master password. - Your organization policies are affecting your vault timeout. Maximum allowed vault timeout is {0} hour(s) and {1} minute(s) + Your organization policies have set your maximum allowed vault timeout to {0} hour(s) and {1} minute(s). + + + Your organization policies are affecting your vault timeout. Maximum allowed vault timeout is {0} hour(s) and {1} minute(s). Your vault timeout action is set to {2}. + + + Your organization policies have set your vault timeout action to {0}. Your vault timeout exceeds the restrictions set by your organization. diff --git a/src/Core/Abstractions/IPolicyService.cs b/src/Core/Abstractions/IPolicyService.cs index caabeca3d..8acca2c9a 100644 --- a/src/Core/Abstractions/IPolicyService.cs +++ b/src/Core/Abstractions/IPolicyService.cs @@ -20,6 +20,7 @@ namespace Bit.Core.Abstractions string orgId); Task PolicyAppliesToUser(PolicyType policyType, Func policyFilter = null, string userId = null); int? GetPolicyInt(Policy policy, string key); + string GetPolicyString(Policy policy, string key); Task ShouldShowVaultFilterAsync(); } } diff --git a/src/Core/Services/PolicyService.cs b/src/Core/Services/PolicyService.cs index c7b374643..448cd1112 100644 --- a/src/Core/Services/PolicyService.cs +++ b/src/Core/Services/PolicyService.cs @@ -17,6 +17,11 @@ namespace Bit.Core.Services private IEnumerable _policyCache; + public const string TIMEOUT_POLICY_MINUTES = "minutes"; + public const string TIMEOUT_POLICY_ACTION = "action"; + public const string TIMEOUT_POLICY_ACTION_LOCK = "lock"; + public const string TIMEOUT_POLICY_ACTION_LOGOUT = "logOut"; + public PolicyService( IStateService stateService, IOrganizationService organizationService) @@ -247,6 +252,10 @@ namespace Bit.Core.Services return null; } + public string GetPolicyString(Policy policy, string key) => + policy.Data.TryGetValue(key, out var val) ? val as string : null; + + public async Task ShouldShowVaultFilterAsync() { var personalOwnershipPolicyApplies = await PolicyAppliesToUser(PolicyType.PersonalOwnership); @@ -272,17 +281,6 @@ 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; - } + } } diff --git a/src/Core/Services/VaultTimeoutService.cs b/src/Core/Services/VaultTimeoutService.cs index 43adc7866..2cef20fc4 100644 --- a/src/Core/Services/VaultTimeoutService.cs +++ b/src/Core/Services/VaultTimeoutService.cs @@ -247,7 +247,7 @@ namespace Bit.Core.Services { var policy = (await _policyService.GetAll(PolicyType.MaximumVaultTimeout, userId)).First(); // Remove negative values, and ensure it's smaller than maximum allowed value according to policy - var policyTimeout = _policyService.GetPolicyInt(policy, "minutes"); + var policyTimeout = _policyService.GetPolicyInt(policy, PolicyService.TIMEOUT_POLICY_MINUTES); if (!policyTimeout.HasValue) { return vaultTimeout;