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