From ac3d7c7c16ea0d24fa818e12345d4d68e929980b Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Thu, 13 Dec 2018 14:10:56 +0300 Subject: [PATCH] Resolved #203: Encrypt option to settings --- .../Volo.Abp.Settings.csproj | 1 + .../Volo/Abp/Settings/AbpSettingsModule.cs | 4 +- .../Abp/Settings/ISettingEncryptionService.cs | 13 ++ .../Volo/Abp/Settings/SettingDefinition.cs | 10 +- .../Abp/Settings/SettingEncryptionService.cs | 36 +++++ .../Volo/Abp/Settings/SettingManager.cs | 130 +++++++++++------- 6 files changed, 144 insertions(+), 50 deletions(-) create mode 100644 framework/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingEncryptionService.cs create mode 100644 framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingEncryptionService.cs diff --git a/framework/src/Volo.Abp.Settings/Volo.Abp.Settings.csproj b/framework/src/Volo.Abp.Settings/Volo.Abp.Settings.csproj index 6ba4d46c1f6..42ab46d477c 100644 --- a/framework/src/Volo.Abp.Settings/Volo.Abp.Settings.csproj +++ b/framework/src/Volo.Abp.Settings/Volo.Abp.Settings.csproj @@ -15,6 +15,7 @@ + diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/AbpSettingsModule.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/AbpSettingsModule.cs index 8900e8e0a35..da871946aee 100644 --- a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/AbpSettingsModule.cs +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/AbpSettingsModule.cs @@ -1,10 +1,12 @@ using Volo.Abp.Localization; using Volo.Abp.Modularity; +using Volo.Abp.Security; namespace Volo.Abp.Settings { [DependsOn( - typeof(AbpLocalizationAbstractionsModule) + typeof(AbpLocalizationAbstractionsModule), + typeof(AbpSecurityModule) )] public class AbpSettingsModule : AbpModule { diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingEncryptionService.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingEncryptionService.cs new file mode 100644 index 00000000000..ffffd7fe975 --- /dev/null +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingEncryptionService.cs @@ -0,0 +1,13 @@ +using JetBrains.Annotations; + +namespace Volo.Abp.Settings +{ + public interface ISettingEncryptionService + { + [CanBeNull] + string Encrypt([NotNull]SettingDefinition settingDefinition, [CanBeNull] string plainValue); + + [CanBeNull] + string Decrypt([NotNull]SettingDefinition settingDefinition, [CanBeNull] string encryptedValue); + } +} diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingDefinition.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingDefinition.cs index 58726492c69..cbbf810f840 100644 --- a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingDefinition.cs +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingDefinition.cs @@ -48,13 +48,20 @@ public ILocalizableString DisplayName [NotNull] public Dictionary Properties { get; } + /// + /// Is this setting stored as encrypted in the data source. + /// Default: False. + /// + public bool IsEncrypted { get; set; } + public SettingDefinition( string name, string defaultValue = null, ILocalizableString displayName = null, ILocalizableString description = null, bool isVisibleToClients = false, - bool isInherited = true) + bool isInherited = true, + bool isEncrypted = false) { Name = name; DefaultValue = defaultValue; @@ -62,6 +69,7 @@ public SettingDefinition( DisplayName = displayName ?? new FixedLocalizableString(name); Description = description; IsInherited = isInherited; + IsEncrypted = isEncrypted; Properties = new Dictionary(); } diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingEncryptionService.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingEncryptionService.cs new file mode 100644 index 00000000000..9fbee476883 --- /dev/null +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingEncryptionService.cs @@ -0,0 +1,36 @@ +using System; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Security.Encryption; + +namespace Volo.Abp.Settings +{ + public class SettingEncryptionService : ISettingEncryptionService, ITransientDependency + { + protected IStringEncryptionService StringEncryptionService { get; } + + public SettingEncryptionService(IStringEncryptionService stringEncryptionService) + { + StringEncryptionService = stringEncryptionService; + } + + public virtual string Encrypt(SettingDefinition settingDefinition, string plainValue) + { + if (plainValue.IsNullOrEmpty()) + { + return plainValue; + } + + return StringEncryptionService.Encrypt(plainValue); + } + + public virtual string Decrypt(SettingDefinition settingDefinition, string encryptedValue) + { + if (encryptedValue.IsNullOrEmpty()) + { + return encryptedValue; + } + + return StringEncryptionService.Decrypt(encryptedValue); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingManager.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingManager.cs index d75eb6ecee5..f2d808644da 100644 --- a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingManager.cs +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingManager.cs @@ -11,17 +11,18 @@ namespace Volo.Abp.Settings public class SettingManager : ISettingManager, ISingletonDependency { protected ISettingDefinitionManager SettingDefinitionManager { get; } - + protected ISettingEncryptionService SettingEncryptionService { get; } protected Lazy> Providers { get; } - protected SettingOptions Options { get; } public SettingManager( IOptions options, IServiceProvider serviceProvider, - ISettingDefinitionManager settingDefinitionManager) + ISettingDefinitionManager settingDefinitionManager, + ISettingEncryptionService settingEncryptionService) { SettingDefinitionManager = settingDefinitionManager; + SettingEncryptionService = settingEncryptionService; Options = options.Value; Providers = new Lazy>( @@ -48,34 +49,6 @@ public virtual Task GetOrNullAsync(string name, string providerName, str return GetOrNullInternalAsync(name, providerName, providerKey, fallback); } - public virtual async Task GetOrNullInternalAsync(string name, string providerName, string providerKey, bool fallback = true) - { - var setting = SettingDefinitionManager.Get(name); - var providers = Enumerable - .Reverse(Providers.Value); - - if (providerName != null) - { - providers = providers.SkipWhile(c => c.Name != providerName); - } - - if (!fallback || !setting.IsInherited) - { - providers = providers.TakeWhile(c => c.Name == providerName); - } - - foreach (var provider in providers) - { - var value = await provider.GetOrNullAsync(setting, providerKey); - if (value != null) - { - return value; - } - } - - return null; - } - public virtual async Task> GetAllAsync() { var settingValues = new Dictionary(); @@ -88,6 +61,11 @@ public virtual async Task> GetAllAsync() var value = await provider.GetOrNullAsync(setting, null); if (value != null) { + if (setting.IsEncrypted) + { + value = SettingEncryptionService.Decrypt(setting, value); + } + settingValues[setting.Name] = new SettingValue(setting.Name, value); } } @@ -100,7 +78,6 @@ public virtual async Task> GetAllAsync(string providerName, s { Check.NotNull(providerName, nameof(providerName)); - var settingValues = new Dictionary(); var settingDefinitions = SettingDefinitionManager.GetAll(); var providers = Enumerable.Reverse(Providers.Value) .SkipWhile(c => c.Name != providerName); @@ -112,29 +89,39 @@ public virtual async Task> GetAllAsync(string providerName, s var providerList = providers.Reverse().ToList(); - if (providerList.Any()) + if (!providerList.Any()) { - foreach (var setting in settingDefinitions) + return new List(); + } + + var settingValues = new Dictionary(); + + foreach (var setting in settingDefinitions) + { + string value = null; + + if (setting.IsInherited) { - if (setting.IsInherited) + foreach (var provider in providerList) { - foreach (var provider in providerList) + var providerValue = await provider.GetOrNullAsync(setting, providerKey); + if (providerValue != null) { - var value = await provider.GetOrNullAsync(setting, providerKey); - if (value != null) - { - settingValues[setting.Name] = new SettingValue(setting.Name, value); - } + value = providerValue; } } - else - { - settingValues[setting.Name] = new SettingValue( - setting.Name, - await providerList[0].GetOrNullAsync(setting, providerKey) - ); - } } + else + { + value = await providerList[0].GetOrNullAsync(setting, providerKey); + } + + if (setting.IsEncrypted) + { + value = SettingEncryptionService.Decrypt(setting, value); + } + + settingValues[setting.Name] = new SettingValue(setting.Name, value); } return settingValues.Values.ToList(); @@ -157,6 +144,11 @@ public virtual async Task SetAsync(string name, string value, string providerNam return; } + if (setting.IsEncrypted) + { + value = SettingEncryptionService.Encrypt(setting, value); + } + if (providers.Count > 1 && !forceToSet && setting.IsInherited && value != null) { //Clear the value if it's same as it's fallback value @@ -186,5 +178,47 @@ public virtual async Task SetAsync(string name, string value, string providerNam } } } + + protected virtual async Task GetOrNullInternalAsync(string name, string providerName, string providerKey, bool fallback = true) + { + var setting = SettingDefinitionManager.Get(name); + var providers = Enumerable + .Reverse(Providers.Value); + + if (providerName != null) + { + providers = providers.SkipWhile(c => c.Name != providerName); + } + + if (!fallback || !setting.IsInherited) + { + providers = providers.TakeWhile(c => c.Name == providerName); + } + + var value = await GetOrNullValueFromProvidersAsync(providerKey, providers, setting); + if (setting.IsEncrypted) + { + value = SettingEncryptionService.Decrypt(setting, value); + } + + return value; + } + + protected virtual async Task GetOrNullValueFromProvidersAsync( + string providerKey, + IEnumerable providers, + SettingDefinition setting) + { + foreach (var provider in providers) + { + var value = await provider.GetOrNullAsync(setting, providerKey); + if (value != null) + { + return value; + } + } + + return null; + } } } \ No newline at end of file