From 991fe6dac5e5b4664c3c069dcd1f5ead6869a201 Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 25 Jul 2024 16:06:13 +0800 Subject: [PATCH] Add `Extension Property Policy` feature. --- .../ObjectExtending/ExtensionPropertyDto.cs | 4 +- .../ExtensionPropertyFeaturePolicyDto.cs | 11 +++ ...ExtensionPropertyGlobalFeaturePolicyDto.cs | 11 +++ .../ExtensionPropertyPermissionPolicyDto.cs | 11 +++ .../ExtensionPropertyPolicyDto.cs | 24 +++++++ .../ui-extensions.js | 31 ++++++++ .../CachedObjectExtensionsDtoService.cs | 19 ++++- .../MvcExtensionPropertyPolicyChecker.cs | 37 ++++++++++ .../AbpBlazoriseUIModule.cs | 8 ++- .../Volo.Abp.BlazoriseUI/AbpCrudPageBase.cs | 20 ++++-- ...BlazoriseExtensionPropertyPolicyChecker.cs | 37 ++++++++++ .../ObjectExtending/ExtensionProperties.razor | 2 +- .../ExtensionProperties.razor.cs | 18 ++++- .../Volo.Abp.BlazoriseUI.csproj | 2 + ...nsionPropertyFeaturePolicyConfiguration.cs | 8 +++ ...ropertyGlobalFeaturePolicyConfiguration.cs | 8 +++ ...onPropertyPermissionPolicyConfiguration.cs | 8 +++ .../ExtensionPropertyPolicyChecker.cs | 70 +++++++++++++++++++ .../ExtensionPropertyPolicyConfiguration.cs | 17 +++++ .../ExtensionPropertyConfiguration.cs | 4 ++ .../ModuleExtensionConfigurationHelper.cs | 1 + .../ObjectExtensionManagerExtensions.cs | 31 ++++++++ .../ObjectExtensionPropertyInfo.cs | 5 +- .../Pages/Identity/RoleManagement.razor.cs | 6 +- .../Pages/Identity/UserManagement.razor.cs | 6 +- .../Pages/Identity/Roles/CreateModal.cshtml | 2 +- .../Pages/Identity/Roles/EditModal.cshtml | 2 +- .../Pages/Identity/Users/CreateModal.cshtml | 2 +- .../Pages/Identity/Users/EditModal.cshtml | 2 +- .../TenantManagement.razor.cs | 6 +- 30 files changed, 386 insertions(+), 27 deletions(-) create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ObjectExtending/ExtensionPropertyFeaturePolicyDto.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ObjectExtending/ExtensionPropertyGlobalFeaturePolicyDto.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ObjectExtending/ExtensionPropertyPermissionPolicyDto.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ObjectExtending/ExtensionPropertyPolicyDto.cs create mode 100644 framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/ObjectExtending/MvcExtensionPropertyPolicyChecker.cs create mode 100644 framework/src/Volo.Abp.BlazoriseUI/BlazoriseExtensionPropertyPolicyChecker.cs create mode 100644 framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensionPropertyFeaturePolicyConfiguration.cs create mode 100644 framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensionPropertyGlobalFeaturePolicyConfiguration.cs create mode 100644 framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensionPropertyPermissionPolicyConfiguration.cs create mode 100644 framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensionPropertyPolicyChecker.cs create mode 100644 framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensionPropertyPolicyConfiguration.cs diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ObjectExtending/ExtensionPropertyDto.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ObjectExtending/ExtensionPropertyDto.cs index 68a915309d..db9a968846 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ObjectExtending/ExtensionPropertyDto.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ObjectExtending/ExtensionPropertyDto.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using JetBrains.Annotations; namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending; @@ -17,6 +16,8 @@ public class ExtensionPropertyDto public ExtensionPropertyUiDto Ui { get; set; } + public ExtensionPropertyPolicyDto Policy { get; set; } + public List Attributes { get; set; } public Dictionary Configuration { get; set; } @@ -27,6 +28,7 @@ public class ExtensionPropertyDto { Api = new ExtensionPropertyApiDto(); Ui = new ExtensionPropertyUiDto(); + Policy = new ExtensionPropertyPolicyDto(); Attributes = new List(); Configuration = new Dictionary(); } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ObjectExtending/ExtensionPropertyFeaturePolicyDto.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ObjectExtending/ExtensionPropertyFeaturePolicyDto.cs new file mode 100644 index 0000000000..1e4f65d702 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ObjectExtending/ExtensionPropertyFeaturePolicyDto.cs @@ -0,0 +1,11 @@ +using System; + +namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending; + +[Serializable] +public class ExtensionPropertyFeaturePolicyDto +{ + public string[] Features { get; set; } = default!; + + public bool RequiresAll { get; set; } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ObjectExtending/ExtensionPropertyGlobalFeaturePolicyDto.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ObjectExtending/ExtensionPropertyGlobalFeaturePolicyDto.cs new file mode 100644 index 0000000000..80b8430257 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ObjectExtending/ExtensionPropertyGlobalFeaturePolicyDto.cs @@ -0,0 +1,11 @@ +using System; + +namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending; + +[Serializable] +public class ExtensionPropertyGlobalFeaturePolicyDto +{ + public string[] Features { get; set; } = default!; + + public bool RequiresAll { get; set; } = default!; +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ObjectExtending/ExtensionPropertyPermissionPolicyDto.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ObjectExtending/ExtensionPropertyPermissionPolicyDto.cs new file mode 100644 index 0000000000..55f3199f0d --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ObjectExtending/ExtensionPropertyPermissionPolicyDto.cs @@ -0,0 +1,11 @@ +using System; + +namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending; + +[Serializable] +public class ExtensionPropertyPermissionPolicyDto +{ + public string[] PermissionNames { get; set; } = default!; + + public bool RequiresAll { get; set; } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ObjectExtending/ExtensionPropertyPolicyDto.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ObjectExtending/ExtensionPropertyPolicyDto.cs new file mode 100644 index 0000000000..37bf1d3404 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ObjectExtending/ExtensionPropertyPolicyDto.cs @@ -0,0 +1,24 @@ +using System; +using JetBrains.Annotations; + +namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ObjectExtending; + +[Serializable] +public class ExtensionPropertyPolicyDto +{ + [NotNull] + public ExtensionPropertyGlobalFeaturePolicyDto GlobalFeatures { get; set; } + + [NotNull] + public ExtensionPropertyFeaturePolicyDto Features { get; set; } + + [NotNull] + public ExtensionPropertyPermissionPolicyDto Permissions { get; set; } + + public ExtensionPropertyPolicyDto() + { + GlobalFeatures = new ExtensionPropertyGlobalFeaturePolicyDto(); + Features = new ExtensionPropertyFeaturePolicyDto(); + Permissions = new ExtensionPropertyPermissionPolicyDto(); + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/ui-extensions.js b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/ui-extensions.js index 0433ed22ad..793ca61113 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/ui-extensions.js +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/ui-extensions.js @@ -187,6 +187,14 @@ var abp = abp || {}; for (var i = 0; i < propertyNames.length; i++) { var propertyName = propertyNames[i]; var propertyConfig = objectConfig.properties[propertyName]; + + var policy = propertyConfig.policy; + if (!checkPolicy(policy.globalFeatures.features, policy.globalFeatures.requiresAll, abp.features.isEnabled) || + !checkPolicy(policy.features.features, policy.features.requiresAll, abp.features.isEnabled) || + !checkPolicy(policy.permissions.permissionNames, policy.permissions.requiresAll, abp.auth.isGranted)) { + continue; + } + if (propertyConfig.ui.onTable.isVisible) { if (propertyName.endsWith("_Text")) { var lookupPropertyName = propertyName.replace("_Text", ""); @@ -216,6 +224,29 @@ var abp = abp || {}; return tableProperties; } + function checkPolicy(names, requiresAll, checkFunc) { + if (names.length === 0) { + return true; + } + + var hasAny = false; + for (var i = 0; i < names.length; i++) { + if (!checkFunc(names[i])) { + if (requiresAll) { + return false; + } + } + else { + hasAny = true; + if (!requiresAll) { + break; + } + } + } + + return hasAny; + } + function getValueFromRow(property, row) { return row.extraProperties[property.name]; } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ObjectExtending/CachedObjectExtensionsDtoService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ObjectExtending/CachedObjectExtensionsDtoService.cs index 66232802c0..10900f6ee4 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ObjectExtending/CachedObjectExtensionsDtoService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ObjectExtending/CachedObjectExtensionsDtoService.cs @@ -142,6 +142,24 @@ public class CachedObjectExtensionsDtoService : ICachedObjectExtensionsDtoServic { IsVisible = propertyConfig.UI.OnTable.IsVisible } + }, + Policy = new ExtensionPropertyPolicyDto + { + GlobalFeatures = new ExtensionPropertyGlobalFeaturePolicyDto + { + Features = propertyConfig.Policy.Features.Features, + RequiresAll = propertyConfig.Policy.Features.RequiresAll + }, + Features = new ExtensionPropertyFeaturePolicyDto + { + Features = propertyConfig.Policy.Features.Features, + RequiresAll = propertyConfig.Policy.Features.RequiresAll + }, + Permissions = new ExtensionPropertyPermissionPolicyDto + { + PermissionNames = propertyConfig.Policy.Permissions.PermissionNames, + RequiresAll = propertyConfig.Policy.Permissions.RequiresAll + } } }; @@ -157,7 +175,6 @@ public class CachedObjectExtensionsDtoService : ICachedObjectExtensionsDtoServic }; } - foreach (var attribute in propertyConfig.Attributes) { extensionPropertyDto.Attributes.Add( diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/ObjectExtending/MvcExtensionPropertyPolicyChecker.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/ObjectExtending/MvcExtensionPropertyPolicyChecker.cs new file mode 100644 index 0000000000..79195cc7c4 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/ObjectExtending/MvcExtensionPropertyPolicyChecker.cs @@ -0,0 +1,37 @@ + +using System.Threading.Tasks; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Features; +using Volo.Abp.GlobalFeatures; + +namespace Volo.Abp.ObjectExtending; + +[Dependency(ReplaceServices = true)] +[ExposeServices(typeof(ExtensionPropertyPolicyChecker))] +public class MvcExtensionPropertyPolicyChecker : ExtensionPropertyPolicyChecker +{ + protected IFeatureChecker FeatureChecker { get; } + protected IPermissionChecker PermissionChecker { get; } + + public MvcExtensionPropertyPolicyChecker(IFeatureChecker featureChecker, IPermissionChecker permissionChecker) + { + FeatureChecker = featureChecker; + PermissionChecker = permissionChecker; + } + + protected override Task CheckGlobalFeaturesAsync(string featureName) + { + return Task.FromResult(GlobalFeatureManager.Instance.IsEnabled(featureName)); + } + + protected async override Task CheckFeaturesAsync(string featureName) + { + return await FeatureChecker.IsEnabledAsync(featureName); + } + + protected async override Task CheckPermissionsAsync(string permissionName) + { + return await PermissionChecker.IsGrantedAsync(permissionName); + } +} diff --git a/framework/src/Volo.Abp.BlazoriseUI/AbpBlazoriseUIModule.cs b/framework/src/Volo.Abp.BlazoriseUI/AbpBlazoriseUIModule.cs index 198dce54fc..a18e584705 100644 --- a/framework/src/Volo.Abp.BlazoriseUI/AbpBlazoriseUIModule.cs +++ b/framework/src/Volo.Abp.BlazoriseUI/AbpBlazoriseUIModule.cs @@ -5,6 +5,8 @@ using Microsoft.Extensions.DependencyInjection.Extensions; using Volo.Abp.Application; using Volo.Abp.AspNetCore.Components.Web; using Volo.Abp.Authorization; +using Volo.Abp.Features; +using Volo.Abp.GlobalFeatures; using Volo.Abp.Modularity; namespace Volo.Abp.BlazoriseUI; @@ -12,7 +14,9 @@ namespace Volo.Abp.BlazoriseUI; [DependsOn( typeof(AbpAspNetCoreComponentsWebModule), typeof(AbpDddApplicationContractsModule), - typeof(AbpAuthorizationModule) + typeof(AbpAuthorizationModule), + typeof(AbpGlobalFeaturesModule), + typeof(AbpFeaturesModule) )] public class AbpBlazoriseUIModule : AbpModule { @@ -32,4 +36,4 @@ public class AbpBlazoriseUIModule : AbpModule context.Services.Replace(ServiceDescriptor.Scoped()); context.Services.AddSingleton(typeof(AbpBlazorMessageLocalizerHelper<>)); } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.BlazoriseUI/AbpCrudPageBase.cs b/framework/src/Volo.Abp.BlazoriseUI/AbpCrudPageBase.cs index 0e99a94460..1018eb3efa 100644 --- a/framework/src/Volo.Abp.BlazoriseUI/AbpCrudPageBase.cs +++ b/framework/src/Volo.Abp.BlazoriseUI/AbpCrudPageBase.cs @@ -177,7 +177,7 @@ public abstract class AbpCrudPageBase< [Inject] protected TAppService AppService { get; set; } = default!; [Inject] protected IStringLocalizer UiLocalizer { get; set; } = default!; [Inject] public IAbpEnumLocalizer AbpEnumLocalizer { get; set; } = default!; - + [Inject]protected ExtensionPropertyPolicyChecker ExtensionPropertyPolicyChecker { get; set; } = default!; protected virtual int PageSize { get; } = LimitedResultRequestDto.DefaultMaxResultCount; protected int CurrentPage = 1; @@ -642,23 +642,29 @@ public abstract class AbpCrudPageBase< return ValueTask.CompletedTask; } - protected virtual IEnumerable GetExtensionTableColumns(string moduleName, string entityType) + protected virtual async Task> GetExtensionTableColumnsAsync(string moduleName, string entityType) { - var properties = ModuleExtensionConfigurationHelper.GetPropertyConfigurations(moduleName, entityType); + var tableColumns = new List(); + var properties = ModuleExtensionConfigurationHelper.GetPropertyConfigurations(moduleName, entityType).ToList(); foreach (var propertyInfo in properties) { + if (!await ExtensionPropertyPolicyChecker.CheckPolicyAsync(propertyInfo.Policy)) + { + continue; + } + if (propertyInfo.IsAvailableToClients && propertyInfo.UI.OnTable.IsVisible) { if (propertyInfo.Name.EndsWith("_Text")) { var lookupPropertyName = propertyInfo.Name.RemovePostFix("_Text"); var lookupPropertyDefinition = properties.SingleOrDefault(t => t.Name == lookupPropertyName)!; - yield return new TableColumn + tableColumns.Add(new TableColumn { Title = lookupPropertyDefinition.GetLocalizedDisplayName(StringLocalizerFactory), Data = $"ExtraProperties[{propertyInfo.Name}]", PropertyName = propertyInfo.Name - }; + }); } else { @@ -680,9 +686,11 @@ public abstract class AbpCrudPageBase< AbpEnumLocalizer.GetString(propertyInfo.Type, val.As().ExtraProperties[propertyInfo.Name]!, new IStringLocalizer?[]{ StringLocalizerFactory.CreateDefaultOrNull() }); } - yield return column; + tableColumns.Add(column); } } } + + return tableColumns; } } diff --git a/framework/src/Volo.Abp.BlazoriseUI/BlazoriseExtensionPropertyPolicyChecker.cs b/framework/src/Volo.Abp.BlazoriseUI/BlazoriseExtensionPropertyPolicyChecker.cs new file mode 100644 index 0000000000..77fbf9dad3 --- /dev/null +++ b/framework/src/Volo.Abp.BlazoriseUI/BlazoriseExtensionPropertyPolicyChecker.cs @@ -0,0 +1,37 @@ +using System.Threading.Tasks; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Features; +using Volo.Abp.GlobalFeatures; +using Volo.Abp.ObjectExtending; + +namespace Volo.Abp.BlazoriseUI; + +[Dependency(ReplaceServices = true)] +[ExposeServices(typeof(ExtensionPropertyPolicyChecker))] +public class BlazoriseExtensionPropertyPolicyChecker : ExtensionPropertyPolicyChecker +{ + protected IFeatureChecker FeatureChecker { get; } + protected IPermissionChecker PermissionChecker { get; } + + public BlazoriseExtensionPropertyPolicyChecker(IFeatureChecker featureChecker, IPermissionChecker permissionChecker) + { + FeatureChecker = featureChecker; + PermissionChecker = permissionChecker; + } + + protected override Task CheckGlobalFeaturesAsync(string featureName) + { + return Task.FromResult(GlobalFeatureManager.Instance.IsEnabled(featureName)); + } + + protected async override Task CheckFeaturesAsync(string featureName) + { + return await FeatureChecker.IsEnabledAsync(featureName); + } + + protected async override Task CheckPermissionsAsync(string permissionName) + { + return await PermissionChecker.IsGrantedAsync(permissionName); + } +} diff --git a/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/ExtensionProperties.razor b/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/ExtensionProperties.razor index aa546793b9..e43426a7ef 100644 --- a/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/ExtensionProperties.razor +++ b/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/ExtensionProperties.razor @@ -6,7 +6,7 @@ @{ Entity.SetDefaultsForExtraProperties(); - foreach (var propertyInfo in ObjectExtensionManager.Instance.GetProperties()) + foreach (var propertyInfo in Properties) { if (!propertyInfo.Name.EndsWith("_Text")) { diff --git a/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/ExtensionProperties.razor.cs b/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/ExtensionProperties.razor.cs index beba718f0b..4890e2c369 100644 --- a/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/ExtensionProperties.razor.cs +++ b/framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/ExtensionProperties.razor.cs @@ -1,4 +1,8 @@ -using Microsoft.AspNetCore.Components; +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Components; using Microsoft.Extensions.Localization; using Volo.Abp.AspNetCore.Components.Web; using Volo.Abp.Data; @@ -17,7 +21,17 @@ public partial class ExtensionProperties : Component [Parameter] public TEntityType Entity { get; set; } = default!; - + + [Inject] + public IServiceProvider ServiceProvider { get; set; } = default!; + [Parameter] public ExtensionPropertyModalType? ModalType { get; set; } + + public ImmutableList Properties { get; set; } = ImmutableList.Empty; + + protected async override Task OnInitializedAsync() + { + Properties = await ObjectExtensionManager.Instance.GetPropertiesAndCheckPolicyAsync(ServiceProvider); + } } diff --git a/framework/src/Volo.Abp.BlazoriseUI/Volo.Abp.BlazoriseUI.csproj b/framework/src/Volo.Abp.BlazoriseUI/Volo.Abp.BlazoriseUI.csproj index b391a5c7ef..ab0c8bc440 100644 --- a/framework/src/Volo.Abp.BlazoriseUI/Volo.Abp.BlazoriseUI.csproj +++ b/framework/src/Volo.Abp.BlazoriseUI/Volo.Abp.BlazoriseUI.csproj @@ -13,6 +13,8 @@ + + diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensionPropertyFeaturePolicyConfiguration.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensionPropertyFeaturePolicyConfiguration.cs new file mode 100644 index 0000000000..1a1ac56487 --- /dev/null +++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensionPropertyFeaturePolicyConfiguration.cs @@ -0,0 +1,8 @@ +namespace Volo.Abp.ObjectExtending; + +public class ExtensionPropertyFeaturePolicyConfiguration +{ + public string[] Features { get; set; } = []; + + public bool RequiresAll { get; set; } = default!; +} diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensionPropertyGlobalFeaturePolicyConfiguration.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensionPropertyGlobalFeaturePolicyConfiguration.cs new file mode 100644 index 0000000000..c6d28a309f --- /dev/null +++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensionPropertyGlobalFeaturePolicyConfiguration.cs @@ -0,0 +1,8 @@ +namespace Volo.Abp.ObjectExtending; + +public class ExtensionPropertyGlobalFeaturePolicyConfiguration +{ + public string[] Features { get; set; } = []; + + public bool RequiresAll { get; set; } = default!; +} diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensionPropertyPermissionPolicyConfiguration.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensionPropertyPermissionPolicyConfiguration.cs new file mode 100644 index 0000000000..6620e4f30b --- /dev/null +++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensionPropertyPermissionPolicyConfiguration.cs @@ -0,0 +1,8 @@ +namespace Volo.Abp.ObjectExtending; + +public class ExtensionPropertyPermissionPolicyConfiguration +{ + public string[] PermissionNames { get; set; } = []; + + public bool RequiresAll { get; set; } = default!; +} diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensionPropertyPolicyChecker.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensionPropertyPolicyChecker.cs new file mode 100644 index 0000000000..ba0c91dbde --- /dev/null +++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensionPropertyPolicyChecker.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using JetBrains.Annotations; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.ObjectExtending; + +public class ExtensionPropertyPolicyChecker : ITransientDependency +{ + public virtual async Task CheckPolicyAsync([NotNull] ExtensionPropertyPolicyConfiguration policy) + { + if (!await CheckAsync(policy.GlobalFeatures.Features, policy.GlobalFeatures.RequiresAll, CheckGlobalFeaturesAsync)) + { + return false; + } + + if (!await CheckAsync(policy.Features.Features, policy.Features.RequiresAll, CheckFeaturesAsync)) + { + return false; + } + + return await CheckAsync(policy.Permissions.PermissionNames, policy.Permissions.RequiresAll, CheckPermissionsAsync); + } + + protected virtual async Task CheckAsync(string[] names, bool requiresAll, Func> checkFunc) + { + if (names.IsNullOrEmpty()) + { + return true; + } + + var hasAny = false; + foreach (var name in names) + { + if (!await checkFunc(name)) + { + if (requiresAll) + { + return false; + } + } + else + { + hasAny = true; + if (!requiresAll) + { + break; + } + } + } + + return hasAny; + } + + protected virtual Task CheckGlobalFeaturesAsync(string featureName) + { + return Task.FromResult(true); + } + + protected virtual Task CheckFeaturesAsync(string featureName) + { + return Task.FromResult(true); + } + + protected virtual Task CheckPermissionsAsync(string permissionName) + { + return Task.FromResult(true); + } +} diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensionPropertyPolicyConfiguration.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensionPropertyPolicyConfiguration.cs new file mode 100644 index 0000000000..8c4303d5e1 --- /dev/null +++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ExtensionPropertyPolicyConfiguration.cs @@ -0,0 +1,17 @@ +namespace Volo.Abp.ObjectExtending; + +public class ExtensionPropertyPolicyConfiguration +{ + public ExtensionPropertyGlobalFeaturePolicyConfiguration GlobalFeatures { get; set; } + + public ExtensionPropertyFeaturePolicyConfiguration Features { get; set; } + + public ExtensionPropertyPermissionPolicyConfiguration Permissions { get; set; } + + public ExtensionPropertyPolicyConfiguration() + { + GlobalFeatures = new ExtensionPropertyGlobalFeaturePolicyConfiguration(); + Features = new ExtensionPropertyFeaturePolicyConfiguration(); + Permissions = new ExtensionPropertyPermissionPolicyConfiguration(); + } +} diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ExtensionPropertyConfiguration.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ExtensionPropertyConfiguration.cs index 8099f1fc14..2b019c4697 100644 --- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ExtensionPropertyConfiguration.cs +++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ExtensionPropertyConfiguration.cs @@ -45,6 +45,9 @@ public class ExtensionPropertyConfiguration : IHasNameWithLocalizableDisplayName [NotNull] public ExtensionPropertyApiConfiguration Api { get; } + [NotNull] + public ExtensionPropertyPolicyConfiguration Policy { get; } + /// /// Uses as the default value if was not set. /// @@ -72,6 +75,7 @@ public class ExtensionPropertyConfiguration : IHasNameWithLocalizableDisplayName Entity = new ExtensionPropertyEntityConfiguration(); UI = new ExtensionPropertyUiConfiguration(); Api = new ExtensionPropertyApiConfiguration(); + Policy = new ExtensionPropertyPolicyConfiguration(); Attributes.AddRange(ExtensionPropertyHelper.GetDefaultAttributes(Type)); DefaultValue = TypeHelper.GetDefaultValue(Type); diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ModuleExtensionConfigurationHelper.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ModuleExtensionConfigurationHelper.cs index c1426e3833..9a13b17028 100644 --- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ModuleExtensionConfigurationHelper.cs +++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/Modularity/ModuleExtensionConfigurationHelper.cs @@ -175,6 +175,7 @@ public static class ModuleExtensionConfigurationHelper property.DefaultValueFactory = propertyConfig.DefaultValueFactory; property.Lookup = propertyConfig.UI.Lookup; property.UI.Order = propertyConfig.UI.Order; + property.Policy = propertyConfig.Policy; foreach (var configuration in propertyConfig.Configuration) { property.Configuration[configuration.Key] = configuration.Value; diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionManagerExtensions.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionManagerExtensions.cs index 71c7d78353..5cffda84ad 100644 --- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionManagerExtensions.cs +++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionManagerExtensions.cs @@ -1,7 +1,9 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; +using System.Threading.Tasks; using JetBrains.Annotations; +using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Data; namespace Volo.Abp.ObjectExtending; @@ -130,4 +132,33 @@ public static class ObjectExtensionManagerExtensions return extensionInfo.GetProperties(); } + + public static Task> GetPropertiesAndCheckPolicyAsync( + [NotNull] this ObjectExtensionManager objectExtensionManager, + [NotNull] IServiceProvider serviceProvider) + { + return objectExtensionManager.GetPropertiesAndCheckPolicyAsync(typeof(TObject), serviceProvider); + } + + public async static Task> GetPropertiesAndCheckPolicyAsync( + [NotNull] this ObjectExtensionManager objectExtensionManager, + [NotNull] Type objectType, + [NotNull] IServiceProvider serviceProvider) + { + Check.NotNull(objectExtensionManager, nameof(objectExtensionManager)); + Check.NotNull(objectType, nameof(objectType)); + Check.NotNull(serviceProvider, nameof(serviceProvider)); + + var extensionPropertyPolicyConfigurationChecker = serviceProvider.GetRequiredService(); + var properties = new List(); + foreach (var propertyInfo in objectExtensionManager.GetProperties(objectType)) + { + if (await extensionPropertyPolicyConfigurationChecker.CheckPolicyAsync(propertyInfo.Policy)) + { + properties.Add(propertyInfo); + } + } + + return properties.ToImmutableList(); + } } diff --git a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionPropertyInfo.cs b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionPropertyInfo.cs index ab941a2f15..e5ed79b99e 100644 --- a/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionPropertyInfo.cs +++ b/framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/ObjectExtensionPropertyInfo.cs @@ -59,6 +59,8 @@ public class ObjectExtensionPropertyInfo : IHasNameWithLocalizableDisplayName, I public ExtensionPropertyUI UI { get; set; } + public ExtensionPropertyPolicyConfiguration Policy { get; set; } + public ObjectExtensionPropertyInfo( [NotNull] ObjectExtensionInfo objectExtension, [NotNull] Type type, @@ -76,6 +78,7 @@ public class ObjectExtensionPropertyInfo : IHasNameWithLocalizableDisplayName, I DefaultValue = TypeHelper.GetDefaultValue(Type); Lookup = new ExtensionPropertyLookupConfiguration(); UI = new ExtensionPropertyUI(); + Policy = new ExtensionPropertyPolicyConfiguration(); } public object? GetDefaultValue() @@ -86,7 +89,7 @@ public class ObjectExtensionPropertyInfo : IHasNameWithLocalizableDisplayName, I public class ExtensionPropertyUI { public int Order { get; set; } - + public ExtensionPropertyUIEditModal EditModal { get; set; } public ExtensionPropertyUI() diff --git a/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/RoleManagement.razor.cs b/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/RoleManagement.razor.cs index a960c051ae..d683823461 100644 --- a/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/RoleManagement.razor.cs +++ b/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/RoleManagement.razor.cs @@ -80,7 +80,7 @@ public partial class RoleManagement return base.SetEntityActionsAsync(); } - protected override ValueTask SetTableColumnsAsync() + protected override async ValueTask SetTableColumnsAsync() { RoleManagementTableColumns .AddRange(new TableColumn[] @@ -99,10 +99,10 @@ public partial class RoleManagement }, }); - RoleManagementTableColumns.AddRange(GetExtensionTableColumns(IdentityModuleExtensionConsts.ModuleName, + RoleManagementTableColumns.AddRange(await GetExtensionTableColumnsAsync(IdentityModuleExtensionConsts.ModuleName, IdentityModuleExtensionConsts.EntityNames.Role)); - return base.SetTableColumnsAsync(); + await base.SetTableColumnsAsync(); } protected override async Task SetPermissionsAsync() diff --git a/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/UserManagement.razor.cs b/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/UserManagement.razor.cs index 53fde974db..a2bf95fa0c 100644 --- a/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/UserManagement.razor.cs +++ b/modules/identity/src/Volo.Abp.Identity.Blazor/Pages/Identity/UserManagement.razor.cs @@ -197,7 +197,7 @@ public partial class UserManagement return base.SetEntityActionsAsync(); } - protected override ValueTask SetTableColumnsAsync() + protected override async ValueTask SetTableColumnsAsync() { UserManagementTableColumns .AddRange(new TableColumn[] @@ -227,9 +227,9 @@ public partial class UserManagement } }); - UserManagementTableColumns.AddRange(GetExtensionTableColumns(IdentityModuleExtensionConsts.ModuleName, + UserManagementTableColumns.AddRange(await GetExtensionTableColumnsAsync(IdentityModuleExtensionConsts.ModuleName, IdentityModuleExtensionConsts.EntityNames.User)); - return base.SetTableColumnsAsync(); + await base.SetTableColumnsAsync(); } protected override ValueTask SetToolbarItemsAsync() diff --git a/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Roles/CreateModal.cshtml b/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Roles/CreateModal.cshtml index 4ebac325fb..0ec8571e8c 100644 --- a/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Roles/CreateModal.cshtml +++ b/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Roles/CreateModal.cshtml @@ -24,7 +24,7 @@ - @foreach (var propertyInfo in ObjectExtensionManager.Instance.GetProperties()) + @foreach (var propertyInfo in await ObjectExtensionManager.Instance.GetPropertiesAndCheckPolicyAsync(HttpContext.RequestServices)) { if (!propertyInfo.Name.EndsWith("_Text")) { diff --git a/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Roles/EditModal.cshtml b/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Roles/EditModal.cshtml index bb83b865e2..e166dd4dd5 100644 --- a/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Roles/EditModal.cshtml +++ b/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Roles/EditModal.cshtml @@ -34,7 +34,7 @@ - @foreach (var propertyInfo in ObjectExtensionManager.Instance.GetProperties()) + @foreach (var propertyInfo in await ObjectExtensionManager.Instance.GetPropertiesAndCheckPolicyAsync(HttpContext.RequestServices)) { if (!propertyInfo.Name.EndsWith("_Text")) { diff --git a/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Users/CreateModal.cshtml b/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Users/CreateModal.cshtml index fdf33444de..6d3ccc655d 100644 --- a/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Users/CreateModal.cshtml +++ b/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Users/CreateModal.cshtml @@ -39,7 +39,7 @@ - @foreach (var propertyInfo in ObjectExtensionManager.Instance.GetProperties()) + @foreach (var propertyInfo in await ObjectExtensionManager.Instance.GetPropertiesAndCheckPolicyAsync(HttpContext.RequestServices)) { if (!propertyInfo.Name.EndsWith("_Text")) { diff --git a/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Users/EditModal.cshtml b/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Users/EditModal.cshtml index 9dc1958d63..2a1e1e8d77 100644 --- a/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Users/EditModal.cshtml +++ b/modules/identity/src/Volo.Abp.Identity.Web/Pages/Identity/Users/EditModal.cshtml @@ -43,7 +43,7 @@ { } - @foreach (var propertyInfo in ObjectExtensionManager.Instance.GetProperties()) + @foreach (var propertyInfo in await ObjectExtensionManager.Instance.GetPropertiesAndCheckPolicyAsync(HttpContext.RequestServices)) { if (!propertyInfo.Name.EndsWith("_Text")) { diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/Pages/TenantManagement/TenantManagement.razor.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/Pages/TenantManagement/TenantManagement.razor.cs index 9d1edbad7a..ee1f339d5d 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/Pages/TenantManagement/TenantManagement.razor.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Blazor/Pages/TenantManagement/TenantManagement.razor.cs @@ -102,7 +102,7 @@ public partial class TenantManagement return base.SetEntityActionsAsync(); } - protected override ValueTask SetTableColumnsAsync() + protected override async ValueTask SetTableColumnsAsync() { TenantManagementTableColumns .AddRange(new TableColumn[] @@ -120,11 +120,11 @@ public partial class TenantManagement }, }); - TenantManagementTableColumns.AddRange(GetExtensionTableColumns( + TenantManagementTableColumns.AddRange(await GetExtensionTableColumnsAsync( TenantManagementModuleExtensionConsts.ModuleName, TenantManagementModuleExtensionConsts.EntityNames.Tenant)); - return base.SetTableColumnsAsync(); + await base.SetTableColumnsAsync(); } protected virtual void TogglePasswordVisibility()