diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AIService/Overrides/MergeFeatureDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AIService/Overrides/MergeFeatureDefinitionManager.cs new file mode 100644 index 000000000..498ac24fe --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AIService/Overrides/MergeFeatureDefinitionManager.cs @@ -0,0 +1,277 @@ +using JetBrains.Annotations; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Features; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergeFeatureDefinitionManager : FeatureDefinitionManager +{ + public MergeFeatureDefinitionManager( + IStaticFeatureDefinitionStore staticStore, + IDynamicFeatureDefinitionStore dynamicStore) + : base(staticStore, dynamicStore) + { + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeFeatureMetadata(staticDefinition, dynamicDefinition); + + foreach (var child in dynamicDefinition.Children) + { + MergeChildFeature(staticDefinition, child); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetAllAsync() + { + var staticFeatures = await StaticStore.GetFeaturesAsync(); + var dynamicFeatures = await DynamicStore.GetFeaturesAsync(); + + var mergedFeatures = new Dictionary(); + + foreach (var staticFeature in staticFeatures) + { + mergedFeatures[staticFeature.Name] = staticFeature; + } + + foreach (var dynamicFeature in dynamicFeatures) + { + if (mergedFeatures.TryGetValue(dynamicFeature.Name, out var existingFeature)) + { + MergeFeatureMetadata(existingFeature, dynamicFeature); + + foreach (var child in dynamicFeature.Children) + { + MergeChildFeature(existingFeature, child); + } + } + else + { + mergedFeatures[dynamicFeature.Name] = dynamicFeature; + } + } + + return mergedFeatures.Values.ToImmutableList(); + } + + public async override Task> GetGroupsAsync() + { + var staticGroups = await StaticStore.GetGroupsAsync(); + var dynamicGroups = await DynamicStore.GetGroupsAsync(); + + var mergedGroups = new Dictionary(); + + foreach (var staticGroup in staticGroups) + { + mergedGroups[staticGroup.Name] = staticGroup; + } + + foreach (var dynamicGroup in dynamicGroups) + { + if (mergedGroups.TryGetValue(dynamicGroup.Name, out var existingGroup)) + { + MergeGroupFeatures(existingGroup, dynamicGroup); + } + else + { + mergedGroups[dynamicGroup.Name] = dynamicGroup; + } + } + + return mergedGroups.Values.ToImmutableList(); + } + + private static void MergeGroupFeatures(FeatureGroupDefinition target, FeatureGroupDefinition source) + { + foreach (var sourceFeature in source.Features) + { + var existingFeature = GetFeatureOrNull(target, sourceFeature.Name); + + if (existingFeature == null) + { + var newFeature = target.AddFeature( + sourceFeature.Name, + sourceFeature.DefaultValue, + sourceFeature.DisplayName, + sourceFeature.Description, + sourceFeature.ValueType, + sourceFeature.IsVisibleToClients, + sourceFeature.IsAvailableToHost + ); + + CopyFeatureDetails(sourceFeature, newFeature); + + foreach (var child in sourceFeature.Children) + { + AddChildFeatureRecursively(newFeature, child); + } + } + else + { + MergeFeatureMetadata(existingFeature, sourceFeature); + + foreach (var child in sourceFeature.Children) + { + MergeChildFeature(existingFeature, child); + } + } + } + } + + private static void AddChildFeatureRecursively(FeatureDefinition parent, FeatureDefinition sourceChild) + { + var newChild = parent.CreateChild( + sourceChild.Name, + sourceChild.DefaultValue, + sourceChild.DisplayName, + sourceChild.Description, + sourceChild.ValueType, + sourceChild.IsVisibleToClients, + sourceChild.IsAvailableToHost + ); + + CopyFeatureDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildFeatureRecursively(newChild, grandchild); + } + } + + private static void MergeChildFeature(FeatureDefinition parent, FeatureDefinition sourceChild) + { + var existingChild = parent.Children.FirstOrDefault(c => c.Name == sourceChild.Name); + + if (existingChild == null) + { + var newChild = parent.CreateChild( + sourceChild.Name, + sourceChild.DefaultValue, + sourceChild.DisplayName, + sourceChild.Description, + sourceChild.ValueType, + sourceChild.IsVisibleToClients, + sourceChild.IsAvailableToHost + ); + CopyFeatureDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildFeatureRecursively(newChild, grandchild); + } + } + else + { + MergeFeatureMetadata(existingChild, sourceChild); + + foreach (var grandchild in sourceChild.Children) + { + MergeChildFeature(existingChild, grandchild); + } + } + } + + private static void CopyFeatureDetails(FeatureDefinition source, FeatureDefinition target) + { + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.AllowedProviders) + { + if (!target.AllowedProviders.Contains(provider)) + { + target.AllowedProviders.Add(provider); + } + } + } + + private static void MergeFeatureMetadata(FeatureDefinition target, FeatureDefinition source) + { + if (source.DisplayName != null) + { + target.DisplayName = source.DisplayName; + } + + if (source.Description != null) + { + target.Description = source.Description; + } + + if (source.DefaultValue != null) + { + target.DefaultValue = source.DefaultValue; + } + + if (source.ValueType != null) + { + target.ValueType = source.ValueType; + } + + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.AllowedProviders) + { + if (!target.AllowedProviders.Contains(provider)) + { + target.AllowedProviders.Add(provider); + } + } + + target.IsVisibleToClients = target.IsVisibleToClients || source.IsVisibleToClients; + target.IsAvailableToHost = target.IsAvailableToHost || source.IsAvailableToHost; + } + + + public static FeatureDefinition? GetFeatureOrNull( + FeatureGroupDefinition group, + [NotNull] string name) + { + Check.NotNull(name, nameof(name)); + + return GetFeatureOrNullRecursively(group.Features, name); + } + + private static FeatureDefinition? GetFeatureOrNullRecursively( + IReadOnlyList features, + string name) + { + foreach (var feature in features) + { + if (feature.Name == name) + { + return feature; + } + + var childFeature = GetFeatureOrNullRecursively(feature.Children, name); + if (childFeature != null) + { + return childFeature; + } + } + + return null; + } +} +#nullable disable \ No newline at end of file diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AIService/Overrides/MergePermissionDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AIService/Overrides/MergePermissionDefinitionManager.cs new file mode 100644 index 000000000..027e7f1c4 --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AIService/Overrides/MergePermissionDefinitionManager.cs @@ -0,0 +1,276 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.MultiTenancy; + +namespace Volo.Abp.Authorization.Permissions; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergePermissionDefinitionManager : PermissionDefinitionManager +{ + private readonly IStaticPermissionDefinitionStore _staticStore; + private readonly IDynamicPermissionDefinitionStore _dynamicStore; + + public MergePermissionDefinitionManager( + IStaticPermissionDefinitionStore staticStore, + IDynamicPermissionDefinitionStore dynamicStore) : base(staticStore, dynamicStore) + { + _staticStore = staticStore; + _dynamicStore = dynamicStore; + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetOrNullAsync(name); + var dynamicDefinition = await _dynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task GetResourcePermissionOrNullAsync(string resourceName, string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetResourcePermissionOrNullAsync(resourceName, name); + var dynamicDefinition = await _dynamicStore.GetResourcePermissionOrNullAsync(resourceName, name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetPermissionsAsync() + { + var staticPermissions = await _staticStore.GetPermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetPermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + + public async override Task> GetResourcePermissionsAsync() + { + var staticPermissions = await _staticStore.GetResourcePermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetResourcePermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + + public async override Task> GetGroupsAsync() + { + var staticGroups = await _staticStore.GetGroupsAsync(); + var dynamicGroups = await _dynamicStore.GetGroupsAsync(); + + var mergedGroups = new Dictionary(); + + foreach (var staticGroup in staticGroups) + { + mergedGroups[staticGroup.Name] = staticGroup; + } + + foreach (var dynamicGroup in dynamicGroups) + { + if (mergedGroups.TryGetValue(dynamicGroup.Name, out var existingGroup)) + { + MergeGroupPermissions(existingGroup, dynamicGroup); + } + else + { + mergedGroups[dynamicGroup.Name] = dynamicGroup; + } + } + + return mergedGroups.Values.ToImmutableList(); + } + + private static void MergeGroupPermissions(PermissionGroupDefinition target, PermissionGroupDefinition source) + { + foreach (var sourcePermission in source.Permissions) + { + var existingPermission = target.GetPermissionOrNull(sourcePermission.Name); + + if (existingPermission == null) + { + var newPermission = target.AddPermission( + sourcePermission.Name, + sourcePermission.DisplayName, + sourcePermission.MultiTenancySide, + sourcePermission.IsEnabled + ); + + CopyPermissionDetails(sourcePermission, newPermission); + + foreach (var child in sourcePermission.Children) + { + AddChildPermissionRecursively(newPermission, child); + } + } + else + { + MergePermissionMetadata(existingPermission, sourcePermission); + + foreach (var sourceChild in sourcePermission.Children) + { + MergeChildPermissions(existingPermission, sourceChild); + } + } + } + } + + private static void AddChildPermissionRecursively(PermissionDefinition parent, PermissionDefinition sourceChild) + { + var newChild = parent.AddChild( + sourceChild.Name, + sourceChild.DisplayName, + sourceChild.MultiTenancySide, + sourceChild.IsEnabled + ); + + CopyPermissionDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildPermissionRecursively(newChild, grandchild); + } + } + + private static IReadOnlyList MergePermissions(IReadOnlyList staticPermissions, IReadOnlyList dynamicPermissions) + { + var mergedPermissions = new Dictionary(); + + foreach (var staticFeature in staticPermissions) + { + mergedPermissions[staticFeature.Name] = staticFeature; + } + + foreach (var dynamicPermission in dynamicPermissions) + { + if (mergedPermissions.TryGetValue(dynamicPermission.Name, out var existingPermission)) + { + MergePermissionMetadata(existingPermission, dynamicPermission); + + foreach (var sourceChild in dynamicPermission.Children) + { + MergeChildPermissions(existingPermission, sourceChild); + } + } + else + { + mergedPermissions[dynamicPermission.Name] = dynamicPermission; + } + } + + return mergedPermissions.Values.ToImmutableList(); + } + + private static void MergeChildPermissions(PermissionDefinition parent, PermissionDefinition sourceChild) + { + var existingChild = parent.Children.FirstOrDefault(c => c.Name == sourceChild.Name); + + if (existingChild == null) + { + var newChild = parent.AddChild( + sourceChild.Name, + sourceChild.DisplayName, + sourceChild.MultiTenancySide, + sourceChild.IsEnabled + ); + CopyPermissionDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildPermissionRecursively(newChild, grandchild); + } + } + else + { + MergePermissionMetadata(existingChild, sourceChild); + + foreach (var grandchild in sourceChild.Children) + { + MergeChildPermissions(existingChild, grandchild); + } + } + } + + private static void CopyPermissionDetails(PermissionDefinition source, PermissionDefinition target) + { + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.Providers) + { + if (!target.Providers.Contains(provider)) + { + target.Providers.Add(provider); + } + } + + foreach (var checker in source.StateCheckers) + { + if (!target.StateCheckers.Contains(checker)) + { + target.StateCheckers.Add(checker); + } + } + } + + private static void MergePermissionMetadata(PermissionDefinition target, PermissionDefinition source) + { + target.DisplayName = source.DisplayName; + + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.Providers) + { + if (!target.Providers.Contains(provider)) + { + target.Providers.Add(provider); + } + } + + foreach (var checker in source.StateCheckers) + { + if (!target.StateCheckers.Contains(checker)) + { + target.StateCheckers.Add(checker); + } + } + + if (source.MultiTenancySide != MultiTenancySides.Both) + { + target.MultiTenancySide |= source.MultiTenancySide; + } + + target.IsEnabled = target.IsEnabled || source.IsEnabled; + } +} +#nullable disable \ No newline at end of file diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AIService/Overrides/MergeSettingDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AIService/Overrides/MergeSettingDefinitionManager.cs new file mode 100644 index 000000000..2fe64a566 --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AIService/Overrides/MergeSettingDefinitionManager.cs @@ -0,0 +1,86 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Settings; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergeSettingDefinitionManager : SettingDefinitionManager +{ + public MergeSettingDefinitionManager( + IStaticSettingDefinitionStore staticStore, + IDynamicSettingDefinitionStore dynamicStore) + : base(staticStore, dynamicStore) + { + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeSetting(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetAllAsync() + { + var staticSettings = await StaticStore.GetAllAsync(); + var dynamicSettings = await DynamicStore.GetAllAsync(); + + var mergedSettings = new Dictionary(); + + foreach (var staticSetting in staticSettings) + { + mergedSettings[staticSetting.Name] = staticSetting; + } + + foreach (var dynamicSetting in dynamicSettings) + { + if (mergedSettings.TryGetValue(dynamicSetting.Name, out var existingSetting)) + { + MergeSetting(existingSetting, dynamicSetting); + } + else + { + mergedSettings[dynamicSetting.Name] = dynamicSetting; + } + } + + return mergedSettings.Values.ToImmutableList(); + } + + private static void MergeSetting(SettingDefinition target, SettingDefinition source) + { + target.DisplayName = source.DisplayName; + target.Description = source.Description ?? target.Description; + target.DefaultValue = source.DefaultValue ?? target.DefaultValue; + target.IsVisibleToClients = target.IsVisibleToClients || source.IsVisibleToClients; + target.IsInherited = target.IsInherited || source.IsInherited; + target.IsEncrypted = target.IsEncrypted || source.IsEncrypted; + + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.Providers) + { + if (!target.Providers.Contains(provider)) + { + target.Providers.Add(provider); + } + } + } +} +#nullable disable + diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AIService/Overrides/MergeTemplateDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AIService/Overrides/MergeTemplateDefinitionManager.cs new file mode 100644 index 000000000..5cb3137cd --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AIService/Overrides/MergeTemplateDefinitionManager.cs @@ -0,0 +1,104 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.TextTemplating; + +namespace Volo.Abp.TextTemplatin; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergeTemplateDefinitionManager : TemplateDefinitionManager +{ + public MergeTemplateDefinitionManager( + IStaticTemplateDefinitionStore staticStore, + IDynamicTemplateDefinitionStore dynamicStore) + : base(staticStore, dynamicStore) + { + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeTemplate(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetAllAsync() + { + var staticTemplates = await StaticStore.GetAllAsync(); + var dynamicTemplates = await DynamicStore.GetAllAsync(); + + var mergedTemplates = new Dictionary(); + + foreach (var staticTemplate in staticTemplates) + { + mergedTemplates[staticTemplate.Name] = staticTemplate; + } + + foreach (var dynamicTemplate in dynamicTemplates) + { + if (mergedTemplates.TryGetValue(dynamicTemplate.Name, out var existingTemplate)) + { + MergeTemplate(existingTemplate, dynamicTemplate); + } + else + { + mergedTemplates[dynamicTemplate.Name] = dynamicTemplate; + } + } + + return mergedTemplates.Values.ToImmutableList(); + } + + private static TemplateDefinition MergeTemplate(TemplateDefinition staticTemplate, TemplateDefinition dynamicTemplate) + { + var localizationResourceName = dynamicTemplate.LocalizationResourceName ?? staticTemplate.LocalizationResourceName; + var defaultCultureName = dynamicTemplate.DefaultCultureName ?? staticTemplate.DefaultCultureName; + var displayName = dynamicTemplate.DisplayName ?? staticTemplate.DisplayName; + var isLayout = dynamicTemplate.IsLayout || staticTemplate.IsLayout; + var layout = dynamicTemplate.Layout ?? staticTemplate.Layout; + + var mergedTemplate = new TemplateDefinition( + staticTemplate.Name, + localizationResourceName, + displayName, + isLayout, + layout, + defaultCultureName + ); + + foreach (var property in staticTemplate.Properties) + { + mergedTemplate.Properties[property.Key] = property.Value; + } + + foreach (var property in dynamicTemplate.Properties) + { + mergedTemplate.Properties[property.Key] = property.Value; + } + + if (!string.IsNullOrEmpty(dynamicTemplate.RenderEngine)) + { + mergedTemplate.RenderEngine = dynamicTemplate.RenderEngine; + } + else if (!string.IsNullOrEmpty(staticTemplate.RenderEngine)) + { + mergedTemplate.RenderEngine = staticTemplate.RenderEngine; + } + + mergedTemplate.IsInlineLocalized = dynamicTemplate.IsInlineLocalized || staticTemplate.IsInlineLocalized; + + return mergedTemplate; + } +} +#nullable disable diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService/Overrides/MergeFeatureDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService/Overrides/MergeFeatureDefinitionManager.cs index e7c395b1f..498ac24fe 100644 --- a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService/Overrides/MergeFeatureDefinitionManager.cs +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService/Overrides/MergeFeatureDefinitionManager.cs @@ -1,8 +1,14 @@ -using System.Collections.Immutable; +using JetBrains.Annotations; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Threading.Tasks; using Volo.Abp.DependencyInjection; namespace Volo.Abp.Features; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergeFeatureDefinitionManager : FeatureDefinitionManager { @@ -13,6 +19,26 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager { } + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeFeatureMetadata(staticDefinition, dynamicDefinition); + + foreach (var child in dynamicDefinition.Children) + { + MergeChildFeature(staticDefinition, child); + } + } + + return staticDefinition ?? dynamicDefinition; + } + public async override Task> GetAllAsync() { var staticFeatures = await StaticStore.GetFeaturesAsync(); @@ -76,7 +102,7 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager { foreach (var sourceFeature in source.Features) { - var existingFeature = target.GetFeatureOrNull(sourceFeature.Name); + var existingFeature = GetFeatureOrNull(target, sourceFeature.Name); if (existingFeature == null) { @@ -216,4 +242,36 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager target.IsVisibleToClients = target.IsVisibleToClients || source.IsVisibleToClients; target.IsAvailableToHost = target.IsAvailableToHost || source.IsAvailableToHost; } + + + public static FeatureDefinition? GetFeatureOrNull( + FeatureGroupDefinition group, + [NotNull] string name) + { + Check.NotNull(name, nameof(name)); + + return GetFeatureOrNullRecursively(group.Features, name); + } + + private static FeatureDefinition? GetFeatureOrNullRecursively( + IReadOnlyList features, + string name) + { + foreach (var feature in features) + { + if (feature.Name == name) + { + return feature; + } + + var childFeature = GetFeatureOrNullRecursively(feature.Children, name); + if (childFeature != null) + { + return childFeature; + } + } + + return null; + } } +#nullable disable \ No newline at end of file diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService/Overrides/MergePermissionDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService/Overrides/MergePermissionDefinitionManager.cs index f224a1dd1..027e7f1c4 100644 --- a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService/Overrides/MergePermissionDefinitionManager.cs +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService/Overrides/MergePermissionDefinitionManager.cs @@ -1,9 +1,14 @@ -using System.Collections.Immutable; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Threading.Tasks; using Volo.Abp.DependencyInjection; using Volo.Abp.MultiTenancy; namespace Volo.Abp.Authorization.Permissions; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergePermissionDefinitionManager : PermissionDefinitionManager { @@ -18,6 +23,62 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager _dynamicStore = dynamicStore; } + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetOrNullAsync(name); + var dynamicDefinition = await _dynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task GetResourcePermissionOrNullAsync(string resourceName, string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetResourcePermissionOrNullAsync(resourceName, name); + var dynamicDefinition = await _dynamicStore.GetResourcePermissionOrNullAsync(resourceName, name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetPermissionsAsync() + { + var staticPermissions = await _staticStore.GetPermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetPermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + + public async override Task> GetResourcePermissionsAsync() + { + var staticPermissions = await _staticStore.GetResourcePermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetResourcePermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + public async override Task> GetGroupsAsync() { var staticGroups = await _staticStore.GetGroupsAsync(); @@ -96,6 +157,35 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager } } + private static IReadOnlyList MergePermissions(IReadOnlyList staticPermissions, IReadOnlyList dynamicPermissions) + { + var mergedPermissions = new Dictionary(); + + foreach (var staticFeature in staticPermissions) + { + mergedPermissions[staticFeature.Name] = staticFeature; + } + + foreach (var dynamicPermission in dynamicPermissions) + { + if (mergedPermissions.TryGetValue(dynamicPermission.Name, out var existingPermission)) + { + MergePermissionMetadata(existingPermission, dynamicPermission); + + foreach (var sourceChild in dynamicPermission.Children) + { + MergeChildPermissions(existingPermission, sourceChild); + } + } + else + { + mergedPermissions[dynamicPermission.Name] = dynamicPermission; + } + } + + return mergedPermissions.Values.ToImmutableList(); + } + private static void MergeChildPermissions(PermissionDefinition parent, PermissionDefinition sourceChild) { var existingChild = parent.Children.FirstOrDefault(c => c.Name == sourceChild.Name); @@ -182,4 +272,5 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager target.IsEnabled = target.IsEnabled || source.IsEnabled; } -} \ No newline at end of file +} +#nullable disable \ No newline at end of file diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService/Overrides/MergeSettingDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService/Overrides/MergeSettingDefinitionManager.cs index 6ed3c40de..2fe64a566 100644 --- a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService/Overrides/MergeSettingDefinitionManager.cs +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService/Overrides/MergeSettingDefinitionManager.cs @@ -1,27 +1,41 @@ -using System.Collections.Immutable; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading.Tasks; using Volo.Abp.DependencyInjection; namespace Volo.Abp.Settings; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergeSettingDefinitionManager : SettingDefinitionManager { - private readonly IStaticSettingDefinitionStore _staticStore; - private readonly IDynamicSettingDefinitionStore _dynamicStore; - public MergeSettingDefinitionManager( IStaticSettingDefinitionStore staticStore, IDynamicSettingDefinitionStore dynamicStore) : base(staticStore, dynamicStore) { - _staticStore = staticStore; - _dynamicStore = dynamicStore; + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeSetting(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; } public async override Task> GetAllAsync() { - var staticSettings = await _staticStore.GetAllAsync(); - var dynamicSettings = await _dynamicStore.GetAllAsync(); + var staticSettings = await StaticStore.GetAllAsync(); + var dynamicSettings = await DynamicStore.GetAllAsync(); var mergedSettings = new Dictionary(); @@ -68,4 +82,5 @@ public class MergeSettingDefinitionManager : SettingDefinitionManager } } } +#nullable disable diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService/Overrides/MergeTemplateDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService/Overrides/MergeTemplateDefinitionManager.cs index 467966c11..5cb3137cd 100644 --- a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService/Overrides/MergeTemplateDefinitionManager.cs +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AdminService/Overrides/MergeTemplateDefinitionManager.cs @@ -1,9 +1,12 @@ -using System.Collections.Immutable; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading.Tasks; using Volo.Abp.DependencyInjection; using Volo.Abp.TextTemplating; namespace Volo.Abp.TextTemplatin; +#nullable enable [Dependency(ReplaceServices = true)] public class MergeTemplateDefinitionManager : TemplateDefinitionManager @@ -14,6 +17,22 @@ public class MergeTemplateDefinitionManager : TemplateDefinitionManager : base(staticStore, dynamicStore) { } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeTemplate(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; + } + public async override Task> GetAllAsync() { var staticTemplates = await StaticStore.GetAllAsync(); @@ -82,3 +101,4 @@ public class MergeTemplateDefinitionManager : TemplateDefinitionManager return mergedTemplate; } } +#nullable disable diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer/Overrides/MergeFeatureDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer/Overrides/MergeFeatureDefinitionManager.cs index 887001b2f..498ac24fe 100644 --- a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer/Overrides/MergeFeatureDefinitionManager.cs +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer/Overrides/MergeFeatureDefinitionManager.cs @@ -7,6 +7,8 @@ using Volo.Abp.DependencyInjection; namespace Volo.Abp.Features; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergeFeatureDefinitionManager : FeatureDefinitionManager { @@ -17,6 +19,26 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager { } + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeFeatureMetadata(staticDefinition, dynamicDefinition); + + foreach (var child in dynamicDefinition.Children) + { + MergeChildFeature(staticDefinition, child); + } + } + + return staticDefinition ?? dynamicDefinition; + } + public async override Task> GetAllAsync() { var staticFeatures = await StaticStore.GetFeaturesAsync(); @@ -222,7 +244,7 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager } - public static FeatureDefinition GetFeatureOrNull( + public static FeatureDefinition? GetFeatureOrNull( FeatureGroupDefinition group, [NotNull] string name) { @@ -231,7 +253,7 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager return GetFeatureOrNullRecursively(group.Features, name); } - private static FeatureDefinition GetFeatureOrNullRecursively( + private static FeatureDefinition? GetFeatureOrNullRecursively( IReadOnlyList features, string name) { @@ -252,3 +274,4 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager return null; } } +#nullable disable \ No newline at end of file diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer/Overrides/MergePermissionDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer/Overrides/MergePermissionDefinitionManager.cs index 68b34e48b..027e7f1c4 100644 --- a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer/Overrides/MergePermissionDefinitionManager.cs +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer/Overrides/MergePermissionDefinitionManager.cs @@ -7,6 +7,8 @@ using Volo.Abp.MultiTenancy; namespace Volo.Abp.Authorization.Permissions; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergePermissionDefinitionManager : PermissionDefinitionManager { @@ -21,6 +23,62 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager _dynamicStore = dynamicStore; } + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetOrNullAsync(name); + var dynamicDefinition = await _dynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task GetResourcePermissionOrNullAsync(string resourceName, string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetResourcePermissionOrNullAsync(resourceName, name); + var dynamicDefinition = await _dynamicStore.GetResourcePermissionOrNullAsync(resourceName, name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetPermissionsAsync() + { + var staticPermissions = await _staticStore.GetPermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetPermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + + public async override Task> GetResourcePermissionsAsync() + { + var staticPermissions = await _staticStore.GetResourcePermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetResourcePermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + public async override Task> GetGroupsAsync() { var staticGroups = await _staticStore.GetGroupsAsync(); @@ -99,6 +157,35 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager } } + private static IReadOnlyList MergePermissions(IReadOnlyList staticPermissions, IReadOnlyList dynamicPermissions) + { + var mergedPermissions = new Dictionary(); + + foreach (var staticFeature in staticPermissions) + { + mergedPermissions[staticFeature.Name] = staticFeature; + } + + foreach (var dynamicPermission in dynamicPermissions) + { + if (mergedPermissions.TryGetValue(dynamicPermission.Name, out var existingPermission)) + { + MergePermissionMetadata(existingPermission, dynamicPermission); + + foreach (var sourceChild in dynamicPermission.Children) + { + MergeChildPermissions(existingPermission, sourceChild); + } + } + else + { + mergedPermissions[dynamicPermission.Name] = dynamicPermission; + } + } + + return mergedPermissions.Values.ToImmutableList(); + } + private static void MergeChildPermissions(PermissionDefinition parent, PermissionDefinition sourceChild) { var existingChild = parent.Children.FirstOrDefault(c => c.Name == sourceChild.Name); @@ -185,4 +272,5 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager target.IsEnabled = target.IsEnabled || source.IsEnabled; } -} \ No newline at end of file +} +#nullable disable \ No newline at end of file diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer/Overrides/MergeSettingDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer/Overrides/MergeSettingDefinitionManager.cs index c3c479f4f..2fe64a566 100644 --- a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer/Overrides/MergeSettingDefinitionManager.cs +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer/Overrides/MergeSettingDefinitionManager.cs @@ -5,25 +5,37 @@ using Volo.Abp.DependencyInjection; namespace Volo.Abp.Settings; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergeSettingDefinitionManager : SettingDefinitionManager { - private readonly IStaticSettingDefinitionStore _staticStore; - private readonly IDynamicSettingDefinitionStore _dynamicStore; - public MergeSettingDefinitionManager( IStaticSettingDefinitionStore staticStore, IDynamicSettingDefinitionStore dynamicStore) : base(staticStore, dynamicStore) { - _staticStore = staticStore; - _dynamicStore = dynamicStore; + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeSetting(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; } public async override Task> GetAllAsync() { - var staticSettings = await _staticStore.GetAllAsync(); - var dynamicSettings = await _dynamicStore.GetAllAsync(); + var staticSettings = await StaticStore.GetAllAsync(); + var dynamicSettings = await DynamicStore.GetAllAsync(); var mergedSettings = new Dictionary(); @@ -70,4 +82,5 @@ public class MergeSettingDefinitionManager : SettingDefinitionManager } } } +#nullable disable diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer/Overrides/MergeTemplateDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer/Overrides/MergeTemplateDefinitionManager.cs index 0a45a8908..5cb3137cd 100644 --- a/aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer/Overrides/MergeTemplateDefinitionManager.cs +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.AuthServer/Overrides/MergeTemplateDefinitionManager.cs @@ -6,6 +6,7 @@ using Volo.Abp.TextTemplating; namespace Volo.Abp.TextTemplatin; +#nullable enable [Dependency(ReplaceServices = true)] public class MergeTemplateDefinitionManager : TemplateDefinitionManager @@ -16,6 +17,22 @@ public class MergeTemplateDefinitionManager : TemplateDefinitionManager : base(staticStore, dynamicStore) { } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeTemplate(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; + } + public async override Task> GetAllAsync() { var staticTemplates = await StaticStore.GetAllAsync(); @@ -84,3 +101,4 @@ public class MergeTemplateDefinitionManager : TemplateDefinitionManager return mergedTemplate; } } +#nullable disable diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.IdentityService/Overrides/MergeFeatureDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.IdentityService/Overrides/MergeFeatureDefinitionManager.cs new file mode 100644 index 000000000..498ac24fe --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.IdentityService/Overrides/MergeFeatureDefinitionManager.cs @@ -0,0 +1,277 @@ +using JetBrains.Annotations; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Features; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergeFeatureDefinitionManager : FeatureDefinitionManager +{ + public MergeFeatureDefinitionManager( + IStaticFeatureDefinitionStore staticStore, + IDynamicFeatureDefinitionStore dynamicStore) + : base(staticStore, dynamicStore) + { + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeFeatureMetadata(staticDefinition, dynamicDefinition); + + foreach (var child in dynamicDefinition.Children) + { + MergeChildFeature(staticDefinition, child); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetAllAsync() + { + var staticFeatures = await StaticStore.GetFeaturesAsync(); + var dynamicFeatures = await DynamicStore.GetFeaturesAsync(); + + var mergedFeatures = new Dictionary(); + + foreach (var staticFeature in staticFeatures) + { + mergedFeatures[staticFeature.Name] = staticFeature; + } + + foreach (var dynamicFeature in dynamicFeatures) + { + if (mergedFeatures.TryGetValue(dynamicFeature.Name, out var existingFeature)) + { + MergeFeatureMetadata(existingFeature, dynamicFeature); + + foreach (var child in dynamicFeature.Children) + { + MergeChildFeature(existingFeature, child); + } + } + else + { + mergedFeatures[dynamicFeature.Name] = dynamicFeature; + } + } + + return mergedFeatures.Values.ToImmutableList(); + } + + public async override Task> GetGroupsAsync() + { + var staticGroups = await StaticStore.GetGroupsAsync(); + var dynamicGroups = await DynamicStore.GetGroupsAsync(); + + var mergedGroups = new Dictionary(); + + foreach (var staticGroup in staticGroups) + { + mergedGroups[staticGroup.Name] = staticGroup; + } + + foreach (var dynamicGroup in dynamicGroups) + { + if (mergedGroups.TryGetValue(dynamicGroup.Name, out var existingGroup)) + { + MergeGroupFeatures(existingGroup, dynamicGroup); + } + else + { + mergedGroups[dynamicGroup.Name] = dynamicGroup; + } + } + + return mergedGroups.Values.ToImmutableList(); + } + + private static void MergeGroupFeatures(FeatureGroupDefinition target, FeatureGroupDefinition source) + { + foreach (var sourceFeature in source.Features) + { + var existingFeature = GetFeatureOrNull(target, sourceFeature.Name); + + if (existingFeature == null) + { + var newFeature = target.AddFeature( + sourceFeature.Name, + sourceFeature.DefaultValue, + sourceFeature.DisplayName, + sourceFeature.Description, + sourceFeature.ValueType, + sourceFeature.IsVisibleToClients, + sourceFeature.IsAvailableToHost + ); + + CopyFeatureDetails(sourceFeature, newFeature); + + foreach (var child in sourceFeature.Children) + { + AddChildFeatureRecursively(newFeature, child); + } + } + else + { + MergeFeatureMetadata(existingFeature, sourceFeature); + + foreach (var child in sourceFeature.Children) + { + MergeChildFeature(existingFeature, child); + } + } + } + } + + private static void AddChildFeatureRecursively(FeatureDefinition parent, FeatureDefinition sourceChild) + { + var newChild = parent.CreateChild( + sourceChild.Name, + sourceChild.DefaultValue, + sourceChild.DisplayName, + sourceChild.Description, + sourceChild.ValueType, + sourceChild.IsVisibleToClients, + sourceChild.IsAvailableToHost + ); + + CopyFeatureDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildFeatureRecursively(newChild, grandchild); + } + } + + private static void MergeChildFeature(FeatureDefinition parent, FeatureDefinition sourceChild) + { + var existingChild = parent.Children.FirstOrDefault(c => c.Name == sourceChild.Name); + + if (existingChild == null) + { + var newChild = parent.CreateChild( + sourceChild.Name, + sourceChild.DefaultValue, + sourceChild.DisplayName, + sourceChild.Description, + sourceChild.ValueType, + sourceChild.IsVisibleToClients, + sourceChild.IsAvailableToHost + ); + CopyFeatureDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildFeatureRecursively(newChild, grandchild); + } + } + else + { + MergeFeatureMetadata(existingChild, sourceChild); + + foreach (var grandchild in sourceChild.Children) + { + MergeChildFeature(existingChild, grandchild); + } + } + } + + private static void CopyFeatureDetails(FeatureDefinition source, FeatureDefinition target) + { + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.AllowedProviders) + { + if (!target.AllowedProviders.Contains(provider)) + { + target.AllowedProviders.Add(provider); + } + } + } + + private static void MergeFeatureMetadata(FeatureDefinition target, FeatureDefinition source) + { + if (source.DisplayName != null) + { + target.DisplayName = source.DisplayName; + } + + if (source.Description != null) + { + target.Description = source.Description; + } + + if (source.DefaultValue != null) + { + target.DefaultValue = source.DefaultValue; + } + + if (source.ValueType != null) + { + target.ValueType = source.ValueType; + } + + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.AllowedProviders) + { + if (!target.AllowedProviders.Contains(provider)) + { + target.AllowedProviders.Add(provider); + } + } + + target.IsVisibleToClients = target.IsVisibleToClients || source.IsVisibleToClients; + target.IsAvailableToHost = target.IsAvailableToHost || source.IsAvailableToHost; + } + + + public static FeatureDefinition? GetFeatureOrNull( + FeatureGroupDefinition group, + [NotNull] string name) + { + Check.NotNull(name, nameof(name)); + + return GetFeatureOrNullRecursively(group.Features, name); + } + + private static FeatureDefinition? GetFeatureOrNullRecursively( + IReadOnlyList features, + string name) + { + foreach (var feature in features) + { + if (feature.Name == name) + { + return feature; + } + + var childFeature = GetFeatureOrNullRecursively(feature.Children, name); + if (childFeature != null) + { + return childFeature; + } + } + + return null; + } +} +#nullable disable \ No newline at end of file diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.IdentityService/Overrides/MergePermissionDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.IdentityService/Overrides/MergePermissionDefinitionManager.cs new file mode 100644 index 000000000..027e7f1c4 --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.IdentityService/Overrides/MergePermissionDefinitionManager.cs @@ -0,0 +1,276 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.MultiTenancy; + +namespace Volo.Abp.Authorization.Permissions; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergePermissionDefinitionManager : PermissionDefinitionManager +{ + private readonly IStaticPermissionDefinitionStore _staticStore; + private readonly IDynamicPermissionDefinitionStore _dynamicStore; + + public MergePermissionDefinitionManager( + IStaticPermissionDefinitionStore staticStore, + IDynamicPermissionDefinitionStore dynamicStore) : base(staticStore, dynamicStore) + { + _staticStore = staticStore; + _dynamicStore = dynamicStore; + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetOrNullAsync(name); + var dynamicDefinition = await _dynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task GetResourcePermissionOrNullAsync(string resourceName, string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetResourcePermissionOrNullAsync(resourceName, name); + var dynamicDefinition = await _dynamicStore.GetResourcePermissionOrNullAsync(resourceName, name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetPermissionsAsync() + { + var staticPermissions = await _staticStore.GetPermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetPermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + + public async override Task> GetResourcePermissionsAsync() + { + var staticPermissions = await _staticStore.GetResourcePermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetResourcePermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + + public async override Task> GetGroupsAsync() + { + var staticGroups = await _staticStore.GetGroupsAsync(); + var dynamicGroups = await _dynamicStore.GetGroupsAsync(); + + var mergedGroups = new Dictionary(); + + foreach (var staticGroup in staticGroups) + { + mergedGroups[staticGroup.Name] = staticGroup; + } + + foreach (var dynamicGroup in dynamicGroups) + { + if (mergedGroups.TryGetValue(dynamicGroup.Name, out var existingGroup)) + { + MergeGroupPermissions(existingGroup, dynamicGroup); + } + else + { + mergedGroups[dynamicGroup.Name] = dynamicGroup; + } + } + + return mergedGroups.Values.ToImmutableList(); + } + + private static void MergeGroupPermissions(PermissionGroupDefinition target, PermissionGroupDefinition source) + { + foreach (var sourcePermission in source.Permissions) + { + var existingPermission = target.GetPermissionOrNull(sourcePermission.Name); + + if (existingPermission == null) + { + var newPermission = target.AddPermission( + sourcePermission.Name, + sourcePermission.DisplayName, + sourcePermission.MultiTenancySide, + sourcePermission.IsEnabled + ); + + CopyPermissionDetails(sourcePermission, newPermission); + + foreach (var child in sourcePermission.Children) + { + AddChildPermissionRecursively(newPermission, child); + } + } + else + { + MergePermissionMetadata(existingPermission, sourcePermission); + + foreach (var sourceChild in sourcePermission.Children) + { + MergeChildPermissions(existingPermission, sourceChild); + } + } + } + } + + private static void AddChildPermissionRecursively(PermissionDefinition parent, PermissionDefinition sourceChild) + { + var newChild = parent.AddChild( + sourceChild.Name, + sourceChild.DisplayName, + sourceChild.MultiTenancySide, + sourceChild.IsEnabled + ); + + CopyPermissionDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildPermissionRecursively(newChild, grandchild); + } + } + + private static IReadOnlyList MergePermissions(IReadOnlyList staticPermissions, IReadOnlyList dynamicPermissions) + { + var mergedPermissions = new Dictionary(); + + foreach (var staticFeature in staticPermissions) + { + mergedPermissions[staticFeature.Name] = staticFeature; + } + + foreach (var dynamicPermission in dynamicPermissions) + { + if (mergedPermissions.TryGetValue(dynamicPermission.Name, out var existingPermission)) + { + MergePermissionMetadata(existingPermission, dynamicPermission); + + foreach (var sourceChild in dynamicPermission.Children) + { + MergeChildPermissions(existingPermission, sourceChild); + } + } + else + { + mergedPermissions[dynamicPermission.Name] = dynamicPermission; + } + } + + return mergedPermissions.Values.ToImmutableList(); + } + + private static void MergeChildPermissions(PermissionDefinition parent, PermissionDefinition sourceChild) + { + var existingChild = parent.Children.FirstOrDefault(c => c.Name == sourceChild.Name); + + if (existingChild == null) + { + var newChild = parent.AddChild( + sourceChild.Name, + sourceChild.DisplayName, + sourceChild.MultiTenancySide, + sourceChild.IsEnabled + ); + CopyPermissionDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildPermissionRecursively(newChild, grandchild); + } + } + else + { + MergePermissionMetadata(existingChild, sourceChild); + + foreach (var grandchild in sourceChild.Children) + { + MergeChildPermissions(existingChild, grandchild); + } + } + } + + private static void CopyPermissionDetails(PermissionDefinition source, PermissionDefinition target) + { + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.Providers) + { + if (!target.Providers.Contains(provider)) + { + target.Providers.Add(provider); + } + } + + foreach (var checker in source.StateCheckers) + { + if (!target.StateCheckers.Contains(checker)) + { + target.StateCheckers.Add(checker); + } + } + } + + private static void MergePermissionMetadata(PermissionDefinition target, PermissionDefinition source) + { + target.DisplayName = source.DisplayName; + + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.Providers) + { + if (!target.Providers.Contains(provider)) + { + target.Providers.Add(provider); + } + } + + foreach (var checker in source.StateCheckers) + { + if (!target.StateCheckers.Contains(checker)) + { + target.StateCheckers.Add(checker); + } + } + + if (source.MultiTenancySide != MultiTenancySides.Both) + { + target.MultiTenancySide |= source.MultiTenancySide; + } + + target.IsEnabled = target.IsEnabled || source.IsEnabled; + } +} +#nullable disable \ No newline at end of file diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.IdentityService/Overrides/MergeSettingDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.IdentityService/Overrides/MergeSettingDefinitionManager.cs new file mode 100644 index 000000000..2fe64a566 --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.IdentityService/Overrides/MergeSettingDefinitionManager.cs @@ -0,0 +1,86 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Settings; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergeSettingDefinitionManager : SettingDefinitionManager +{ + public MergeSettingDefinitionManager( + IStaticSettingDefinitionStore staticStore, + IDynamicSettingDefinitionStore dynamicStore) + : base(staticStore, dynamicStore) + { + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeSetting(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetAllAsync() + { + var staticSettings = await StaticStore.GetAllAsync(); + var dynamicSettings = await DynamicStore.GetAllAsync(); + + var mergedSettings = new Dictionary(); + + foreach (var staticSetting in staticSettings) + { + mergedSettings[staticSetting.Name] = staticSetting; + } + + foreach (var dynamicSetting in dynamicSettings) + { + if (mergedSettings.TryGetValue(dynamicSetting.Name, out var existingSetting)) + { + MergeSetting(existingSetting, dynamicSetting); + } + else + { + mergedSettings[dynamicSetting.Name] = dynamicSetting; + } + } + + return mergedSettings.Values.ToImmutableList(); + } + + private static void MergeSetting(SettingDefinition target, SettingDefinition source) + { + target.DisplayName = source.DisplayName; + target.Description = source.Description ?? target.Description; + target.DefaultValue = source.DefaultValue ?? target.DefaultValue; + target.IsVisibleToClients = target.IsVisibleToClients || source.IsVisibleToClients; + target.IsInherited = target.IsInherited || source.IsInherited; + target.IsEncrypted = target.IsEncrypted || source.IsEncrypted; + + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.Providers) + { + if (!target.Providers.Contains(provider)) + { + target.Providers.Add(provider); + } + } + } +} +#nullable disable + diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.IdentityService/Overrides/MergeTemplateDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.IdentityService/Overrides/MergeTemplateDefinitionManager.cs new file mode 100644 index 000000000..5cb3137cd --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.IdentityService/Overrides/MergeTemplateDefinitionManager.cs @@ -0,0 +1,104 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.TextTemplating; + +namespace Volo.Abp.TextTemplatin; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergeTemplateDefinitionManager : TemplateDefinitionManager +{ + public MergeTemplateDefinitionManager( + IStaticTemplateDefinitionStore staticStore, + IDynamicTemplateDefinitionStore dynamicStore) + : base(staticStore, dynamicStore) + { + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeTemplate(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetAllAsync() + { + var staticTemplates = await StaticStore.GetAllAsync(); + var dynamicTemplates = await DynamicStore.GetAllAsync(); + + var mergedTemplates = new Dictionary(); + + foreach (var staticTemplate in staticTemplates) + { + mergedTemplates[staticTemplate.Name] = staticTemplate; + } + + foreach (var dynamicTemplate in dynamicTemplates) + { + if (mergedTemplates.TryGetValue(dynamicTemplate.Name, out var existingTemplate)) + { + MergeTemplate(existingTemplate, dynamicTemplate); + } + else + { + mergedTemplates[dynamicTemplate.Name] = dynamicTemplate; + } + } + + return mergedTemplates.Values.ToImmutableList(); + } + + private static TemplateDefinition MergeTemplate(TemplateDefinition staticTemplate, TemplateDefinition dynamicTemplate) + { + var localizationResourceName = dynamicTemplate.LocalizationResourceName ?? staticTemplate.LocalizationResourceName; + var defaultCultureName = dynamicTemplate.DefaultCultureName ?? staticTemplate.DefaultCultureName; + var displayName = dynamicTemplate.DisplayName ?? staticTemplate.DisplayName; + var isLayout = dynamicTemplate.IsLayout || staticTemplate.IsLayout; + var layout = dynamicTemplate.Layout ?? staticTemplate.Layout; + + var mergedTemplate = new TemplateDefinition( + staticTemplate.Name, + localizationResourceName, + displayName, + isLayout, + layout, + defaultCultureName + ); + + foreach (var property in staticTemplate.Properties) + { + mergedTemplate.Properties[property.Key] = property.Value; + } + + foreach (var property in dynamicTemplate.Properties) + { + mergedTemplate.Properties[property.Key] = property.Value; + } + + if (!string.IsNullOrEmpty(dynamicTemplate.RenderEngine)) + { + mergedTemplate.RenderEngine = dynamicTemplate.RenderEngine; + } + else if (!string.IsNullOrEmpty(staticTemplate.RenderEngine)) + { + mergedTemplate.RenderEngine = staticTemplate.RenderEngine; + } + + mergedTemplate.IsInlineLocalized = dynamicTemplate.IsInlineLocalized || staticTemplate.IsInlineLocalized; + + return mergedTemplate; + } +} +#nullable disable diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.LocalizationService/Overrides/MergeFeatureDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.LocalizationService/Overrides/MergeFeatureDefinitionManager.cs new file mode 100644 index 000000000..498ac24fe --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.LocalizationService/Overrides/MergeFeatureDefinitionManager.cs @@ -0,0 +1,277 @@ +using JetBrains.Annotations; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Features; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergeFeatureDefinitionManager : FeatureDefinitionManager +{ + public MergeFeatureDefinitionManager( + IStaticFeatureDefinitionStore staticStore, + IDynamicFeatureDefinitionStore dynamicStore) + : base(staticStore, dynamicStore) + { + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeFeatureMetadata(staticDefinition, dynamicDefinition); + + foreach (var child in dynamicDefinition.Children) + { + MergeChildFeature(staticDefinition, child); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetAllAsync() + { + var staticFeatures = await StaticStore.GetFeaturesAsync(); + var dynamicFeatures = await DynamicStore.GetFeaturesAsync(); + + var mergedFeatures = new Dictionary(); + + foreach (var staticFeature in staticFeatures) + { + mergedFeatures[staticFeature.Name] = staticFeature; + } + + foreach (var dynamicFeature in dynamicFeatures) + { + if (mergedFeatures.TryGetValue(dynamicFeature.Name, out var existingFeature)) + { + MergeFeatureMetadata(existingFeature, dynamicFeature); + + foreach (var child in dynamicFeature.Children) + { + MergeChildFeature(existingFeature, child); + } + } + else + { + mergedFeatures[dynamicFeature.Name] = dynamicFeature; + } + } + + return mergedFeatures.Values.ToImmutableList(); + } + + public async override Task> GetGroupsAsync() + { + var staticGroups = await StaticStore.GetGroupsAsync(); + var dynamicGroups = await DynamicStore.GetGroupsAsync(); + + var mergedGroups = new Dictionary(); + + foreach (var staticGroup in staticGroups) + { + mergedGroups[staticGroup.Name] = staticGroup; + } + + foreach (var dynamicGroup in dynamicGroups) + { + if (mergedGroups.TryGetValue(dynamicGroup.Name, out var existingGroup)) + { + MergeGroupFeatures(existingGroup, dynamicGroup); + } + else + { + mergedGroups[dynamicGroup.Name] = dynamicGroup; + } + } + + return mergedGroups.Values.ToImmutableList(); + } + + private static void MergeGroupFeatures(FeatureGroupDefinition target, FeatureGroupDefinition source) + { + foreach (var sourceFeature in source.Features) + { + var existingFeature = GetFeatureOrNull(target, sourceFeature.Name); + + if (existingFeature == null) + { + var newFeature = target.AddFeature( + sourceFeature.Name, + sourceFeature.DefaultValue, + sourceFeature.DisplayName, + sourceFeature.Description, + sourceFeature.ValueType, + sourceFeature.IsVisibleToClients, + sourceFeature.IsAvailableToHost + ); + + CopyFeatureDetails(sourceFeature, newFeature); + + foreach (var child in sourceFeature.Children) + { + AddChildFeatureRecursively(newFeature, child); + } + } + else + { + MergeFeatureMetadata(existingFeature, sourceFeature); + + foreach (var child in sourceFeature.Children) + { + MergeChildFeature(existingFeature, child); + } + } + } + } + + private static void AddChildFeatureRecursively(FeatureDefinition parent, FeatureDefinition sourceChild) + { + var newChild = parent.CreateChild( + sourceChild.Name, + sourceChild.DefaultValue, + sourceChild.DisplayName, + sourceChild.Description, + sourceChild.ValueType, + sourceChild.IsVisibleToClients, + sourceChild.IsAvailableToHost + ); + + CopyFeatureDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildFeatureRecursively(newChild, grandchild); + } + } + + private static void MergeChildFeature(FeatureDefinition parent, FeatureDefinition sourceChild) + { + var existingChild = parent.Children.FirstOrDefault(c => c.Name == sourceChild.Name); + + if (existingChild == null) + { + var newChild = parent.CreateChild( + sourceChild.Name, + sourceChild.DefaultValue, + sourceChild.DisplayName, + sourceChild.Description, + sourceChild.ValueType, + sourceChild.IsVisibleToClients, + sourceChild.IsAvailableToHost + ); + CopyFeatureDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildFeatureRecursively(newChild, grandchild); + } + } + else + { + MergeFeatureMetadata(existingChild, sourceChild); + + foreach (var grandchild in sourceChild.Children) + { + MergeChildFeature(existingChild, grandchild); + } + } + } + + private static void CopyFeatureDetails(FeatureDefinition source, FeatureDefinition target) + { + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.AllowedProviders) + { + if (!target.AllowedProviders.Contains(provider)) + { + target.AllowedProviders.Add(provider); + } + } + } + + private static void MergeFeatureMetadata(FeatureDefinition target, FeatureDefinition source) + { + if (source.DisplayName != null) + { + target.DisplayName = source.DisplayName; + } + + if (source.Description != null) + { + target.Description = source.Description; + } + + if (source.DefaultValue != null) + { + target.DefaultValue = source.DefaultValue; + } + + if (source.ValueType != null) + { + target.ValueType = source.ValueType; + } + + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.AllowedProviders) + { + if (!target.AllowedProviders.Contains(provider)) + { + target.AllowedProviders.Add(provider); + } + } + + target.IsVisibleToClients = target.IsVisibleToClients || source.IsVisibleToClients; + target.IsAvailableToHost = target.IsAvailableToHost || source.IsAvailableToHost; + } + + + public static FeatureDefinition? GetFeatureOrNull( + FeatureGroupDefinition group, + [NotNull] string name) + { + Check.NotNull(name, nameof(name)); + + return GetFeatureOrNullRecursively(group.Features, name); + } + + private static FeatureDefinition? GetFeatureOrNullRecursively( + IReadOnlyList features, + string name) + { + foreach (var feature in features) + { + if (feature.Name == name) + { + return feature; + } + + var childFeature = GetFeatureOrNullRecursively(feature.Children, name); + if (childFeature != null) + { + return childFeature; + } + } + + return null; + } +} +#nullable disable \ No newline at end of file diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.LocalizationService/Overrides/MergePermissionDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.LocalizationService/Overrides/MergePermissionDefinitionManager.cs new file mode 100644 index 000000000..027e7f1c4 --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.LocalizationService/Overrides/MergePermissionDefinitionManager.cs @@ -0,0 +1,276 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.MultiTenancy; + +namespace Volo.Abp.Authorization.Permissions; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergePermissionDefinitionManager : PermissionDefinitionManager +{ + private readonly IStaticPermissionDefinitionStore _staticStore; + private readonly IDynamicPermissionDefinitionStore _dynamicStore; + + public MergePermissionDefinitionManager( + IStaticPermissionDefinitionStore staticStore, + IDynamicPermissionDefinitionStore dynamicStore) : base(staticStore, dynamicStore) + { + _staticStore = staticStore; + _dynamicStore = dynamicStore; + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetOrNullAsync(name); + var dynamicDefinition = await _dynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task GetResourcePermissionOrNullAsync(string resourceName, string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetResourcePermissionOrNullAsync(resourceName, name); + var dynamicDefinition = await _dynamicStore.GetResourcePermissionOrNullAsync(resourceName, name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetPermissionsAsync() + { + var staticPermissions = await _staticStore.GetPermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetPermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + + public async override Task> GetResourcePermissionsAsync() + { + var staticPermissions = await _staticStore.GetResourcePermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetResourcePermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + + public async override Task> GetGroupsAsync() + { + var staticGroups = await _staticStore.GetGroupsAsync(); + var dynamicGroups = await _dynamicStore.GetGroupsAsync(); + + var mergedGroups = new Dictionary(); + + foreach (var staticGroup in staticGroups) + { + mergedGroups[staticGroup.Name] = staticGroup; + } + + foreach (var dynamicGroup in dynamicGroups) + { + if (mergedGroups.TryGetValue(dynamicGroup.Name, out var existingGroup)) + { + MergeGroupPermissions(existingGroup, dynamicGroup); + } + else + { + mergedGroups[dynamicGroup.Name] = dynamicGroup; + } + } + + return mergedGroups.Values.ToImmutableList(); + } + + private static void MergeGroupPermissions(PermissionGroupDefinition target, PermissionGroupDefinition source) + { + foreach (var sourcePermission in source.Permissions) + { + var existingPermission = target.GetPermissionOrNull(sourcePermission.Name); + + if (existingPermission == null) + { + var newPermission = target.AddPermission( + sourcePermission.Name, + sourcePermission.DisplayName, + sourcePermission.MultiTenancySide, + sourcePermission.IsEnabled + ); + + CopyPermissionDetails(sourcePermission, newPermission); + + foreach (var child in sourcePermission.Children) + { + AddChildPermissionRecursively(newPermission, child); + } + } + else + { + MergePermissionMetadata(existingPermission, sourcePermission); + + foreach (var sourceChild in sourcePermission.Children) + { + MergeChildPermissions(existingPermission, sourceChild); + } + } + } + } + + private static void AddChildPermissionRecursively(PermissionDefinition parent, PermissionDefinition sourceChild) + { + var newChild = parent.AddChild( + sourceChild.Name, + sourceChild.DisplayName, + sourceChild.MultiTenancySide, + sourceChild.IsEnabled + ); + + CopyPermissionDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildPermissionRecursively(newChild, grandchild); + } + } + + private static IReadOnlyList MergePermissions(IReadOnlyList staticPermissions, IReadOnlyList dynamicPermissions) + { + var mergedPermissions = new Dictionary(); + + foreach (var staticFeature in staticPermissions) + { + mergedPermissions[staticFeature.Name] = staticFeature; + } + + foreach (var dynamicPermission in dynamicPermissions) + { + if (mergedPermissions.TryGetValue(dynamicPermission.Name, out var existingPermission)) + { + MergePermissionMetadata(existingPermission, dynamicPermission); + + foreach (var sourceChild in dynamicPermission.Children) + { + MergeChildPermissions(existingPermission, sourceChild); + } + } + else + { + mergedPermissions[dynamicPermission.Name] = dynamicPermission; + } + } + + return mergedPermissions.Values.ToImmutableList(); + } + + private static void MergeChildPermissions(PermissionDefinition parent, PermissionDefinition sourceChild) + { + var existingChild = parent.Children.FirstOrDefault(c => c.Name == sourceChild.Name); + + if (existingChild == null) + { + var newChild = parent.AddChild( + sourceChild.Name, + sourceChild.DisplayName, + sourceChild.MultiTenancySide, + sourceChild.IsEnabled + ); + CopyPermissionDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildPermissionRecursively(newChild, grandchild); + } + } + else + { + MergePermissionMetadata(existingChild, sourceChild); + + foreach (var grandchild in sourceChild.Children) + { + MergeChildPermissions(existingChild, grandchild); + } + } + } + + private static void CopyPermissionDetails(PermissionDefinition source, PermissionDefinition target) + { + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.Providers) + { + if (!target.Providers.Contains(provider)) + { + target.Providers.Add(provider); + } + } + + foreach (var checker in source.StateCheckers) + { + if (!target.StateCheckers.Contains(checker)) + { + target.StateCheckers.Add(checker); + } + } + } + + private static void MergePermissionMetadata(PermissionDefinition target, PermissionDefinition source) + { + target.DisplayName = source.DisplayName; + + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.Providers) + { + if (!target.Providers.Contains(provider)) + { + target.Providers.Add(provider); + } + } + + foreach (var checker in source.StateCheckers) + { + if (!target.StateCheckers.Contains(checker)) + { + target.StateCheckers.Add(checker); + } + } + + if (source.MultiTenancySide != MultiTenancySides.Both) + { + target.MultiTenancySide |= source.MultiTenancySide; + } + + target.IsEnabled = target.IsEnabled || source.IsEnabled; + } +} +#nullable disable \ No newline at end of file diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.LocalizationService/Overrides/MergeSettingDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.LocalizationService/Overrides/MergeSettingDefinitionManager.cs new file mode 100644 index 000000000..2fe64a566 --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.LocalizationService/Overrides/MergeSettingDefinitionManager.cs @@ -0,0 +1,86 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Settings; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergeSettingDefinitionManager : SettingDefinitionManager +{ + public MergeSettingDefinitionManager( + IStaticSettingDefinitionStore staticStore, + IDynamicSettingDefinitionStore dynamicStore) + : base(staticStore, dynamicStore) + { + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeSetting(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetAllAsync() + { + var staticSettings = await StaticStore.GetAllAsync(); + var dynamicSettings = await DynamicStore.GetAllAsync(); + + var mergedSettings = new Dictionary(); + + foreach (var staticSetting in staticSettings) + { + mergedSettings[staticSetting.Name] = staticSetting; + } + + foreach (var dynamicSetting in dynamicSettings) + { + if (mergedSettings.TryGetValue(dynamicSetting.Name, out var existingSetting)) + { + MergeSetting(existingSetting, dynamicSetting); + } + else + { + mergedSettings[dynamicSetting.Name] = dynamicSetting; + } + } + + return mergedSettings.Values.ToImmutableList(); + } + + private static void MergeSetting(SettingDefinition target, SettingDefinition source) + { + target.DisplayName = source.DisplayName; + target.Description = source.Description ?? target.Description; + target.DefaultValue = source.DefaultValue ?? target.DefaultValue; + target.IsVisibleToClients = target.IsVisibleToClients || source.IsVisibleToClients; + target.IsInherited = target.IsInherited || source.IsInherited; + target.IsEncrypted = target.IsEncrypted || source.IsEncrypted; + + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.Providers) + { + if (!target.Providers.Contains(provider)) + { + target.Providers.Add(provider); + } + } + } +} +#nullable disable + diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.LocalizationService/Overrides/MergeTemplateDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.LocalizationService/Overrides/MergeTemplateDefinitionManager.cs new file mode 100644 index 000000000..5cb3137cd --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.LocalizationService/Overrides/MergeTemplateDefinitionManager.cs @@ -0,0 +1,104 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.TextTemplating; + +namespace Volo.Abp.TextTemplatin; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergeTemplateDefinitionManager : TemplateDefinitionManager +{ + public MergeTemplateDefinitionManager( + IStaticTemplateDefinitionStore staticStore, + IDynamicTemplateDefinitionStore dynamicStore) + : base(staticStore, dynamicStore) + { + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeTemplate(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetAllAsync() + { + var staticTemplates = await StaticStore.GetAllAsync(); + var dynamicTemplates = await DynamicStore.GetAllAsync(); + + var mergedTemplates = new Dictionary(); + + foreach (var staticTemplate in staticTemplates) + { + mergedTemplates[staticTemplate.Name] = staticTemplate; + } + + foreach (var dynamicTemplate in dynamicTemplates) + { + if (mergedTemplates.TryGetValue(dynamicTemplate.Name, out var existingTemplate)) + { + MergeTemplate(existingTemplate, dynamicTemplate); + } + else + { + mergedTemplates[dynamicTemplate.Name] = dynamicTemplate; + } + } + + return mergedTemplates.Values.ToImmutableList(); + } + + private static TemplateDefinition MergeTemplate(TemplateDefinition staticTemplate, TemplateDefinition dynamicTemplate) + { + var localizationResourceName = dynamicTemplate.LocalizationResourceName ?? staticTemplate.LocalizationResourceName; + var defaultCultureName = dynamicTemplate.DefaultCultureName ?? staticTemplate.DefaultCultureName; + var displayName = dynamicTemplate.DisplayName ?? staticTemplate.DisplayName; + var isLayout = dynamicTemplate.IsLayout || staticTemplate.IsLayout; + var layout = dynamicTemplate.Layout ?? staticTemplate.Layout; + + var mergedTemplate = new TemplateDefinition( + staticTemplate.Name, + localizationResourceName, + displayName, + isLayout, + layout, + defaultCultureName + ); + + foreach (var property in staticTemplate.Properties) + { + mergedTemplate.Properties[property.Key] = property.Value; + } + + foreach (var property in dynamicTemplate.Properties) + { + mergedTemplate.Properties[property.Key] = property.Value; + } + + if (!string.IsNullOrEmpty(dynamicTemplate.RenderEngine)) + { + mergedTemplate.RenderEngine = dynamicTemplate.RenderEngine; + } + else if (!string.IsNullOrEmpty(staticTemplate.RenderEngine)) + { + mergedTemplate.RenderEngine = staticTemplate.RenderEngine; + } + + mergedTemplate.IsInlineLocalized = dynamicTemplate.IsInlineLocalized || staticTemplate.IsInlineLocalized; + + return mergedTemplate; + } +} +#nullable disable diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.MessageService/Overrides/MergeFeatureDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.MessageService/Overrides/MergeFeatureDefinitionManager.cs new file mode 100644 index 000000000..498ac24fe --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.MessageService/Overrides/MergeFeatureDefinitionManager.cs @@ -0,0 +1,277 @@ +using JetBrains.Annotations; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Features; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergeFeatureDefinitionManager : FeatureDefinitionManager +{ + public MergeFeatureDefinitionManager( + IStaticFeatureDefinitionStore staticStore, + IDynamicFeatureDefinitionStore dynamicStore) + : base(staticStore, dynamicStore) + { + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeFeatureMetadata(staticDefinition, dynamicDefinition); + + foreach (var child in dynamicDefinition.Children) + { + MergeChildFeature(staticDefinition, child); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetAllAsync() + { + var staticFeatures = await StaticStore.GetFeaturesAsync(); + var dynamicFeatures = await DynamicStore.GetFeaturesAsync(); + + var mergedFeatures = new Dictionary(); + + foreach (var staticFeature in staticFeatures) + { + mergedFeatures[staticFeature.Name] = staticFeature; + } + + foreach (var dynamicFeature in dynamicFeatures) + { + if (mergedFeatures.TryGetValue(dynamicFeature.Name, out var existingFeature)) + { + MergeFeatureMetadata(existingFeature, dynamicFeature); + + foreach (var child in dynamicFeature.Children) + { + MergeChildFeature(existingFeature, child); + } + } + else + { + mergedFeatures[dynamicFeature.Name] = dynamicFeature; + } + } + + return mergedFeatures.Values.ToImmutableList(); + } + + public async override Task> GetGroupsAsync() + { + var staticGroups = await StaticStore.GetGroupsAsync(); + var dynamicGroups = await DynamicStore.GetGroupsAsync(); + + var mergedGroups = new Dictionary(); + + foreach (var staticGroup in staticGroups) + { + mergedGroups[staticGroup.Name] = staticGroup; + } + + foreach (var dynamicGroup in dynamicGroups) + { + if (mergedGroups.TryGetValue(dynamicGroup.Name, out var existingGroup)) + { + MergeGroupFeatures(existingGroup, dynamicGroup); + } + else + { + mergedGroups[dynamicGroup.Name] = dynamicGroup; + } + } + + return mergedGroups.Values.ToImmutableList(); + } + + private static void MergeGroupFeatures(FeatureGroupDefinition target, FeatureGroupDefinition source) + { + foreach (var sourceFeature in source.Features) + { + var existingFeature = GetFeatureOrNull(target, sourceFeature.Name); + + if (existingFeature == null) + { + var newFeature = target.AddFeature( + sourceFeature.Name, + sourceFeature.DefaultValue, + sourceFeature.DisplayName, + sourceFeature.Description, + sourceFeature.ValueType, + sourceFeature.IsVisibleToClients, + sourceFeature.IsAvailableToHost + ); + + CopyFeatureDetails(sourceFeature, newFeature); + + foreach (var child in sourceFeature.Children) + { + AddChildFeatureRecursively(newFeature, child); + } + } + else + { + MergeFeatureMetadata(existingFeature, sourceFeature); + + foreach (var child in sourceFeature.Children) + { + MergeChildFeature(existingFeature, child); + } + } + } + } + + private static void AddChildFeatureRecursively(FeatureDefinition parent, FeatureDefinition sourceChild) + { + var newChild = parent.CreateChild( + sourceChild.Name, + sourceChild.DefaultValue, + sourceChild.DisplayName, + sourceChild.Description, + sourceChild.ValueType, + sourceChild.IsVisibleToClients, + sourceChild.IsAvailableToHost + ); + + CopyFeatureDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildFeatureRecursively(newChild, grandchild); + } + } + + private static void MergeChildFeature(FeatureDefinition parent, FeatureDefinition sourceChild) + { + var existingChild = parent.Children.FirstOrDefault(c => c.Name == sourceChild.Name); + + if (existingChild == null) + { + var newChild = parent.CreateChild( + sourceChild.Name, + sourceChild.DefaultValue, + sourceChild.DisplayName, + sourceChild.Description, + sourceChild.ValueType, + sourceChild.IsVisibleToClients, + sourceChild.IsAvailableToHost + ); + CopyFeatureDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildFeatureRecursively(newChild, grandchild); + } + } + else + { + MergeFeatureMetadata(existingChild, sourceChild); + + foreach (var grandchild in sourceChild.Children) + { + MergeChildFeature(existingChild, grandchild); + } + } + } + + private static void CopyFeatureDetails(FeatureDefinition source, FeatureDefinition target) + { + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.AllowedProviders) + { + if (!target.AllowedProviders.Contains(provider)) + { + target.AllowedProviders.Add(provider); + } + } + } + + private static void MergeFeatureMetadata(FeatureDefinition target, FeatureDefinition source) + { + if (source.DisplayName != null) + { + target.DisplayName = source.DisplayName; + } + + if (source.Description != null) + { + target.Description = source.Description; + } + + if (source.DefaultValue != null) + { + target.DefaultValue = source.DefaultValue; + } + + if (source.ValueType != null) + { + target.ValueType = source.ValueType; + } + + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.AllowedProviders) + { + if (!target.AllowedProviders.Contains(provider)) + { + target.AllowedProviders.Add(provider); + } + } + + target.IsVisibleToClients = target.IsVisibleToClients || source.IsVisibleToClients; + target.IsAvailableToHost = target.IsAvailableToHost || source.IsAvailableToHost; + } + + + public static FeatureDefinition? GetFeatureOrNull( + FeatureGroupDefinition group, + [NotNull] string name) + { + Check.NotNull(name, nameof(name)); + + return GetFeatureOrNullRecursively(group.Features, name); + } + + private static FeatureDefinition? GetFeatureOrNullRecursively( + IReadOnlyList features, + string name) + { + foreach (var feature in features) + { + if (feature.Name == name) + { + return feature; + } + + var childFeature = GetFeatureOrNullRecursively(feature.Children, name); + if (childFeature != null) + { + return childFeature; + } + } + + return null; + } +} +#nullable disable \ No newline at end of file diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.MessageService/Overrides/MergePermissionDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.MessageService/Overrides/MergePermissionDefinitionManager.cs new file mode 100644 index 000000000..027e7f1c4 --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.MessageService/Overrides/MergePermissionDefinitionManager.cs @@ -0,0 +1,276 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.MultiTenancy; + +namespace Volo.Abp.Authorization.Permissions; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergePermissionDefinitionManager : PermissionDefinitionManager +{ + private readonly IStaticPermissionDefinitionStore _staticStore; + private readonly IDynamicPermissionDefinitionStore _dynamicStore; + + public MergePermissionDefinitionManager( + IStaticPermissionDefinitionStore staticStore, + IDynamicPermissionDefinitionStore dynamicStore) : base(staticStore, dynamicStore) + { + _staticStore = staticStore; + _dynamicStore = dynamicStore; + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetOrNullAsync(name); + var dynamicDefinition = await _dynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task GetResourcePermissionOrNullAsync(string resourceName, string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetResourcePermissionOrNullAsync(resourceName, name); + var dynamicDefinition = await _dynamicStore.GetResourcePermissionOrNullAsync(resourceName, name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetPermissionsAsync() + { + var staticPermissions = await _staticStore.GetPermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetPermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + + public async override Task> GetResourcePermissionsAsync() + { + var staticPermissions = await _staticStore.GetResourcePermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetResourcePermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + + public async override Task> GetGroupsAsync() + { + var staticGroups = await _staticStore.GetGroupsAsync(); + var dynamicGroups = await _dynamicStore.GetGroupsAsync(); + + var mergedGroups = new Dictionary(); + + foreach (var staticGroup in staticGroups) + { + mergedGroups[staticGroup.Name] = staticGroup; + } + + foreach (var dynamicGroup in dynamicGroups) + { + if (mergedGroups.TryGetValue(dynamicGroup.Name, out var existingGroup)) + { + MergeGroupPermissions(existingGroup, dynamicGroup); + } + else + { + mergedGroups[dynamicGroup.Name] = dynamicGroup; + } + } + + return mergedGroups.Values.ToImmutableList(); + } + + private static void MergeGroupPermissions(PermissionGroupDefinition target, PermissionGroupDefinition source) + { + foreach (var sourcePermission in source.Permissions) + { + var existingPermission = target.GetPermissionOrNull(sourcePermission.Name); + + if (existingPermission == null) + { + var newPermission = target.AddPermission( + sourcePermission.Name, + sourcePermission.DisplayName, + sourcePermission.MultiTenancySide, + sourcePermission.IsEnabled + ); + + CopyPermissionDetails(sourcePermission, newPermission); + + foreach (var child in sourcePermission.Children) + { + AddChildPermissionRecursively(newPermission, child); + } + } + else + { + MergePermissionMetadata(existingPermission, sourcePermission); + + foreach (var sourceChild in sourcePermission.Children) + { + MergeChildPermissions(existingPermission, sourceChild); + } + } + } + } + + private static void AddChildPermissionRecursively(PermissionDefinition parent, PermissionDefinition sourceChild) + { + var newChild = parent.AddChild( + sourceChild.Name, + sourceChild.DisplayName, + sourceChild.MultiTenancySide, + sourceChild.IsEnabled + ); + + CopyPermissionDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildPermissionRecursively(newChild, grandchild); + } + } + + private static IReadOnlyList MergePermissions(IReadOnlyList staticPermissions, IReadOnlyList dynamicPermissions) + { + var mergedPermissions = new Dictionary(); + + foreach (var staticFeature in staticPermissions) + { + mergedPermissions[staticFeature.Name] = staticFeature; + } + + foreach (var dynamicPermission in dynamicPermissions) + { + if (mergedPermissions.TryGetValue(dynamicPermission.Name, out var existingPermission)) + { + MergePermissionMetadata(existingPermission, dynamicPermission); + + foreach (var sourceChild in dynamicPermission.Children) + { + MergeChildPermissions(existingPermission, sourceChild); + } + } + else + { + mergedPermissions[dynamicPermission.Name] = dynamicPermission; + } + } + + return mergedPermissions.Values.ToImmutableList(); + } + + private static void MergeChildPermissions(PermissionDefinition parent, PermissionDefinition sourceChild) + { + var existingChild = parent.Children.FirstOrDefault(c => c.Name == sourceChild.Name); + + if (existingChild == null) + { + var newChild = parent.AddChild( + sourceChild.Name, + sourceChild.DisplayName, + sourceChild.MultiTenancySide, + sourceChild.IsEnabled + ); + CopyPermissionDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildPermissionRecursively(newChild, grandchild); + } + } + else + { + MergePermissionMetadata(existingChild, sourceChild); + + foreach (var grandchild in sourceChild.Children) + { + MergeChildPermissions(existingChild, grandchild); + } + } + } + + private static void CopyPermissionDetails(PermissionDefinition source, PermissionDefinition target) + { + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.Providers) + { + if (!target.Providers.Contains(provider)) + { + target.Providers.Add(provider); + } + } + + foreach (var checker in source.StateCheckers) + { + if (!target.StateCheckers.Contains(checker)) + { + target.StateCheckers.Add(checker); + } + } + } + + private static void MergePermissionMetadata(PermissionDefinition target, PermissionDefinition source) + { + target.DisplayName = source.DisplayName; + + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.Providers) + { + if (!target.Providers.Contains(provider)) + { + target.Providers.Add(provider); + } + } + + foreach (var checker in source.StateCheckers) + { + if (!target.StateCheckers.Contains(checker)) + { + target.StateCheckers.Add(checker); + } + } + + if (source.MultiTenancySide != MultiTenancySides.Both) + { + target.MultiTenancySide |= source.MultiTenancySide; + } + + target.IsEnabled = target.IsEnabled || source.IsEnabled; + } +} +#nullable disable \ No newline at end of file diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.MessageService/Overrides/MergeSettingDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.MessageService/Overrides/MergeSettingDefinitionManager.cs new file mode 100644 index 000000000..2fe64a566 --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.MessageService/Overrides/MergeSettingDefinitionManager.cs @@ -0,0 +1,86 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Settings; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergeSettingDefinitionManager : SettingDefinitionManager +{ + public MergeSettingDefinitionManager( + IStaticSettingDefinitionStore staticStore, + IDynamicSettingDefinitionStore dynamicStore) + : base(staticStore, dynamicStore) + { + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeSetting(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetAllAsync() + { + var staticSettings = await StaticStore.GetAllAsync(); + var dynamicSettings = await DynamicStore.GetAllAsync(); + + var mergedSettings = new Dictionary(); + + foreach (var staticSetting in staticSettings) + { + mergedSettings[staticSetting.Name] = staticSetting; + } + + foreach (var dynamicSetting in dynamicSettings) + { + if (mergedSettings.TryGetValue(dynamicSetting.Name, out var existingSetting)) + { + MergeSetting(existingSetting, dynamicSetting); + } + else + { + mergedSettings[dynamicSetting.Name] = dynamicSetting; + } + } + + return mergedSettings.Values.ToImmutableList(); + } + + private static void MergeSetting(SettingDefinition target, SettingDefinition source) + { + target.DisplayName = source.DisplayName; + target.Description = source.Description ?? target.Description; + target.DefaultValue = source.DefaultValue ?? target.DefaultValue; + target.IsVisibleToClients = target.IsVisibleToClients || source.IsVisibleToClients; + target.IsInherited = target.IsInherited || source.IsInherited; + target.IsEncrypted = target.IsEncrypted || source.IsEncrypted; + + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.Providers) + { + if (!target.Providers.Contains(provider)) + { + target.Providers.Add(provider); + } + } + } +} +#nullable disable + diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.MessageService/Overrides/MergeTemplateDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.MessageService/Overrides/MergeTemplateDefinitionManager.cs new file mode 100644 index 000000000..5cb3137cd --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.MessageService/Overrides/MergeTemplateDefinitionManager.cs @@ -0,0 +1,104 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.TextTemplating; + +namespace Volo.Abp.TextTemplatin; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergeTemplateDefinitionManager : TemplateDefinitionManager +{ + public MergeTemplateDefinitionManager( + IStaticTemplateDefinitionStore staticStore, + IDynamicTemplateDefinitionStore dynamicStore) + : base(staticStore, dynamicStore) + { + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeTemplate(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetAllAsync() + { + var staticTemplates = await StaticStore.GetAllAsync(); + var dynamicTemplates = await DynamicStore.GetAllAsync(); + + var mergedTemplates = new Dictionary(); + + foreach (var staticTemplate in staticTemplates) + { + mergedTemplates[staticTemplate.Name] = staticTemplate; + } + + foreach (var dynamicTemplate in dynamicTemplates) + { + if (mergedTemplates.TryGetValue(dynamicTemplate.Name, out var existingTemplate)) + { + MergeTemplate(existingTemplate, dynamicTemplate); + } + else + { + mergedTemplates[dynamicTemplate.Name] = dynamicTemplate; + } + } + + return mergedTemplates.Values.ToImmutableList(); + } + + private static TemplateDefinition MergeTemplate(TemplateDefinition staticTemplate, TemplateDefinition dynamicTemplate) + { + var localizationResourceName = dynamicTemplate.LocalizationResourceName ?? staticTemplate.LocalizationResourceName; + var defaultCultureName = dynamicTemplate.DefaultCultureName ?? staticTemplate.DefaultCultureName; + var displayName = dynamicTemplate.DisplayName ?? staticTemplate.DisplayName; + var isLayout = dynamicTemplate.IsLayout || staticTemplate.IsLayout; + var layout = dynamicTemplate.Layout ?? staticTemplate.Layout; + + var mergedTemplate = new TemplateDefinition( + staticTemplate.Name, + localizationResourceName, + displayName, + isLayout, + layout, + defaultCultureName + ); + + foreach (var property in staticTemplate.Properties) + { + mergedTemplate.Properties[property.Key] = property.Value; + } + + foreach (var property in dynamicTemplate.Properties) + { + mergedTemplate.Properties[property.Key] = property.Value; + } + + if (!string.IsNullOrEmpty(dynamicTemplate.RenderEngine)) + { + mergedTemplate.RenderEngine = dynamicTemplate.RenderEngine; + } + else if (!string.IsNullOrEmpty(staticTemplate.RenderEngine)) + { + mergedTemplate.RenderEngine = staticTemplate.RenderEngine; + } + + mergedTemplate.IsInlineLocalized = dynamicTemplate.IsInlineLocalized || staticTemplate.IsInlineLocalized; + + return mergedTemplate; + } +} +#nullable disable diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.PlatformService/Overrides/MergeFeatureDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.PlatformService/Overrides/MergeFeatureDefinitionManager.cs new file mode 100644 index 000000000..498ac24fe --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.PlatformService/Overrides/MergeFeatureDefinitionManager.cs @@ -0,0 +1,277 @@ +using JetBrains.Annotations; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Features; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergeFeatureDefinitionManager : FeatureDefinitionManager +{ + public MergeFeatureDefinitionManager( + IStaticFeatureDefinitionStore staticStore, + IDynamicFeatureDefinitionStore dynamicStore) + : base(staticStore, dynamicStore) + { + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeFeatureMetadata(staticDefinition, dynamicDefinition); + + foreach (var child in dynamicDefinition.Children) + { + MergeChildFeature(staticDefinition, child); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetAllAsync() + { + var staticFeatures = await StaticStore.GetFeaturesAsync(); + var dynamicFeatures = await DynamicStore.GetFeaturesAsync(); + + var mergedFeatures = new Dictionary(); + + foreach (var staticFeature in staticFeatures) + { + mergedFeatures[staticFeature.Name] = staticFeature; + } + + foreach (var dynamicFeature in dynamicFeatures) + { + if (mergedFeatures.TryGetValue(dynamicFeature.Name, out var existingFeature)) + { + MergeFeatureMetadata(existingFeature, dynamicFeature); + + foreach (var child in dynamicFeature.Children) + { + MergeChildFeature(existingFeature, child); + } + } + else + { + mergedFeatures[dynamicFeature.Name] = dynamicFeature; + } + } + + return mergedFeatures.Values.ToImmutableList(); + } + + public async override Task> GetGroupsAsync() + { + var staticGroups = await StaticStore.GetGroupsAsync(); + var dynamicGroups = await DynamicStore.GetGroupsAsync(); + + var mergedGroups = new Dictionary(); + + foreach (var staticGroup in staticGroups) + { + mergedGroups[staticGroup.Name] = staticGroup; + } + + foreach (var dynamicGroup in dynamicGroups) + { + if (mergedGroups.TryGetValue(dynamicGroup.Name, out var existingGroup)) + { + MergeGroupFeatures(existingGroup, dynamicGroup); + } + else + { + mergedGroups[dynamicGroup.Name] = dynamicGroup; + } + } + + return mergedGroups.Values.ToImmutableList(); + } + + private static void MergeGroupFeatures(FeatureGroupDefinition target, FeatureGroupDefinition source) + { + foreach (var sourceFeature in source.Features) + { + var existingFeature = GetFeatureOrNull(target, sourceFeature.Name); + + if (existingFeature == null) + { + var newFeature = target.AddFeature( + sourceFeature.Name, + sourceFeature.DefaultValue, + sourceFeature.DisplayName, + sourceFeature.Description, + sourceFeature.ValueType, + sourceFeature.IsVisibleToClients, + sourceFeature.IsAvailableToHost + ); + + CopyFeatureDetails(sourceFeature, newFeature); + + foreach (var child in sourceFeature.Children) + { + AddChildFeatureRecursively(newFeature, child); + } + } + else + { + MergeFeatureMetadata(existingFeature, sourceFeature); + + foreach (var child in sourceFeature.Children) + { + MergeChildFeature(existingFeature, child); + } + } + } + } + + private static void AddChildFeatureRecursively(FeatureDefinition parent, FeatureDefinition sourceChild) + { + var newChild = parent.CreateChild( + sourceChild.Name, + sourceChild.DefaultValue, + sourceChild.DisplayName, + sourceChild.Description, + sourceChild.ValueType, + sourceChild.IsVisibleToClients, + sourceChild.IsAvailableToHost + ); + + CopyFeatureDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildFeatureRecursively(newChild, grandchild); + } + } + + private static void MergeChildFeature(FeatureDefinition parent, FeatureDefinition sourceChild) + { + var existingChild = parent.Children.FirstOrDefault(c => c.Name == sourceChild.Name); + + if (existingChild == null) + { + var newChild = parent.CreateChild( + sourceChild.Name, + sourceChild.DefaultValue, + sourceChild.DisplayName, + sourceChild.Description, + sourceChild.ValueType, + sourceChild.IsVisibleToClients, + sourceChild.IsAvailableToHost + ); + CopyFeatureDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildFeatureRecursively(newChild, grandchild); + } + } + else + { + MergeFeatureMetadata(existingChild, sourceChild); + + foreach (var grandchild in sourceChild.Children) + { + MergeChildFeature(existingChild, grandchild); + } + } + } + + private static void CopyFeatureDetails(FeatureDefinition source, FeatureDefinition target) + { + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.AllowedProviders) + { + if (!target.AllowedProviders.Contains(provider)) + { + target.AllowedProviders.Add(provider); + } + } + } + + private static void MergeFeatureMetadata(FeatureDefinition target, FeatureDefinition source) + { + if (source.DisplayName != null) + { + target.DisplayName = source.DisplayName; + } + + if (source.Description != null) + { + target.Description = source.Description; + } + + if (source.DefaultValue != null) + { + target.DefaultValue = source.DefaultValue; + } + + if (source.ValueType != null) + { + target.ValueType = source.ValueType; + } + + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.AllowedProviders) + { + if (!target.AllowedProviders.Contains(provider)) + { + target.AllowedProviders.Add(provider); + } + } + + target.IsVisibleToClients = target.IsVisibleToClients || source.IsVisibleToClients; + target.IsAvailableToHost = target.IsAvailableToHost || source.IsAvailableToHost; + } + + + public static FeatureDefinition? GetFeatureOrNull( + FeatureGroupDefinition group, + [NotNull] string name) + { + Check.NotNull(name, nameof(name)); + + return GetFeatureOrNullRecursively(group.Features, name); + } + + private static FeatureDefinition? GetFeatureOrNullRecursively( + IReadOnlyList features, + string name) + { + foreach (var feature in features) + { + if (feature.Name == name) + { + return feature; + } + + var childFeature = GetFeatureOrNullRecursively(feature.Children, name); + if (childFeature != null) + { + return childFeature; + } + } + + return null; + } +} +#nullable disable \ No newline at end of file diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.PlatformService/Overrides/MergePermissionDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.PlatformService/Overrides/MergePermissionDefinitionManager.cs new file mode 100644 index 000000000..027e7f1c4 --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.PlatformService/Overrides/MergePermissionDefinitionManager.cs @@ -0,0 +1,276 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.MultiTenancy; + +namespace Volo.Abp.Authorization.Permissions; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergePermissionDefinitionManager : PermissionDefinitionManager +{ + private readonly IStaticPermissionDefinitionStore _staticStore; + private readonly IDynamicPermissionDefinitionStore _dynamicStore; + + public MergePermissionDefinitionManager( + IStaticPermissionDefinitionStore staticStore, + IDynamicPermissionDefinitionStore dynamicStore) : base(staticStore, dynamicStore) + { + _staticStore = staticStore; + _dynamicStore = dynamicStore; + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetOrNullAsync(name); + var dynamicDefinition = await _dynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task GetResourcePermissionOrNullAsync(string resourceName, string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetResourcePermissionOrNullAsync(resourceName, name); + var dynamicDefinition = await _dynamicStore.GetResourcePermissionOrNullAsync(resourceName, name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetPermissionsAsync() + { + var staticPermissions = await _staticStore.GetPermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetPermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + + public async override Task> GetResourcePermissionsAsync() + { + var staticPermissions = await _staticStore.GetResourcePermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetResourcePermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + + public async override Task> GetGroupsAsync() + { + var staticGroups = await _staticStore.GetGroupsAsync(); + var dynamicGroups = await _dynamicStore.GetGroupsAsync(); + + var mergedGroups = new Dictionary(); + + foreach (var staticGroup in staticGroups) + { + mergedGroups[staticGroup.Name] = staticGroup; + } + + foreach (var dynamicGroup in dynamicGroups) + { + if (mergedGroups.TryGetValue(dynamicGroup.Name, out var existingGroup)) + { + MergeGroupPermissions(existingGroup, dynamicGroup); + } + else + { + mergedGroups[dynamicGroup.Name] = dynamicGroup; + } + } + + return mergedGroups.Values.ToImmutableList(); + } + + private static void MergeGroupPermissions(PermissionGroupDefinition target, PermissionGroupDefinition source) + { + foreach (var sourcePermission in source.Permissions) + { + var existingPermission = target.GetPermissionOrNull(sourcePermission.Name); + + if (existingPermission == null) + { + var newPermission = target.AddPermission( + sourcePermission.Name, + sourcePermission.DisplayName, + sourcePermission.MultiTenancySide, + sourcePermission.IsEnabled + ); + + CopyPermissionDetails(sourcePermission, newPermission); + + foreach (var child in sourcePermission.Children) + { + AddChildPermissionRecursively(newPermission, child); + } + } + else + { + MergePermissionMetadata(existingPermission, sourcePermission); + + foreach (var sourceChild in sourcePermission.Children) + { + MergeChildPermissions(existingPermission, sourceChild); + } + } + } + } + + private static void AddChildPermissionRecursively(PermissionDefinition parent, PermissionDefinition sourceChild) + { + var newChild = parent.AddChild( + sourceChild.Name, + sourceChild.DisplayName, + sourceChild.MultiTenancySide, + sourceChild.IsEnabled + ); + + CopyPermissionDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildPermissionRecursively(newChild, grandchild); + } + } + + private static IReadOnlyList MergePermissions(IReadOnlyList staticPermissions, IReadOnlyList dynamicPermissions) + { + var mergedPermissions = new Dictionary(); + + foreach (var staticFeature in staticPermissions) + { + mergedPermissions[staticFeature.Name] = staticFeature; + } + + foreach (var dynamicPermission in dynamicPermissions) + { + if (mergedPermissions.TryGetValue(dynamicPermission.Name, out var existingPermission)) + { + MergePermissionMetadata(existingPermission, dynamicPermission); + + foreach (var sourceChild in dynamicPermission.Children) + { + MergeChildPermissions(existingPermission, sourceChild); + } + } + else + { + mergedPermissions[dynamicPermission.Name] = dynamicPermission; + } + } + + return mergedPermissions.Values.ToImmutableList(); + } + + private static void MergeChildPermissions(PermissionDefinition parent, PermissionDefinition sourceChild) + { + var existingChild = parent.Children.FirstOrDefault(c => c.Name == sourceChild.Name); + + if (existingChild == null) + { + var newChild = parent.AddChild( + sourceChild.Name, + sourceChild.DisplayName, + sourceChild.MultiTenancySide, + sourceChild.IsEnabled + ); + CopyPermissionDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildPermissionRecursively(newChild, grandchild); + } + } + else + { + MergePermissionMetadata(existingChild, sourceChild); + + foreach (var grandchild in sourceChild.Children) + { + MergeChildPermissions(existingChild, grandchild); + } + } + } + + private static void CopyPermissionDetails(PermissionDefinition source, PermissionDefinition target) + { + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.Providers) + { + if (!target.Providers.Contains(provider)) + { + target.Providers.Add(provider); + } + } + + foreach (var checker in source.StateCheckers) + { + if (!target.StateCheckers.Contains(checker)) + { + target.StateCheckers.Add(checker); + } + } + } + + private static void MergePermissionMetadata(PermissionDefinition target, PermissionDefinition source) + { + target.DisplayName = source.DisplayName; + + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.Providers) + { + if (!target.Providers.Contains(provider)) + { + target.Providers.Add(provider); + } + } + + foreach (var checker in source.StateCheckers) + { + if (!target.StateCheckers.Contains(checker)) + { + target.StateCheckers.Add(checker); + } + } + + if (source.MultiTenancySide != MultiTenancySides.Both) + { + target.MultiTenancySide |= source.MultiTenancySide; + } + + target.IsEnabled = target.IsEnabled || source.IsEnabled; + } +} +#nullable disable \ No newline at end of file diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.PlatformService/Overrides/MergeSettingDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.PlatformService/Overrides/MergeSettingDefinitionManager.cs new file mode 100644 index 000000000..2fe64a566 --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.PlatformService/Overrides/MergeSettingDefinitionManager.cs @@ -0,0 +1,86 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Settings; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergeSettingDefinitionManager : SettingDefinitionManager +{ + public MergeSettingDefinitionManager( + IStaticSettingDefinitionStore staticStore, + IDynamicSettingDefinitionStore dynamicStore) + : base(staticStore, dynamicStore) + { + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeSetting(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetAllAsync() + { + var staticSettings = await StaticStore.GetAllAsync(); + var dynamicSettings = await DynamicStore.GetAllAsync(); + + var mergedSettings = new Dictionary(); + + foreach (var staticSetting in staticSettings) + { + mergedSettings[staticSetting.Name] = staticSetting; + } + + foreach (var dynamicSetting in dynamicSettings) + { + if (mergedSettings.TryGetValue(dynamicSetting.Name, out var existingSetting)) + { + MergeSetting(existingSetting, dynamicSetting); + } + else + { + mergedSettings[dynamicSetting.Name] = dynamicSetting; + } + } + + return mergedSettings.Values.ToImmutableList(); + } + + private static void MergeSetting(SettingDefinition target, SettingDefinition source) + { + target.DisplayName = source.DisplayName; + target.Description = source.Description ?? target.Description; + target.DefaultValue = source.DefaultValue ?? target.DefaultValue; + target.IsVisibleToClients = target.IsVisibleToClients || source.IsVisibleToClients; + target.IsInherited = target.IsInherited || source.IsInherited; + target.IsEncrypted = target.IsEncrypted || source.IsEncrypted; + + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.Providers) + { + if (!target.Providers.Contains(provider)) + { + target.Providers.Add(provider); + } + } + } +} +#nullable disable + diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.PlatformService/Overrides/MergeTemplateDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.PlatformService/Overrides/MergeTemplateDefinitionManager.cs new file mode 100644 index 000000000..5cb3137cd --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.PlatformService/Overrides/MergeTemplateDefinitionManager.cs @@ -0,0 +1,104 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.TextTemplating; + +namespace Volo.Abp.TextTemplatin; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergeTemplateDefinitionManager : TemplateDefinitionManager +{ + public MergeTemplateDefinitionManager( + IStaticTemplateDefinitionStore staticStore, + IDynamicTemplateDefinitionStore dynamicStore) + : base(staticStore, dynamicStore) + { + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeTemplate(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetAllAsync() + { + var staticTemplates = await StaticStore.GetAllAsync(); + var dynamicTemplates = await DynamicStore.GetAllAsync(); + + var mergedTemplates = new Dictionary(); + + foreach (var staticTemplate in staticTemplates) + { + mergedTemplates[staticTemplate.Name] = staticTemplate; + } + + foreach (var dynamicTemplate in dynamicTemplates) + { + if (mergedTemplates.TryGetValue(dynamicTemplate.Name, out var existingTemplate)) + { + MergeTemplate(existingTemplate, dynamicTemplate); + } + else + { + mergedTemplates[dynamicTemplate.Name] = dynamicTemplate; + } + } + + return mergedTemplates.Values.ToImmutableList(); + } + + private static TemplateDefinition MergeTemplate(TemplateDefinition staticTemplate, TemplateDefinition dynamicTemplate) + { + var localizationResourceName = dynamicTemplate.LocalizationResourceName ?? staticTemplate.LocalizationResourceName; + var defaultCultureName = dynamicTemplate.DefaultCultureName ?? staticTemplate.DefaultCultureName; + var displayName = dynamicTemplate.DisplayName ?? staticTemplate.DisplayName; + var isLayout = dynamicTemplate.IsLayout || staticTemplate.IsLayout; + var layout = dynamicTemplate.Layout ?? staticTemplate.Layout; + + var mergedTemplate = new TemplateDefinition( + staticTemplate.Name, + localizationResourceName, + displayName, + isLayout, + layout, + defaultCultureName + ); + + foreach (var property in staticTemplate.Properties) + { + mergedTemplate.Properties[property.Key] = property.Value; + } + + foreach (var property in dynamicTemplate.Properties) + { + mergedTemplate.Properties[property.Key] = property.Value; + } + + if (!string.IsNullOrEmpty(dynamicTemplate.RenderEngine)) + { + mergedTemplate.RenderEngine = dynamicTemplate.RenderEngine; + } + else if (!string.IsNullOrEmpty(staticTemplate.RenderEngine)) + { + mergedTemplate.RenderEngine = staticTemplate.RenderEngine; + } + + mergedTemplate.IsInlineLocalized = dynamicTemplate.IsInlineLocalized || staticTemplate.IsInlineLocalized; + + return mergedTemplate; + } +} +#nullable disable diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.TaskService/Overrides/MergeFeatureDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.TaskService/Overrides/MergeFeatureDefinitionManager.cs new file mode 100644 index 000000000..498ac24fe --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.TaskService/Overrides/MergeFeatureDefinitionManager.cs @@ -0,0 +1,277 @@ +using JetBrains.Annotations; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Features; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergeFeatureDefinitionManager : FeatureDefinitionManager +{ + public MergeFeatureDefinitionManager( + IStaticFeatureDefinitionStore staticStore, + IDynamicFeatureDefinitionStore dynamicStore) + : base(staticStore, dynamicStore) + { + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeFeatureMetadata(staticDefinition, dynamicDefinition); + + foreach (var child in dynamicDefinition.Children) + { + MergeChildFeature(staticDefinition, child); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetAllAsync() + { + var staticFeatures = await StaticStore.GetFeaturesAsync(); + var dynamicFeatures = await DynamicStore.GetFeaturesAsync(); + + var mergedFeatures = new Dictionary(); + + foreach (var staticFeature in staticFeatures) + { + mergedFeatures[staticFeature.Name] = staticFeature; + } + + foreach (var dynamicFeature in dynamicFeatures) + { + if (mergedFeatures.TryGetValue(dynamicFeature.Name, out var existingFeature)) + { + MergeFeatureMetadata(existingFeature, dynamicFeature); + + foreach (var child in dynamicFeature.Children) + { + MergeChildFeature(existingFeature, child); + } + } + else + { + mergedFeatures[dynamicFeature.Name] = dynamicFeature; + } + } + + return mergedFeatures.Values.ToImmutableList(); + } + + public async override Task> GetGroupsAsync() + { + var staticGroups = await StaticStore.GetGroupsAsync(); + var dynamicGroups = await DynamicStore.GetGroupsAsync(); + + var mergedGroups = new Dictionary(); + + foreach (var staticGroup in staticGroups) + { + mergedGroups[staticGroup.Name] = staticGroup; + } + + foreach (var dynamicGroup in dynamicGroups) + { + if (mergedGroups.TryGetValue(dynamicGroup.Name, out var existingGroup)) + { + MergeGroupFeatures(existingGroup, dynamicGroup); + } + else + { + mergedGroups[dynamicGroup.Name] = dynamicGroup; + } + } + + return mergedGroups.Values.ToImmutableList(); + } + + private static void MergeGroupFeatures(FeatureGroupDefinition target, FeatureGroupDefinition source) + { + foreach (var sourceFeature in source.Features) + { + var existingFeature = GetFeatureOrNull(target, sourceFeature.Name); + + if (existingFeature == null) + { + var newFeature = target.AddFeature( + sourceFeature.Name, + sourceFeature.DefaultValue, + sourceFeature.DisplayName, + sourceFeature.Description, + sourceFeature.ValueType, + sourceFeature.IsVisibleToClients, + sourceFeature.IsAvailableToHost + ); + + CopyFeatureDetails(sourceFeature, newFeature); + + foreach (var child in sourceFeature.Children) + { + AddChildFeatureRecursively(newFeature, child); + } + } + else + { + MergeFeatureMetadata(existingFeature, sourceFeature); + + foreach (var child in sourceFeature.Children) + { + MergeChildFeature(existingFeature, child); + } + } + } + } + + private static void AddChildFeatureRecursively(FeatureDefinition parent, FeatureDefinition sourceChild) + { + var newChild = parent.CreateChild( + sourceChild.Name, + sourceChild.DefaultValue, + sourceChild.DisplayName, + sourceChild.Description, + sourceChild.ValueType, + sourceChild.IsVisibleToClients, + sourceChild.IsAvailableToHost + ); + + CopyFeatureDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildFeatureRecursively(newChild, grandchild); + } + } + + private static void MergeChildFeature(FeatureDefinition parent, FeatureDefinition sourceChild) + { + var existingChild = parent.Children.FirstOrDefault(c => c.Name == sourceChild.Name); + + if (existingChild == null) + { + var newChild = parent.CreateChild( + sourceChild.Name, + sourceChild.DefaultValue, + sourceChild.DisplayName, + sourceChild.Description, + sourceChild.ValueType, + sourceChild.IsVisibleToClients, + sourceChild.IsAvailableToHost + ); + CopyFeatureDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildFeatureRecursively(newChild, grandchild); + } + } + else + { + MergeFeatureMetadata(existingChild, sourceChild); + + foreach (var grandchild in sourceChild.Children) + { + MergeChildFeature(existingChild, grandchild); + } + } + } + + private static void CopyFeatureDetails(FeatureDefinition source, FeatureDefinition target) + { + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.AllowedProviders) + { + if (!target.AllowedProviders.Contains(provider)) + { + target.AllowedProviders.Add(provider); + } + } + } + + private static void MergeFeatureMetadata(FeatureDefinition target, FeatureDefinition source) + { + if (source.DisplayName != null) + { + target.DisplayName = source.DisplayName; + } + + if (source.Description != null) + { + target.Description = source.Description; + } + + if (source.DefaultValue != null) + { + target.DefaultValue = source.DefaultValue; + } + + if (source.ValueType != null) + { + target.ValueType = source.ValueType; + } + + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.AllowedProviders) + { + if (!target.AllowedProviders.Contains(provider)) + { + target.AllowedProviders.Add(provider); + } + } + + target.IsVisibleToClients = target.IsVisibleToClients || source.IsVisibleToClients; + target.IsAvailableToHost = target.IsAvailableToHost || source.IsAvailableToHost; + } + + + public static FeatureDefinition? GetFeatureOrNull( + FeatureGroupDefinition group, + [NotNull] string name) + { + Check.NotNull(name, nameof(name)); + + return GetFeatureOrNullRecursively(group.Features, name); + } + + private static FeatureDefinition? GetFeatureOrNullRecursively( + IReadOnlyList features, + string name) + { + foreach (var feature in features) + { + if (feature.Name == name) + { + return feature; + } + + var childFeature = GetFeatureOrNullRecursively(feature.Children, name); + if (childFeature != null) + { + return childFeature; + } + } + + return null; + } +} +#nullable disable \ No newline at end of file diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.TaskService/Overrides/MergePermissionDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.TaskService/Overrides/MergePermissionDefinitionManager.cs new file mode 100644 index 000000000..027e7f1c4 --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.TaskService/Overrides/MergePermissionDefinitionManager.cs @@ -0,0 +1,276 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.MultiTenancy; + +namespace Volo.Abp.Authorization.Permissions; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergePermissionDefinitionManager : PermissionDefinitionManager +{ + private readonly IStaticPermissionDefinitionStore _staticStore; + private readonly IDynamicPermissionDefinitionStore _dynamicStore; + + public MergePermissionDefinitionManager( + IStaticPermissionDefinitionStore staticStore, + IDynamicPermissionDefinitionStore dynamicStore) : base(staticStore, dynamicStore) + { + _staticStore = staticStore; + _dynamicStore = dynamicStore; + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetOrNullAsync(name); + var dynamicDefinition = await _dynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task GetResourcePermissionOrNullAsync(string resourceName, string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetResourcePermissionOrNullAsync(resourceName, name); + var dynamicDefinition = await _dynamicStore.GetResourcePermissionOrNullAsync(resourceName, name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetPermissionsAsync() + { + var staticPermissions = await _staticStore.GetPermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetPermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + + public async override Task> GetResourcePermissionsAsync() + { + var staticPermissions = await _staticStore.GetResourcePermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetResourcePermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + + public async override Task> GetGroupsAsync() + { + var staticGroups = await _staticStore.GetGroupsAsync(); + var dynamicGroups = await _dynamicStore.GetGroupsAsync(); + + var mergedGroups = new Dictionary(); + + foreach (var staticGroup in staticGroups) + { + mergedGroups[staticGroup.Name] = staticGroup; + } + + foreach (var dynamicGroup in dynamicGroups) + { + if (mergedGroups.TryGetValue(dynamicGroup.Name, out var existingGroup)) + { + MergeGroupPermissions(existingGroup, dynamicGroup); + } + else + { + mergedGroups[dynamicGroup.Name] = dynamicGroup; + } + } + + return mergedGroups.Values.ToImmutableList(); + } + + private static void MergeGroupPermissions(PermissionGroupDefinition target, PermissionGroupDefinition source) + { + foreach (var sourcePermission in source.Permissions) + { + var existingPermission = target.GetPermissionOrNull(sourcePermission.Name); + + if (existingPermission == null) + { + var newPermission = target.AddPermission( + sourcePermission.Name, + sourcePermission.DisplayName, + sourcePermission.MultiTenancySide, + sourcePermission.IsEnabled + ); + + CopyPermissionDetails(sourcePermission, newPermission); + + foreach (var child in sourcePermission.Children) + { + AddChildPermissionRecursively(newPermission, child); + } + } + else + { + MergePermissionMetadata(existingPermission, sourcePermission); + + foreach (var sourceChild in sourcePermission.Children) + { + MergeChildPermissions(existingPermission, sourceChild); + } + } + } + } + + private static void AddChildPermissionRecursively(PermissionDefinition parent, PermissionDefinition sourceChild) + { + var newChild = parent.AddChild( + sourceChild.Name, + sourceChild.DisplayName, + sourceChild.MultiTenancySide, + sourceChild.IsEnabled + ); + + CopyPermissionDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildPermissionRecursively(newChild, grandchild); + } + } + + private static IReadOnlyList MergePermissions(IReadOnlyList staticPermissions, IReadOnlyList dynamicPermissions) + { + var mergedPermissions = new Dictionary(); + + foreach (var staticFeature in staticPermissions) + { + mergedPermissions[staticFeature.Name] = staticFeature; + } + + foreach (var dynamicPermission in dynamicPermissions) + { + if (mergedPermissions.TryGetValue(dynamicPermission.Name, out var existingPermission)) + { + MergePermissionMetadata(existingPermission, dynamicPermission); + + foreach (var sourceChild in dynamicPermission.Children) + { + MergeChildPermissions(existingPermission, sourceChild); + } + } + else + { + mergedPermissions[dynamicPermission.Name] = dynamicPermission; + } + } + + return mergedPermissions.Values.ToImmutableList(); + } + + private static void MergeChildPermissions(PermissionDefinition parent, PermissionDefinition sourceChild) + { + var existingChild = parent.Children.FirstOrDefault(c => c.Name == sourceChild.Name); + + if (existingChild == null) + { + var newChild = parent.AddChild( + sourceChild.Name, + sourceChild.DisplayName, + sourceChild.MultiTenancySide, + sourceChild.IsEnabled + ); + CopyPermissionDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildPermissionRecursively(newChild, grandchild); + } + } + else + { + MergePermissionMetadata(existingChild, sourceChild); + + foreach (var grandchild in sourceChild.Children) + { + MergeChildPermissions(existingChild, grandchild); + } + } + } + + private static void CopyPermissionDetails(PermissionDefinition source, PermissionDefinition target) + { + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.Providers) + { + if (!target.Providers.Contains(provider)) + { + target.Providers.Add(provider); + } + } + + foreach (var checker in source.StateCheckers) + { + if (!target.StateCheckers.Contains(checker)) + { + target.StateCheckers.Add(checker); + } + } + } + + private static void MergePermissionMetadata(PermissionDefinition target, PermissionDefinition source) + { + target.DisplayName = source.DisplayName; + + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.Providers) + { + if (!target.Providers.Contains(provider)) + { + target.Providers.Add(provider); + } + } + + foreach (var checker in source.StateCheckers) + { + if (!target.StateCheckers.Contains(checker)) + { + target.StateCheckers.Add(checker); + } + } + + if (source.MultiTenancySide != MultiTenancySides.Both) + { + target.MultiTenancySide |= source.MultiTenancySide; + } + + target.IsEnabled = target.IsEnabled || source.IsEnabled; + } +} +#nullable disable \ No newline at end of file diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.TaskService/Overrides/MergeSettingDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.TaskService/Overrides/MergeSettingDefinitionManager.cs new file mode 100644 index 000000000..2fe64a566 --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.TaskService/Overrides/MergeSettingDefinitionManager.cs @@ -0,0 +1,86 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Settings; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergeSettingDefinitionManager : SettingDefinitionManager +{ + public MergeSettingDefinitionManager( + IStaticSettingDefinitionStore staticStore, + IDynamicSettingDefinitionStore dynamicStore) + : base(staticStore, dynamicStore) + { + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeSetting(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetAllAsync() + { + var staticSettings = await StaticStore.GetAllAsync(); + var dynamicSettings = await DynamicStore.GetAllAsync(); + + var mergedSettings = new Dictionary(); + + foreach (var staticSetting in staticSettings) + { + mergedSettings[staticSetting.Name] = staticSetting; + } + + foreach (var dynamicSetting in dynamicSettings) + { + if (mergedSettings.TryGetValue(dynamicSetting.Name, out var existingSetting)) + { + MergeSetting(existingSetting, dynamicSetting); + } + else + { + mergedSettings[dynamicSetting.Name] = dynamicSetting; + } + } + + return mergedSettings.Values.ToImmutableList(); + } + + private static void MergeSetting(SettingDefinition target, SettingDefinition source) + { + target.DisplayName = source.DisplayName; + target.Description = source.Description ?? target.Description; + target.DefaultValue = source.DefaultValue ?? target.DefaultValue; + target.IsVisibleToClients = target.IsVisibleToClients || source.IsVisibleToClients; + target.IsInherited = target.IsInherited || source.IsInherited; + target.IsEncrypted = target.IsEncrypted || source.IsEncrypted; + + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.Providers) + { + if (!target.Providers.Contains(provider)) + { + target.Providers.Add(provider); + } + } + } +} +#nullable disable + diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.TaskService/Overrides/MergeTemplateDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.TaskService/Overrides/MergeTemplateDefinitionManager.cs new file mode 100644 index 000000000..5cb3137cd --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.TaskService/Overrides/MergeTemplateDefinitionManager.cs @@ -0,0 +1,104 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.TextTemplating; + +namespace Volo.Abp.TextTemplatin; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergeTemplateDefinitionManager : TemplateDefinitionManager +{ + public MergeTemplateDefinitionManager( + IStaticTemplateDefinitionStore staticStore, + IDynamicTemplateDefinitionStore dynamicStore) + : base(staticStore, dynamicStore) + { + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeTemplate(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetAllAsync() + { + var staticTemplates = await StaticStore.GetAllAsync(); + var dynamicTemplates = await DynamicStore.GetAllAsync(); + + var mergedTemplates = new Dictionary(); + + foreach (var staticTemplate in staticTemplates) + { + mergedTemplates[staticTemplate.Name] = staticTemplate; + } + + foreach (var dynamicTemplate in dynamicTemplates) + { + if (mergedTemplates.TryGetValue(dynamicTemplate.Name, out var existingTemplate)) + { + MergeTemplate(existingTemplate, dynamicTemplate); + } + else + { + mergedTemplates[dynamicTemplate.Name] = dynamicTemplate; + } + } + + return mergedTemplates.Values.ToImmutableList(); + } + + private static TemplateDefinition MergeTemplate(TemplateDefinition staticTemplate, TemplateDefinition dynamicTemplate) + { + var localizationResourceName = dynamicTemplate.LocalizationResourceName ?? staticTemplate.LocalizationResourceName; + var defaultCultureName = dynamicTemplate.DefaultCultureName ?? staticTemplate.DefaultCultureName; + var displayName = dynamicTemplate.DisplayName ?? staticTemplate.DisplayName; + var isLayout = dynamicTemplate.IsLayout || staticTemplate.IsLayout; + var layout = dynamicTemplate.Layout ?? staticTemplate.Layout; + + var mergedTemplate = new TemplateDefinition( + staticTemplate.Name, + localizationResourceName, + displayName, + isLayout, + layout, + defaultCultureName + ); + + foreach (var property in staticTemplate.Properties) + { + mergedTemplate.Properties[property.Key] = property.Value; + } + + foreach (var property in dynamicTemplate.Properties) + { + mergedTemplate.Properties[property.Key] = property.Value; + } + + if (!string.IsNullOrEmpty(dynamicTemplate.RenderEngine)) + { + mergedTemplate.RenderEngine = dynamicTemplate.RenderEngine; + } + else if (!string.IsNullOrEmpty(staticTemplate.RenderEngine)) + { + mergedTemplate.RenderEngine = staticTemplate.RenderEngine; + } + + mergedTemplate.IsInlineLocalized = dynamicTemplate.IsInlineLocalized || staticTemplate.IsInlineLocalized; + + return mergedTemplate; + } +} +#nullable disable diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.WeChatService/Overrides/MergeFeatureDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.WeChatService/Overrides/MergeFeatureDefinitionManager.cs new file mode 100644 index 000000000..498ac24fe --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.WeChatService/Overrides/MergeFeatureDefinitionManager.cs @@ -0,0 +1,277 @@ +using JetBrains.Annotations; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Features; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergeFeatureDefinitionManager : FeatureDefinitionManager +{ + public MergeFeatureDefinitionManager( + IStaticFeatureDefinitionStore staticStore, + IDynamicFeatureDefinitionStore dynamicStore) + : base(staticStore, dynamicStore) + { + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeFeatureMetadata(staticDefinition, dynamicDefinition); + + foreach (var child in dynamicDefinition.Children) + { + MergeChildFeature(staticDefinition, child); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetAllAsync() + { + var staticFeatures = await StaticStore.GetFeaturesAsync(); + var dynamicFeatures = await DynamicStore.GetFeaturesAsync(); + + var mergedFeatures = new Dictionary(); + + foreach (var staticFeature in staticFeatures) + { + mergedFeatures[staticFeature.Name] = staticFeature; + } + + foreach (var dynamicFeature in dynamicFeatures) + { + if (mergedFeatures.TryGetValue(dynamicFeature.Name, out var existingFeature)) + { + MergeFeatureMetadata(existingFeature, dynamicFeature); + + foreach (var child in dynamicFeature.Children) + { + MergeChildFeature(existingFeature, child); + } + } + else + { + mergedFeatures[dynamicFeature.Name] = dynamicFeature; + } + } + + return mergedFeatures.Values.ToImmutableList(); + } + + public async override Task> GetGroupsAsync() + { + var staticGroups = await StaticStore.GetGroupsAsync(); + var dynamicGroups = await DynamicStore.GetGroupsAsync(); + + var mergedGroups = new Dictionary(); + + foreach (var staticGroup in staticGroups) + { + mergedGroups[staticGroup.Name] = staticGroup; + } + + foreach (var dynamicGroup in dynamicGroups) + { + if (mergedGroups.TryGetValue(dynamicGroup.Name, out var existingGroup)) + { + MergeGroupFeatures(existingGroup, dynamicGroup); + } + else + { + mergedGroups[dynamicGroup.Name] = dynamicGroup; + } + } + + return mergedGroups.Values.ToImmutableList(); + } + + private static void MergeGroupFeatures(FeatureGroupDefinition target, FeatureGroupDefinition source) + { + foreach (var sourceFeature in source.Features) + { + var existingFeature = GetFeatureOrNull(target, sourceFeature.Name); + + if (existingFeature == null) + { + var newFeature = target.AddFeature( + sourceFeature.Name, + sourceFeature.DefaultValue, + sourceFeature.DisplayName, + sourceFeature.Description, + sourceFeature.ValueType, + sourceFeature.IsVisibleToClients, + sourceFeature.IsAvailableToHost + ); + + CopyFeatureDetails(sourceFeature, newFeature); + + foreach (var child in sourceFeature.Children) + { + AddChildFeatureRecursively(newFeature, child); + } + } + else + { + MergeFeatureMetadata(existingFeature, sourceFeature); + + foreach (var child in sourceFeature.Children) + { + MergeChildFeature(existingFeature, child); + } + } + } + } + + private static void AddChildFeatureRecursively(FeatureDefinition parent, FeatureDefinition sourceChild) + { + var newChild = parent.CreateChild( + sourceChild.Name, + sourceChild.DefaultValue, + sourceChild.DisplayName, + sourceChild.Description, + sourceChild.ValueType, + sourceChild.IsVisibleToClients, + sourceChild.IsAvailableToHost + ); + + CopyFeatureDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildFeatureRecursively(newChild, grandchild); + } + } + + private static void MergeChildFeature(FeatureDefinition parent, FeatureDefinition sourceChild) + { + var existingChild = parent.Children.FirstOrDefault(c => c.Name == sourceChild.Name); + + if (existingChild == null) + { + var newChild = parent.CreateChild( + sourceChild.Name, + sourceChild.DefaultValue, + sourceChild.DisplayName, + sourceChild.Description, + sourceChild.ValueType, + sourceChild.IsVisibleToClients, + sourceChild.IsAvailableToHost + ); + CopyFeatureDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildFeatureRecursively(newChild, grandchild); + } + } + else + { + MergeFeatureMetadata(existingChild, sourceChild); + + foreach (var grandchild in sourceChild.Children) + { + MergeChildFeature(existingChild, grandchild); + } + } + } + + private static void CopyFeatureDetails(FeatureDefinition source, FeatureDefinition target) + { + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.AllowedProviders) + { + if (!target.AllowedProviders.Contains(provider)) + { + target.AllowedProviders.Add(provider); + } + } + } + + private static void MergeFeatureMetadata(FeatureDefinition target, FeatureDefinition source) + { + if (source.DisplayName != null) + { + target.DisplayName = source.DisplayName; + } + + if (source.Description != null) + { + target.Description = source.Description; + } + + if (source.DefaultValue != null) + { + target.DefaultValue = source.DefaultValue; + } + + if (source.ValueType != null) + { + target.ValueType = source.ValueType; + } + + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.AllowedProviders) + { + if (!target.AllowedProviders.Contains(provider)) + { + target.AllowedProviders.Add(provider); + } + } + + target.IsVisibleToClients = target.IsVisibleToClients || source.IsVisibleToClients; + target.IsAvailableToHost = target.IsAvailableToHost || source.IsAvailableToHost; + } + + + public static FeatureDefinition? GetFeatureOrNull( + FeatureGroupDefinition group, + [NotNull] string name) + { + Check.NotNull(name, nameof(name)); + + return GetFeatureOrNullRecursively(group.Features, name); + } + + private static FeatureDefinition? GetFeatureOrNullRecursively( + IReadOnlyList features, + string name) + { + foreach (var feature in features) + { + if (feature.Name == name) + { + return feature; + } + + var childFeature = GetFeatureOrNullRecursively(feature.Children, name); + if (childFeature != null) + { + return childFeature; + } + } + + return null; + } +} +#nullable disable \ No newline at end of file diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.WeChatService/Overrides/MergePermissionDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.WeChatService/Overrides/MergePermissionDefinitionManager.cs new file mode 100644 index 000000000..027e7f1c4 --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.WeChatService/Overrides/MergePermissionDefinitionManager.cs @@ -0,0 +1,276 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.MultiTenancy; + +namespace Volo.Abp.Authorization.Permissions; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergePermissionDefinitionManager : PermissionDefinitionManager +{ + private readonly IStaticPermissionDefinitionStore _staticStore; + private readonly IDynamicPermissionDefinitionStore _dynamicStore; + + public MergePermissionDefinitionManager( + IStaticPermissionDefinitionStore staticStore, + IDynamicPermissionDefinitionStore dynamicStore) : base(staticStore, dynamicStore) + { + _staticStore = staticStore; + _dynamicStore = dynamicStore; + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetOrNullAsync(name); + var dynamicDefinition = await _dynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task GetResourcePermissionOrNullAsync(string resourceName, string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetResourcePermissionOrNullAsync(resourceName, name); + var dynamicDefinition = await _dynamicStore.GetResourcePermissionOrNullAsync(resourceName, name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetPermissionsAsync() + { + var staticPermissions = await _staticStore.GetPermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetPermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + + public async override Task> GetResourcePermissionsAsync() + { + var staticPermissions = await _staticStore.GetResourcePermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetResourcePermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + + public async override Task> GetGroupsAsync() + { + var staticGroups = await _staticStore.GetGroupsAsync(); + var dynamicGroups = await _dynamicStore.GetGroupsAsync(); + + var mergedGroups = new Dictionary(); + + foreach (var staticGroup in staticGroups) + { + mergedGroups[staticGroup.Name] = staticGroup; + } + + foreach (var dynamicGroup in dynamicGroups) + { + if (mergedGroups.TryGetValue(dynamicGroup.Name, out var existingGroup)) + { + MergeGroupPermissions(existingGroup, dynamicGroup); + } + else + { + mergedGroups[dynamicGroup.Name] = dynamicGroup; + } + } + + return mergedGroups.Values.ToImmutableList(); + } + + private static void MergeGroupPermissions(PermissionGroupDefinition target, PermissionGroupDefinition source) + { + foreach (var sourcePermission in source.Permissions) + { + var existingPermission = target.GetPermissionOrNull(sourcePermission.Name); + + if (existingPermission == null) + { + var newPermission = target.AddPermission( + sourcePermission.Name, + sourcePermission.DisplayName, + sourcePermission.MultiTenancySide, + sourcePermission.IsEnabled + ); + + CopyPermissionDetails(sourcePermission, newPermission); + + foreach (var child in sourcePermission.Children) + { + AddChildPermissionRecursively(newPermission, child); + } + } + else + { + MergePermissionMetadata(existingPermission, sourcePermission); + + foreach (var sourceChild in sourcePermission.Children) + { + MergeChildPermissions(existingPermission, sourceChild); + } + } + } + } + + private static void AddChildPermissionRecursively(PermissionDefinition parent, PermissionDefinition sourceChild) + { + var newChild = parent.AddChild( + sourceChild.Name, + sourceChild.DisplayName, + sourceChild.MultiTenancySide, + sourceChild.IsEnabled + ); + + CopyPermissionDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildPermissionRecursively(newChild, grandchild); + } + } + + private static IReadOnlyList MergePermissions(IReadOnlyList staticPermissions, IReadOnlyList dynamicPermissions) + { + var mergedPermissions = new Dictionary(); + + foreach (var staticFeature in staticPermissions) + { + mergedPermissions[staticFeature.Name] = staticFeature; + } + + foreach (var dynamicPermission in dynamicPermissions) + { + if (mergedPermissions.TryGetValue(dynamicPermission.Name, out var existingPermission)) + { + MergePermissionMetadata(existingPermission, dynamicPermission); + + foreach (var sourceChild in dynamicPermission.Children) + { + MergeChildPermissions(existingPermission, sourceChild); + } + } + else + { + mergedPermissions[dynamicPermission.Name] = dynamicPermission; + } + } + + return mergedPermissions.Values.ToImmutableList(); + } + + private static void MergeChildPermissions(PermissionDefinition parent, PermissionDefinition sourceChild) + { + var existingChild = parent.Children.FirstOrDefault(c => c.Name == sourceChild.Name); + + if (existingChild == null) + { + var newChild = parent.AddChild( + sourceChild.Name, + sourceChild.DisplayName, + sourceChild.MultiTenancySide, + sourceChild.IsEnabled + ); + CopyPermissionDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildPermissionRecursively(newChild, grandchild); + } + } + else + { + MergePermissionMetadata(existingChild, sourceChild); + + foreach (var grandchild in sourceChild.Children) + { + MergeChildPermissions(existingChild, grandchild); + } + } + } + + private static void CopyPermissionDetails(PermissionDefinition source, PermissionDefinition target) + { + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.Providers) + { + if (!target.Providers.Contains(provider)) + { + target.Providers.Add(provider); + } + } + + foreach (var checker in source.StateCheckers) + { + if (!target.StateCheckers.Contains(checker)) + { + target.StateCheckers.Add(checker); + } + } + } + + private static void MergePermissionMetadata(PermissionDefinition target, PermissionDefinition source) + { + target.DisplayName = source.DisplayName; + + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.Providers) + { + if (!target.Providers.Contains(provider)) + { + target.Providers.Add(provider); + } + } + + foreach (var checker in source.StateCheckers) + { + if (!target.StateCheckers.Contains(checker)) + { + target.StateCheckers.Add(checker); + } + } + + if (source.MultiTenancySide != MultiTenancySides.Both) + { + target.MultiTenancySide |= source.MultiTenancySide; + } + + target.IsEnabled = target.IsEnabled || source.IsEnabled; + } +} +#nullable disable \ No newline at end of file diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.WeChatService/Overrides/MergeSettingDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.WeChatService/Overrides/MergeSettingDefinitionManager.cs new file mode 100644 index 000000000..2fe64a566 --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.WeChatService/Overrides/MergeSettingDefinitionManager.cs @@ -0,0 +1,86 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Settings; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergeSettingDefinitionManager : SettingDefinitionManager +{ + public MergeSettingDefinitionManager( + IStaticSettingDefinitionStore staticStore, + IDynamicSettingDefinitionStore dynamicStore) + : base(staticStore, dynamicStore) + { + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeSetting(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetAllAsync() + { + var staticSettings = await StaticStore.GetAllAsync(); + var dynamicSettings = await DynamicStore.GetAllAsync(); + + var mergedSettings = new Dictionary(); + + foreach (var staticSetting in staticSettings) + { + mergedSettings[staticSetting.Name] = staticSetting; + } + + foreach (var dynamicSetting in dynamicSettings) + { + if (mergedSettings.TryGetValue(dynamicSetting.Name, out var existingSetting)) + { + MergeSetting(existingSetting, dynamicSetting); + } + else + { + mergedSettings[dynamicSetting.Name] = dynamicSetting; + } + } + + return mergedSettings.Values.ToImmutableList(); + } + + private static void MergeSetting(SettingDefinition target, SettingDefinition source) + { + target.DisplayName = source.DisplayName; + target.Description = source.Description ?? target.Description; + target.DefaultValue = source.DefaultValue ?? target.DefaultValue; + target.IsVisibleToClients = target.IsVisibleToClients || source.IsVisibleToClients; + target.IsInherited = target.IsInherited || source.IsInherited; + target.IsEncrypted = target.IsEncrypted || source.IsEncrypted; + + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.Providers) + { + if (!target.Providers.Contains(provider)) + { + target.Providers.Add(provider); + } + } + } +} +#nullable disable + diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.WeChatService/Overrides/MergeTemplateDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.WeChatService/Overrides/MergeTemplateDefinitionManager.cs new file mode 100644 index 000000000..5cb3137cd --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.WeChatService/Overrides/MergeTemplateDefinitionManager.cs @@ -0,0 +1,104 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.TextTemplating; + +namespace Volo.Abp.TextTemplatin; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergeTemplateDefinitionManager : TemplateDefinitionManager +{ + public MergeTemplateDefinitionManager( + IStaticTemplateDefinitionStore staticStore, + IDynamicTemplateDefinitionStore dynamicStore) + : base(staticStore, dynamicStore) + { + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeTemplate(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetAllAsync() + { + var staticTemplates = await StaticStore.GetAllAsync(); + var dynamicTemplates = await DynamicStore.GetAllAsync(); + + var mergedTemplates = new Dictionary(); + + foreach (var staticTemplate in staticTemplates) + { + mergedTemplates[staticTemplate.Name] = staticTemplate; + } + + foreach (var dynamicTemplate in dynamicTemplates) + { + if (mergedTemplates.TryGetValue(dynamicTemplate.Name, out var existingTemplate)) + { + MergeTemplate(existingTemplate, dynamicTemplate); + } + else + { + mergedTemplates[dynamicTemplate.Name] = dynamicTemplate; + } + } + + return mergedTemplates.Values.ToImmutableList(); + } + + private static TemplateDefinition MergeTemplate(TemplateDefinition staticTemplate, TemplateDefinition dynamicTemplate) + { + var localizationResourceName = dynamicTemplate.LocalizationResourceName ?? staticTemplate.LocalizationResourceName; + var defaultCultureName = dynamicTemplate.DefaultCultureName ?? staticTemplate.DefaultCultureName; + var displayName = dynamicTemplate.DisplayName ?? staticTemplate.DisplayName; + var isLayout = dynamicTemplate.IsLayout || staticTemplate.IsLayout; + var layout = dynamicTemplate.Layout ?? staticTemplate.Layout; + + var mergedTemplate = new TemplateDefinition( + staticTemplate.Name, + localizationResourceName, + displayName, + isLayout, + layout, + defaultCultureName + ); + + foreach (var property in staticTemplate.Properties) + { + mergedTemplate.Properties[property.Key] = property.Value; + } + + foreach (var property in dynamicTemplate.Properties) + { + mergedTemplate.Properties[property.Key] = property.Value; + } + + if (!string.IsNullOrEmpty(dynamicTemplate.RenderEngine)) + { + mergedTemplate.RenderEngine = dynamicTemplate.RenderEngine; + } + else if (!string.IsNullOrEmpty(staticTemplate.RenderEngine)) + { + mergedTemplate.RenderEngine = staticTemplate.RenderEngine; + } + + mergedTemplate.IsInlineLocalized = dynamicTemplate.IsInlineLocalized || staticTemplate.IsInlineLocalized; + + return mergedTemplate; + } +} +#nullable disable diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.WebhookService/Overrides/MergeFeatureDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.WebhookService/Overrides/MergeFeatureDefinitionManager.cs new file mode 100644 index 000000000..498ac24fe --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.WebhookService/Overrides/MergeFeatureDefinitionManager.cs @@ -0,0 +1,277 @@ +using JetBrains.Annotations; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Features; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergeFeatureDefinitionManager : FeatureDefinitionManager +{ + public MergeFeatureDefinitionManager( + IStaticFeatureDefinitionStore staticStore, + IDynamicFeatureDefinitionStore dynamicStore) + : base(staticStore, dynamicStore) + { + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeFeatureMetadata(staticDefinition, dynamicDefinition); + + foreach (var child in dynamicDefinition.Children) + { + MergeChildFeature(staticDefinition, child); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetAllAsync() + { + var staticFeatures = await StaticStore.GetFeaturesAsync(); + var dynamicFeatures = await DynamicStore.GetFeaturesAsync(); + + var mergedFeatures = new Dictionary(); + + foreach (var staticFeature in staticFeatures) + { + mergedFeatures[staticFeature.Name] = staticFeature; + } + + foreach (var dynamicFeature in dynamicFeatures) + { + if (mergedFeatures.TryGetValue(dynamicFeature.Name, out var existingFeature)) + { + MergeFeatureMetadata(existingFeature, dynamicFeature); + + foreach (var child in dynamicFeature.Children) + { + MergeChildFeature(existingFeature, child); + } + } + else + { + mergedFeatures[dynamicFeature.Name] = dynamicFeature; + } + } + + return mergedFeatures.Values.ToImmutableList(); + } + + public async override Task> GetGroupsAsync() + { + var staticGroups = await StaticStore.GetGroupsAsync(); + var dynamicGroups = await DynamicStore.GetGroupsAsync(); + + var mergedGroups = new Dictionary(); + + foreach (var staticGroup in staticGroups) + { + mergedGroups[staticGroup.Name] = staticGroup; + } + + foreach (var dynamicGroup in dynamicGroups) + { + if (mergedGroups.TryGetValue(dynamicGroup.Name, out var existingGroup)) + { + MergeGroupFeatures(existingGroup, dynamicGroup); + } + else + { + mergedGroups[dynamicGroup.Name] = dynamicGroup; + } + } + + return mergedGroups.Values.ToImmutableList(); + } + + private static void MergeGroupFeatures(FeatureGroupDefinition target, FeatureGroupDefinition source) + { + foreach (var sourceFeature in source.Features) + { + var existingFeature = GetFeatureOrNull(target, sourceFeature.Name); + + if (existingFeature == null) + { + var newFeature = target.AddFeature( + sourceFeature.Name, + sourceFeature.DefaultValue, + sourceFeature.DisplayName, + sourceFeature.Description, + sourceFeature.ValueType, + sourceFeature.IsVisibleToClients, + sourceFeature.IsAvailableToHost + ); + + CopyFeatureDetails(sourceFeature, newFeature); + + foreach (var child in sourceFeature.Children) + { + AddChildFeatureRecursively(newFeature, child); + } + } + else + { + MergeFeatureMetadata(existingFeature, sourceFeature); + + foreach (var child in sourceFeature.Children) + { + MergeChildFeature(existingFeature, child); + } + } + } + } + + private static void AddChildFeatureRecursively(FeatureDefinition parent, FeatureDefinition sourceChild) + { + var newChild = parent.CreateChild( + sourceChild.Name, + sourceChild.DefaultValue, + sourceChild.DisplayName, + sourceChild.Description, + sourceChild.ValueType, + sourceChild.IsVisibleToClients, + sourceChild.IsAvailableToHost + ); + + CopyFeatureDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildFeatureRecursively(newChild, grandchild); + } + } + + private static void MergeChildFeature(FeatureDefinition parent, FeatureDefinition sourceChild) + { + var existingChild = parent.Children.FirstOrDefault(c => c.Name == sourceChild.Name); + + if (existingChild == null) + { + var newChild = parent.CreateChild( + sourceChild.Name, + sourceChild.DefaultValue, + sourceChild.DisplayName, + sourceChild.Description, + sourceChild.ValueType, + sourceChild.IsVisibleToClients, + sourceChild.IsAvailableToHost + ); + CopyFeatureDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildFeatureRecursively(newChild, grandchild); + } + } + else + { + MergeFeatureMetadata(existingChild, sourceChild); + + foreach (var grandchild in sourceChild.Children) + { + MergeChildFeature(existingChild, grandchild); + } + } + } + + private static void CopyFeatureDetails(FeatureDefinition source, FeatureDefinition target) + { + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.AllowedProviders) + { + if (!target.AllowedProviders.Contains(provider)) + { + target.AllowedProviders.Add(provider); + } + } + } + + private static void MergeFeatureMetadata(FeatureDefinition target, FeatureDefinition source) + { + if (source.DisplayName != null) + { + target.DisplayName = source.DisplayName; + } + + if (source.Description != null) + { + target.Description = source.Description; + } + + if (source.DefaultValue != null) + { + target.DefaultValue = source.DefaultValue; + } + + if (source.ValueType != null) + { + target.ValueType = source.ValueType; + } + + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.AllowedProviders) + { + if (!target.AllowedProviders.Contains(provider)) + { + target.AllowedProviders.Add(provider); + } + } + + target.IsVisibleToClients = target.IsVisibleToClients || source.IsVisibleToClients; + target.IsAvailableToHost = target.IsAvailableToHost || source.IsAvailableToHost; + } + + + public static FeatureDefinition? GetFeatureOrNull( + FeatureGroupDefinition group, + [NotNull] string name) + { + Check.NotNull(name, nameof(name)); + + return GetFeatureOrNullRecursively(group.Features, name); + } + + private static FeatureDefinition? GetFeatureOrNullRecursively( + IReadOnlyList features, + string name) + { + foreach (var feature in features) + { + if (feature.Name == name) + { + return feature; + } + + var childFeature = GetFeatureOrNullRecursively(feature.Children, name); + if (childFeature != null) + { + return childFeature; + } + } + + return null; + } +} +#nullable disable \ No newline at end of file diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.WebhookService/Overrides/MergePermissionDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.WebhookService/Overrides/MergePermissionDefinitionManager.cs new file mode 100644 index 000000000..027e7f1c4 --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.WebhookService/Overrides/MergePermissionDefinitionManager.cs @@ -0,0 +1,276 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.MultiTenancy; + +namespace Volo.Abp.Authorization.Permissions; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergePermissionDefinitionManager : PermissionDefinitionManager +{ + private readonly IStaticPermissionDefinitionStore _staticStore; + private readonly IDynamicPermissionDefinitionStore _dynamicStore; + + public MergePermissionDefinitionManager( + IStaticPermissionDefinitionStore staticStore, + IDynamicPermissionDefinitionStore dynamicStore) : base(staticStore, dynamicStore) + { + _staticStore = staticStore; + _dynamicStore = dynamicStore; + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetOrNullAsync(name); + var dynamicDefinition = await _dynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task GetResourcePermissionOrNullAsync(string resourceName, string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetResourcePermissionOrNullAsync(resourceName, name); + var dynamicDefinition = await _dynamicStore.GetResourcePermissionOrNullAsync(resourceName, name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetPermissionsAsync() + { + var staticPermissions = await _staticStore.GetPermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetPermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + + public async override Task> GetResourcePermissionsAsync() + { + var staticPermissions = await _staticStore.GetResourcePermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetResourcePermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + + public async override Task> GetGroupsAsync() + { + var staticGroups = await _staticStore.GetGroupsAsync(); + var dynamicGroups = await _dynamicStore.GetGroupsAsync(); + + var mergedGroups = new Dictionary(); + + foreach (var staticGroup in staticGroups) + { + mergedGroups[staticGroup.Name] = staticGroup; + } + + foreach (var dynamicGroup in dynamicGroups) + { + if (mergedGroups.TryGetValue(dynamicGroup.Name, out var existingGroup)) + { + MergeGroupPermissions(existingGroup, dynamicGroup); + } + else + { + mergedGroups[dynamicGroup.Name] = dynamicGroup; + } + } + + return mergedGroups.Values.ToImmutableList(); + } + + private static void MergeGroupPermissions(PermissionGroupDefinition target, PermissionGroupDefinition source) + { + foreach (var sourcePermission in source.Permissions) + { + var existingPermission = target.GetPermissionOrNull(sourcePermission.Name); + + if (existingPermission == null) + { + var newPermission = target.AddPermission( + sourcePermission.Name, + sourcePermission.DisplayName, + sourcePermission.MultiTenancySide, + sourcePermission.IsEnabled + ); + + CopyPermissionDetails(sourcePermission, newPermission); + + foreach (var child in sourcePermission.Children) + { + AddChildPermissionRecursively(newPermission, child); + } + } + else + { + MergePermissionMetadata(existingPermission, sourcePermission); + + foreach (var sourceChild in sourcePermission.Children) + { + MergeChildPermissions(existingPermission, sourceChild); + } + } + } + } + + private static void AddChildPermissionRecursively(PermissionDefinition parent, PermissionDefinition sourceChild) + { + var newChild = parent.AddChild( + sourceChild.Name, + sourceChild.DisplayName, + sourceChild.MultiTenancySide, + sourceChild.IsEnabled + ); + + CopyPermissionDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildPermissionRecursively(newChild, grandchild); + } + } + + private static IReadOnlyList MergePermissions(IReadOnlyList staticPermissions, IReadOnlyList dynamicPermissions) + { + var mergedPermissions = new Dictionary(); + + foreach (var staticFeature in staticPermissions) + { + mergedPermissions[staticFeature.Name] = staticFeature; + } + + foreach (var dynamicPermission in dynamicPermissions) + { + if (mergedPermissions.TryGetValue(dynamicPermission.Name, out var existingPermission)) + { + MergePermissionMetadata(existingPermission, dynamicPermission); + + foreach (var sourceChild in dynamicPermission.Children) + { + MergeChildPermissions(existingPermission, sourceChild); + } + } + else + { + mergedPermissions[dynamicPermission.Name] = dynamicPermission; + } + } + + return mergedPermissions.Values.ToImmutableList(); + } + + private static void MergeChildPermissions(PermissionDefinition parent, PermissionDefinition sourceChild) + { + var existingChild = parent.Children.FirstOrDefault(c => c.Name == sourceChild.Name); + + if (existingChild == null) + { + var newChild = parent.AddChild( + sourceChild.Name, + sourceChild.DisplayName, + sourceChild.MultiTenancySide, + sourceChild.IsEnabled + ); + CopyPermissionDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildPermissionRecursively(newChild, grandchild); + } + } + else + { + MergePermissionMetadata(existingChild, sourceChild); + + foreach (var grandchild in sourceChild.Children) + { + MergeChildPermissions(existingChild, grandchild); + } + } + } + + private static void CopyPermissionDetails(PermissionDefinition source, PermissionDefinition target) + { + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.Providers) + { + if (!target.Providers.Contains(provider)) + { + target.Providers.Add(provider); + } + } + + foreach (var checker in source.StateCheckers) + { + if (!target.StateCheckers.Contains(checker)) + { + target.StateCheckers.Add(checker); + } + } + } + + private static void MergePermissionMetadata(PermissionDefinition target, PermissionDefinition source) + { + target.DisplayName = source.DisplayName; + + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.Providers) + { + if (!target.Providers.Contains(provider)) + { + target.Providers.Add(provider); + } + } + + foreach (var checker in source.StateCheckers) + { + if (!target.StateCheckers.Contains(checker)) + { + target.StateCheckers.Add(checker); + } + } + + if (source.MultiTenancySide != MultiTenancySides.Both) + { + target.MultiTenancySide |= source.MultiTenancySide; + } + + target.IsEnabled = target.IsEnabled || source.IsEnabled; + } +} +#nullable disable \ No newline at end of file diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.WebhookService/Overrides/MergeSettingDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.WebhookService/Overrides/MergeSettingDefinitionManager.cs new file mode 100644 index 000000000..2fe64a566 --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.WebhookService/Overrides/MergeSettingDefinitionManager.cs @@ -0,0 +1,86 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Settings; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergeSettingDefinitionManager : SettingDefinitionManager +{ + public MergeSettingDefinitionManager( + IStaticSettingDefinitionStore staticStore, + IDynamicSettingDefinitionStore dynamicStore) + : base(staticStore, dynamicStore) + { + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeSetting(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetAllAsync() + { + var staticSettings = await StaticStore.GetAllAsync(); + var dynamicSettings = await DynamicStore.GetAllAsync(); + + var mergedSettings = new Dictionary(); + + foreach (var staticSetting in staticSettings) + { + mergedSettings[staticSetting.Name] = staticSetting; + } + + foreach (var dynamicSetting in dynamicSettings) + { + if (mergedSettings.TryGetValue(dynamicSetting.Name, out var existingSetting)) + { + MergeSetting(existingSetting, dynamicSetting); + } + else + { + mergedSettings[dynamicSetting.Name] = dynamicSetting; + } + } + + return mergedSettings.Values.ToImmutableList(); + } + + private static void MergeSetting(SettingDefinition target, SettingDefinition source) + { + target.DisplayName = source.DisplayName; + target.Description = source.Description ?? target.Description; + target.DefaultValue = source.DefaultValue ?? target.DefaultValue; + target.IsVisibleToClients = target.IsVisibleToClients || source.IsVisibleToClients; + target.IsInherited = target.IsInherited || source.IsInherited; + target.IsEncrypted = target.IsEncrypted || source.IsEncrypted; + + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.Providers) + { + if (!target.Providers.Contains(provider)) + { + target.Providers.Add(provider); + } + } + } +} +#nullable disable + diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.WebhookService/Overrides/MergeTemplateDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.WebhookService/Overrides/MergeTemplateDefinitionManager.cs new file mode 100644 index 000000000..5cb3137cd --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.WebhookService/Overrides/MergeTemplateDefinitionManager.cs @@ -0,0 +1,104 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.TextTemplating; + +namespace Volo.Abp.TextTemplatin; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergeTemplateDefinitionManager : TemplateDefinitionManager +{ + public MergeTemplateDefinitionManager( + IStaticTemplateDefinitionStore staticStore, + IDynamicTemplateDefinitionStore dynamicStore) + : base(staticStore, dynamicStore) + { + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeTemplate(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetAllAsync() + { + var staticTemplates = await StaticStore.GetAllAsync(); + var dynamicTemplates = await DynamicStore.GetAllAsync(); + + var mergedTemplates = new Dictionary(); + + foreach (var staticTemplate in staticTemplates) + { + mergedTemplates[staticTemplate.Name] = staticTemplate; + } + + foreach (var dynamicTemplate in dynamicTemplates) + { + if (mergedTemplates.TryGetValue(dynamicTemplate.Name, out var existingTemplate)) + { + MergeTemplate(existingTemplate, dynamicTemplate); + } + else + { + mergedTemplates[dynamicTemplate.Name] = dynamicTemplate; + } + } + + return mergedTemplates.Values.ToImmutableList(); + } + + private static TemplateDefinition MergeTemplate(TemplateDefinition staticTemplate, TemplateDefinition dynamicTemplate) + { + var localizationResourceName = dynamicTemplate.LocalizationResourceName ?? staticTemplate.LocalizationResourceName; + var defaultCultureName = dynamicTemplate.DefaultCultureName ?? staticTemplate.DefaultCultureName; + var displayName = dynamicTemplate.DisplayName ?? staticTemplate.DisplayName; + var isLayout = dynamicTemplate.IsLayout || staticTemplate.IsLayout; + var layout = dynamicTemplate.Layout ?? staticTemplate.Layout; + + var mergedTemplate = new TemplateDefinition( + staticTemplate.Name, + localizationResourceName, + displayName, + isLayout, + layout, + defaultCultureName + ); + + foreach (var property in staticTemplate.Properties) + { + mergedTemplate.Properties[property.Key] = property.Value; + } + + foreach (var property in dynamicTemplate.Properties) + { + mergedTemplate.Properties[property.Key] = property.Value; + } + + if (!string.IsNullOrEmpty(dynamicTemplate.RenderEngine)) + { + mergedTemplate.RenderEngine = dynamicTemplate.RenderEngine; + } + else if (!string.IsNullOrEmpty(staticTemplate.RenderEngine)) + { + mergedTemplate.RenderEngine = staticTemplate.RenderEngine; + } + + mergedTemplate.IsInlineLocalized = dynamicTemplate.IsInlineLocalized || staticTemplate.IsInlineLocalized; + + return mergedTemplate; + } +} +#nullable disable diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.WorkflowService/Overrides/MergeFeatureDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.WorkflowService/Overrides/MergeFeatureDefinitionManager.cs new file mode 100644 index 000000000..498ac24fe --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.WorkflowService/Overrides/MergeFeatureDefinitionManager.cs @@ -0,0 +1,277 @@ +using JetBrains.Annotations; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Features; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergeFeatureDefinitionManager : FeatureDefinitionManager +{ + public MergeFeatureDefinitionManager( + IStaticFeatureDefinitionStore staticStore, + IDynamicFeatureDefinitionStore dynamicStore) + : base(staticStore, dynamicStore) + { + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeFeatureMetadata(staticDefinition, dynamicDefinition); + + foreach (var child in dynamicDefinition.Children) + { + MergeChildFeature(staticDefinition, child); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetAllAsync() + { + var staticFeatures = await StaticStore.GetFeaturesAsync(); + var dynamicFeatures = await DynamicStore.GetFeaturesAsync(); + + var mergedFeatures = new Dictionary(); + + foreach (var staticFeature in staticFeatures) + { + mergedFeatures[staticFeature.Name] = staticFeature; + } + + foreach (var dynamicFeature in dynamicFeatures) + { + if (mergedFeatures.TryGetValue(dynamicFeature.Name, out var existingFeature)) + { + MergeFeatureMetadata(existingFeature, dynamicFeature); + + foreach (var child in dynamicFeature.Children) + { + MergeChildFeature(existingFeature, child); + } + } + else + { + mergedFeatures[dynamicFeature.Name] = dynamicFeature; + } + } + + return mergedFeatures.Values.ToImmutableList(); + } + + public async override Task> GetGroupsAsync() + { + var staticGroups = await StaticStore.GetGroupsAsync(); + var dynamicGroups = await DynamicStore.GetGroupsAsync(); + + var mergedGroups = new Dictionary(); + + foreach (var staticGroup in staticGroups) + { + mergedGroups[staticGroup.Name] = staticGroup; + } + + foreach (var dynamicGroup in dynamicGroups) + { + if (mergedGroups.TryGetValue(dynamicGroup.Name, out var existingGroup)) + { + MergeGroupFeatures(existingGroup, dynamicGroup); + } + else + { + mergedGroups[dynamicGroup.Name] = dynamicGroup; + } + } + + return mergedGroups.Values.ToImmutableList(); + } + + private static void MergeGroupFeatures(FeatureGroupDefinition target, FeatureGroupDefinition source) + { + foreach (var sourceFeature in source.Features) + { + var existingFeature = GetFeatureOrNull(target, sourceFeature.Name); + + if (existingFeature == null) + { + var newFeature = target.AddFeature( + sourceFeature.Name, + sourceFeature.DefaultValue, + sourceFeature.DisplayName, + sourceFeature.Description, + sourceFeature.ValueType, + sourceFeature.IsVisibleToClients, + sourceFeature.IsAvailableToHost + ); + + CopyFeatureDetails(sourceFeature, newFeature); + + foreach (var child in sourceFeature.Children) + { + AddChildFeatureRecursively(newFeature, child); + } + } + else + { + MergeFeatureMetadata(existingFeature, sourceFeature); + + foreach (var child in sourceFeature.Children) + { + MergeChildFeature(existingFeature, child); + } + } + } + } + + private static void AddChildFeatureRecursively(FeatureDefinition parent, FeatureDefinition sourceChild) + { + var newChild = parent.CreateChild( + sourceChild.Name, + sourceChild.DefaultValue, + sourceChild.DisplayName, + sourceChild.Description, + sourceChild.ValueType, + sourceChild.IsVisibleToClients, + sourceChild.IsAvailableToHost + ); + + CopyFeatureDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildFeatureRecursively(newChild, grandchild); + } + } + + private static void MergeChildFeature(FeatureDefinition parent, FeatureDefinition sourceChild) + { + var existingChild = parent.Children.FirstOrDefault(c => c.Name == sourceChild.Name); + + if (existingChild == null) + { + var newChild = parent.CreateChild( + sourceChild.Name, + sourceChild.DefaultValue, + sourceChild.DisplayName, + sourceChild.Description, + sourceChild.ValueType, + sourceChild.IsVisibleToClients, + sourceChild.IsAvailableToHost + ); + CopyFeatureDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildFeatureRecursively(newChild, grandchild); + } + } + else + { + MergeFeatureMetadata(existingChild, sourceChild); + + foreach (var grandchild in sourceChild.Children) + { + MergeChildFeature(existingChild, grandchild); + } + } + } + + private static void CopyFeatureDetails(FeatureDefinition source, FeatureDefinition target) + { + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.AllowedProviders) + { + if (!target.AllowedProviders.Contains(provider)) + { + target.AllowedProviders.Add(provider); + } + } + } + + private static void MergeFeatureMetadata(FeatureDefinition target, FeatureDefinition source) + { + if (source.DisplayName != null) + { + target.DisplayName = source.DisplayName; + } + + if (source.Description != null) + { + target.Description = source.Description; + } + + if (source.DefaultValue != null) + { + target.DefaultValue = source.DefaultValue; + } + + if (source.ValueType != null) + { + target.ValueType = source.ValueType; + } + + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.AllowedProviders) + { + if (!target.AllowedProviders.Contains(provider)) + { + target.AllowedProviders.Add(provider); + } + } + + target.IsVisibleToClients = target.IsVisibleToClients || source.IsVisibleToClients; + target.IsAvailableToHost = target.IsAvailableToHost || source.IsAvailableToHost; + } + + + public static FeatureDefinition? GetFeatureOrNull( + FeatureGroupDefinition group, + [NotNull] string name) + { + Check.NotNull(name, nameof(name)); + + return GetFeatureOrNullRecursively(group.Features, name); + } + + private static FeatureDefinition? GetFeatureOrNullRecursively( + IReadOnlyList features, + string name) + { + foreach (var feature in features) + { + if (feature.Name == name) + { + return feature; + } + + var childFeature = GetFeatureOrNullRecursively(feature.Children, name); + if (childFeature != null) + { + return childFeature; + } + } + + return null; + } +} +#nullable disable \ No newline at end of file diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.WorkflowService/Overrides/MergePermissionDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.WorkflowService/Overrides/MergePermissionDefinitionManager.cs new file mode 100644 index 000000000..027e7f1c4 --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.WorkflowService/Overrides/MergePermissionDefinitionManager.cs @@ -0,0 +1,276 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.MultiTenancy; + +namespace Volo.Abp.Authorization.Permissions; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergePermissionDefinitionManager : PermissionDefinitionManager +{ + private readonly IStaticPermissionDefinitionStore _staticStore; + private readonly IDynamicPermissionDefinitionStore _dynamicStore; + + public MergePermissionDefinitionManager( + IStaticPermissionDefinitionStore staticStore, + IDynamicPermissionDefinitionStore dynamicStore) : base(staticStore, dynamicStore) + { + _staticStore = staticStore; + _dynamicStore = dynamicStore; + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetOrNullAsync(name); + var dynamicDefinition = await _dynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task GetResourcePermissionOrNullAsync(string resourceName, string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetResourcePermissionOrNullAsync(resourceName, name); + var dynamicDefinition = await _dynamicStore.GetResourcePermissionOrNullAsync(resourceName, name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetPermissionsAsync() + { + var staticPermissions = await _staticStore.GetPermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetPermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + + public async override Task> GetResourcePermissionsAsync() + { + var staticPermissions = await _staticStore.GetResourcePermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetResourcePermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + + public async override Task> GetGroupsAsync() + { + var staticGroups = await _staticStore.GetGroupsAsync(); + var dynamicGroups = await _dynamicStore.GetGroupsAsync(); + + var mergedGroups = new Dictionary(); + + foreach (var staticGroup in staticGroups) + { + mergedGroups[staticGroup.Name] = staticGroup; + } + + foreach (var dynamicGroup in dynamicGroups) + { + if (mergedGroups.TryGetValue(dynamicGroup.Name, out var existingGroup)) + { + MergeGroupPermissions(existingGroup, dynamicGroup); + } + else + { + mergedGroups[dynamicGroup.Name] = dynamicGroup; + } + } + + return mergedGroups.Values.ToImmutableList(); + } + + private static void MergeGroupPermissions(PermissionGroupDefinition target, PermissionGroupDefinition source) + { + foreach (var sourcePermission in source.Permissions) + { + var existingPermission = target.GetPermissionOrNull(sourcePermission.Name); + + if (existingPermission == null) + { + var newPermission = target.AddPermission( + sourcePermission.Name, + sourcePermission.DisplayName, + sourcePermission.MultiTenancySide, + sourcePermission.IsEnabled + ); + + CopyPermissionDetails(sourcePermission, newPermission); + + foreach (var child in sourcePermission.Children) + { + AddChildPermissionRecursively(newPermission, child); + } + } + else + { + MergePermissionMetadata(existingPermission, sourcePermission); + + foreach (var sourceChild in sourcePermission.Children) + { + MergeChildPermissions(existingPermission, sourceChild); + } + } + } + } + + private static void AddChildPermissionRecursively(PermissionDefinition parent, PermissionDefinition sourceChild) + { + var newChild = parent.AddChild( + sourceChild.Name, + sourceChild.DisplayName, + sourceChild.MultiTenancySide, + sourceChild.IsEnabled + ); + + CopyPermissionDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildPermissionRecursively(newChild, grandchild); + } + } + + private static IReadOnlyList MergePermissions(IReadOnlyList staticPermissions, IReadOnlyList dynamicPermissions) + { + var mergedPermissions = new Dictionary(); + + foreach (var staticFeature in staticPermissions) + { + mergedPermissions[staticFeature.Name] = staticFeature; + } + + foreach (var dynamicPermission in dynamicPermissions) + { + if (mergedPermissions.TryGetValue(dynamicPermission.Name, out var existingPermission)) + { + MergePermissionMetadata(existingPermission, dynamicPermission); + + foreach (var sourceChild in dynamicPermission.Children) + { + MergeChildPermissions(existingPermission, sourceChild); + } + } + else + { + mergedPermissions[dynamicPermission.Name] = dynamicPermission; + } + } + + return mergedPermissions.Values.ToImmutableList(); + } + + private static void MergeChildPermissions(PermissionDefinition parent, PermissionDefinition sourceChild) + { + var existingChild = parent.Children.FirstOrDefault(c => c.Name == sourceChild.Name); + + if (existingChild == null) + { + var newChild = parent.AddChild( + sourceChild.Name, + sourceChild.DisplayName, + sourceChild.MultiTenancySide, + sourceChild.IsEnabled + ); + CopyPermissionDetails(sourceChild, newChild); + + foreach (var grandchild in sourceChild.Children) + { + AddChildPermissionRecursively(newChild, grandchild); + } + } + else + { + MergePermissionMetadata(existingChild, sourceChild); + + foreach (var grandchild in sourceChild.Children) + { + MergeChildPermissions(existingChild, grandchild); + } + } + } + + private static void CopyPermissionDetails(PermissionDefinition source, PermissionDefinition target) + { + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.Providers) + { + if (!target.Providers.Contains(provider)) + { + target.Providers.Add(provider); + } + } + + foreach (var checker in source.StateCheckers) + { + if (!target.StateCheckers.Contains(checker)) + { + target.StateCheckers.Add(checker); + } + } + } + + private static void MergePermissionMetadata(PermissionDefinition target, PermissionDefinition source) + { + target.DisplayName = source.DisplayName; + + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.Providers) + { + if (!target.Providers.Contains(provider)) + { + target.Providers.Add(provider); + } + } + + foreach (var checker in source.StateCheckers) + { + if (!target.StateCheckers.Contains(checker)) + { + target.StateCheckers.Add(checker); + } + } + + if (source.MultiTenancySide != MultiTenancySides.Both) + { + target.MultiTenancySide |= source.MultiTenancySide; + } + + target.IsEnabled = target.IsEnabled || source.IsEnabled; + } +} +#nullable disable \ No newline at end of file diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.WorkflowService/Overrides/MergeSettingDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.WorkflowService/Overrides/MergeSettingDefinitionManager.cs new file mode 100644 index 000000000..2fe64a566 --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.WorkflowService/Overrides/MergeSettingDefinitionManager.cs @@ -0,0 +1,86 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Settings; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergeSettingDefinitionManager : SettingDefinitionManager +{ + public MergeSettingDefinitionManager( + IStaticSettingDefinitionStore staticStore, + IDynamicSettingDefinitionStore dynamicStore) + : base(staticStore, dynamicStore) + { + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeSetting(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetAllAsync() + { + var staticSettings = await StaticStore.GetAllAsync(); + var dynamicSettings = await DynamicStore.GetAllAsync(); + + var mergedSettings = new Dictionary(); + + foreach (var staticSetting in staticSettings) + { + mergedSettings[staticSetting.Name] = staticSetting; + } + + foreach (var dynamicSetting in dynamicSettings) + { + if (mergedSettings.TryGetValue(dynamicSetting.Name, out var existingSetting)) + { + MergeSetting(existingSetting, dynamicSetting); + } + else + { + mergedSettings[dynamicSetting.Name] = dynamicSetting; + } + } + + return mergedSettings.Values.ToImmutableList(); + } + + private static void MergeSetting(SettingDefinition target, SettingDefinition source) + { + target.DisplayName = source.DisplayName; + target.Description = source.Description ?? target.Description; + target.DefaultValue = source.DefaultValue ?? target.DefaultValue; + target.IsVisibleToClients = target.IsVisibleToClients || source.IsVisibleToClients; + target.IsInherited = target.IsInherited || source.IsInherited; + target.IsEncrypted = target.IsEncrypted || source.IsEncrypted; + + foreach (var property in source.Properties) + { + target.Properties[property.Key] = property.Value; + } + + foreach (var provider in source.Providers) + { + if (!target.Providers.Contains(provider)) + { + target.Providers.Add(provider); + } + } + } +} +#nullable disable + diff --git a/aspnet-core/aspire/LINGYUN.Abp.MicroService.WorkflowService/Overrides/MergeTemplateDefinitionManager.cs b/aspnet-core/aspire/LINGYUN.Abp.MicroService.WorkflowService/Overrides/MergeTemplateDefinitionManager.cs new file mode 100644 index 000000000..5cb3137cd --- /dev/null +++ b/aspnet-core/aspire/LINGYUN.Abp.MicroService.WorkflowService/Overrides/MergeTemplateDefinitionManager.cs @@ -0,0 +1,104 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.TextTemplating; + +namespace Volo.Abp.TextTemplatin; + +#nullable enable + +[Dependency(ReplaceServices = true)] +public class MergeTemplateDefinitionManager : TemplateDefinitionManager +{ + public MergeTemplateDefinitionManager( + IStaticTemplateDefinitionStore staticStore, + IDynamicTemplateDefinitionStore dynamicStore) + : base(staticStore, dynamicStore) + { + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeTemplate(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetAllAsync() + { + var staticTemplates = await StaticStore.GetAllAsync(); + var dynamicTemplates = await DynamicStore.GetAllAsync(); + + var mergedTemplates = new Dictionary(); + + foreach (var staticTemplate in staticTemplates) + { + mergedTemplates[staticTemplate.Name] = staticTemplate; + } + + foreach (var dynamicTemplate in dynamicTemplates) + { + if (mergedTemplates.TryGetValue(dynamicTemplate.Name, out var existingTemplate)) + { + MergeTemplate(existingTemplate, dynamicTemplate); + } + else + { + mergedTemplates[dynamicTemplate.Name] = dynamicTemplate; + } + } + + return mergedTemplates.Values.ToImmutableList(); + } + + private static TemplateDefinition MergeTemplate(TemplateDefinition staticTemplate, TemplateDefinition dynamicTemplate) + { + var localizationResourceName = dynamicTemplate.LocalizationResourceName ?? staticTemplate.LocalizationResourceName; + var defaultCultureName = dynamicTemplate.DefaultCultureName ?? staticTemplate.DefaultCultureName; + var displayName = dynamicTemplate.DisplayName ?? staticTemplate.DisplayName; + var isLayout = dynamicTemplate.IsLayout || staticTemplate.IsLayout; + var layout = dynamicTemplate.Layout ?? staticTemplate.Layout; + + var mergedTemplate = new TemplateDefinition( + staticTemplate.Name, + localizationResourceName, + displayName, + isLayout, + layout, + defaultCultureName + ); + + foreach (var property in staticTemplate.Properties) + { + mergedTemplate.Properties[property.Key] = property.Value; + } + + foreach (var property in dynamicTemplate.Properties) + { + mergedTemplate.Properties[property.Key] = property.Value; + } + + if (!string.IsNullOrEmpty(dynamicTemplate.RenderEngine)) + { + mergedTemplate.RenderEngine = dynamicTemplate.RenderEngine; + } + else if (!string.IsNullOrEmpty(staticTemplate.RenderEngine)) + { + mergedTemplate.RenderEngine = staticTemplate.RenderEngine; + } + + mergedTemplate.IsInlineLocalized = dynamicTemplate.IsInlineLocalized || staticTemplate.IsInlineLocalized; + + return mergedTemplate; + } +} +#nullable disable diff --git a/aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/AbpAICoreOptions.cs b/aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/AbpAICoreOptions.cs index 3b25830bd..3a4a78b8d 100644 --- a/aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/AbpAICoreOptions.cs +++ b/aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/AbpAICoreOptions.cs @@ -9,6 +9,7 @@ using Volo.Abp.Collections; namespace LINGYUN.Abp.AI; public class AbpAICoreOptions { + public DynamicWorkspaceStrategy DynamicWorkspaceStrategy { get; set; } public ITypeList DefinitionProviders { get; } public ITypeList ChatClientProviders { get; } public ITypeList KernelProviders { get; } @@ -20,6 +21,7 @@ public class AbpAICoreOptions public AbpAICoreOptions() { + DynamicWorkspaceStrategy = DynamicWorkspaceStrategy.Merge; DefinitionProviders = new TypeList(); ChatClientProviders = new TypeList(); KernelProviders = new TypeList(); diff --git a/aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/Workspaces/DynamicWorkspaceStrategy.cs b/aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/Workspaces/DynamicWorkspaceStrategy.cs new file mode 100644 index 000000000..6aa754874 --- /dev/null +++ b/aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/Workspaces/DynamicWorkspaceStrategy.cs @@ -0,0 +1,21 @@ +namespace LINGYUN.Abp.AI.Workspaces; +/// +/// 动态工作区策略 +/// +public enum DynamicWorkspaceStrategy +{ + /// + /// 忽略动态工作区(静态优先) + /// + Ignore, + + /// + /// 动态覆盖静态 + /// + Covering, + + /// + /// 合并策略 + /// + Merge +} diff --git a/aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/Workspaces/WorkspaceDefinitionManager.cs b/aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/Workspaces/WorkspaceDefinitionManager.cs index 8b5b8048d..0a4ef9102 100644 --- a/aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/Workspaces/WorkspaceDefinitionManager.cs +++ b/aspnet-core/modules/ai/LINGYUN.Abp.AI.Core/LINGYUN/Abp/AI/Workspaces/WorkspaceDefinitionManager.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using Microsoft.Extensions.Options; +using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using System.Threading.Tasks; @@ -8,15 +9,18 @@ using Volo.Abp.DependencyInjection; namespace LINGYUN.Abp.AI.Workspaces; public class WorkspaceDefinitionManager : IWorkspaceDefinitionManager, ISingletonDependency { + protected readonly AbpAICoreOptions Options; protected readonly IStaticWorkspaceDefinitionStore StaticStore; protected readonly IDynamicWorkspaceDefinitionStore DynamicStore; public WorkspaceDefinitionManager( - IStaticWorkspaceDefinitionStore staticStore, - IDynamicWorkspaceDefinitionStore dynamicStore) + IStaticWorkspaceDefinitionStore staticStore, + IDynamicWorkspaceDefinitionStore dynamicStore, + IOptions options) { StaticStore = staticStore; DynamicStore = dynamicStore; + Options = options.Value; } public virtual async Task GetAsync(string name) @@ -34,19 +38,239 @@ public class WorkspaceDefinitionManager : IWorkspaceDefinitionManager, ISingleto { Check.NotNull(name, nameof(name)); - return await StaticStore.GetOrNullAsync(name) ?? await DynamicStore.GetOrNullAsync(name); + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + return Options.DynamicWorkspaceStrategy switch + { + DynamicWorkspaceStrategy.Ignore => staticDefinition, + DynamicWorkspaceStrategy.Covering => dynamicDefinition, + DynamicWorkspaceStrategy.Merge => MergeWorkspace(staticDefinition, dynamicDefinition), + _ => MergeWorkspace(staticDefinition, dynamicDefinition) + }; + } + + return staticDefinition ?? dynamicDefinition; } public virtual async Task> GetAllAsync() { var staticWorkspaces = await StaticStore.GetAllAsync(); + var dynamicWorkspaces = await DynamicStore.GetAllAsync(); + + // 根据策略处理工作区定义 + return Options.DynamicWorkspaceStrategy switch + { + DynamicWorkspaceStrategy.Ignore => await GetWorkspacesWithIgnoreStrategy(staticWorkspaces, dynamicWorkspaces), + DynamicWorkspaceStrategy.Covering => await GetWorkspacesWithCoveringStrategy(staticWorkspaces, dynamicWorkspaces), + DynamicWorkspaceStrategy.Merge => await GetWorkspacesWithMergeStrategy(staticWorkspaces, dynamicWorkspaces), + _ => await GetWorkspacesWithMergeStrategy(staticWorkspaces, dynamicWorkspaces) // 默认使用合并策略 + }; + } + + #region 工作区定义策略 + + /// + /// 忽略策略:静态优先,过滤掉同名的动态工作区 + /// + protected virtual Task> GetWorkspacesWithIgnoreStrategy( + IReadOnlyList staticWorkspaces, + IReadOnlyList dynamicWorkspaces) + { var staticWorkspaceNames = staticWorkspaces .Select(p => p.Name) .ToImmutableHashSet(); - var dynamicWorkspaces = await DynamicStore.GetAllAsync(); + return Task.FromResult>( + staticWorkspaces + .Concat(dynamicWorkspaces.Where(d => !staticWorkspaceNames.Contains(d.Name))) + .ToImmutableList() + ); + } - return staticWorkspaces.Concat(dynamicWorkspaces.Where(d => !staticWorkspaceNames.Contains(d.Name))) + /// + /// 覆盖策略:动态完全覆盖静态工作区 + /// + protected virtual Task> GetWorkspacesWithCoveringStrategy( + IReadOnlyList staticWorkspaces, + IReadOnlyList dynamicWorkspaces) + { + var dynamicWorkspaceNames = dynamicWorkspaces + .Select(p => p.Name) + .ToImmutableHashSet(); + + // 动态工作区完全覆盖静态工作区 + var result = dynamicWorkspaces + .Concat(staticWorkspaces.Where(s => !dynamicWorkspaceNames.Contains(s.Name))) .ToImmutableList(); + + return Task.FromResult>(result); + } + + /// + /// 合并策略:合并静态和动态工作区,创建新实例 + /// + protected virtual Task> GetWorkspacesWithMergeStrategy( + IReadOnlyList staticWorkspaces, + IReadOnlyList dynamicWorkspaces) + { + var mergedWorkspaces = new Dictionary(); + + // 先添加所有静态工作区 + foreach (var staticWorkspace in staticWorkspaces) + { + mergedWorkspaces[staticWorkspace.Name] = staticWorkspace; + } + + // 合并动态工作区 + foreach (var dynamicWorkspace in dynamicWorkspaces) + { + if (mergedWorkspaces.TryGetValue(dynamicWorkspace.Name, out var existingWorkspace)) + { + // 工作区已存在,创建新的合并工作区 + var mergedWorkspace = MergeWorkspace(existingWorkspace, dynamicWorkspace); + mergedWorkspaces[dynamicWorkspace.Name] = mergedWorkspace; + } + else + { + // 添加新的动态工作区 + mergedWorkspaces[dynamicWorkspace.Name] = dynamicWorkspace; + } + } + + // 处理被删除的工作区 + foreach (var deletedWorkspaceName in Options.DeletedWorkspaces) + { + if (mergedWorkspaces.ContainsKey(deletedWorkspaceName)) + { + mergedWorkspaces.Remove(deletedWorkspaceName); + } + } + + return Task.FromResult>(mergedWorkspaces.Values.ToImmutableList()); } + + /// + /// 合并两个工作区定义,返回新的 WorkspaceDefinition 实例 + /// + protected virtual WorkspaceDefinition MergeWorkspace( + WorkspaceDefinition staticWorkspace, + WorkspaceDefinition dynamicWorkspace) + { + // 决定使用哪个提供者(优先使用动态的) + var provider = !string.IsNullOrEmpty(dynamicWorkspace.Provider) + ? dynamicWorkspace.Provider + : staticWorkspace.Provider; + + // 决定使用哪个模型名称(优先使用动态的) + var modelName = !string.IsNullOrEmpty(dynamicWorkspace.ModelName) + ? dynamicWorkspace.ModelName + : staticWorkspace.ModelName; + + // 决定使用哪个显示名称(优先使用动态的) + var displayName = dynamicWorkspace.DisplayName ?? staticWorkspace.DisplayName; + + // 创建新的工作区实例(Name是只读的) + var mergedWorkspace = new WorkspaceDefinition( + staticWorkspace.Name, // 保持名称不变 + provider, + modelName, + displayName + ); + + // 设置描述(优先使用动态的) + mergedWorkspace.Description = dynamicWorkspace.Description ?? staticWorkspace.Description; + + // 设置API密钥(优先使用动态的) + if (!string.IsNullOrEmpty(dynamicWorkspace.ApiKey)) + { + mergedWorkspace.WithApiKey(dynamicWorkspace.ApiKey!); + } + else if (!string.IsNullOrEmpty(staticWorkspace.ApiKey)) + { + mergedWorkspace.WithApiKey(staticWorkspace.ApiKey!); + } + + // 设置API基础URL(优先使用动态的) + if (!string.IsNullOrEmpty(dynamicWorkspace.ApiBaseUrl)) + { + mergedWorkspace.WithApiBaseUrl(dynamicWorkspace.ApiBaseUrl!); + } + else if (!string.IsNullOrEmpty(staticWorkspace.ApiBaseUrl)) + { + mergedWorkspace.WithApiBaseUrl(staticWorkspace.ApiBaseUrl!); + } + + // 设置系统提示词(优先使用动态的) + mergedWorkspace.SystemPrompt = dynamicWorkspace.SystemPrompt ?? staticWorkspace.SystemPrompt; + + // 设置附加系统提示词(优先使用动态的) + mergedWorkspace.Instructions = dynamicWorkspace.Instructions ?? staticWorkspace.Instructions; + + // 设置温度值(优先使用动态的) + mergedWorkspace.Temperature = dynamicWorkspace.Temperature ?? staticWorkspace.Temperature; + + // 设置最大输出token数(优先使用动态的) + mergedWorkspace.MaxOutputTokens = dynamicWorkspace.MaxOutputTokens ?? staticWorkspace.MaxOutputTokens; + + // 设置频率惩罚(优先使用动态的) + mergedWorkspace.FrequencyPenalty = dynamicWorkspace.FrequencyPenalty ?? staticWorkspace.FrequencyPenalty; + + // 设置存在惩罚(优先使用动态的) + mergedWorkspace.PresencePenalty = dynamicWorkspace.PresencePenalty ?? staticWorkspace.PresencePenalty; + + // 设置是否启用(只要有一方启用,结果就是启用) + mergedWorkspace.IsEnabled = staticWorkspace.IsEnabled || dynamicWorkspace.IsEnabled; + + // 合并状态检查器 + foreach (var checker in staticWorkspace.StateCheckers) + { + if (!mergedWorkspace.StateCheckers.Contains(checker)) + { + mergedWorkspace.StateCheckers.Add(checker); + } + } + + foreach (var checker in dynamicWorkspace.StateCheckers) + { + if (!mergedWorkspace.StateCheckers.Contains(checker)) + { + mergedWorkspace.StateCheckers.Add(checker); + } + } + + // 合并工具列表(去重) + foreach (var tool in staticWorkspace.Tools) + { + if (!mergedWorkspace.Tools.Contains(tool)) + { + mergedWorkspace.Tools.Add(tool); + } + } + + foreach (var tool in dynamicWorkspace.Tools) + { + if (!mergedWorkspace.Tools.Contains(tool)) + { + mergedWorkspace.Tools.Add(tool); + } + } + + // 合并属性(动态覆盖静态) + foreach (var property in staticWorkspace.Properties) + { + mergedWorkspace.Properties[property.Key] = property.Value; + } + + foreach (var property in dynamicWorkspace.Properties) + { + mergedWorkspace.Properties[property.Key] = property.Value; + } + + return mergedWorkspace; + } + + #endregion } diff --git a/aspnet-core/modules/ai/LINGYUN.Abp.AI.Tools/LINGYUN/Abp/AI/Tools/AIToolDefinitionManager.cs b/aspnet-core/modules/ai/LINGYUN.Abp.AI.Tools/LINGYUN/Abp/AI/Tools/AIToolDefinitionManager.cs index fceacf1cd..630842b08 100644 --- a/aspnet-core/modules/ai/LINGYUN.Abp.AI.Tools/LINGYUN/Abp/AI/Tools/AIToolDefinitionManager.cs +++ b/aspnet-core/modules/ai/LINGYUN.Abp.AI.Tools/LINGYUN/Abp/AI/Tools/AIToolDefinitionManager.cs @@ -39,8 +39,21 @@ public class AIToolDefinitionManager : IAIToolDefinitionManager, ISingletonDepen { Check.NotNull(name, nameof(name)); - return await StaticStore.GetOrNullAsync(name) ?? - await DynamicStore.GetOrNullAsync(name); + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + return AIToolOptions.DynamicAItoolStrategy switch + { + DynamicAItoolStrategy.Ignore => staticDefinition, + DynamicAItoolStrategy.Covering => dynamicDefinition, + DynamicAItoolStrategy.Merge => MergeAITool(staticDefinition, dynamicDefinition), + _ => MergeAITool(staticDefinition, dynamicDefinition) + }; + } + + return staticDefinition ?? dynamicDefinition; } public virtual async Task> GetAllAsync() diff --git a/aspnet-core/modules/feature-management/LINGYUN.Abp.FeatureManagement.Application/LINGYUN/Abp/FeatureManagement/Definitions/FeatureDefinitionAppService.cs b/aspnet-core/modules/feature-management/LINGYUN.Abp.FeatureManagement.Application/LINGYUN/Abp/FeatureManagement/Definitions/FeatureDefinitionAppService.cs index 349079347..fa07c7ad2 100644 --- a/aspnet-core/modules/feature-management/LINGYUN.Abp.FeatureManagement.Application/LINGYUN/Abp/FeatureManagement/Definitions/FeatureDefinitionAppService.cs +++ b/aspnet-core/modules/feature-management/LINGYUN.Abp.FeatureManagement.Application/LINGYUN/Abp/FeatureManagement/Definitions/FeatureDefinitionAppService.cs @@ -121,7 +121,7 @@ public class FeatureDefinitionAppService : FeatureManagementAppServiceBase, IFea Expression> predicate = _ => true; if (!input.GroupName.IsNullOrWhiteSpace()) { - predicate = predicate.And(x => x.Name == input.GroupName); + predicate = predicate.And(x => x.GroupName == input.GroupName); } var definitionRecords = await _definitionBasicRepository.GetListAsync(predicate); featureDtoList.AddRange(definitionRecords.Select(DefinitionRecordToDto)); diff --git a/aspnet-core/modules/permissions-management/LINGYUN.Abp.PermissionManagement.Application/LINGYUN/Abp/PermissionManagement/Definitions/PermissionDefinitionAppService.cs b/aspnet-core/modules/permissions-management/LINGYUN.Abp.PermissionManagement.Application/LINGYUN/Abp/PermissionManagement/Definitions/PermissionDefinitionAppService.cs index 43539aec2..74b4a8222 100644 --- a/aspnet-core/modules/permissions-management/LINGYUN.Abp.PermissionManagement.Application/LINGYUN/Abp/PermissionManagement/Definitions/PermissionDefinitionAppService.cs +++ b/aspnet-core/modules/permissions-management/LINGYUN.Abp.PermissionManagement.Application/LINGYUN/Abp/PermissionManagement/Definitions/PermissionDefinitionAppService.cs @@ -123,7 +123,7 @@ public class PermissionDefinitionAppService : PermissionManagementAppServiceBase Expression> predicate = _ => true; if (!input.GroupName.IsNullOrWhiteSpace()) { - predicate = predicate.And(x => x.Name == input.GroupName); + predicate = predicate.And(x => x.GroupName == input.GroupName); } var permissionDefinitions = await _definitionBasicRepository.GetListAsync(predicate); permissionDtoList.AddRange(permissionDefinitions.Select(DefinitionRecordToDto)); diff --git a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Core/LINGYUN/Abp/Notifications/NotificationDefinitionManager.cs b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Core/LINGYUN/Abp/Notifications/NotificationDefinitionManager.cs index 11f0a8b88..0fa26ae5e 100644 --- a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Core/LINGYUN/Abp/Notifications/NotificationDefinitionManager.cs +++ b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Core/LINGYUN/Abp/Notifications/NotificationDefinitionManager.cs @@ -39,8 +39,21 @@ public class NotificationDefinitionManager : INotificationDefinitionManager, ITr { Check.NotNull(name, nameof(name)); - return await _staticStore.GetOrNullAsync(name) ?? - await _dynamicStore.GetOrNullAsync(name); + var staticDefinition = await _staticStore.GetOrNullAsync(name); + var dynamicDefinition = await _dynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + return _notificationsOptions.DynamicNotificationStrategy switch + { + DynamicNotificationStrategy.Ignore => staticDefinition, + DynamicNotificationStrategy.Covering => dynamicDefinition, + DynamicNotificationStrategy.Merge => MergeNotification(staticDefinition, dynamicDefinition), + _ => staticDefinition + }; + } + + return staticDefinition ?? dynamicDefinition; } public async virtual Task> GetNotificationsAsync() @@ -62,8 +75,26 @@ public class NotificationDefinitionManager : INotificationDefinitionManager, ITr { Check.NotNull(name, nameof(name)); - return await _staticStore.GetGroupOrNullAsync(name) ?? - await _dynamicStore.GetGroupOrNullAsync(name); + var staticDefinition = await _staticStore.GetGroupOrNullAsync(name); + var dynamicDefinition = await _dynamicStore.GetGroupOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + switch (_notificationsOptions.DynamicNotificationStrategy) + { + case DynamicNotificationStrategy.Ignore: + return staticDefinition; + case DynamicNotificationStrategy.Covering: + return dynamicDefinition; + case DynamicNotificationStrategy.Merge: + MergeGroupNotifications(staticDefinition, dynamicDefinition); + return staticDefinition; + default: + return staticDefinition; + } + } + + return staticDefinition ?? dynamicDefinition; } public async virtual Task> GetGroupsAsync() diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/LINGYUN/Abp/Webhooks/WebhookDefinitionManager.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/LINGYUN/Abp/Webhooks/WebhookDefinitionManager.cs index 2b726b4c0..ac6c4ab3f 100644 --- a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/LINGYUN/Abp/Webhooks/WebhookDefinitionManager.cs +++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks.Core/LINGYUN/Abp/Webhooks/WebhookDefinitionManager.cs @@ -35,8 +35,21 @@ internal class WebhookDefinitionManager : IWebhookDefinitionManager, ISingletonD { Check.NotNull(name, nameof(name)); - return await _staticStore.GetOrNullAsync(name) ?? - await _dynamicStore.GetOrNullAsync(name); + var staticDefinition = await _staticStore.GetOrNullAsync(name); + var dynamicDefinition = await _dynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + return _webhooksOptions.DynamicWebhookStrategy switch + { + DynamicWebhookStrategy.Ignore => staticDefinition, + DynamicWebhookStrategy.Covering => dynamicDefinition, + DynamicWebhookStrategy.Merge => MergeWebhook(staticDefinition, dynamicDefinition), + _ => staticDefinition + }; + } + + return staticDefinition ?? dynamicDefinition; } public async virtual Task GetAsync(string name) @@ -69,8 +82,26 @@ internal class WebhookDefinitionManager : IWebhookDefinitionManager, ISingletonD { Check.NotNull(name, nameof(name)); - return await _staticStore.GetGroupOrNullAsync(name) ?? - await _dynamicStore.GetGroupOrNullAsync(name); + var staticDefinition = await _staticStore.GetGroupOrNullAsync(name); + var dynamicDefinition = await _dynamicStore.GetGroupOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + switch (_webhooksOptions.DynamicWebhookStrategy) + { + case DynamicWebhookStrategy.Ignore: + return staticDefinition; + case DynamicWebhookStrategy.Covering: + return dynamicDefinition; + case DynamicWebhookStrategy.Merge: + MergeGroupWebhooks(staticDefinition, dynamicDefinition); + return staticDefinition; + default: + return staticDefinition; + } + } + + return staticDefinition ?? dynamicDefinition; } public async virtual Task GetGroupAsync(string name) diff --git a/aspnet-core/services/LY.MicroService.Applications.Single/MicroServiceApplicationsSingleModule.cs b/aspnet-core/services/LY.MicroService.Applications.Single/MicroServiceApplicationsSingleModule.cs index eea00c887..63b96919b 100644 --- a/aspnet-core/services/LY.MicroService.Applications.Single/MicroServiceApplicationsSingleModule.cs +++ b/aspnet-core/services/LY.MicroService.Applications.Single/MicroServiceApplicationsSingleModule.cs @@ -1,6 +1,7 @@ using LINGYUN.Abp.BlobManagement.MimeCheck; using LINGYUN.Abp.Identity.AspNetCore; using LINGYUN.Abp.Identity.Jobs; +using LINGYUN.Abp.Logging.Serilog.Elasticsearch; using LINGYUN.Abp.Notifications.Calendar; using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy; @@ -397,6 +398,7 @@ namespace LY.MicroService.Applications.Single; // 虚拟文件浏览器 Mvc视图 typeof(AbpVirtualFileExplorerWebModule), + typeof(AbpLoggingSerilogElasticsearchModule), typeof(AbpHttpClientWrapperModule), typeof(AbpAspNetCoreMvcWrapperModule), typeof(AbpAspNetCoreMvcIdempotentWrapperModule), diff --git a/aspnet-core/services/LY.MicroService.Applications.Single/Overrides/MergeFeatureDefinitionManager.cs b/aspnet-core/services/LY.MicroService.Applications.Single/Overrides/MergeFeatureDefinitionManager.cs index 887001b2f..276ca1889 100644 --- a/aspnet-core/services/LY.MicroService.Applications.Single/Overrides/MergeFeatureDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.Applications.Single/Overrides/MergeFeatureDefinitionManager.cs @@ -1,12 +1,11 @@ using JetBrains.Annotations; -using System.Collections.Generic; using System.Collections.Immutable; -using System.Linq; -using System.Threading.Tasks; using Volo.Abp.DependencyInjection; namespace Volo.Abp.Features; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergeFeatureDefinitionManager : FeatureDefinitionManager { @@ -17,6 +16,26 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager { } + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeFeatureMetadata(staticDefinition, dynamicDefinition); + + foreach (var child in dynamicDefinition.Children) + { + MergeChildFeature(staticDefinition, child); + } + } + + return staticDefinition ?? dynamicDefinition; + } + public async override Task> GetAllAsync() { var staticFeatures = await StaticStore.GetFeaturesAsync(); @@ -222,7 +241,7 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager } - public static FeatureDefinition GetFeatureOrNull( + public static FeatureDefinition? GetFeatureOrNull( FeatureGroupDefinition group, [NotNull] string name) { @@ -231,7 +250,7 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager return GetFeatureOrNullRecursively(group.Features, name); } - private static FeatureDefinition GetFeatureOrNullRecursively( + private static FeatureDefinition? GetFeatureOrNullRecursively( IReadOnlyList features, string name) { @@ -252,3 +271,4 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager return null; } } +#nullable disable \ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.Applications.Single/Overrides/MergePermissionDefinitionManager.cs b/aspnet-core/services/LY.MicroService.Applications.Single/Overrides/MergePermissionDefinitionManager.cs index 68b34e48b..007bbe01f 100644 --- a/aspnet-core/services/LY.MicroService.Applications.Single/Overrides/MergePermissionDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.Applications.Single/Overrides/MergePermissionDefinitionManager.cs @@ -1,12 +1,10 @@ -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Linq; -using System.Threading.Tasks; +using System.Collections.Immutable; using Volo.Abp.DependencyInjection; -using Volo.Abp.MultiTenancy; namespace Volo.Abp.Authorization.Permissions; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergePermissionDefinitionManager : PermissionDefinitionManager { @@ -21,6 +19,62 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager _dynamicStore = dynamicStore; } + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetOrNullAsync(name); + var dynamicDefinition = await _dynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task GetResourcePermissionOrNullAsync(string resourceName, string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetResourcePermissionOrNullAsync(resourceName, name); + var dynamicDefinition = await _dynamicStore.GetResourcePermissionOrNullAsync(resourceName, name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetPermissionsAsync() + { + var staticPermissions = await _staticStore.GetPermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetPermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + + public async override Task> GetResourcePermissionsAsync() + { + var staticPermissions = await _staticStore.GetResourcePermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetResourcePermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + public async override Task> GetGroupsAsync() { var staticGroups = await _staticStore.GetGroupsAsync(); @@ -99,6 +153,35 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager } } + private static IReadOnlyList MergePermissions(IReadOnlyList staticPermissions, IReadOnlyList dynamicPermissions) + { + var mergedPermissions = new Dictionary(); + + foreach (var staticFeature in staticPermissions) + { + mergedPermissions[staticFeature.Name] = staticFeature; + } + + foreach (var dynamicPermission in dynamicPermissions) + { + if (mergedPermissions.TryGetValue(dynamicPermission.Name, out var existingPermission)) + { + MergePermissionMetadata(existingPermission, dynamicPermission); + + foreach (var sourceChild in dynamicPermission.Children) + { + MergeChildPermissions(existingPermission, sourceChild); + } + } + else + { + mergedPermissions[dynamicPermission.Name] = dynamicPermission; + } + } + + return mergedPermissions.Values.ToImmutableList(); + } + private static void MergeChildPermissions(PermissionDefinition parent, PermissionDefinition sourceChild) { var existingChild = parent.Children.FirstOrDefault(c => c.Name == sourceChild.Name); @@ -185,4 +268,5 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager target.IsEnabled = target.IsEnabled || source.IsEnabled; } -} \ No newline at end of file +} +#nullable disable \ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.Applications.Single/Overrides/MergeSettingDefinitionManager.cs b/aspnet-core/services/LY.MicroService.Applications.Single/Overrides/MergeSettingDefinitionManager.cs index c3c479f4f..f4269d56e 100644 --- a/aspnet-core/services/LY.MicroService.Applications.Single/Overrides/MergeSettingDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.Applications.Single/Overrides/MergeSettingDefinitionManager.cs @@ -1,29 +1,39 @@ -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Threading.Tasks; +using System.Collections.Immutable; using Volo.Abp.DependencyInjection; namespace Volo.Abp.Settings; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergeSettingDefinitionManager : SettingDefinitionManager { - private readonly IStaticSettingDefinitionStore _staticStore; - private readonly IDynamicSettingDefinitionStore _dynamicStore; - public MergeSettingDefinitionManager( IStaticSettingDefinitionStore staticStore, IDynamicSettingDefinitionStore dynamicStore) : base(staticStore, dynamicStore) { - _staticStore = staticStore; - _dynamicStore = dynamicStore; + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeSetting(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; } public async override Task> GetAllAsync() { - var staticSettings = await _staticStore.GetAllAsync(); - var dynamicSettings = await _dynamicStore.GetAllAsync(); + var staticSettings = await StaticStore.GetAllAsync(); + var dynamicSettings = await DynamicStore.GetAllAsync(); var mergedSettings = new Dictionary(); @@ -70,4 +80,5 @@ public class MergeSettingDefinitionManager : SettingDefinitionManager } } } +#nullable disable diff --git a/aspnet-core/services/LY.MicroService.Applications.Single/Overrides/MergeTemplateDefinitionManager.cs b/aspnet-core/services/LY.MicroService.Applications.Single/Overrides/MergeTemplateDefinitionManager.cs index 0a45a8908..03a2c2f0d 100644 --- a/aspnet-core/services/LY.MicroService.Applications.Single/Overrides/MergeTemplateDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.Applications.Single/Overrides/MergeTemplateDefinitionManager.cs @@ -1,11 +1,10 @@ -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Threading.Tasks; +using System.Collections.Immutable; using Volo.Abp.DependencyInjection; using Volo.Abp.TextTemplating; namespace Volo.Abp.TextTemplatin; +#nullable enable [Dependency(ReplaceServices = true)] public class MergeTemplateDefinitionManager : TemplateDefinitionManager @@ -16,6 +15,22 @@ public class MergeTemplateDefinitionManager : TemplateDefinitionManager : base(staticStore, dynamicStore) { } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeTemplate(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; + } + public async override Task> GetAllAsync() { var staticTemplates = await StaticStore.GetAllAsync(); @@ -84,3 +99,4 @@ public class MergeTemplateDefinitionManager : TemplateDefinitionManager return mergedTemplate; } } +#nullable disable diff --git a/aspnet-core/services/LY.MicroService.AuthServer.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs b/aspnet-core/services/LY.MicroService.AuthServer.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs index 887001b2f..498ac24fe 100644 --- a/aspnet-core/services/LY.MicroService.AuthServer.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.AuthServer.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs @@ -7,6 +7,8 @@ using Volo.Abp.DependencyInjection; namespace Volo.Abp.Features; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergeFeatureDefinitionManager : FeatureDefinitionManager { @@ -17,6 +19,26 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager { } + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeFeatureMetadata(staticDefinition, dynamicDefinition); + + foreach (var child in dynamicDefinition.Children) + { + MergeChildFeature(staticDefinition, child); + } + } + + return staticDefinition ?? dynamicDefinition; + } + public async override Task> GetAllAsync() { var staticFeatures = await StaticStore.GetFeaturesAsync(); @@ -222,7 +244,7 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager } - public static FeatureDefinition GetFeatureOrNull( + public static FeatureDefinition? GetFeatureOrNull( FeatureGroupDefinition group, [NotNull] string name) { @@ -231,7 +253,7 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager return GetFeatureOrNullRecursively(group.Features, name); } - private static FeatureDefinition GetFeatureOrNullRecursively( + private static FeatureDefinition? GetFeatureOrNullRecursively( IReadOnlyList features, string name) { @@ -252,3 +274,4 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager return null; } } +#nullable disable \ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.AuthServer.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs b/aspnet-core/services/LY.MicroService.AuthServer.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs index 68b34e48b..027e7f1c4 100644 --- a/aspnet-core/services/LY.MicroService.AuthServer.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.AuthServer.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs @@ -7,6 +7,8 @@ using Volo.Abp.MultiTenancy; namespace Volo.Abp.Authorization.Permissions; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergePermissionDefinitionManager : PermissionDefinitionManager { @@ -21,6 +23,62 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager _dynamicStore = dynamicStore; } + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetOrNullAsync(name); + var dynamicDefinition = await _dynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task GetResourcePermissionOrNullAsync(string resourceName, string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetResourcePermissionOrNullAsync(resourceName, name); + var dynamicDefinition = await _dynamicStore.GetResourcePermissionOrNullAsync(resourceName, name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetPermissionsAsync() + { + var staticPermissions = await _staticStore.GetPermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetPermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + + public async override Task> GetResourcePermissionsAsync() + { + var staticPermissions = await _staticStore.GetResourcePermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetResourcePermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + public async override Task> GetGroupsAsync() { var staticGroups = await _staticStore.GetGroupsAsync(); @@ -99,6 +157,35 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager } } + private static IReadOnlyList MergePermissions(IReadOnlyList staticPermissions, IReadOnlyList dynamicPermissions) + { + var mergedPermissions = new Dictionary(); + + foreach (var staticFeature in staticPermissions) + { + mergedPermissions[staticFeature.Name] = staticFeature; + } + + foreach (var dynamicPermission in dynamicPermissions) + { + if (mergedPermissions.TryGetValue(dynamicPermission.Name, out var existingPermission)) + { + MergePermissionMetadata(existingPermission, dynamicPermission); + + foreach (var sourceChild in dynamicPermission.Children) + { + MergeChildPermissions(existingPermission, sourceChild); + } + } + else + { + mergedPermissions[dynamicPermission.Name] = dynamicPermission; + } + } + + return mergedPermissions.Values.ToImmutableList(); + } + private static void MergeChildPermissions(PermissionDefinition parent, PermissionDefinition sourceChild) { var existingChild = parent.Children.FirstOrDefault(c => c.Name == sourceChild.Name); @@ -185,4 +272,5 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager target.IsEnabled = target.IsEnabled || source.IsEnabled; } -} \ No newline at end of file +} +#nullable disable \ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.AuthServer.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs b/aspnet-core/services/LY.MicroService.AuthServer.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs index c3c479f4f..2fe64a566 100644 --- a/aspnet-core/services/LY.MicroService.AuthServer.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.AuthServer.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs @@ -5,25 +5,37 @@ using Volo.Abp.DependencyInjection; namespace Volo.Abp.Settings; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergeSettingDefinitionManager : SettingDefinitionManager { - private readonly IStaticSettingDefinitionStore _staticStore; - private readonly IDynamicSettingDefinitionStore _dynamicStore; - public MergeSettingDefinitionManager( IStaticSettingDefinitionStore staticStore, IDynamicSettingDefinitionStore dynamicStore) : base(staticStore, dynamicStore) { - _staticStore = staticStore; - _dynamicStore = dynamicStore; + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeSetting(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; } public async override Task> GetAllAsync() { - var staticSettings = await _staticStore.GetAllAsync(); - var dynamicSettings = await _dynamicStore.GetAllAsync(); + var staticSettings = await StaticStore.GetAllAsync(); + var dynamicSettings = await DynamicStore.GetAllAsync(); var mergedSettings = new Dictionary(); @@ -70,4 +82,5 @@ public class MergeSettingDefinitionManager : SettingDefinitionManager } } } +#nullable disable diff --git a/aspnet-core/services/LY.MicroService.AuthServer.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs b/aspnet-core/services/LY.MicroService.AuthServer.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs index 0a45a8908..5cb3137cd 100644 --- a/aspnet-core/services/LY.MicroService.AuthServer.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.AuthServer.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs @@ -6,6 +6,7 @@ using Volo.Abp.TextTemplating; namespace Volo.Abp.TextTemplatin; +#nullable enable [Dependency(ReplaceServices = true)] public class MergeTemplateDefinitionManager : TemplateDefinitionManager @@ -16,6 +17,22 @@ public class MergeTemplateDefinitionManager : TemplateDefinitionManager : base(staticStore, dynamicStore) { } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeTemplate(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; + } + public async override Task> GetAllAsync() { var staticTemplates = await StaticStore.GetAllAsync(); @@ -84,3 +101,4 @@ public class MergeTemplateDefinitionManager : TemplateDefinitionManager return mergedTemplate; } } +#nullable disable diff --git a/aspnet-core/services/LY.MicroService.AuthServer/Overrides/MergeFeatureDefinitionManager.cs b/aspnet-core/services/LY.MicroService.AuthServer/Overrides/MergeFeatureDefinitionManager.cs index 887001b2f..498ac24fe 100644 --- a/aspnet-core/services/LY.MicroService.AuthServer/Overrides/MergeFeatureDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.AuthServer/Overrides/MergeFeatureDefinitionManager.cs @@ -7,6 +7,8 @@ using Volo.Abp.DependencyInjection; namespace Volo.Abp.Features; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergeFeatureDefinitionManager : FeatureDefinitionManager { @@ -17,6 +19,26 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager { } + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeFeatureMetadata(staticDefinition, dynamicDefinition); + + foreach (var child in dynamicDefinition.Children) + { + MergeChildFeature(staticDefinition, child); + } + } + + return staticDefinition ?? dynamicDefinition; + } + public async override Task> GetAllAsync() { var staticFeatures = await StaticStore.GetFeaturesAsync(); @@ -222,7 +244,7 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager } - public static FeatureDefinition GetFeatureOrNull( + public static FeatureDefinition? GetFeatureOrNull( FeatureGroupDefinition group, [NotNull] string name) { @@ -231,7 +253,7 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager return GetFeatureOrNullRecursively(group.Features, name); } - private static FeatureDefinition GetFeatureOrNullRecursively( + private static FeatureDefinition? GetFeatureOrNullRecursively( IReadOnlyList features, string name) { @@ -252,3 +274,4 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager return null; } } +#nullable disable \ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.AuthServer/Overrides/MergePermissionDefinitionManager.cs b/aspnet-core/services/LY.MicroService.AuthServer/Overrides/MergePermissionDefinitionManager.cs index 68b34e48b..027e7f1c4 100644 --- a/aspnet-core/services/LY.MicroService.AuthServer/Overrides/MergePermissionDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.AuthServer/Overrides/MergePermissionDefinitionManager.cs @@ -7,6 +7,8 @@ using Volo.Abp.MultiTenancy; namespace Volo.Abp.Authorization.Permissions; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergePermissionDefinitionManager : PermissionDefinitionManager { @@ -21,6 +23,62 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager _dynamicStore = dynamicStore; } + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetOrNullAsync(name); + var dynamicDefinition = await _dynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task GetResourcePermissionOrNullAsync(string resourceName, string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetResourcePermissionOrNullAsync(resourceName, name); + var dynamicDefinition = await _dynamicStore.GetResourcePermissionOrNullAsync(resourceName, name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetPermissionsAsync() + { + var staticPermissions = await _staticStore.GetPermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetPermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + + public async override Task> GetResourcePermissionsAsync() + { + var staticPermissions = await _staticStore.GetResourcePermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetResourcePermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + public async override Task> GetGroupsAsync() { var staticGroups = await _staticStore.GetGroupsAsync(); @@ -99,6 +157,35 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager } } + private static IReadOnlyList MergePermissions(IReadOnlyList staticPermissions, IReadOnlyList dynamicPermissions) + { + var mergedPermissions = new Dictionary(); + + foreach (var staticFeature in staticPermissions) + { + mergedPermissions[staticFeature.Name] = staticFeature; + } + + foreach (var dynamicPermission in dynamicPermissions) + { + if (mergedPermissions.TryGetValue(dynamicPermission.Name, out var existingPermission)) + { + MergePermissionMetadata(existingPermission, dynamicPermission); + + foreach (var sourceChild in dynamicPermission.Children) + { + MergeChildPermissions(existingPermission, sourceChild); + } + } + else + { + mergedPermissions[dynamicPermission.Name] = dynamicPermission; + } + } + + return mergedPermissions.Values.ToImmutableList(); + } + private static void MergeChildPermissions(PermissionDefinition parent, PermissionDefinition sourceChild) { var existingChild = parent.Children.FirstOrDefault(c => c.Name == sourceChild.Name); @@ -185,4 +272,5 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager target.IsEnabled = target.IsEnabled || source.IsEnabled; } -} \ No newline at end of file +} +#nullable disable \ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.AuthServer/Overrides/MergeSettingDefinitionManager.cs b/aspnet-core/services/LY.MicroService.AuthServer/Overrides/MergeSettingDefinitionManager.cs index c3c479f4f..2fe64a566 100644 --- a/aspnet-core/services/LY.MicroService.AuthServer/Overrides/MergeSettingDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.AuthServer/Overrides/MergeSettingDefinitionManager.cs @@ -5,25 +5,37 @@ using Volo.Abp.DependencyInjection; namespace Volo.Abp.Settings; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergeSettingDefinitionManager : SettingDefinitionManager { - private readonly IStaticSettingDefinitionStore _staticStore; - private readonly IDynamicSettingDefinitionStore _dynamicStore; - public MergeSettingDefinitionManager( IStaticSettingDefinitionStore staticStore, IDynamicSettingDefinitionStore dynamicStore) : base(staticStore, dynamicStore) { - _staticStore = staticStore; - _dynamicStore = dynamicStore; + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeSetting(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; } public async override Task> GetAllAsync() { - var staticSettings = await _staticStore.GetAllAsync(); - var dynamicSettings = await _dynamicStore.GetAllAsync(); + var staticSettings = await StaticStore.GetAllAsync(); + var dynamicSettings = await DynamicStore.GetAllAsync(); var mergedSettings = new Dictionary(); @@ -70,4 +82,5 @@ public class MergeSettingDefinitionManager : SettingDefinitionManager } } } +#nullable disable diff --git a/aspnet-core/services/LY.MicroService.AuthServer/Overrides/MergeTemplateDefinitionManager.cs b/aspnet-core/services/LY.MicroService.AuthServer/Overrides/MergeTemplateDefinitionManager.cs index 0a45a8908..5cb3137cd 100644 --- a/aspnet-core/services/LY.MicroService.AuthServer/Overrides/MergeTemplateDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.AuthServer/Overrides/MergeTemplateDefinitionManager.cs @@ -6,6 +6,7 @@ using Volo.Abp.TextTemplating; namespace Volo.Abp.TextTemplatin; +#nullable enable [Dependency(ReplaceServices = true)] public class MergeTemplateDefinitionManager : TemplateDefinitionManager @@ -16,6 +17,22 @@ public class MergeTemplateDefinitionManager : TemplateDefinitionManager : base(staticStore, dynamicStore) { } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeTemplate(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; + } + public async override Task> GetAllAsync() { var staticTemplates = await StaticStore.GetAllAsync(); @@ -84,3 +101,4 @@ public class MergeTemplateDefinitionManager : TemplateDefinitionManager return mergedTemplate; } } +#nullable disable diff --git a/aspnet-core/services/LY.MicroService.BackendAdmin.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs b/aspnet-core/services/LY.MicroService.BackendAdmin.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs index 645d6e1bf..498ac24fe 100644 --- a/aspnet-core/services/LY.MicroService.BackendAdmin.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.BackendAdmin.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs @@ -1,22 +1,44 @@ -using System.Collections.Generic; +using JetBrains.Annotations; +using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using System.Threading.Tasks; using Volo.Abp.DependencyInjection; -using Volo.Abp.Features; -namespace LY.MicroService.BackendAdmin.Overrides; +namespace Volo.Abp.Features; + +#nullable enable [Dependency(ReplaceServices = true)] public class MergeFeatureDefinitionManager : FeatureDefinitionManager { public MergeFeatureDefinitionManager( - IStaticFeatureDefinitionStore staticStore, - IDynamicFeatureDefinitionStore dynamicStore) + IStaticFeatureDefinitionStore staticStore, + IDynamicFeatureDefinitionStore dynamicStore) : base(staticStore, dynamicStore) { } + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeFeatureMetadata(staticDefinition, dynamicDefinition); + + foreach (var child in dynamicDefinition.Children) + { + MergeChildFeature(staticDefinition, child); + } + } + + return staticDefinition ?? dynamicDefinition; + } + public async override Task> GetAllAsync() { var staticFeatures = await StaticStore.GetFeaturesAsync(); @@ -80,7 +102,7 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager { foreach (var sourceFeature in source.Features) { - var existingFeature = target.GetFeatureOrNull(sourceFeature.Name); + var existingFeature = GetFeatureOrNull(target, sourceFeature.Name); if (existingFeature == null) { @@ -220,4 +242,36 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager target.IsVisibleToClients = target.IsVisibleToClients || source.IsVisibleToClients; target.IsAvailableToHost = target.IsAvailableToHost || source.IsAvailableToHost; } + + + public static FeatureDefinition? GetFeatureOrNull( + FeatureGroupDefinition group, + [NotNull] string name) + { + Check.NotNull(name, nameof(name)); + + return GetFeatureOrNullRecursively(group.Features, name); + } + + private static FeatureDefinition? GetFeatureOrNullRecursively( + IReadOnlyList features, + string name) + { + foreach (var feature in features) + { + if (feature.Name == name) + { + return feature; + } + + var childFeature = GetFeatureOrNullRecursively(feature.Children, name); + if (childFeature != null) + { + return childFeature; + } + } + + return null; + } } +#nullable disable \ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.BackendAdmin.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs b/aspnet-core/services/LY.MicroService.BackendAdmin.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs index 889516ee2..027e7f1c4 100644 --- a/aspnet-core/services/LY.MicroService.BackendAdmin.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.BackendAdmin.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs @@ -2,11 +2,12 @@ using System.Collections.Immutable; using System.Linq; using System.Threading.Tasks; -using Volo.Abp.Authorization.Permissions; using Volo.Abp.DependencyInjection; using Volo.Abp.MultiTenancy; -namespace LY.MicroService.BackendAdmin.Overrides; +namespace Volo.Abp.Authorization.Permissions; + +#nullable enable [Dependency(ReplaceServices = true)] public class MergePermissionDefinitionManager : PermissionDefinitionManager @@ -15,13 +16,69 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager private readonly IDynamicPermissionDefinitionStore _dynamicStore; public MergePermissionDefinitionManager( - IStaticPermissionDefinitionStore staticStore, + IStaticPermissionDefinitionStore staticStore, IDynamicPermissionDefinitionStore dynamicStore) : base(staticStore, dynamicStore) { _staticStore = staticStore; _dynamicStore = dynamicStore; } + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetOrNullAsync(name); + var dynamicDefinition = await _dynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task GetResourcePermissionOrNullAsync(string resourceName, string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetResourcePermissionOrNullAsync(resourceName, name); + var dynamicDefinition = await _dynamicStore.GetResourcePermissionOrNullAsync(resourceName, name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetPermissionsAsync() + { + var staticPermissions = await _staticStore.GetPermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetPermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + + public async override Task> GetResourcePermissionsAsync() + { + var staticPermissions = await _staticStore.GetResourcePermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetResourcePermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + public async override Task> GetGroupsAsync() { var staticGroups = await _staticStore.GetGroupsAsync(); @@ -100,6 +157,35 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager } } + private static IReadOnlyList MergePermissions(IReadOnlyList staticPermissions, IReadOnlyList dynamicPermissions) + { + var mergedPermissions = new Dictionary(); + + foreach (var staticFeature in staticPermissions) + { + mergedPermissions[staticFeature.Name] = staticFeature; + } + + foreach (var dynamicPermission in dynamicPermissions) + { + if (mergedPermissions.TryGetValue(dynamicPermission.Name, out var existingPermission)) + { + MergePermissionMetadata(existingPermission, dynamicPermission); + + foreach (var sourceChild in dynamicPermission.Children) + { + MergeChildPermissions(existingPermission, sourceChild); + } + } + else + { + mergedPermissions[dynamicPermission.Name] = dynamicPermission; + } + } + + return mergedPermissions.Values.ToImmutableList(); + } + private static void MergeChildPermissions(PermissionDefinition parent, PermissionDefinition sourceChild) { var existingChild = parent.Children.FirstOrDefault(c => c.Name == sourceChild.Name); @@ -187,3 +273,4 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager target.IsEnabled = target.IsEnabled || source.IsEnabled; } } +#nullable disable \ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.BackendAdmin.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs b/aspnet-core/services/LY.MicroService.BackendAdmin.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs index 0fa2047d9..2fe64a566 100644 --- a/aspnet-core/services/LY.MicroService.BackendAdmin.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.BackendAdmin.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs @@ -2,29 +2,40 @@ using System.Collections.Immutable; using System.Threading.Tasks; using Volo.Abp.DependencyInjection; -using Volo.Abp.Settings; -namespace LY.MicroService.BackendAdmin.Overrides; +namespace Volo.Abp.Settings; + +#nullable enable [Dependency(ReplaceServices = true)] public class MergeSettingDefinitionManager : SettingDefinitionManager { - private readonly IStaticSettingDefinitionStore _staticStore; - private readonly IDynamicSettingDefinitionStore _dynamicStore; - public MergeSettingDefinitionManager( - IStaticSettingDefinitionStore staticStore, - IDynamicSettingDefinitionStore dynamicStore) + IStaticSettingDefinitionStore staticStore, + IDynamicSettingDefinitionStore dynamicStore) : base(staticStore, dynamicStore) { - _staticStore = staticStore; - _dynamicStore = dynamicStore; + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeSetting(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; } public async override Task> GetAllAsync() { - var staticSettings = await _staticStore.GetAllAsync(); - var dynamicSettings = await _dynamicStore.GetAllAsync(); + var staticSettings = await StaticStore.GetAllAsync(); + var dynamicSettings = await DynamicStore.GetAllAsync(); var mergedSettings = new Dictionary(); @@ -71,3 +82,5 @@ public class MergeSettingDefinitionManager : SettingDefinitionManager } } } +#nullable disable + diff --git a/aspnet-core/services/LY.MicroService.BackendAdmin.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs b/aspnet-core/services/LY.MicroService.BackendAdmin.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs index 79d3edd07..5cb3137cd 100644 --- a/aspnet-core/services/LY.MicroService.BackendAdmin.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.BackendAdmin.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs @@ -4,17 +4,35 @@ using System.Threading.Tasks; using Volo.Abp.DependencyInjection; using Volo.Abp.TextTemplating; -namespace LY.MicroService.BackendAdmin.Overrides; +namespace Volo.Abp.TextTemplatin; + +#nullable enable [Dependency(ReplaceServices = true)] public class MergeTemplateDefinitionManager : TemplateDefinitionManager { public MergeTemplateDefinitionManager( - IStaticTemplateDefinitionStore staticStore, - IDynamicTemplateDefinitionStore dynamicStore) + IStaticTemplateDefinitionStore staticStore, + IDynamicTemplateDefinitionStore dynamicStore) : base(staticStore, dynamicStore) { } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeTemplate(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; + } + public async override Task> GetAllAsync() { var staticTemplates = await StaticStore.GetAllAsync(); @@ -83,3 +101,4 @@ public class MergeTemplateDefinitionManager : TemplateDefinitionManager return mergedTemplate; } } +#nullable disable diff --git a/aspnet-core/services/LY.MicroService.LocalizationManagement.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs b/aspnet-core/services/LY.MicroService.LocalizationManagement.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs index 887001b2f..498ac24fe 100644 --- a/aspnet-core/services/LY.MicroService.LocalizationManagement.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.LocalizationManagement.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs @@ -7,6 +7,8 @@ using Volo.Abp.DependencyInjection; namespace Volo.Abp.Features; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergeFeatureDefinitionManager : FeatureDefinitionManager { @@ -17,6 +19,26 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager { } + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeFeatureMetadata(staticDefinition, dynamicDefinition); + + foreach (var child in dynamicDefinition.Children) + { + MergeChildFeature(staticDefinition, child); + } + } + + return staticDefinition ?? dynamicDefinition; + } + public async override Task> GetAllAsync() { var staticFeatures = await StaticStore.GetFeaturesAsync(); @@ -222,7 +244,7 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager } - public static FeatureDefinition GetFeatureOrNull( + public static FeatureDefinition? GetFeatureOrNull( FeatureGroupDefinition group, [NotNull] string name) { @@ -231,7 +253,7 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager return GetFeatureOrNullRecursively(group.Features, name); } - private static FeatureDefinition GetFeatureOrNullRecursively( + private static FeatureDefinition? GetFeatureOrNullRecursively( IReadOnlyList features, string name) { @@ -252,3 +274,4 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager return null; } } +#nullable disable \ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.LocalizationManagement.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs b/aspnet-core/services/LY.MicroService.LocalizationManagement.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs index 68b34e48b..027e7f1c4 100644 --- a/aspnet-core/services/LY.MicroService.LocalizationManagement.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.LocalizationManagement.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs @@ -7,6 +7,8 @@ using Volo.Abp.MultiTenancy; namespace Volo.Abp.Authorization.Permissions; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergePermissionDefinitionManager : PermissionDefinitionManager { @@ -21,6 +23,62 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager _dynamicStore = dynamicStore; } + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetOrNullAsync(name); + var dynamicDefinition = await _dynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task GetResourcePermissionOrNullAsync(string resourceName, string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetResourcePermissionOrNullAsync(resourceName, name); + var dynamicDefinition = await _dynamicStore.GetResourcePermissionOrNullAsync(resourceName, name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetPermissionsAsync() + { + var staticPermissions = await _staticStore.GetPermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetPermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + + public async override Task> GetResourcePermissionsAsync() + { + var staticPermissions = await _staticStore.GetResourcePermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetResourcePermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + public async override Task> GetGroupsAsync() { var staticGroups = await _staticStore.GetGroupsAsync(); @@ -99,6 +157,35 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager } } + private static IReadOnlyList MergePermissions(IReadOnlyList staticPermissions, IReadOnlyList dynamicPermissions) + { + var mergedPermissions = new Dictionary(); + + foreach (var staticFeature in staticPermissions) + { + mergedPermissions[staticFeature.Name] = staticFeature; + } + + foreach (var dynamicPermission in dynamicPermissions) + { + if (mergedPermissions.TryGetValue(dynamicPermission.Name, out var existingPermission)) + { + MergePermissionMetadata(existingPermission, dynamicPermission); + + foreach (var sourceChild in dynamicPermission.Children) + { + MergeChildPermissions(existingPermission, sourceChild); + } + } + else + { + mergedPermissions[dynamicPermission.Name] = dynamicPermission; + } + } + + return mergedPermissions.Values.ToImmutableList(); + } + private static void MergeChildPermissions(PermissionDefinition parent, PermissionDefinition sourceChild) { var existingChild = parent.Children.FirstOrDefault(c => c.Name == sourceChild.Name); @@ -185,4 +272,5 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager target.IsEnabled = target.IsEnabled || source.IsEnabled; } -} \ No newline at end of file +} +#nullable disable \ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.LocalizationManagement.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs b/aspnet-core/services/LY.MicroService.LocalizationManagement.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs index c3c479f4f..2fe64a566 100644 --- a/aspnet-core/services/LY.MicroService.LocalizationManagement.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.LocalizationManagement.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs @@ -5,25 +5,37 @@ using Volo.Abp.DependencyInjection; namespace Volo.Abp.Settings; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergeSettingDefinitionManager : SettingDefinitionManager { - private readonly IStaticSettingDefinitionStore _staticStore; - private readonly IDynamicSettingDefinitionStore _dynamicStore; - public MergeSettingDefinitionManager( IStaticSettingDefinitionStore staticStore, IDynamicSettingDefinitionStore dynamicStore) : base(staticStore, dynamicStore) { - _staticStore = staticStore; - _dynamicStore = dynamicStore; + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeSetting(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; } public async override Task> GetAllAsync() { - var staticSettings = await _staticStore.GetAllAsync(); - var dynamicSettings = await _dynamicStore.GetAllAsync(); + var staticSettings = await StaticStore.GetAllAsync(); + var dynamicSettings = await DynamicStore.GetAllAsync(); var mergedSettings = new Dictionary(); @@ -70,4 +82,5 @@ public class MergeSettingDefinitionManager : SettingDefinitionManager } } } +#nullable disable diff --git a/aspnet-core/services/LY.MicroService.LocalizationManagement.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs b/aspnet-core/services/LY.MicroService.LocalizationManagement.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs index 0a45a8908..5cb3137cd 100644 --- a/aspnet-core/services/LY.MicroService.LocalizationManagement.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.LocalizationManagement.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs @@ -6,6 +6,7 @@ using Volo.Abp.TextTemplating; namespace Volo.Abp.TextTemplatin; +#nullable enable [Dependency(ReplaceServices = true)] public class MergeTemplateDefinitionManager : TemplateDefinitionManager @@ -16,6 +17,22 @@ public class MergeTemplateDefinitionManager : TemplateDefinitionManager : base(staticStore, dynamicStore) { } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeTemplate(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; + } + public async override Task> GetAllAsync() { var staticTemplates = await StaticStore.GetAllAsync(); @@ -84,3 +101,4 @@ public class MergeTemplateDefinitionManager : TemplateDefinitionManager return mergedTemplate; } } +#nullable disable diff --git a/aspnet-core/services/LY.MicroService.PlatformManagement.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs b/aspnet-core/services/LY.MicroService.PlatformManagement.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs index 887001b2f..498ac24fe 100644 --- a/aspnet-core/services/LY.MicroService.PlatformManagement.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.PlatformManagement.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs @@ -7,6 +7,8 @@ using Volo.Abp.DependencyInjection; namespace Volo.Abp.Features; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergeFeatureDefinitionManager : FeatureDefinitionManager { @@ -17,6 +19,26 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager { } + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeFeatureMetadata(staticDefinition, dynamicDefinition); + + foreach (var child in dynamicDefinition.Children) + { + MergeChildFeature(staticDefinition, child); + } + } + + return staticDefinition ?? dynamicDefinition; + } + public async override Task> GetAllAsync() { var staticFeatures = await StaticStore.GetFeaturesAsync(); @@ -222,7 +244,7 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager } - public static FeatureDefinition GetFeatureOrNull( + public static FeatureDefinition? GetFeatureOrNull( FeatureGroupDefinition group, [NotNull] string name) { @@ -231,7 +253,7 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager return GetFeatureOrNullRecursively(group.Features, name); } - private static FeatureDefinition GetFeatureOrNullRecursively( + private static FeatureDefinition? GetFeatureOrNullRecursively( IReadOnlyList features, string name) { @@ -252,3 +274,4 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager return null; } } +#nullable disable \ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.PlatformManagement.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs b/aspnet-core/services/LY.MicroService.PlatformManagement.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs index 68b34e48b..027e7f1c4 100644 --- a/aspnet-core/services/LY.MicroService.PlatformManagement.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.PlatformManagement.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs @@ -7,6 +7,8 @@ using Volo.Abp.MultiTenancy; namespace Volo.Abp.Authorization.Permissions; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergePermissionDefinitionManager : PermissionDefinitionManager { @@ -21,6 +23,62 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager _dynamicStore = dynamicStore; } + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetOrNullAsync(name); + var dynamicDefinition = await _dynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task GetResourcePermissionOrNullAsync(string resourceName, string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetResourcePermissionOrNullAsync(resourceName, name); + var dynamicDefinition = await _dynamicStore.GetResourcePermissionOrNullAsync(resourceName, name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetPermissionsAsync() + { + var staticPermissions = await _staticStore.GetPermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetPermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + + public async override Task> GetResourcePermissionsAsync() + { + var staticPermissions = await _staticStore.GetResourcePermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetResourcePermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + public async override Task> GetGroupsAsync() { var staticGroups = await _staticStore.GetGroupsAsync(); @@ -99,6 +157,35 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager } } + private static IReadOnlyList MergePermissions(IReadOnlyList staticPermissions, IReadOnlyList dynamicPermissions) + { + var mergedPermissions = new Dictionary(); + + foreach (var staticFeature in staticPermissions) + { + mergedPermissions[staticFeature.Name] = staticFeature; + } + + foreach (var dynamicPermission in dynamicPermissions) + { + if (mergedPermissions.TryGetValue(dynamicPermission.Name, out var existingPermission)) + { + MergePermissionMetadata(existingPermission, dynamicPermission); + + foreach (var sourceChild in dynamicPermission.Children) + { + MergeChildPermissions(existingPermission, sourceChild); + } + } + else + { + mergedPermissions[dynamicPermission.Name] = dynamicPermission; + } + } + + return mergedPermissions.Values.ToImmutableList(); + } + private static void MergeChildPermissions(PermissionDefinition parent, PermissionDefinition sourceChild) { var existingChild = parent.Children.FirstOrDefault(c => c.Name == sourceChild.Name); @@ -185,4 +272,5 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager target.IsEnabled = target.IsEnabled || source.IsEnabled; } -} \ No newline at end of file +} +#nullable disable \ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.PlatformManagement.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs b/aspnet-core/services/LY.MicroService.PlatformManagement.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs index c3c479f4f..2fe64a566 100644 --- a/aspnet-core/services/LY.MicroService.PlatformManagement.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.PlatformManagement.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs @@ -5,25 +5,37 @@ using Volo.Abp.DependencyInjection; namespace Volo.Abp.Settings; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergeSettingDefinitionManager : SettingDefinitionManager { - private readonly IStaticSettingDefinitionStore _staticStore; - private readonly IDynamicSettingDefinitionStore _dynamicStore; - public MergeSettingDefinitionManager( IStaticSettingDefinitionStore staticStore, IDynamicSettingDefinitionStore dynamicStore) : base(staticStore, dynamicStore) { - _staticStore = staticStore; - _dynamicStore = dynamicStore; + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeSetting(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; } public async override Task> GetAllAsync() { - var staticSettings = await _staticStore.GetAllAsync(); - var dynamicSettings = await _dynamicStore.GetAllAsync(); + var staticSettings = await StaticStore.GetAllAsync(); + var dynamicSettings = await DynamicStore.GetAllAsync(); var mergedSettings = new Dictionary(); @@ -70,4 +82,5 @@ public class MergeSettingDefinitionManager : SettingDefinitionManager } } } +#nullable disable diff --git a/aspnet-core/services/LY.MicroService.PlatformManagement.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs b/aspnet-core/services/LY.MicroService.PlatformManagement.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs index 0a45a8908..5cb3137cd 100644 --- a/aspnet-core/services/LY.MicroService.PlatformManagement.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.PlatformManagement.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs @@ -6,6 +6,7 @@ using Volo.Abp.TextTemplating; namespace Volo.Abp.TextTemplatin; +#nullable enable [Dependency(ReplaceServices = true)] public class MergeTemplateDefinitionManager : TemplateDefinitionManager @@ -16,6 +17,22 @@ public class MergeTemplateDefinitionManager : TemplateDefinitionManager : base(staticStore, dynamicStore) { } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeTemplate(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; + } + public async override Task> GetAllAsync() { var staticTemplates = await StaticStore.GetAllAsync(); @@ -84,3 +101,4 @@ public class MergeTemplateDefinitionManager : TemplateDefinitionManager return mergedTemplate; } } +#nullable disable diff --git a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs index 887001b2f..498ac24fe 100644 --- a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs @@ -7,6 +7,8 @@ using Volo.Abp.DependencyInjection; namespace Volo.Abp.Features; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergeFeatureDefinitionManager : FeatureDefinitionManager { @@ -17,6 +19,26 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager { } + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeFeatureMetadata(staticDefinition, dynamicDefinition); + + foreach (var child in dynamicDefinition.Children) + { + MergeChildFeature(staticDefinition, child); + } + } + + return staticDefinition ?? dynamicDefinition; + } + public async override Task> GetAllAsync() { var staticFeatures = await StaticStore.GetFeaturesAsync(); @@ -222,7 +244,7 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager } - public static FeatureDefinition GetFeatureOrNull( + public static FeatureDefinition? GetFeatureOrNull( FeatureGroupDefinition group, [NotNull] string name) { @@ -231,7 +253,7 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager return GetFeatureOrNullRecursively(group.Features, name); } - private static FeatureDefinition GetFeatureOrNullRecursively( + private static FeatureDefinition? GetFeatureOrNullRecursively( IReadOnlyList features, string name) { @@ -252,3 +274,4 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager return null; } } +#nullable disable \ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs index 68b34e48b..027e7f1c4 100644 --- a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs @@ -7,6 +7,8 @@ using Volo.Abp.MultiTenancy; namespace Volo.Abp.Authorization.Permissions; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergePermissionDefinitionManager : PermissionDefinitionManager { @@ -21,6 +23,62 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager _dynamicStore = dynamicStore; } + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetOrNullAsync(name); + var dynamicDefinition = await _dynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task GetResourcePermissionOrNullAsync(string resourceName, string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetResourcePermissionOrNullAsync(resourceName, name); + var dynamicDefinition = await _dynamicStore.GetResourcePermissionOrNullAsync(resourceName, name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetPermissionsAsync() + { + var staticPermissions = await _staticStore.GetPermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetPermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + + public async override Task> GetResourcePermissionsAsync() + { + var staticPermissions = await _staticStore.GetResourcePermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetResourcePermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + public async override Task> GetGroupsAsync() { var staticGroups = await _staticStore.GetGroupsAsync(); @@ -99,6 +157,35 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager } } + private static IReadOnlyList MergePermissions(IReadOnlyList staticPermissions, IReadOnlyList dynamicPermissions) + { + var mergedPermissions = new Dictionary(); + + foreach (var staticFeature in staticPermissions) + { + mergedPermissions[staticFeature.Name] = staticFeature; + } + + foreach (var dynamicPermission in dynamicPermissions) + { + if (mergedPermissions.TryGetValue(dynamicPermission.Name, out var existingPermission)) + { + MergePermissionMetadata(existingPermission, dynamicPermission); + + foreach (var sourceChild in dynamicPermission.Children) + { + MergeChildPermissions(existingPermission, sourceChild); + } + } + else + { + mergedPermissions[dynamicPermission.Name] = dynamicPermission; + } + } + + return mergedPermissions.Values.ToImmutableList(); + } + private static void MergeChildPermissions(PermissionDefinition parent, PermissionDefinition sourceChild) { var existingChild = parent.Children.FirstOrDefault(c => c.Name == sourceChild.Name); @@ -185,4 +272,5 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager target.IsEnabled = target.IsEnabled || source.IsEnabled; } -} \ No newline at end of file +} +#nullable disable \ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs index c3c479f4f..2fe64a566 100644 --- a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs @@ -5,25 +5,37 @@ using Volo.Abp.DependencyInjection; namespace Volo.Abp.Settings; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergeSettingDefinitionManager : SettingDefinitionManager { - private readonly IStaticSettingDefinitionStore _staticStore; - private readonly IDynamicSettingDefinitionStore _dynamicStore; - public MergeSettingDefinitionManager( IStaticSettingDefinitionStore staticStore, IDynamicSettingDefinitionStore dynamicStore) : base(staticStore, dynamicStore) { - _staticStore = staticStore; - _dynamicStore = dynamicStore; + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeSetting(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; } public async override Task> GetAllAsync() { - var staticSettings = await _staticStore.GetAllAsync(); - var dynamicSettings = await _dynamicStore.GetAllAsync(); + var staticSettings = await StaticStore.GetAllAsync(); + var dynamicSettings = await DynamicStore.GetAllAsync(); var mergedSettings = new Dictionary(); @@ -70,4 +82,5 @@ public class MergeSettingDefinitionManager : SettingDefinitionManager } } } +#nullable disable diff --git a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs index 0a45a8908..5cb3137cd 100644 --- a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs @@ -6,6 +6,7 @@ using Volo.Abp.TextTemplating; namespace Volo.Abp.TextTemplatin; +#nullable enable [Dependency(ReplaceServices = true)] public class MergeTemplateDefinitionManager : TemplateDefinitionManager @@ -16,6 +17,22 @@ public class MergeTemplateDefinitionManager : TemplateDefinitionManager : base(staticStore, dynamicStore) { } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeTemplate(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; + } + public async override Task> GetAllAsync() { var staticTemplates = await StaticStore.GetAllAsync(); @@ -84,3 +101,4 @@ public class MergeTemplateDefinitionManager : TemplateDefinitionManager return mergedTemplate; } } +#nullable disable diff --git a/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs b/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs index 887001b2f..498ac24fe 100644 --- a/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs @@ -7,6 +7,8 @@ using Volo.Abp.DependencyInjection; namespace Volo.Abp.Features; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergeFeatureDefinitionManager : FeatureDefinitionManager { @@ -17,6 +19,26 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager { } + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeFeatureMetadata(staticDefinition, dynamicDefinition); + + foreach (var child in dynamicDefinition.Children) + { + MergeChildFeature(staticDefinition, child); + } + } + + return staticDefinition ?? dynamicDefinition; + } + public async override Task> GetAllAsync() { var staticFeatures = await StaticStore.GetFeaturesAsync(); @@ -222,7 +244,7 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager } - public static FeatureDefinition GetFeatureOrNull( + public static FeatureDefinition? GetFeatureOrNull( FeatureGroupDefinition group, [NotNull] string name) { @@ -231,7 +253,7 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager return GetFeatureOrNullRecursively(group.Features, name); } - private static FeatureDefinition GetFeatureOrNullRecursively( + private static FeatureDefinition? GetFeatureOrNullRecursively( IReadOnlyList features, string name) { @@ -252,3 +274,4 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager return null; } } +#nullable disable \ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs b/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs index 68b34e48b..027e7f1c4 100644 --- a/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs @@ -7,6 +7,8 @@ using Volo.Abp.MultiTenancy; namespace Volo.Abp.Authorization.Permissions; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergePermissionDefinitionManager : PermissionDefinitionManager { @@ -21,6 +23,62 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager _dynamicStore = dynamicStore; } + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetOrNullAsync(name); + var dynamicDefinition = await _dynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task GetResourcePermissionOrNullAsync(string resourceName, string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetResourcePermissionOrNullAsync(resourceName, name); + var dynamicDefinition = await _dynamicStore.GetResourcePermissionOrNullAsync(resourceName, name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetPermissionsAsync() + { + var staticPermissions = await _staticStore.GetPermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetPermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + + public async override Task> GetResourcePermissionsAsync() + { + var staticPermissions = await _staticStore.GetResourcePermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetResourcePermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + public async override Task> GetGroupsAsync() { var staticGroups = await _staticStore.GetGroupsAsync(); @@ -99,6 +157,35 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager } } + private static IReadOnlyList MergePermissions(IReadOnlyList staticPermissions, IReadOnlyList dynamicPermissions) + { + var mergedPermissions = new Dictionary(); + + foreach (var staticFeature in staticPermissions) + { + mergedPermissions[staticFeature.Name] = staticFeature; + } + + foreach (var dynamicPermission in dynamicPermissions) + { + if (mergedPermissions.TryGetValue(dynamicPermission.Name, out var existingPermission)) + { + MergePermissionMetadata(existingPermission, dynamicPermission); + + foreach (var sourceChild in dynamicPermission.Children) + { + MergeChildPermissions(existingPermission, sourceChild); + } + } + else + { + mergedPermissions[dynamicPermission.Name] = dynamicPermission; + } + } + + return mergedPermissions.Values.ToImmutableList(); + } + private static void MergeChildPermissions(PermissionDefinition parent, PermissionDefinition sourceChild) { var existingChild = parent.Children.FirstOrDefault(c => c.Name == sourceChild.Name); @@ -185,4 +272,5 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager target.IsEnabled = target.IsEnabled || source.IsEnabled; } -} \ No newline at end of file +} +#nullable disable \ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs b/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs index c3c479f4f..2fe64a566 100644 --- a/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs @@ -5,25 +5,37 @@ using Volo.Abp.DependencyInjection; namespace Volo.Abp.Settings; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergeSettingDefinitionManager : SettingDefinitionManager { - private readonly IStaticSettingDefinitionStore _staticStore; - private readonly IDynamicSettingDefinitionStore _dynamicStore; - public MergeSettingDefinitionManager( IStaticSettingDefinitionStore staticStore, IDynamicSettingDefinitionStore dynamicStore) : base(staticStore, dynamicStore) { - _staticStore = staticStore; - _dynamicStore = dynamicStore; + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeSetting(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; } public async override Task> GetAllAsync() { - var staticSettings = await _staticStore.GetAllAsync(); - var dynamicSettings = await _dynamicStore.GetAllAsync(); + var staticSettings = await StaticStore.GetAllAsync(); + var dynamicSettings = await DynamicStore.GetAllAsync(); var mergedSettings = new Dictionary(); @@ -70,4 +82,5 @@ public class MergeSettingDefinitionManager : SettingDefinitionManager } } } +#nullable disable diff --git a/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs b/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs index 0a45a8908..5cb3137cd 100644 --- a/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs @@ -6,6 +6,7 @@ using Volo.Abp.TextTemplating; namespace Volo.Abp.TextTemplatin; +#nullable enable [Dependency(ReplaceServices = true)] public class MergeTemplateDefinitionManager : TemplateDefinitionManager @@ -16,6 +17,22 @@ public class MergeTemplateDefinitionManager : TemplateDefinitionManager : base(staticStore, dynamicStore) { } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeTemplate(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; + } + public async override Task> GetAllAsync() { var staticTemplates = await StaticStore.GetAllAsync(); @@ -84,3 +101,4 @@ public class MergeTemplateDefinitionManager : TemplateDefinitionManager return mergedTemplate; } } +#nullable disable diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs index 887001b2f..498ac24fe 100644 --- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs @@ -7,6 +7,8 @@ using Volo.Abp.DependencyInjection; namespace Volo.Abp.Features; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergeFeatureDefinitionManager : FeatureDefinitionManager { @@ -17,6 +19,26 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager { } + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeFeatureMetadata(staticDefinition, dynamicDefinition); + + foreach (var child in dynamicDefinition.Children) + { + MergeChildFeature(staticDefinition, child); + } + } + + return staticDefinition ?? dynamicDefinition; + } + public async override Task> GetAllAsync() { var staticFeatures = await StaticStore.GetFeaturesAsync(); @@ -222,7 +244,7 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager } - public static FeatureDefinition GetFeatureOrNull( + public static FeatureDefinition? GetFeatureOrNull( FeatureGroupDefinition group, [NotNull] string name) { @@ -231,7 +253,7 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager return GetFeatureOrNullRecursively(group.Features, name); } - private static FeatureDefinition GetFeatureOrNullRecursively( + private static FeatureDefinition? GetFeatureOrNullRecursively( IReadOnlyList features, string name) { @@ -252,3 +274,4 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager return null; } } +#nullable disable \ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs index 68b34e48b..027e7f1c4 100644 --- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs @@ -7,6 +7,8 @@ using Volo.Abp.MultiTenancy; namespace Volo.Abp.Authorization.Permissions; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergePermissionDefinitionManager : PermissionDefinitionManager { @@ -21,6 +23,62 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager _dynamicStore = dynamicStore; } + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetOrNullAsync(name); + var dynamicDefinition = await _dynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task GetResourcePermissionOrNullAsync(string resourceName, string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetResourcePermissionOrNullAsync(resourceName, name); + var dynamicDefinition = await _dynamicStore.GetResourcePermissionOrNullAsync(resourceName, name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetPermissionsAsync() + { + var staticPermissions = await _staticStore.GetPermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetPermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + + public async override Task> GetResourcePermissionsAsync() + { + var staticPermissions = await _staticStore.GetResourcePermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetResourcePermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + public async override Task> GetGroupsAsync() { var staticGroups = await _staticStore.GetGroupsAsync(); @@ -99,6 +157,35 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager } } + private static IReadOnlyList MergePermissions(IReadOnlyList staticPermissions, IReadOnlyList dynamicPermissions) + { + var mergedPermissions = new Dictionary(); + + foreach (var staticFeature in staticPermissions) + { + mergedPermissions[staticFeature.Name] = staticFeature; + } + + foreach (var dynamicPermission in dynamicPermissions) + { + if (mergedPermissions.TryGetValue(dynamicPermission.Name, out var existingPermission)) + { + MergePermissionMetadata(existingPermission, dynamicPermission); + + foreach (var sourceChild in dynamicPermission.Children) + { + MergeChildPermissions(existingPermission, sourceChild); + } + } + else + { + mergedPermissions[dynamicPermission.Name] = dynamicPermission; + } + } + + return mergedPermissions.Values.ToImmutableList(); + } + private static void MergeChildPermissions(PermissionDefinition parent, PermissionDefinition sourceChild) { var existingChild = parent.Children.FirstOrDefault(c => c.Name == sourceChild.Name); @@ -185,4 +272,5 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager target.IsEnabled = target.IsEnabled || source.IsEnabled; } -} \ No newline at end of file +} +#nullable disable \ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs index c3c479f4f..2fe64a566 100644 --- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs @@ -5,25 +5,37 @@ using Volo.Abp.DependencyInjection; namespace Volo.Abp.Settings; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergeSettingDefinitionManager : SettingDefinitionManager { - private readonly IStaticSettingDefinitionStore _staticStore; - private readonly IDynamicSettingDefinitionStore _dynamicStore; - public MergeSettingDefinitionManager( IStaticSettingDefinitionStore staticStore, IDynamicSettingDefinitionStore dynamicStore) : base(staticStore, dynamicStore) { - _staticStore = staticStore; - _dynamicStore = dynamicStore; + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeSetting(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; } public async override Task> GetAllAsync() { - var staticSettings = await _staticStore.GetAllAsync(); - var dynamicSettings = await _dynamicStore.GetAllAsync(); + var staticSettings = await StaticStore.GetAllAsync(); + var dynamicSettings = await DynamicStore.GetAllAsync(); var mergedSettings = new Dictionary(); @@ -70,4 +82,5 @@ public class MergeSettingDefinitionManager : SettingDefinitionManager } } } +#nullable disable diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs index 0a45a8908..5cb3137cd 100644 --- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs @@ -6,6 +6,7 @@ using Volo.Abp.TextTemplating; namespace Volo.Abp.TextTemplatin; +#nullable enable [Dependency(ReplaceServices = true)] public class MergeTemplateDefinitionManager : TemplateDefinitionManager @@ -16,6 +17,22 @@ public class MergeTemplateDefinitionManager : TemplateDefinitionManager : base(staticStore, dynamicStore) { } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeTemplate(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; + } + public async override Task> GetAllAsync() { var staticTemplates = await StaticStore.GetAllAsync(); @@ -84,3 +101,4 @@ public class MergeTemplateDefinitionManager : TemplateDefinitionManager return mergedTemplate; } } +#nullable disable diff --git a/aspnet-core/services/LY.MicroService.WechatManagement.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs b/aspnet-core/services/LY.MicroService.WechatManagement.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs index 887001b2f..498ac24fe 100644 --- a/aspnet-core/services/LY.MicroService.WechatManagement.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.WechatManagement.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs @@ -7,6 +7,8 @@ using Volo.Abp.DependencyInjection; namespace Volo.Abp.Features; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergeFeatureDefinitionManager : FeatureDefinitionManager { @@ -17,6 +19,26 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager { } + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeFeatureMetadata(staticDefinition, dynamicDefinition); + + foreach (var child in dynamicDefinition.Children) + { + MergeChildFeature(staticDefinition, child); + } + } + + return staticDefinition ?? dynamicDefinition; + } + public async override Task> GetAllAsync() { var staticFeatures = await StaticStore.GetFeaturesAsync(); @@ -222,7 +244,7 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager } - public static FeatureDefinition GetFeatureOrNull( + public static FeatureDefinition? GetFeatureOrNull( FeatureGroupDefinition group, [NotNull] string name) { @@ -231,7 +253,7 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager return GetFeatureOrNullRecursively(group.Features, name); } - private static FeatureDefinition GetFeatureOrNullRecursively( + private static FeatureDefinition? GetFeatureOrNullRecursively( IReadOnlyList features, string name) { @@ -252,3 +274,4 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager return null; } } +#nullable disable \ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.WechatManagement.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs b/aspnet-core/services/LY.MicroService.WechatManagement.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs index 68b34e48b..027e7f1c4 100644 --- a/aspnet-core/services/LY.MicroService.WechatManagement.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.WechatManagement.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs @@ -7,6 +7,8 @@ using Volo.Abp.MultiTenancy; namespace Volo.Abp.Authorization.Permissions; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergePermissionDefinitionManager : PermissionDefinitionManager { @@ -21,6 +23,62 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager _dynamicStore = dynamicStore; } + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetOrNullAsync(name); + var dynamicDefinition = await _dynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task GetResourcePermissionOrNullAsync(string resourceName, string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetResourcePermissionOrNullAsync(resourceName, name); + var dynamicDefinition = await _dynamicStore.GetResourcePermissionOrNullAsync(resourceName, name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetPermissionsAsync() + { + var staticPermissions = await _staticStore.GetPermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetPermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + + public async override Task> GetResourcePermissionsAsync() + { + var staticPermissions = await _staticStore.GetResourcePermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetResourcePermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + public async override Task> GetGroupsAsync() { var staticGroups = await _staticStore.GetGroupsAsync(); @@ -99,6 +157,35 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager } } + private static IReadOnlyList MergePermissions(IReadOnlyList staticPermissions, IReadOnlyList dynamicPermissions) + { + var mergedPermissions = new Dictionary(); + + foreach (var staticFeature in staticPermissions) + { + mergedPermissions[staticFeature.Name] = staticFeature; + } + + foreach (var dynamicPermission in dynamicPermissions) + { + if (mergedPermissions.TryGetValue(dynamicPermission.Name, out var existingPermission)) + { + MergePermissionMetadata(existingPermission, dynamicPermission); + + foreach (var sourceChild in dynamicPermission.Children) + { + MergeChildPermissions(existingPermission, sourceChild); + } + } + else + { + mergedPermissions[dynamicPermission.Name] = dynamicPermission; + } + } + + return mergedPermissions.Values.ToImmutableList(); + } + private static void MergeChildPermissions(PermissionDefinition parent, PermissionDefinition sourceChild) { var existingChild = parent.Children.FirstOrDefault(c => c.Name == sourceChild.Name); @@ -185,4 +272,5 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager target.IsEnabled = target.IsEnabled || source.IsEnabled; } -} \ No newline at end of file +} +#nullable disable \ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.WechatManagement.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs b/aspnet-core/services/LY.MicroService.WechatManagement.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs index c3c479f4f..2fe64a566 100644 --- a/aspnet-core/services/LY.MicroService.WechatManagement.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.WechatManagement.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs @@ -5,25 +5,37 @@ using Volo.Abp.DependencyInjection; namespace Volo.Abp.Settings; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergeSettingDefinitionManager : SettingDefinitionManager { - private readonly IStaticSettingDefinitionStore _staticStore; - private readonly IDynamicSettingDefinitionStore _dynamicStore; - public MergeSettingDefinitionManager( IStaticSettingDefinitionStore staticStore, IDynamicSettingDefinitionStore dynamicStore) : base(staticStore, dynamicStore) { - _staticStore = staticStore; - _dynamicStore = dynamicStore; + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeSetting(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; } public async override Task> GetAllAsync() { - var staticSettings = await _staticStore.GetAllAsync(); - var dynamicSettings = await _dynamicStore.GetAllAsync(); + var staticSettings = await StaticStore.GetAllAsync(); + var dynamicSettings = await DynamicStore.GetAllAsync(); var mergedSettings = new Dictionary(); @@ -70,4 +82,5 @@ public class MergeSettingDefinitionManager : SettingDefinitionManager } } } +#nullable disable diff --git a/aspnet-core/services/LY.MicroService.WechatManagement.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs b/aspnet-core/services/LY.MicroService.WechatManagement.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs index 0a45a8908..5cb3137cd 100644 --- a/aspnet-core/services/LY.MicroService.WechatManagement.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.WechatManagement.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs @@ -6,6 +6,7 @@ using Volo.Abp.TextTemplating; namespace Volo.Abp.TextTemplatin; +#nullable enable [Dependency(ReplaceServices = true)] public class MergeTemplateDefinitionManager : TemplateDefinitionManager @@ -16,6 +17,22 @@ public class MergeTemplateDefinitionManager : TemplateDefinitionManager : base(staticStore, dynamicStore) { } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeTemplate(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; + } + public async override Task> GetAllAsync() { var staticTemplates = await StaticStore.GetAllAsync(); @@ -84,3 +101,4 @@ public class MergeTemplateDefinitionManager : TemplateDefinitionManager return mergedTemplate; } } +#nullable disable diff --git a/aspnet-core/services/LY.MicroService.WorkflowManagement.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs b/aspnet-core/services/LY.MicroService.WorkflowManagement.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs index 887001b2f..498ac24fe 100644 --- a/aspnet-core/services/LY.MicroService.WorkflowManagement.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.WorkflowManagement.HttpApi.Host/Overrides/MergeFeatureDefinitionManager.cs @@ -7,6 +7,8 @@ using Volo.Abp.DependencyInjection; namespace Volo.Abp.Features; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergeFeatureDefinitionManager : FeatureDefinitionManager { @@ -17,6 +19,26 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager { } + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeFeatureMetadata(staticDefinition, dynamicDefinition); + + foreach (var child in dynamicDefinition.Children) + { + MergeChildFeature(staticDefinition, child); + } + } + + return staticDefinition ?? dynamicDefinition; + } + public async override Task> GetAllAsync() { var staticFeatures = await StaticStore.GetFeaturesAsync(); @@ -222,7 +244,7 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager } - public static FeatureDefinition GetFeatureOrNull( + public static FeatureDefinition? GetFeatureOrNull( FeatureGroupDefinition group, [NotNull] string name) { @@ -231,7 +253,7 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager return GetFeatureOrNullRecursively(group.Features, name); } - private static FeatureDefinition GetFeatureOrNullRecursively( + private static FeatureDefinition? GetFeatureOrNullRecursively( IReadOnlyList features, string name) { @@ -252,3 +274,4 @@ public class MergeFeatureDefinitionManager : FeatureDefinitionManager return null; } } +#nullable disable \ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.WorkflowManagement.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs b/aspnet-core/services/LY.MicroService.WorkflowManagement.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs index 68b34e48b..027e7f1c4 100644 --- a/aspnet-core/services/LY.MicroService.WorkflowManagement.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.WorkflowManagement.HttpApi.Host/Overrides/MergePermissionDefinitionManager.cs @@ -7,6 +7,8 @@ using Volo.Abp.MultiTenancy; namespace Volo.Abp.Authorization.Permissions; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergePermissionDefinitionManager : PermissionDefinitionManager { @@ -21,6 +23,62 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager _dynamicStore = dynamicStore; } + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetOrNullAsync(name); + var dynamicDefinition = await _dynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task GetResourcePermissionOrNullAsync(string resourceName, string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await _staticStore.GetResourcePermissionOrNullAsync(resourceName, name); + var dynamicDefinition = await _dynamicStore.GetResourcePermissionOrNullAsync(resourceName, name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergePermissionMetadata(staticDefinition, dynamicDefinition); + + foreach (var grandchild in dynamicDefinition.Children) + { + MergeChildPermissions(staticDefinition, grandchild); + } + } + + return staticDefinition ?? dynamicDefinition; + } + + public async override Task> GetPermissionsAsync() + { + var staticPermissions = await _staticStore.GetPermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetPermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + + public async override Task> GetResourcePermissionsAsync() + { + var staticPermissions = await _staticStore.GetResourcePermissionsAsync(); + var dynamicPermissions = await _dynamicStore.GetResourcePermissionsAsync(); + + return MergePermissions(staticPermissions, dynamicPermissions); + } + public async override Task> GetGroupsAsync() { var staticGroups = await _staticStore.GetGroupsAsync(); @@ -99,6 +157,35 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager } } + private static IReadOnlyList MergePermissions(IReadOnlyList staticPermissions, IReadOnlyList dynamicPermissions) + { + var mergedPermissions = new Dictionary(); + + foreach (var staticFeature in staticPermissions) + { + mergedPermissions[staticFeature.Name] = staticFeature; + } + + foreach (var dynamicPermission in dynamicPermissions) + { + if (mergedPermissions.TryGetValue(dynamicPermission.Name, out var existingPermission)) + { + MergePermissionMetadata(existingPermission, dynamicPermission); + + foreach (var sourceChild in dynamicPermission.Children) + { + MergeChildPermissions(existingPermission, sourceChild); + } + } + else + { + mergedPermissions[dynamicPermission.Name] = dynamicPermission; + } + } + + return mergedPermissions.Values.ToImmutableList(); + } + private static void MergeChildPermissions(PermissionDefinition parent, PermissionDefinition sourceChild) { var existingChild = parent.Children.FirstOrDefault(c => c.Name == sourceChild.Name); @@ -185,4 +272,5 @@ public class MergePermissionDefinitionManager : PermissionDefinitionManager target.IsEnabled = target.IsEnabled || source.IsEnabled; } -} \ No newline at end of file +} +#nullable disable \ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.WorkflowManagement.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs b/aspnet-core/services/LY.MicroService.WorkflowManagement.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs index c3c479f4f..2fe64a566 100644 --- a/aspnet-core/services/LY.MicroService.WorkflowManagement.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.WorkflowManagement.HttpApi.Host/Overrides/MergeSettingDefinitionManager.cs @@ -5,25 +5,37 @@ using Volo.Abp.DependencyInjection; namespace Volo.Abp.Settings; +#nullable enable + [Dependency(ReplaceServices = true)] public class MergeSettingDefinitionManager : SettingDefinitionManager { - private readonly IStaticSettingDefinitionStore _staticStore; - private readonly IDynamicSettingDefinitionStore _dynamicStore; - public MergeSettingDefinitionManager( IStaticSettingDefinitionStore staticStore, IDynamicSettingDefinitionStore dynamicStore) : base(staticStore, dynamicStore) { - _staticStore = staticStore; - _dynamicStore = dynamicStore; + } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeSetting(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; } public async override Task> GetAllAsync() { - var staticSettings = await _staticStore.GetAllAsync(); - var dynamicSettings = await _dynamicStore.GetAllAsync(); + var staticSettings = await StaticStore.GetAllAsync(); + var dynamicSettings = await DynamicStore.GetAllAsync(); var mergedSettings = new Dictionary(); @@ -70,4 +82,5 @@ public class MergeSettingDefinitionManager : SettingDefinitionManager } } } +#nullable disable diff --git a/aspnet-core/services/LY.MicroService.WorkflowManagement.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs b/aspnet-core/services/LY.MicroService.WorkflowManagement.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs index 0a45a8908..5cb3137cd 100644 --- a/aspnet-core/services/LY.MicroService.WorkflowManagement.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs +++ b/aspnet-core/services/LY.MicroService.WorkflowManagement.HttpApi.Host/Overrides/MergeTemplateDefinitionManager.cs @@ -6,6 +6,7 @@ using Volo.Abp.TextTemplating; namespace Volo.Abp.TextTemplatin; +#nullable enable [Dependency(ReplaceServices = true)] public class MergeTemplateDefinitionManager : TemplateDefinitionManager @@ -16,6 +17,22 @@ public class MergeTemplateDefinitionManager : TemplateDefinitionManager : base(staticStore, dynamicStore) { } + + public async override Task GetOrNullAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var staticDefinition = await StaticStore.GetOrNullAsync(name); + var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); + + if (staticDefinition != null && dynamicDefinition != null) + { + MergeTemplate(staticDefinition, dynamicDefinition); + } + + return staticDefinition ?? dynamicDefinition; + } + public async override Task> GetAllAsync() { var staticTemplates = await StaticStore.GetAllAsync(); @@ -84,3 +101,4 @@ public class MergeTemplateDefinitionManager : TemplateDefinitionManager return mergedTemplate; } } +#nullable disable