committed by
GitHub
210 changed files with 2002 additions and 17499 deletions
@ -0,0 +1,71 @@ |
|||
<script setup lang="ts"> |
|||
import type { WorkspaceDefinitionRecordDto } from '../../types/workspaces'; |
|||
|
|||
import { ref } from 'vue'; |
|||
|
|||
import { useVbenForm, useVbenModal } from '@vben/common-ui'; |
|||
import { $t } from '@vben/locales'; |
|||
|
|||
import { useMessage } from '@abp/ui'; |
|||
|
|||
import { useWorkspaceDefinitionsApi } from '../../api/useWorkspaceDefinitionsApi'; |
|||
|
|||
const emit = defineEmits<{ |
|||
(event: 'change', data: WorkspaceDefinitionRecordDto): void; |
|||
}>(); |
|||
|
|||
const message = useMessage(); |
|||
const { getApi, updateApi } = useWorkspaceDefinitionsApi(); |
|||
|
|||
const formModel = ref<WorkspaceDefinitionRecordDto>(); |
|||
|
|||
const [Form, formApi] = useVbenForm({ |
|||
schema: [ |
|||
{ |
|||
fieldName: 'apiKey', |
|||
component: 'InputPassword', |
|||
label: $t('AIManagement.DisplayName:ApiKey'), |
|||
rules: 'required', |
|||
}, |
|||
], |
|||
showDefaultActions: false, |
|||
handleSubmit: onSubmit, |
|||
}); |
|||
|
|||
const [Modal, modalApi] = useVbenModal({ |
|||
title: $t('AIManagement.ResetApiKey'), |
|||
async onOpenChange(isOpen) { |
|||
if (isOpen) { |
|||
const { id } = modalApi.getData<WorkspaceDefinitionRecordDto>(); |
|||
const dto = await getApi(id); |
|||
formModel.value = dto; |
|||
} |
|||
}, |
|||
async onConfirm() { |
|||
await formApi.validateAndSubmitForm(); |
|||
}, |
|||
}); |
|||
|
|||
async function onSubmit(values: Record<string, string>) { |
|||
try { |
|||
modalApi.lock(); |
|||
const dto = await updateApi(formModel.value!.id, { |
|||
...formModel.value!, |
|||
apiKey: values.apiKey, |
|||
}); |
|||
message.success($t('AbpUi.SavedSuccessfully')); |
|||
emit('change', dto); |
|||
modalApi.close(); |
|||
} finally { |
|||
modalApi.unlock(); |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<template> |
|||
<Modal> |
|||
<Form /> |
|||
</Modal> |
|||
</template> |
|||
|
|||
<style scoped></style> |
|||
@ -1,277 +0,0 @@ |
|||
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<FeatureDefinition?> 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<IReadOnlyList<FeatureDefinition>> GetAllAsync() |
|||
{ |
|||
var staticFeatures = await StaticStore.GetFeaturesAsync(); |
|||
var dynamicFeatures = await DynamicStore.GetFeaturesAsync(); |
|||
|
|||
var mergedFeatures = new Dictionary<string, FeatureDefinition>(); |
|||
|
|||
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<IReadOnlyList<FeatureGroupDefinition>> GetGroupsAsync() |
|||
{ |
|||
var staticGroups = await StaticStore.GetGroupsAsync(); |
|||
var dynamicGroups = await DynamicStore.GetGroupsAsync(); |
|||
|
|||
var mergedGroups = new Dictionary<string, FeatureGroupDefinition>(); |
|||
|
|||
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<FeatureDefinition> 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 |
|||
@ -1,276 +0,0 @@ |
|||
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<PermissionDefinition?> 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<PermissionDefinition?> 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<IReadOnlyList<PermissionDefinition>> GetPermissionsAsync() |
|||
{ |
|||
var staticPermissions = await _staticStore.GetPermissionsAsync(); |
|||
var dynamicPermissions = await _dynamicStore.GetPermissionsAsync(); |
|||
|
|||
return MergePermissions(staticPermissions, dynamicPermissions); |
|||
} |
|||
|
|||
public async override Task<IReadOnlyList<PermissionDefinition>> GetResourcePermissionsAsync() |
|||
{ |
|||
var staticPermissions = await _staticStore.GetResourcePermissionsAsync(); |
|||
var dynamicPermissions = await _dynamicStore.GetResourcePermissionsAsync(); |
|||
|
|||
return MergePermissions(staticPermissions, dynamicPermissions); |
|||
} |
|||
|
|||
public async override Task<IReadOnlyList<PermissionGroupDefinition>> GetGroupsAsync() |
|||
{ |
|||
var staticGroups = await _staticStore.GetGroupsAsync(); |
|||
var dynamicGroups = await _dynamicStore.GetGroupsAsync(); |
|||
|
|||
var mergedGroups = new Dictionary<string, PermissionGroupDefinition>(); |
|||
|
|||
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<PermissionDefinition> MergePermissions(IReadOnlyList<PermissionDefinition> staticPermissions, IReadOnlyList<PermissionDefinition> dynamicPermissions) |
|||
{ |
|||
var mergedPermissions = new Dictionary<string, PermissionDefinition>(); |
|||
|
|||
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 |
|||
@ -1,86 +0,0 @@ |
|||
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<SettingDefinition?> 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<IReadOnlyList<SettingDefinition>> GetAllAsync() |
|||
{ |
|||
var staticSettings = await StaticStore.GetAllAsync(); |
|||
var dynamicSettings = await DynamicStore.GetAllAsync(); |
|||
|
|||
var mergedSettings = new Dictionary<string, SettingDefinition>(); |
|||
|
|||
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 |
|||
|
|||
@ -1,104 +0,0 @@ |
|||
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<TemplateDefinition?> 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<IReadOnlyList<TemplateDefinition>> GetAllAsync() |
|||
{ |
|||
var staticTemplates = await StaticStore.GetAllAsync(); |
|||
var dynamicTemplates = await DynamicStore.GetAllAsync(); |
|||
|
|||
var mergedTemplates = new Dictionary<string, TemplateDefinition>(); |
|||
|
|||
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 |
|||
@ -1,277 +0,0 @@ |
|||
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<FeatureDefinition?> 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<IReadOnlyList<FeatureDefinition>> GetAllAsync() |
|||
{ |
|||
var staticFeatures = await StaticStore.GetFeaturesAsync(); |
|||
var dynamicFeatures = await DynamicStore.GetFeaturesAsync(); |
|||
|
|||
var mergedFeatures = new Dictionary<string, FeatureDefinition>(); |
|||
|
|||
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<IReadOnlyList<FeatureGroupDefinition>> GetGroupsAsync() |
|||
{ |
|||
var staticGroups = await StaticStore.GetGroupsAsync(); |
|||
var dynamicGroups = await DynamicStore.GetGroupsAsync(); |
|||
|
|||
var mergedGroups = new Dictionary<string, FeatureGroupDefinition>(); |
|||
|
|||
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<FeatureDefinition> 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 |
|||
@ -1,276 +0,0 @@ |
|||
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<PermissionDefinition?> 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<PermissionDefinition?> 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<IReadOnlyList<PermissionDefinition>> GetPermissionsAsync() |
|||
{ |
|||
var staticPermissions = await _staticStore.GetPermissionsAsync(); |
|||
var dynamicPermissions = await _dynamicStore.GetPermissionsAsync(); |
|||
|
|||
return MergePermissions(staticPermissions, dynamicPermissions); |
|||
} |
|||
|
|||
public async override Task<IReadOnlyList<PermissionDefinition>> GetResourcePermissionsAsync() |
|||
{ |
|||
var staticPermissions = await _staticStore.GetResourcePermissionsAsync(); |
|||
var dynamicPermissions = await _dynamicStore.GetResourcePermissionsAsync(); |
|||
|
|||
return MergePermissions(staticPermissions, dynamicPermissions); |
|||
} |
|||
|
|||
public async override Task<IReadOnlyList<PermissionGroupDefinition>> GetGroupsAsync() |
|||
{ |
|||
var staticGroups = await _staticStore.GetGroupsAsync(); |
|||
var dynamicGroups = await _dynamicStore.GetGroupsAsync(); |
|||
|
|||
var mergedGroups = new Dictionary<string, PermissionGroupDefinition>(); |
|||
|
|||
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<PermissionDefinition> MergePermissions(IReadOnlyList<PermissionDefinition> staticPermissions, IReadOnlyList<PermissionDefinition> dynamicPermissions) |
|||
{ |
|||
var mergedPermissions = new Dictionary<string, PermissionDefinition>(); |
|||
|
|||
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 |
|||
@ -1,86 +0,0 @@ |
|||
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<SettingDefinition?> 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<IReadOnlyList<SettingDefinition>> GetAllAsync() |
|||
{ |
|||
var staticSettings = await StaticStore.GetAllAsync(); |
|||
var dynamicSettings = await DynamicStore.GetAllAsync(); |
|||
|
|||
var mergedSettings = new Dictionary<string, SettingDefinition>(); |
|||
|
|||
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 |
|||
|
|||
@ -1,104 +0,0 @@ |
|||
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<TemplateDefinition?> 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<IReadOnlyList<TemplateDefinition>> GetAllAsync() |
|||
{ |
|||
var staticTemplates = await StaticStore.GetAllAsync(); |
|||
var dynamicTemplates = await DynamicStore.GetAllAsync(); |
|||
|
|||
var mergedTemplates = new Dictionary<string, TemplateDefinition>(); |
|||
|
|||
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 |
|||
@ -1,277 +0,0 @@ |
|||
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<FeatureDefinition?> 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<IReadOnlyList<FeatureDefinition>> GetAllAsync() |
|||
{ |
|||
var staticFeatures = await StaticStore.GetFeaturesAsync(); |
|||
var dynamicFeatures = await DynamicStore.GetFeaturesAsync(); |
|||
|
|||
var mergedFeatures = new Dictionary<string, FeatureDefinition>(); |
|||
|
|||
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<IReadOnlyList<FeatureGroupDefinition>> GetGroupsAsync() |
|||
{ |
|||
var staticGroups = await StaticStore.GetGroupsAsync(); |
|||
var dynamicGroups = await DynamicStore.GetGroupsAsync(); |
|||
|
|||
var mergedGroups = new Dictionary<string, FeatureGroupDefinition>(); |
|||
|
|||
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<FeatureDefinition> 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 |
|||
@ -1,276 +0,0 @@ |
|||
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<PermissionDefinition?> 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<PermissionDefinition?> 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<IReadOnlyList<PermissionDefinition>> GetPermissionsAsync() |
|||
{ |
|||
var staticPermissions = await _staticStore.GetPermissionsAsync(); |
|||
var dynamicPermissions = await _dynamicStore.GetPermissionsAsync(); |
|||
|
|||
return MergePermissions(staticPermissions, dynamicPermissions); |
|||
} |
|||
|
|||
public async override Task<IReadOnlyList<PermissionDefinition>> GetResourcePermissionsAsync() |
|||
{ |
|||
var staticPermissions = await _staticStore.GetResourcePermissionsAsync(); |
|||
var dynamicPermissions = await _dynamicStore.GetResourcePermissionsAsync(); |
|||
|
|||
return MergePermissions(staticPermissions, dynamicPermissions); |
|||
} |
|||
|
|||
public async override Task<IReadOnlyList<PermissionGroupDefinition>> GetGroupsAsync() |
|||
{ |
|||
var staticGroups = await _staticStore.GetGroupsAsync(); |
|||
var dynamicGroups = await _dynamicStore.GetGroupsAsync(); |
|||
|
|||
var mergedGroups = new Dictionary<string, PermissionGroupDefinition>(); |
|||
|
|||
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<PermissionDefinition> MergePermissions(IReadOnlyList<PermissionDefinition> staticPermissions, IReadOnlyList<PermissionDefinition> dynamicPermissions) |
|||
{ |
|||
var mergedPermissions = new Dictionary<string, PermissionDefinition>(); |
|||
|
|||
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 |
|||
@ -1,86 +0,0 @@ |
|||
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<SettingDefinition?> 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<IReadOnlyList<SettingDefinition>> GetAllAsync() |
|||
{ |
|||
var staticSettings = await StaticStore.GetAllAsync(); |
|||
var dynamicSettings = await DynamicStore.GetAllAsync(); |
|||
|
|||
var mergedSettings = new Dictionary<string, SettingDefinition>(); |
|||
|
|||
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 |
|||
|
|||
@ -1,104 +0,0 @@ |
|||
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<TemplateDefinition?> 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<IReadOnlyList<TemplateDefinition>> GetAllAsync() |
|||
{ |
|||
var staticTemplates = await StaticStore.GetAllAsync(); |
|||
var dynamicTemplates = await DynamicStore.GetAllAsync(); |
|||
|
|||
var mergedTemplates = new Dictionary<string, TemplateDefinition>(); |
|||
|
|||
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 |
|||
@ -1,277 +0,0 @@ |
|||
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<FeatureDefinition?> 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<IReadOnlyList<FeatureDefinition>> GetAllAsync() |
|||
{ |
|||
var staticFeatures = await StaticStore.GetFeaturesAsync(); |
|||
var dynamicFeatures = await DynamicStore.GetFeaturesAsync(); |
|||
|
|||
var mergedFeatures = new Dictionary<string, FeatureDefinition>(); |
|||
|
|||
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<IReadOnlyList<FeatureGroupDefinition>> GetGroupsAsync() |
|||
{ |
|||
var staticGroups = await StaticStore.GetGroupsAsync(); |
|||
var dynamicGroups = await DynamicStore.GetGroupsAsync(); |
|||
|
|||
var mergedGroups = new Dictionary<string, FeatureGroupDefinition>(); |
|||
|
|||
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<FeatureDefinition> 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 |
|||
@ -1,276 +0,0 @@ |
|||
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<PermissionDefinition?> 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<PermissionDefinition?> 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<IReadOnlyList<PermissionDefinition>> GetPermissionsAsync() |
|||
{ |
|||
var staticPermissions = await _staticStore.GetPermissionsAsync(); |
|||
var dynamicPermissions = await _dynamicStore.GetPermissionsAsync(); |
|||
|
|||
return MergePermissions(staticPermissions, dynamicPermissions); |
|||
} |
|||
|
|||
public async override Task<IReadOnlyList<PermissionDefinition>> GetResourcePermissionsAsync() |
|||
{ |
|||
var staticPermissions = await _staticStore.GetResourcePermissionsAsync(); |
|||
var dynamicPermissions = await _dynamicStore.GetResourcePermissionsAsync(); |
|||
|
|||
return MergePermissions(staticPermissions, dynamicPermissions); |
|||
} |
|||
|
|||
public async override Task<IReadOnlyList<PermissionGroupDefinition>> GetGroupsAsync() |
|||
{ |
|||
var staticGroups = await _staticStore.GetGroupsAsync(); |
|||
var dynamicGroups = await _dynamicStore.GetGroupsAsync(); |
|||
|
|||
var mergedGroups = new Dictionary<string, PermissionGroupDefinition>(); |
|||
|
|||
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<PermissionDefinition> MergePermissions(IReadOnlyList<PermissionDefinition> staticPermissions, IReadOnlyList<PermissionDefinition> dynamicPermissions) |
|||
{ |
|||
var mergedPermissions = new Dictionary<string, PermissionDefinition>(); |
|||
|
|||
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 |
|||
@ -1,86 +0,0 @@ |
|||
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<SettingDefinition?> 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<IReadOnlyList<SettingDefinition>> GetAllAsync() |
|||
{ |
|||
var staticSettings = await StaticStore.GetAllAsync(); |
|||
var dynamicSettings = await DynamicStore.GetAllAsync(); |
|||
|
|||
var mergedSettings = new Dictionary<string, SettingDefinition>(); |
|||
|
|||
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 |
|||
|
|||
@ -1,104 +0,0 @@ |
|||
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<TemplateDefinition?> 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<IReadOnlyList<TemplateDefinition>> GetAllAsync() |
|||
{ |
|||
var staticTemplates = await StaticStore.GetAllAsync(); |
|||
var dynamicTemplates = await DynamicStore.GetAllAsync(); |
|||
|
|||
var mergedTemplates = new Dictionary<string, TemplateDefinition>(); |
|||
|
|||
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 |
|||
@ -1,277 +0,0 @@ |
|||
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<FeatureDefinition?> 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<IReadOnlyList<FeatureDefinition>> GetAllAsync() |
|||
{ |
|||
var staticFeatures = await StaticStore.GetFeaturesAsync(); |
|||
var dynamicFeatures = await DynamicStore.GetFeaturesAsync(); |
|||
|
|||
var mergedFeatures = new Dictionary<string, FeatureDefinition>(); |
|||
|
|||
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<IReadOnlyList<FeatureGroupDefinition>> GetGroupsAsync() |
|||
{ |
|||
var staticGroups = await StaticStore.GetGroupsAsync(); |
|||
var dynamicGroups = await DynamicStore.GetGroupsAsync(); |
|||
|
|||
var mergedGroups = new Dictionary<string, FeatureGroupDefinition>(); |
|||
|
|||
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<FeatureDefinition> 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 |
|||
@ -1,276 +0,0 @@ |
|||
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<PermissionDefinition?> 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<PermissionDefinition?> 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<IReadOnlyList<PermissionDefinition>> GetPermissionsAsync() |
|||
{ |
|||
var staticPermissions = await _staticStore.GetPermissionsAsync(); |
|||
var dynamicPermissions = await _dynamicStore.GetPermissionsAsync(); |
|||
|
|||
return MergePermissions(staticPermissions, dynamicPermissions); |
|||
} |
|||
|
|||
public async override Task<IReadOnlyList<PermissionDefinition>> GetResourcePermissionsAsync() |
|||
{ |
|||
var staticPermissions = await _staticStore.GetResourcePermissionsAsync(); |
|||
var dynamicPermissions = await _dynamicStore.GetResourcePermissionsAsync(); |
|||
|
|||
return MergePermissions(staticPermissions, dynamicPermissions); |
|||
} |
|||
|
|||
public async override Task<IReadOnlyList<PermissionGroupDefinition>> GetGroupsAsync() |
|||
{ |
|||
var staticGroups = await _staticStore.GetGroupsAsync(); |
|||
var dynamicGroups = await _dynamicStore.GetGroupsAsync(); |
|||
|
|||
var mergedGroups = new Dictionary<string, PermissionGroupDefinition>(); |
|||
|
|||
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<PermissionDefinition> MergePermissions(IReadOnlyList<PermissionDefinition> staticPermissions, IReadOnlyList<PermissionDefinition> dynamicPermissions) |
|||
{ |
|||
var mergedPermissions = new Dictionary<string, PermissionDefinition>(); |
|||
|
|||
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 |
|||
@ -1,86 +0,0 @@ |
|||
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<SettingDefinition?> 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<IReadOnlyList<SettingDefinition>> GetAllAsync() |
|||
{ |
|||
var staticSettings = await StaticStore.GetAllAsync(); |
|||
var dynamicSettings = await DynamicStore.GetAllAsync(); |
|||
|
|||
var mergedSettings = new Dictionary<string, SettingDefinition>(); |
|||
|
|||
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 |
|||
|
|||
@ -1,104 +0,0 @@ |
|||
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<TemplateDefinition?> 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<IReadOnlyList<TemplateDefinition>> GetAllAsync() |
|||
{ |
|||
var staticTemplates = await StaticStore.GetAllAsync(); |
|||
var dynamicTemplates = await DynamicStore.GetAllAsync(); |
|||
|
|||
var mergedTemplates = new Dictionary<string, TemplateDefinition>(); |
|||
|
|||
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 |
|||
@ -1,277 +0,0 @@ |
|||
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<FeatureDefinition?> 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<IReadOnlyList<FeatureDefinition>> GetAllAsync() |
|||
{ |
|||
var staticFeatures = await StaticStore.GetFeaturesAsync(); |
|||
var dynamicFeatures = await DynamicStore.GetFeaturesAsync(); |
|||
|
|||
var mergedFeatures = new Dictionary<string, FeatureDefinition>(); |
|||
|
|||
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<IReadOnlyList<FeatureGroupDefinition>> GetGroupsAsync() |
|||
{ |
|||
var staticGroups = await StaticStore.GetGroupsAsync(); |
|||
var dynamicGroups = await DynamicStore.GetGroupsAsync(); |
|||
|
|||
var mergedGroups = new Dictionary<string, FeatureGroupDefinition>(); |
|||
|
|||
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<FeatureDefinition> 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 |
|||
@ -1,276 +0,0 @@ |
|||
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<PermissionDefinition?> 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<PermissionDefinition?> 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<IReadOnlyList<PermissionDefinition>> GetPermissionsAsync() |
|||
{ |
|||
var staticPermissions = await _staticStore.GetPermissionsAsync(); |
|||
var dynamicPermissions = await _dynamicStore.GetPermissionsAsync(); |
|||
|
|||
return MergePermissions(staticPermissions, dynamicPermissions); |
|||
} |
|||
|
|||
public async override Task<IReadOnlyList<PermissionDefinition>> GetResourcePermissionsAsync() |
|||
{ |
|||
var staticPermissions = await _staticStore.GetResourcePermissionsAsync(); |
|||
var dynamicPermissions = await _dynamicStore.GetResourcePermissionsAsync(); |
|||
|
|||
return MergePermissions(staticPermissions, dynamicPermissions); |
|||
} |
|||
|
|||
public async override Task<IReadOnlyList<PermissionGroupDefinition>> GetGroupsAsync() |
|||
{ |
|||
var staticGroups = await _staticStore.GetGroupsAsync(); |
|||
var dynamicGroups = await _dynamicStore.GetGroupsAsync(); |
|||
|
|||
var mergedGroups = new Dictionary<string, PermissionGroupDefinition>(); |
|||
|
|||
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<PermissionDefinition> MergePermissions(IReadOnlyList<PermissionDefinition> staticPermissions, IReadOnlyList<PermissionDefinition> dynamicPermissions) |
|||
{ |
|||
var mergedPermissions = new Dictionary<string, PermissionDefinition>(); |
|||
|
|||
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 |
|||
@ -1,86 +0,0 @@ |
|||
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<SettingDefinition?> 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<IReadOnlyList<SettingDefinition>> GetAllAsync() |
|||
{ |
|||
var staticSettings = await StaticStore.GetAllAsync(); |
|||
var dynamicSettings = await DynamicStore.GetAllAsync(); |
|||
|
|||
var mergedSettings = new Dictionary<string, SettingDefinition>(); |
|||
|
|||
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 |
|||
|
|||
@ -1,104 +0,0 @@ |
|||
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<TemplateDefinition?> 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<IReadOnlyList<TemplateDefinition>> GetAllAsync() |
|||
{ |
|||
var staticTemplates = await StaticStore.GetAllAsync(); |
|||
var dynamicTemplates = await DynamicStore.GetAllAsync(); |
|||
|
|||
var mergedTemplates = new Dictionary<string, TemplateDefinition>(); |
|||
|
|||
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 |
|||
@ -1,277 +0,0 @@ |
|||
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<FeatureDefinition?> 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<IReadOnlyList<FeatureDefinition>> GetAllAsync() |
|||
{ |
|||
var staticFeatures = await StaticStore.GetFeaturesAsync(); |
|||
var dynamicFeatures = await DynamicStore.GetFeaturesAsync(); |
|||
|
|||
var mergedFeatures = new Dictionary<string, FeatureDefinition>(); |
|||
|
|||
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<IReadOnlyList<FeatureGroupDefinition>> GetGroupsAsync() |
|||
{ |
|||
var staticGroups = await StaticStore.GetGroupsAsync(); |
|||
var dynamicGroups = await DynamicStore.GetGroupsAsync(); |
|||
|
|||
var mergedGroups = new Dictionary<string, FeatureGroupDefinition>(); |
|||
|
|||
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<FeatureDefinition> 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 |
|||
@ -1,276 +0,0 @@ |
|||
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<PermissionDefinition?> 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<PermissionDefinition?> 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<IReadOnlyList<PermissionDefinition>> GetPermissionsAsync() |
|||
{ |
|||
var staticPermissions = await _staticStore.GetPermissionsAsync(); |
|||
var dynamicPermissions = await _dynamicStore.GetPermissionsAsync(); |
|||
|
|||
return MergePermissions(staticPermissions, dynamicPermissions); |
|||
} |
|||
|
|||
public async override Task<IReadOnlyList<PermissionDefinition>> GetResourcePermissionsAsync() |
|||
{ |
|||
var staticPermissions = await _staticStore.GetResourcePermissionsAsync(); |
|||
var dynamicPermissions = await _dynamicStore.GetResourcePermissionsAsync(); |
|||
|
|||
return MergePermissions(staticPermissions, dynamicPermissions); |
|||
} |
|||
|
|||
public async override Task<IReadOnlyList<PermissionGroupDefinition>> GetGroupsAsync() |
|||
{ |
|||
var staticGroups = await _staticStore.GetGroupsAsync(); |
|||
var dynamicGroups = await _dynamicStore.GetGroupsAsync(); |
|||
|
|||
var mergedGroups = new Dictionary<string, PermissionGroupDefinition>(); |
|||
|
|||
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<PermissionDefinition> MergePermissions(IReadOnlyList<PermissionDefinition> staticPermissions, IReadOnlyList<PermissionDefinition> dynamicPermissions) |
|||
{ |
|||
var mergedPermissions = new Dictionary<string, PermissionDefinition>(); |
|||
|
|||
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 |
|||
@ -1,86 +0,0 @@ |
|||
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<SettingDefinition?> 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<IReadOnlyList<SettingDefinition>> GetAllAsync() |
|||
{ |
|||
var staticSettings = await StaticStore.GetAllAsync(); |
|||
var dynamicSettings = await DynamicStore.GetAllAsync(); |
|||
|
|||
var mergedSettings = new Dictionary<string, SettingDefinition>(); |
|||
|
|||
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 |
|||
|
|||
@ -1,104 +0,0 @@ |
|||
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<TemplateDefinition?> 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<IReadOnlyList<TemplateDefinition>> GetAllAsync() |
|||
{ |
|||
var staticTemplates = await StaticStore.GetAllAsync(); |
|||
var dynamicTemplates = await DynamicStore.GetAllAsync(); |
|||
|
|||
var mergedTemplates = new Dictionary<string, TemplateDefinition>(); |
|||
|
|||
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 |
|||
@ -1,277 +0,0 @@ |
|||
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<FeatureDefinition?> 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<IReadOnlyList<FeatureDefinition>> GetAllAsync() |
|||
{ |
|||
var staticFeatures = await StaticStore.GetFeaturesAsync(); |
|||
var dynamicFeatures = await DynamicStore.GetFeaturesAsync(); |
|||
|
|||
var mergedFeatures = new Dictionary<string, FeatureDefinition>(); |
|||
|
|||
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<IReadOnlyList<FeatureGroupDefinition>> GetGroupsAsync() |
|||
{ |
|||
var staticGroups = await StaticStore.GetGroupsAsync(); |
|||
var dynamicGroups = await DynamicStore.GetGroupsAsync(); |
|||
|
|||
var mergedGroups = new Dictionary<string, FeatureGroupDefinition>(); |
|||
|
|||
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<FeatureDefinition> 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 |
|||
@ -1,276 +0,0 @@ |
|||
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<PermissionDefinition?> 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<PermissionDefinition?> 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<IReadOnlyList<PermissionDefinition>> GetPermissionsAsync() |
|||
{ |
|||
var staticPermissions = await _staticStore.GetPermissionsAsync(); |
|||
var dynamicPermissions = await _dynamicStore.GetPermissionsAsync(); |
|||
|
|||
return MergePermissions(staticPermissions, dynamicPermissions); |
|||
} |
|||
|
|||
public async override Task<IReadOnlyList<PermissionDefinition>> GetResourcePermissionsAsync() |
|||
{ |
|||
var staticPermissions = await _staticStore.GetResourcePermissionsAsync(); |
|||
var dynamicPermissions = await _dynamicStore.GetResourcePermissionsAsync(); |
|||
|
|||
return MergePermissions(staticPermissions, dynamicPermissions); |
|||
} |
|||
|
|||
public async override Task<IReadOnlyList<PermissionGroupDefinition>> GetGroupsAsync() |
|||
{ |
|||
var staticGroups = await _staticStore.GetGroupsAsync(); |
|||
var dynamicGroups = await _dynamicStore.GetGroupsAsync(); |
|||
|
|||
var mergedGroups = new Dictionary<string, PermissionGroupDefinition>(); |
|||
|
|||
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<PermissionDefinition> MergePermissions(IReadOnlyList<PermissionDefinition> staticPermissions, IReadOnlyList<PermissionDefinition> dynamicPermissions) |
|||
{ |
|||
var mergedPermissions = new Dictionary<string, PermissionDefinition>(); |
|||
|
|||
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 |
|||
@ -1,86 +0,0 @@ |
|||
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<SettingDefinition?> 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<IReadOnlyList<SettingDefinition>> GetAllAsync() |
|||
{ |
|||
var staticSettings = await StaticStore.GetAllAsync(); |
|||
var dynamicSettings = await DynamicStore.GetAllAsync(); |
|||
|
|||
var mergedSettings = new Dictionary<string, SettingDefinition>(); |
|||
|
|||
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 |
|||
|
|||
@ -1,104 +0,0 @@ |
|||
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<TemplateDefinition?> 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<IReadOnlyList<TemplateDefinition>> GetAllAsync() |
|||
{ |
|||
var staticTemplates = await StaticStore.GetAllAsync(); |
|||
var dynamicTemplates = await DynamicStore.GetAllAsync(); |
|||
|
|||
var mergedTemplates = new Dictionary<string, TemplateDefinition>(); |
|||
|
|||
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 |
|||
@ -1,277 +0,0 @@ |
|||
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<FeatureDefinition?> 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<IReadOnlyList<FeatureDefinition>> GetAllAsync() |
|||
{ |
|||
var staticFeatures = await StaticStore.GetFeaturesAsync(); |
|||
var dynamicFeatures = await DynamicStore.GetFeaturesAsync(); |
|||
|
|||
var mergedFeatures = new Dictionary<string, FeatureDefinition>(); |
|||
|
|||
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<IReadOnlyList<FeatureGroupDefinition>> GetGroupsAsync() |
|||
{ |
|||
var staticGroups = await StaticStore.GetGroupsAsync(); |
|||
var dynamicGroups = await DynamicStore.GetGroupsAsync(); |
|||
|
|||
var mergedGroups = new Dictionary<string, FeatureGroupDefinition>(); |
|||
|
|||
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<FeatureDefinition> 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 |
|||
@ -1,276 +0,0 @@ |
|||
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<PermissionDefinition?> 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<PermissionDefinition?> 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<IReadOnlyList<PermissionDefinition>> GetPermissionsAsync() |
|||
{ |
|||
var staticPermissions = await _staticStore.GetPermissionsAsync(); |
|||
var dynamicPermissions = await _dynamicStore.GetPermissionsAsync(); |
|||
|
|||
return MergePermissions(staticPermissions, dynamicPermissions); |
|||
} |
|||
|
|||
public async override Task<IReadOnlyList<PermissionDefinition>> GetResourcePermissionsAsync() |
|||
{ |
|||
var staticPermissions = await _staticStore.GetResourcePermissionsAsync(); |
|||
var dynamicPermissions = await _dynamicStore.GetResourcePermissionsAsync(); |
|||
|
|||
return MergePermissions(staticPermissions, dynamicPermissions); |
|||
} |
|||
|
|||
public async override Task<IReadOnlyList<PermissionGroupDefinition>> GetGroupsAsync() |
|||
{ |
|||
var staticGroups = await _staticStore.GetGroupsAsync(); |
|||
var dynamicGroups = await _dynamicStore.GetGroupsAsync(); |
|||
|
|||
var mergedGroups = new Dictionary<string, PermissionGroupDefinition>(); |
|||
|
|||
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<PermissionDefinition> MergePermissions(IReadOnlyList<PermissionDefinition> staticPermissions, IReadOnlyList<PermissionDefinition> dynamicPermissions) |
|||
{ |
|||
var mergedPermissions = new Dictionary<string, PermissionDefinition>(); |
|||
|
|||
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 |
|||
@ -1,86 +0,0 @@ |
|||
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<SettingDefinition?> 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<IReadOnlyList<SettingDefinition>> GetAllAsync() |
|||
{ |
|||
var staticSettings = await StaticStore.GetAllAsync(); |
|||
var dynamicSettings = await DynamicStore.GetAllAsync(); |
|||
|
|||
var mergedSettings = new Dictionary<string, SettingDefinition>(); |
|||
|
|||
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 |
|||
|
|||
@ -1,104 +0,0 @@ |
|||
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<TemplateDefinition?> 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<IReadOnlyList<TemplateDefinition>> GetAllAsync() |
|||
{ |
|||
var staticTemplates = await StaticStore.GetAllAsync(); |
|||
var dynamicTemplates = await DynamicStore.GetAllAsync(); |
|||
|
|||
var mergedTemplates = new Dictionary<string, TemplateDefinition>(); |
|||
|
|||
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 |
|||
@ -1,277 +0,0 @@ |
|||
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<FeatureDefinition?> 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<IReadOnlyList<FeatureDefinition>> GetAllAsync() |
|||
{ |
|||
var staticFeatures = await StaticStore.GetFeaturesAsync(); |
|||
var dynamicFeatures = await DynamicStore.GetFeaturesAsync(); |
|||
|
|||
var mergedFeatures = new Dictionary<string, FeatureDefinition>(); |
|||
|
|||
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<IReadOnlyList<FeatureGroupDefinition>> GetGroupsAsync() |
|||
{ |
|||
var staticGroups = await StaticStore.GetGroupsAsync(); |
|||
var dynamicGroups = await DynamicStore.GetGroupsAsync(); |
|||
|
|||
var mergedGroups = new Dictionary<string, FeatureGroupDefinition>(); |
|||
|
|||
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<FeatureDefinition> 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 |
|||
@ -1,276 +0,0 @@ |
|||
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<PermissionDefinition?> 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<PermissionDefinition?> 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<IReadOnlyList<PermissionDefinition>> GetPermissionsAsync() |
|||
{ |
|||
var staticPermissions = await _staticStore.GetPermissionsAsync(); |
|||
var dynamicPermissions = await _dynamicStore.GetPermissionsAsync(); |
|||
|
|||
return MergePermissions(staticPermissions, dynamicPermissions); |
|||
} |
|||
|
|||
public async override Task<IReadOnlyList<PermissionDefinition>> GetResourcePermissionsAsync() |
|||
{ |
|||
var staticPermissions = await _staticStore.GetResourcePermissionsAsync(); |
|||
var dynamicPermissions = await _dynamicStore.GetResourcePermissionsAsync(); |
|||
|
|||
return MergePermissions(staticPermissions, dynamicPermissions); |
|||
} |
|||
|
|||
public async override Task<IReadOnlyList<PermissionGroupDefinition>> GetGroupsAsync() |
|||
{ |
|||
var staticGroups = await _staticStore.GetGroupsAsync(); |
|||
var dynamicGroups = await _dynamicStore.GetGroupsAsync(); |
|||
|
|||
var mergedGroups = new Dictionary<string, PermissionGroupDefinition>(); |
|||
|
|||
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<PermissionDefinition> MergePermissions(IReadOnlyList<PermissionDefinition> staticPermissions, IReadOnlyList<PermissionDefinition> dynamicPermissions) |
|||
{ |
|||
var mergedPermissions = new Dictionary<string, PermissionDefinition>(); |
|||
|
|||
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 |
|||
@ -1,86 +0,0 @@ |
|||
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<SettingDefinition?> 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<IReadOnlyList<SettingDefinition>> GetAllAsync() |
|||
{ |
|||
var staticSettings = await StaticStore.GetAllAsync(); |
|||
var dynamicSettings = await DynamicStore.GetAllAsync(); |
|||
|
|||
var mergedSettings = new Dictionary<string, SettingDefinition>(); |
|||
|
|||
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 |
|||
|
|||
@ -1,104 +0,0 @@ |
|||
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<TemplateDefinition?> 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<IReadOnlyList<TemplateDefinition>> GetAllAsync() |
|||
{ |
|||
var staticTemplates = await StaticStore.GetAllAsync(); |
|||
var dynamicTemplates = await DynamicStore.GetAllAsync(); |
|||
|
|||
var mergedTemplates = new Dictionary<string, TemplateDefinition>(); |
|||
|
|||
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 |
|||
@ -1,277 +0,0 @@ |
|||
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<FeatureDefinition?> 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<IReadOnlyList<FeatureDefinition>> GetAllAsync() |
|||
{ |
|||
var staticFeatures = await StaticStore.GetFeaturesAsync(); |
|||
var dynamicFeatures = await DynamicStore.GetFeaturesAsync(); |
|||
|
|||
var mergedFeatures = new Dictionary<string, FeatureDefinition>(); |
|||
|
|||
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<IReadOnlyList<FeatureGroupDefinition>> GetGroupsAsync() |
|||
{ |
|||
var staticGroups = await StaticStore.GetGroupsAsync(); |
|||
var dynamicGroups = await DynamicStore.GetGroupsAsync(); |
|||
|
|||
var mergedGroups = new Dictionary<string, FeatureGroupDefinition>(); |
|||
|
|||
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<FeatureDefinition> 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 |
|||
@ -1,276 +0,0 @@ |
|||
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<PermissionDefinition?> 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<PermissionDefinition?> 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<IReadOnlyList<PermissionDefinition>> GetPermissionsAsync() |
|||
{ |
|||
var staticPermissions = await _staticStore.GetPermissionsAsync(); |
|||
var dynamicPermissions = await _dynamicStore.GetPermissionsAsync(); |
|||
|
|||
return MergePermissions(staticPermissions, dynamicPermissions); |
|||
} |
|||
|
|||
public async override Task<IReadOnlyList<PermissionDefinition>> GetResourcePermissionsAsync() |
|||
{ |
|||
var staticPermissions = await _staticStore.GetResourcePermissionsAsync(); |
|||
var dynamicPermissions = await _dynamicStore.GetResourcePermissionsAsync(); |
|||
|
|||
return MergePermissions(staticPermissions, dynamicPermissions); |
|||
} |
|||
|
|||
public async override Task<IReadOnlyList<PermissionGroupDefinition>> GetGroupsAsync() |
|||
{ |
|||
var staticGroups = await _staticStore.GetGroupsAsync(); |
|||
var dynamicGroups = await _dynamicStore.GetGroupsAsync(); |
|||
|
|||
var mergedGroups = new Dictionary<string, PermissionGroupDefinition>(); |
|||
|
|||
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<PermissionDefinition> MergePermissions(IReadOnlyList<PermissionDefinition> staticPermissions, IReadOnlyList<PermissionDefinition> dynamicPermissions) |
|||
{ |
|||
var mergedPermissions = new Dictionary<string, PermissionDefinition>(); |
|||
|
|||
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 |
|||
@ -1,86 +0,0 @@ |
|||
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<SettingDefinition?> 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<IReadOnlyList<SettingDefinition>> GetAllAsync() |
|||
{ |
|||
var staticSettings = await StaticStore.GetAllAsync(); |
|||
var dynamicSettings = await DynamicStore.GetAllAsync(); |
|||
|
|||
var mergedSettings = new Dictionary<string, SettingDefinition>(); |
|||
|
|||
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 |
|||
|
|||
@ -1,104 +0,0 @@ |
|||
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<TemplateDefinition?> 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<IReadOnlyList<TemplateDefinition>> GetAllAsync() |
|||
{ |
|||
var staticTemplates = await StaticStore.GetAllAsync(); |
|||
var dynamicTemplates = await DynamicStore.GetAllAsync(); |
|||
|
|||
var mergedTemplates = new Dictionary<string, TemplateDefinition>(); |
|||
|
|||
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 |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -0,0 +1,20 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFrameworks>netstandard2.0;netstandard2.1;net8.0;net9.0;net10.0</TargetFrameworks> |
|||
<AssemblyName>LINGYUN.Abp.Dynamic.Definitions.Core</AssemblyName> |
|||
<PackageId>LINGYUN.Abp.Dynamic.Definitions.Core</PackageId> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.Core" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,8 @@ |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.Dynamic.Definitions; |
|||
|
|||
public class AbpDynamicDefinitionsCoreModule : AbpModule |
|||
{ |
|||
|
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
|
|||
namespace LINGYUN.Abp.Dynamic.Definitions; |
|||
|
|||
public class AbpDynamicDefinitionsOptions |
|||
{ |
|||
public DynamicDefinitionStrategy DefaultStrategy { get; set; } |
|||
public Dictionary<Type, DynamicDefinitionStrategy> DefinitionStrategy { get; set; } |
|||
public AbpDynamicDefinitionsOptions() |
|||
{ |
|||
DefaultStrategy = DynamicDefinitionStrategy.Static; |
|||
DefinitionStrategy = new Dictionary<Type, DynamicDefinitionStrategy>(); |
|||
} |
|||
|
|||
public void MapStrategy<T>(DynamicDefinitionStrategy strategy = DynamicDefinitionStrategy.Static) |
|||
{ |
|||
DefinitionStrategy[typeof(T)] = strategy; |
|||
} |
|||
|
|||
public DynamicDefinitionStrategy GetStrategy<T>() |
|||
{ |
|||
return GetStrategy(typeof(T)); |
|||
} |
|||
|
|||
public DynamicDefinitionStrategy GetStrategy(Type type) |
|||
{ |
|||
if (DefinitionStrategy.TryGetValue(type, out var strategy)) |
|||
{ |
|||
return strategy; |
|||
} |
|||
|
|||
return DefaultStrategy; |
|||
} |
|||
} |
|||
@ -0,0 +1,240 @@ |
|||
using Microsoft.Extensions.Options; |
|||
using System.Collections.Generic; |
|||
using System.Collections.Immutable; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.Dynamic.Definitions; |
|||
|
|||
public abstract class DynamicDefinitionManager<TGroupDefinition, TDefinition> : DynamicDefinitionManager<TDefinition> |
|||
{ |
|||
protected DynamicDefinitionManager( |
|||
IOptions<AbpDynamicDefinitionsOptions> options) : base(options) |
|||
{ |
|||
} |
|||
|
|||
public async virtual Task<TGroupDefinition?> GetGroupDefinitionAsync( |
|||
TGroupDefinition? staticGroupDefinition, |
|||
TGroupDefinition? dynamicGroupDefinition) |
|||
{ |
|||
if (staticGroupDefinition != null && dynamicGroupDefinition != null) |
|||
{ |
|||
var strategy = Options.GetStrategy<TGroupDefinition>(); |
|||
switch (strategy) |
|||
{ |
|||
case DynamicDefinitionStrategy.Dynamic: |
|||
return dynamicGroupDefinition; |
|||
case DynamicDefinitionStrategy.Merge: |
|||
await MergeGroupDefinitionAsync(staticGroupDefinition, dynamicGroupDefinition); |
|||
return staticGroupDefinition; |
|||
case DynamicDefinitionStrategy.Static: |
|||
default: |
|||
return staticGroupDefinition; |
|||
} |
|||
} |
|||
|
|||
return staticGroupDefinition ?? dynamicGroupDefinition; |
|||
} |
|||
|
|||
public async virtual Task<IReadOnlyList<TGroupDefinition>> GetGroupDefinitionsAsync( |
|||
IReadOnlyList<TGroupDefinition> staticGroupDefinitions, |
|||
IReadOnlyList<TGroupDefinition> dynamicGroupDefinitions) |
|||
{ |
|||
var strategy = Options.GetStrategy<TGroupDefinition>(); |
|||
return strategy switch |
|||
{ |
|||
DynamicDefinitionStrategy.Dynamic => await GetDynamicGroupDefinitionsAsync(staticGroupDefinitions, dynamicGroupDefinitions), |
|||
DynamicDefinitionStrategy.Merge => await GetMergedGroupDefinitionsAsync(staticGroupDefinitions, dynamicGroupDefinitions), |
|||
_ => await GetStaticGroupDefinitionsAsync(staticGroupDefinitions, dynamicGroupDefinitions), |
|||
}; |
|||
} |
|||
|
|||
protected virtual Task<IReadOnlyList<TGroupDefinition>> GetStaticGroupDefinitionsAsync( |
|||
IReadOnlyList<TGroupDefinition> staticGroupDefinitions, |
|||
IReadOnlyList<TGroupDefinition> dynamicGroupDefinitions) |
|||
{ |
|||
var staticDefinitionKeys = staticGroupDefinitions |
|||
.Select(GetGroupDefinitionKey) |
|||
.ToImmutableHashSet(); |
|||
|
|||
return Task.FromResult<IReadOnlyList<TGroupDefinition>>( |
|||
staticGroupDefinitions |
|||
.Concat(dynamicGroupDefinitions.Where(d => !staticDefinitionKeys.Contains(GetGroupDefinitionKey(d)))) |
|||
.ToImmutableList() |
|||
); |
|||
} |
|||
|
|||
protected virtual Task<IReadOnlyList<TGroupDefinition>> GetDynamicGroupDefinitionsAsync( |
|||
IReadOnlyList<TGroupDefinition> staticGroupDefinitions, |
|||
IReadOnlyList<TGroupDefinition> dynamicGroupDefinitions) |
|||
{ |
|||
var dynamicDefinitionKeys = dynamicGroupDefinitions |
|||
.Select(GetGroupDefinitionKey) |
|||
.ToImmutableHashSet(); |
|||
|
|||
return Task.FromResult<IReadOnlyList<TGroupDefinition>>( |
|||
dynamicGroupDefinitions |
|||
.Concat(staticGroupDefinitions.Where(s => !dynamicDefinitionKeys.Contains(GetGroupDefinitionKey(s)))) |
|||
.ToImmutableList() |
|||
); |
|||
} |
|||
|
|||
protected async virtual Task<IReadOnlyList<TGroupDefinition>> GetMergedGroupDefinitionsAsync( |
|||
IReadOnlyList<TGroupDefinition> staticGroupDefinitions, |
|||
IReadOnlyList<TGroupDefinition> dynamicGroupDefinitions) |
|||
{ |
|||
var mergedGroups = new Dictionary<string, TGroupDefinition>(); |
|||
|
|||
foreach (var staticGroup in staticGroupDefinitions) |
|||
{ |
|||
mergedGroups[GetGroupDefinitionKey(staticGroup)] = staticGroup; |
|||
} |
|||
|
|||
foreach (var dynamicGroup in dynamicGroupDefinitions) |
|||
{ |
|||
if (mergedGroups.TryGetValue(GetGroupDefinitionKey(dynamicGroup), out var existingGroup)) |
|||
{ |
|||
await BeforeMergeGroupDefinitionAsync(existingGroup, dynamicGroup); |
|||
await MergeGroupDefinitionAsync(existingGroup, dynamicGroup); |
|||
await AfterMergeGroupDefinitionAsync(existingGroup, dynamicGroup); |
|||
} |
|||
else |
|||
{ |
|||
mergedGroups[GetGroupDefinitionKey(dynamicGroup)] = dynamicGroup; |
|||
} |
|||
} |
|||
|
|||
await AfterMergedGroupDefinitionsAsync(mergedGroups); |
|||
|
|||
return mergedGroups.Values.ToImmutableList(); |
|||
} |
|||
|
|||
protected abstract string GetGroupDefinitionKey(TGroupDefinition groupDefinition); |
|||
|
|||
protected abstract Task MergeGroupDefinitionAsync(TGroupDefinition targetGroupDefinition, TGroupDefinition sourceGroupDefinition); |
|||
|
|||
protected virtual Task BeforeMergeGroupDefinitionAsync(TGroupDefinition targetGroupDefinition, TGroupDefinition sourceGroupDefinition) |
|||
{ |
|||
return Task.CompletedTask; |
|||
} |
|||
|
|||
protected virtual Task AfterMergeGroupDefinitionAsync(TGroupDefinition targetGroupDefinition, TGroupDefinition sourceGroupDefinition) |
|||
{ |
|||
return Task.CompletedTask; |
|||
} |
|||
|
|||
protected virtual Task AfterMergedGroupDefinitionsAsync(Dictionary<string, TGroupDefinition> mergedDefinitions) |
|||
{ |
|||
return Task.CompletedTask; |
|||
} |
|||
} |
|||
|
|||
public abstract class DynamicDefinitionManager<TDefinition> |
|||
{ |
|||
protected AbpDynamicDefinitionsOptions Options { get; } |
|||
protected DynamicDefinitionManager(IOptions<AbpDynamicDefinitionsOptions> options) |
|||
{ |
|||
Options = options.Value; |
|||
} |
|||
|
|||
public async virtual Task<TDefinition?> GetDefinitionAsync(TDefinition? staticDefinition, TDefinition? dynamicDefinition) |
|||
{ |
|||
if (staticDefinition != null && dynamicDefinition != null) |
|||
{ |
|||
var strategy = Options.GetStrategy<TDefinition>(); |
|||
return strategy switch |
|||
{ |
|||
DynamicDefinitionStrategy.Static => staticDefinition, |
|||
DynamicDefinitionStrategy.Dynamic => dynamicDefinition, |
|||
DynamicDefinitionStrategy.Merge => await MergeDefinitionAsync(staticDefinition, dynamicDefinition), |
|||
_ => staticDefinition |
|||
}; |
|||
} |
|||
|
|||
return staticDefinition ?? dynamicDefinition; |
|||
} |
|||
|
|||
public async virtual Task<IReadOnlyList<TDefinition>> GetDefinitionsAsync(IReadOnlyList<TDefinition> staticDefinitions, IReadOnlyList<TDefinition> dynamicDefinitions) |
|||
{ |
|||
var strategy = Options.GetStrategy<TDefinition>(); |
|||
return strategy switch |
|||
{ |
|||
DynamicDefinitionStrategy.Dynamic => await GetDynamicDefinitionsAsync(staticDefinitions, dynamicDefinitions), |
|||
DynamicDefinitionStrategy.Merge => await GetMergedDefinitionsAsync(staticDefinitions, dynamicDefinitions), |
|||
_ => await GetStaticDefinitionsAsync(staticDefinitions, dynamicDefinitions), |
|||
}; |
|||
} |
|||
|
|||
protected virtual Task<IReadOnlyList<TDefinition>> GetStaticDefinitionsAsync(IReadOnlyList<TDefinition> staticDefinitions, IReadOnlyList<TDefinition> dynamicDefinitions) |
|||
{ |
|||
var staticDefinitionKeys = staticDefinitions |
|||
.Select(GetDefinitionKey) |
|||
.ToImmutableHashSet(); |
|||
|
|||
return Task.FromResult<IReadOnlyList<TDefinition>>( |
|||
staticDefinitions |
|||
.Concat(dynamicDefinitions.Where(d => !staticDefinitionKeys.Contains(GetDefinitionKey(d)))) |
|||
.ToImmutableList() |
|||
); |
|||
} |
|||
|
|||
protected virtual Task<IReadOnlyList<TDefinition>> GetDynamicDefinitionsAsync(IReadOnlyList<TDefinition> staticDefinitions, IReadOnlyList<TDefinition> dynamicDefinitions) |
|||
{ |
|||
var dynamicDefinitionKeys = dynamicDefinitions |
|||
.Select(GetDefinitionKey) |
|||
.ToImmutableHashSet(); |
|||
|
|||
return Task.FromResult<IReadOnlyList<TDefinition>>( |
|||
dynamicDefinitions |
|||
.Concat(staticDefinitions.Where(s => !dynamicDefinitionKeys.Contains(GetDefinitionKey(s)))) |
|||
.ToImmutableList() |
|||
); |
|||
} |
|||
|
|||
protected async virtual Task<IReadOnlyList<TDefinition>> GetMergedDefinitionsAsync(IReadOnlyList<TDefinition> staticDefinitions, IReadOnlyList<TDefinition> dynamicDefinitions) |
|||
{ |
|||
var mergedDefinitions = new Dictionary<string, TDefinition>(); |
|||
|
|||
foreach (var staticDefinition in staticDefinitions) |
|||
{ |
|||
mergedDefinitions[GetDefinitionKey(staticDefinition)] = staticDefinition; |
|||
} |
|||
|
|||
foreach (var dynamicDefinition in dynamicDefinitions) |
|||
{ |
|||
if (mergedDefinitions.TryGetValue(GetDefinitionKey(dynamicDefinition), out var existingDefinition)) |
|||
{ |
|||
await BeforeMergeDefinitionAsync(existingDefinition, dynamicDefinition); |
|||
await MergeDefinitionAsync(existingDefinition, dynamicDefinition); |
|||
await AfterMergeDefinitionAsync(existingDefinition, dynamicDefinition); |
|||
} |
|||
else |
|||
{ |
|||
mergedDefinitions[GetDefinitionKey(dynamicDefinition)] = dynamicDefinition; |
|||
} |
|||
} |
|||
|
|||
await AfterMergedDefinitionsAsync(mergedDefinitions); |
|||
|
|||
return mergedDefinitions.Values.ToImmutableList(); |
|||
} |
|||
|
|||
protected abstract string GetDefinitionKey(TDefinition definition); |
|||
|
|||
protected abstract Task<TDefinition> MergeDefinitionAsync(TDefinition targetDefinition, TDefinition sourceDefinition); |
|||
|
|||
protected virtual Task BeforeMergeDefinitionAsync(TDefinition targetDefinition, TDefinition sourceDefinition) |
|||
{ |
|||
return Task.CompletedTask; |
|||
} |
|||
|
|||
protected virtual Task AfterMergeDefinitionAsync(TDefinition targetDefinition, TDefinition sourceDefinition) |
|||
{ |
|||
return Task.CompletedTask; |
|||
} |
|||
|
|||
protected virtual Task AfterMergedDefinitionsAsync(Dictionary<string, TDefinition> mergedDefinitions) |
|||
{ |
|||
return Task.CompletedTask; |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
namespace LINGYUN.Abp.Dynamic.Definitions; |
|||
|
|||
public enum DynamicDefinitionStrategy |
|||
{ |
|||
Static = 0, |
|||
Dynamic = 1, |
|||
Merge = 2, |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -0,0 +1,27 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFrameworks>netstandard2.0;netstandard2.1;net8.0;net9.0;net10.0</TargetFrameworks> |
|||
<AssemblyName>LINGYUN.Abp.Dynamic.Definitions</AssemblyName> |
|||
<PackageId>LINGYUN.Abp.Dynamic.Definitions</PackageId> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.Authorization" /> |
|||
<PackageReference Include="Volo.Abp.Features" /> |
|||
<PackageReference Include="Volo.Abp.Settings" /> |
|||
<PackageReference Include="Volo.Abp.TextTemplating.Core" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\LINGYUN.Abp.Dynamic.Definitions.Core\LINGYUN.Abp.Dynamic.Definitions.Core.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,32 @@ |
|||
using Volo.Abp.Authorization; |
|||
using Volo.Abp.Authorization.Permissions; |
|||
using Volo.Abp.Features; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.Settings; |
|||
using Volo.Abp.TextTemplating; |
|||
|
|||
namespace LINGYUN.Abp.Dynamic.Definitions; |
|||
|
|||
[DependsOn( |
|||
typeof(AbpFeaturesModule), |
|||
typeof(AbpAuthorizationModule), |
|||
typeof(AbpTextTemplatingCoreModule), |
|||
typeof(AbpDynamicDefinitionsCoreModule))] |
|||
public class AbpDynamicDefinitionsModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpDynamicDefinitionsOptions>(options => |
|||
{ |
|||
options.MapStrategy<FeatureDefinition>(DynamicDefinitionStrategy.Merge); |
|||
options.MapStrategy<FeatureGroupDefinition>(DynamicDefinitionStrategy.Merge); |
|||
|
|||
options.MapStrategy<PermissionDefinition>(DynamicDefinitionStrategy.Merge); |
|||
options.MapStrategy<PermissionGroupDefinition>(DynamicDefinitionStrategy.Merge); |
|||
|
|||
options.MapStrategy<SettingDefinition>(DynamicDefinitionStrategy.Merge); |
|||
|
|||
options.MapStrategy<TemplateDefinition>(DynamicDefinitionStrategy.Merge); |
|||
}); |
|||
} |
|||
} |
|||
@ -0,0 +1,253 @@ |
|||
using JetBrains.Annotations; |
|||
using Microsoft.Extensions.Options; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Features; |
|||
|
|||
namespace LINGYUN.Abp.Dynamic.Definitions; |
|||
|
|||
[Dependency(ReplaceServices = true)] |
|||
[ExposeServices( |
|||
typeof(IFeatureDefinitionManager), |
|||
typeof(FeatureDynamicDefinitionManager))] |
|||
public class FeatureDynamicDefinitionManager : |
|||
DynamicDefinitionManager<FeatureGroupDefinition, FeatureDefinition>, |
|||
IFeatureDefinitionManager, |
|||
ISingletonDependency |
|||
{ |
|||
protected IStaticFeatureDefinitionStore StaticStore { get; } |
|||
protected IDynamicFeatureDefinitionStore DynamicStore { get; } |
|||
public FeatureDynamicDefinitionManager( |
|||
IStaticFeatureDefinitionStore staticStore, |
|||
IDynamicFeatureDefinitionStore dynamicStore, |
|||
IOptions<AbpDynamicDefinitionsOptions> options) |
|||
: base(options) |
|||
{ |
|||
StaticStore = staticStore; |
|||
DynamicStore = dynamicStore; |
|||
} |
|||
|
|||
public async virtual Task<IReadOnlyList<FeatureDefinition>> GetAllAsync() |
|||
{ |
|||
var staticDefinitions = await StaticStore.GetFeaturesAsync(); |
|||
var dynamicDefinitions = await DynamicStore.GetFeaturesAsync(); |
|||
|
|||
return await GetDefinitionsAsync(staticDefinitions, dynamicDefinitions); |
|||
} |
|||
|
|||
public async virtual Task<FeatureDefinition> GetAsync(string name) |
|||
{ |
|||
return await GetOrNullAsync(name) ?? throw new AbpException("Undefined feature: " + name); |
|||
} |
|||
|
|||
public async virtual Task<IReadOnlyList<FeatureGroupDefinition>> GetGroupsAsync() |
|||
{ |
|||
var staticGroupDefinitions = await StaticStore.GetGroupsAsync(); |
|||
var dynamicGroupDefinitions = await DynamicStore.GetGroupsAsync(); |
|||
|
|||
return await GetGroupDefinitionsAsync(staticGroupDefinitions, dynamicGroupDefinitions); |
|||
} |
|||
|
|||
public async virtual Task<FeatureDefinition?> GetOrNullAsync(string name) |
|||
{ |
|||
Check.NotNull(name, nameof(name)); |
|||
|
|||
var staticDefinition = await StaticStore.GetOrNullAsync(name); |
|||
var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); |
|||
|
|||
return await GetDefinitionAsync(staticDefinition, dynamicDefinition); |
|||
} |
|||
|
|||
protected override string GetDefinitionKey(FeatureDefinition definition) |
|||
{ |
|||
return definition.Name; |
|||
} |
|||
|
|||
protected override string GetGroupDefinitionKey(FeatureGroupDefinition groupDefinition) |
|||
{ |
|||
return groupDefinition.Name; |
|||
} |
|||
|
|||
protected override Task<FeatureDefinition> MergeDefinitionAsync(FeatureDefinition targetDefinition, FeatureDefinition sourceDefinition) |
|||
{ |
|||
targetDefinition.DisplayName = sourceDefinition.DisplayName; |
|||
|
|||
if (sourceDefinition.Description != null) |
|||
{ |
|||
targetDefinition.Description = sourceDefinition.Description; |
|||
} |
|||
|
|||
if (sourceDefinition.DefaultValue != null) |
|||
{ |
|||
targetDefinition.DefaultValue = sourceDefinition.DefaultValue; |
|||
} |
|||
|
|||
if (sourceDefinition.ValueType != null) |
|||
{ |
|||
targetDefinition.ValueType = sourceDefinition.ValueType; |
|||
} |
|||
|
|||
targetDefinition.IsVisibleToClients = targetDefinition.IsVisibleToClients || sourceDefinition.IsVisibleToClients; |
|||
targetDefinition.IsAvailableToHost = targetDefinition.IsAvailableToHost || sourceDefinition.IsAvailableToHost; |
|||
|
|||
CopyFeatureDetails(targetDefinition, sourceDefinition); |
|||
|
|||
return Task.FromResult(targetDefinition); |
|||
} |
|||
|
|||
protected async override Task AfterMergeDefinitionAsync(FeatureDefinition targetDefinition, FeatureDefinition sourceDefinition) |
|||
{ |
|||
foreach (var child in sourceDefinition.Children) |
|||
{ |
|||
await MergeChildFeature(targetDefinition, child); |
|||
} |
|||
} |
|||
|
|||
protected async override Task MergeGroupDefinitionAsync(FeatureGroupDefinition targetGroupDefinition, FeatureGroupDefinition sourceGroupDefinition) |
|||
{ |
|||
if (sourceGroupDefinition.DisplayName != null) |
|||
{ |
|||
targetGroupDefinition.DisplayName = sourceGroupDefinition.DisplayName; |
|||
} |
|||
foreach (var property in sourceGroupDefinition.Properties) |
|||
{ |
|||
targetGroupDefinition.Properties[property.Key] = property.Value; |
|||
} |
|||
|
|||
foreach (var sourceFeature in sourceGroupDefinition.Features) |
|||
{ |
|||
var existingFeature = GetFeatureOrNull(targetGroupDefinition, sourceFeature.Name); |
|||
|
|||
if (existingFeature == null) |
|||
{ |
|||
var newFeature = targetGroupDefinition.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 |
|||
{ |
|||
await MergeDefinitionAsync(existingFeature, sourceFeature); |
|||
|
|||
foreach (var child in sourceFeature.Children) |
|||
{ |
|||
await MergeChildFeature(existingFeature, child); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
private async Task 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 |
|||
{ |
|||
await MergeDefinitionAsync(existingChild, sourceChild); |
|||
|
|||
foreach (var grandchild in sourceChild.Children) |
|||
{ |
|||
await MergeChildFeature(existingChild, grandchild); |
|||
} |
|||
} |
|||
} |
|||
|
|||
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 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); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public static FeatureDefinition? GetFeatureOrNull( |
|||
FeatureGroupDefinition group, |
|||
[NotNull] string name) |
|||
{ |
|||
Check.NotNull(name, nameof(name)); |
|||
|
|||
return GetFeatureOrNullRecursively(group.Features, name); |
|||
} |
|||
|
|||
private static FeatureDefinition? GetFeatureOrNullRecursively( |
|||
IReadOnlyList<FeatureDefinition> 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; |
|||
} |
|||
} |
|||
@ -0,0 +1,249 @@ |
|||
using Microsoft.Extensions.Options; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Authorization.Permissions; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace LINGYUN.Abp.Dynamic.Definitions; |
|||
|
|||
[Dependency(ReplaceServices = true)] |
|||
[ExposeServices( |
|||
typeof(IPermissionDefinitionManager), |
|||
typeof(PermissionDynamicDefinitionManager))] |
|||
public class PermissionDynamicDefinitionManager : |
|||
DynamicDefinitionManager<PermissionGroupDefinition, PermissionDefinition>, |
|||
IPermissionDefinitionManager, |
|||
ITransientDependency |
|||
{ |
|||
protected IStaticPermissionDefinitionStore StaticStore { get; } |
|||
protected IDynamicPermissionDefinitionStore DynamicStore { get; } |
|||
public PermissionDynamicDefinitionManager( |
|||
IStaticPermissionDefinitionStore staticStore, |
|||
IDynamicPermissionDefinitionStore dynamicStore, |
|||
IOptions<AbpDynamicDefinitionsOptions> options) : base(options) |
|||
{ |
|||
StaticStore = staticStore; |
|||
DynamicStore = dynamicStore; |
|||
} |
|||
|
|||
public async virtual Task<PermissionDefinition> GetAsync(string name) |
|||
{ |
|||
return await GetOrNullAsync(name) ?? throw new AbpException("Undefined permission: " + name); |
|||
} |
|||
|
|||
public async virtual Task<IReadOnlyList<PermissionGroupDefinition>> GetGroupsAsync() |
|||
{ |
|||
var staticGroupDefinitions = await StaticStore.GetGroupsAsync(); |
|||
var dynamicGroupDefinitions = await DynamicStore.GetGroupsAsync(); |
|||
|
|||
return await GetGroupDefinitionsAsync(staticGroupDefinitions, dynamicGroupDefinitions); |
|||
} |
|||
|
|||
public async virtual Task<PermissionDefinition?> GetOrNullAsync(string name) |
|||
{ |
|||
Check.NotNull(name, nameof(name)); |
|||
|
|||
var staticDefinition = await StaticStore.GetOrNullAsync(name); |
|||
var dynamicDefinition = await DynamicStore.GetOrNullAsync(name); |
|||
|
|||
return await GetDefinitionAsync(staticDefinition, dynamicDefinition); |
|||
} |
|||
|
|||
public async virtual Task<IReadOnlyList<PermissionDefinition>> GetPermissionsAsync() |
|||
{ |
|||
var staticDefinitions = await StaticStore.GetPermissionsAsync(); |
|||
var dynamicDefinitions = await DynamicStore.GetPermissionsAsync(); |
|||
|
|||
return await GetDefinitionsAsync(staticDefinitions, dynamicDefinitions); |
|||
} |
|||
|
|||
public async virtual Task<PermissionDefinition> GetResourcePermissionAsync(string resourceName, string name) |
|||
{ |
|||
return await GetResourcePermissionOrNullAsync(resourceName, name) |
|||
?? throw new AbpException($"Undefined resource permission: {name} for resource: {resourceName}"); |
|||
} |
|||
|
|||
public async virtual Task<PermissionDefinition?> GetResourcePermissionOrNullAsync(string resourceName, string name) |
|||
{ |
|||
Check.NotNull(name, nameof(name)); |
|||
|
|||
var staticDefinition = await StaticStore.GetResourcePermissionOrNullAsync(resourceName, name); |
|||
var dynamicDefinition = await DynamicStore.GetResourcePermissionOrNullAsync(resourceName, name); |
|||
|
|||
return await GetDefinitionAsync(staticDefinition, dynamicDefinition); |
|||
} |
|||
|
|||
public async virtual Task<IReadOnlyList<PermissionDefinition>> GetResourcePermissionsAsync() |
|||
{ |
|||
var staticDefinitions = await StaticStore.GetResourcePermissionsAsync(); |
|||
var dynamicDefinitions = await DynamicStore.GetResourcePermissionsAsync(); |
|||
|
|||
return await GetDefinitionsAsync(staticDefinitions, dynamicDefinitions); |
|||
} |
|||
|
|||
protected override string GetDefinitionKey(PermissionDefinition definition) |
|||
{ |
|||
return definition.Name; |
|||
} |
|||
|
|||
protected override string GetGroupDefinitionKey(PermissionGroupDefinition groupDefinition) |
|||
{ |
|||
return groupDefinition.Name; |
|||
} |
|||
|
|||
protected override Task<PermissionDefinition> MergeDefinitionAsync(PermissionDefinition targetDefinition, PermissionDefinition sourceDefinition) |
|||
{ |
|||
targetDefinition.DisplayName = sourceDefinition.DisplayName; |
|||
if (sourceDefinition.ResourceName != null) |
|||
{ |
|||
targetDefinition.ResourceName = sourceDefinition.ResourceName; |
|||
} |
|||
if (sourceDefinition.ManagementPermissionName != null) |
|||
{ |
|||
targetDefinition.ManagementPermissionName = sourceDefinition.ManagementPermissionName; |
|||
} |
|||
|
|||
if (sourceDefinition.MultiTenancySide != MultiTenancySides.Both) |
|||
{ |
|||
targetDefinition.MultiTenancySide |= sourceDefinition.MultiTenancySide; |
|||
} |
|||
|
|||
targetDefinition.IsEnabled = targetDefinition.IsEnabled || sourceDefinition.IsEnabled; |
|||
|
|||
CopyPermissionDetails(targetDefinition, sourceDefinition); |
|||
|
|||
return Task.FromResult(targetDefinition); |
|||
} |
|||
|
|||
protected async override Task MergeGroupDefinitionAsync(PermissionGroupDefinition targetGroupDefinition, PermissionGroupDefinition sourceGroupDefinition) |
|||
{ |
|||
if (sourceGroupDefinition.DisplayName != null) |
|||
{ |
|||
targetGroupDefinition.DisplayName = sourceGroupDefinition.DisplayName; |
|||
} |
|||
foreach (var property in sourceGroupDefinition.Properties) |
|||
{ |
|||
targetGroupDefinition.Properties[property.Key] = property.Value; |
|||
} |
|||
|
|||
foreach (var sourcePermission in sourceGroupDefinition.Permissions) |
|||
{ |
|||
var existingPermission = targetGroupDefinition.GetPermissionOrNull(sourcePermission.Name); |
|||
|
|||
if (existingPermission == null) |
|||
{ |
|||
var newPermission = targetGroupDefinition.AddPermission( |
|||
sourcePermission.Name, |
|||
sourcePermission.DisplayName, |
|||
sourcePermission.MultiTenancySide, |
|||
sourcePermission.IsEnabled |
|||
); |
|||
newPermission.ResourceName = sourcePermission.ResourceName; |
|||
newPermission.ManagementPermissionName = sourcePermission.ManagementPermissionName; |
|||
|
|||
CopyPermissionDetails(sourcePermission, newPermission); |
|||
|
|||
foreach (var child in sourcePermission.Children) |
|||
{ |
|||
AddChildPermissionRecursively(newPermission, child); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
await MergeDefinitionAsync(existingPermission, sourcePermission); |
|||
|
|||
foreach (var sourceChild in sourcePermission.Children) |
|||
{ |
|||
await MergeChildPermissions(existingPermission, sourceChild); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
protected async override Task AfterMergeDefinitionAsync(PermissionDefinition targetDefinition, PermissionDefinition sourceDefinition) |
|||
{ |
|||
foreach (var child in sourceDefinition.Children) |
|||
{ |
|||
await MergeChildPermissions(targetDefinition, child); |
|||
} |
|||
} |
|||
|
|||
private async Task 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 |
|||
); |
|||
newChild.ResourceName = sourceChild.ResourceName; |
|||
newChild.ManagementPermissionName = sourceChild.ManagementPermissionName; |
|||
|
|||
CopyPermissionDetails(sourceChild, newChild); |
|||
|
|||
foreach (var grandchild in sourceChild.Children) |
|||
{ |
|||
AddChildPermissionRecursively(newChild, grandchild); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
await MergeDefinitionAsync(existingChild, sourceChild); |
|||
|
|||
foreach (var grandchild in sourceChild.Children) |
|||
{ |
|||
await MergeChildPermissions(existingChild, grandchild); |
|||
} |
|||
} |
|||
} |
|||
|
|||
private static void AddChildPermissionRecursively(PermissionDefinition parent, PermissionDefinition sourceChild) |
|||
{ |
|||
var newChild = parent.AddChild( |
|||
sourceChild.Name, |
|||
sourceChild.DisplayName, |
|||
sourceChild.MultiTenancySide, |
|||
sourceChild.IsEnabled |
|||
); |
|||
newChild.ResourceName = sourceChild.ResourceName; |
|||
newChild.ManagementPermissionName = sourceChild.ManagementPermissionName; |
|||
|
|||
CopyPermissionDetails(sourceChild, newChild); |
|||
|
|||
foreach (var grandchild in sourceChild.Children) |
|||
{ |
|||
AddChildPermissionRecursively(newChild, 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); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue