diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureDefinition.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureDefinition.cs index bd79480326..b2b11f0a18 100644 --- a/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureDefinition.cs +++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureDefinition.cs @@ -51,6 +51,12 @@ namespace Volo.Abp.Features /// public bool IsVisibleToClients { get; set; } + /// + /// Can host use this feature. + /// Default: true. + /// + public bool IsAvailableToHost { get; set; } + /// /// A list of allowed providers to get/set value of this feature. /// An empty list indicates that all providers are allowed. @@ -93,7 +99,8 @@ namespace Volo.Abp.Features ILocalizableString displayName = null, ILocalizableString description = null, IStringValueType valueType = null, - bool isVisibleToClients = true) + bool isVisibleToClients = true, + bool isAvailableToHost = true) { Name = name; DefaultValue = defaultValue; @@ -101,6 +108,7 @@ namespace Volo.Abp.Features Description = description; ValueType = valueType; IsVisibleToClients = isVisibleToClients; + IsAvailableToHost = isAvailableToHost; Properties = new Dictionary(); AllowedProviders = new List(); @@ -136,20 +144,22 @@ namespace Volo.Abp.Features /// /// Returns a newly created child feature public FeatureDefinition CreateChild( - string name, - string defaultValue = null, - ILocalizableString displayName = null, + string name, + string defaultValue = null, + ILocalizableString displayName = null, ILocalizableString description = null, IStringValueType valueType = null, - bool isVisibleToClients = true) + bool isVisibleToClients = true, + bool isAvailableToHost = true) { var feature = new FeatureDefinition( - name, - defaultValue, - displayName, + name, + defaultValue, + displayName, description, valueType, - isVisibleToClients) + isVisibleToClients, + isAvailableToHost) { Parent = this }; @@ -175,4 +185,4 @@ namespace Volo.Abp.Features return $"[{nameof(FeatureDefinition)}: {Name}]"; } } -} \ No newline at end of file +} diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/FeatureManagementPermissions.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/FeatureManagementPermissions.cs new file mode 100644 index 0000000000..86772c0a7b --- /dev/null +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/FeatureManagementPermissions.cs @@ -0,0 +1,16 @@ +using Volo.Abp.Reflection; + +namespace Volo.Abp.FeatureManagement +{ + public class FeatureManagementPermissions + { + public const string GroupName = "FeatureManagement"; + + public const string ManageHostFeatures = GroupName + ".ManageHostFeatures"; + + public static string[] GetAll() + { + return ReflectionHelper.GetPublicConstantsRecursively(typeof(FeatureManagementPermissions)); + } + } +} diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/FeaturePermissionDefinitionProvider.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/FeaturePermissionDefinitionProvider.cs new file mode 100644 index 0000000000..27e159ee8a --- /dev/null +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/FeaturePermissionDefinitionProvider.cs @@ -0,0 +1,28 @@ +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.FeatureManagement.Localization; +using Volo.Abp.Localization; +using Volo.Abp.MultiTenancy; + +namespace Volo.Abp.FeatureManagement +{ + public class FeaturePermissionDefinitionProvider : PermissionDefinitionProvider + { + public override void Define(IPermissionDefinitionContext context) + { + var featureManagementGroup = context.AddGroup( + FeatureManagementPermissions.GroupName, + L("Permission:FeatureManagement"), + multiTenancySide: MultiTenancySides.Host); + + featureManagementGroup.AddPermission( + FeatureManagementPermissions.ManageHostFeatures, + L("Permission:FeatureManagement.ManageHostFeatures"), + multiTenancySide: MultiTenancySides.Host); + } + + private static LocalizableString L(string name) + { + return LocalizableString.Create(name); + } + } +} diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/IFeatureAppService.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/IFeatureAppService.cs index 00c36b7f55..9ddddc7401 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/IFeatureAppService.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/IFeatureAppService.cs @@ -6,8 +6,8 @@ namespace Volo.Abp.FeatureManagement { public interface IFeatureAppService : IApplicationService { - Task GetAsync([NotNull] string providerName, [NotNull] string providerKey); + Task GetAsync([NotNull] string providerName, string providerKey); - Task UpdateAsync([NotNull] string providerName, [NotNull] string providerKey, UpdateFeaturesDto input); + Task UpdateAsync([NotNull] string providerName, string providerKey, UpdateFeaturesDto input); } } diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Application/Volo/Abp/FeatureManagement/FeatureAppService.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application/Volo/Abp/FeatureManagement/FeatureAppService.cs index dbe649e51f..bfb6e65ea8 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Application/Volo/Abp/FeatureManagement/FeatureAppService.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application/Volo/Abp/FeatureManagement/FeatureAppService.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using JetBrains.Annotations; using Microsoft.AspNetCore.Authorization; @@ -25,9 +26,9 @@ namespace Volo.Abp.FeatureManagement Options = options.Value; } - public virtual async Task GetAsync([NotNull] string providerName, [NotNull] string providerKey) + public virtual async Task GetAsync([NotNull] string providerName, string providerKey) { - await CheckProviderPolicy(providerName); + await CheckProviderPolicy(providerName, providerKey); var result = new GetFeatureListResultDto { @@ -45,6 +46,14 @@ namespace Volo.Abp.FeatureManagement foreach (var featureDefinition in group.GetFeaturesWithChildren()) { + if (providerName == TenantFeatureValueProvider.ProviderName && + CurrentTenant.Id == null && + providerKey == null && + !featureDefinition.IsAvailableToHost) + { + continue; + } + var feature = await FeatureManager.GetOrNullWithProviderAsync(featureDefinition.Name, providerName, providerKey); groupDto.Features.Add(new FeatureDto { @@ -70,9 +79,9 @@ namespace Volo.Abp.FeatureManagement return result; } - public virtual async Task UpdateAsync([NotNull] string providerName, [NotNull] string providerKey, UpdateFeaturesDto input) + public virtual async Task UpdateAsync([NotNull] string providerName, string providerKey, UpdateFeaturesDto input) { - await CheckProviderPolicy(providerName); + await CheckProviderPolicy(providerName, providerKey); foreach (var feature in input.Features) { @@ -93,12 +102,20 @@ namespace Volo.Abp.FeatureManagement } } - protected virtual async Task CheckProviderPolicy(string providerName) + protected virtual async Task CheckProviderPolicy(string providerName, string providerKey) { - var policyName = Options.ProviderPolicies.GetOrDefault(providerName); - if (policyName.IsNullOrEmpty()) + string policyName; + if (providerName == TenantFeatureValueProvider.ProviderName && CurrentTenant.Id == null && providerKey == null ) + { + policyName = "FeatureManagement.ManageHostFeatures"; + } + else { - throw new AbpException($"No policy defined to get/set permissions for the provider '{policyName}'. Use {nameof(FeatureManagementOptions)} to map the policy."); + policyName = Options.ProviderPolicies.GetOrDefault(providerName); + if (policyName.IsNullOrEmpty()) + { + throw new AbpException($"No policy defined to get/set permissions for the provider '{policyName}'. Use {nameof(FeatureManagementOptions)} to map the policy."); + } } await AuthorizationService.CheckAsync(policyName); diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/en.json b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/en.json index e5a2406aaf..26f5dc736b 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/en.json +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/en.json @@ -2,6 +2,8 @@ "culture": "en", "texts": { "Features": "Features", - "NoFeatureFoundMessage": "There isn't any available feature." + "NoFeatureFoundMessage": "There isn't any available feature.", + "Permission:FeatureManagement": "Feature management", + "Permission:FeatureManagement.ManageHostFeatures": "Manage Host features" } -} \ No newline at end of file +} diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/tr.json b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/tr.json index b566f654ca..8233674933 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/tr.json +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/tr.json @@ -2,6 +2,8 @@ "culture": "tr", "texts": { "Features": "Özellikler", - "NoFeatureFoundMessage": "Hiç özellik yok." + "NoFeatureFoundMessage": "Hiç özellik yok.", + "Permission:FeatureManagement": "Özellik yönetimi", + "Permission:FeatureManagement.ManageHostFeatures": "Host özelliklerini düzenle" } -} \ No newline at end of file +} diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/zh-Hans.json b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/zh-Hans.json index 69b8ca89b1..9737a9a59c 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/zh-Hans.json +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/zh-Hans.json @@ -2,6 +2,8 @@ "culture": "zh-Hans", "texts": { "Features": "功能", - "NoFeatureFoundMessage": "没有可用的功能." + "NoFeatureFoundMessage": "没有可用的功能.", + "Permission:FeatureManagement": "特性管理", + "Permission:FeatureManagement.ManageHostFeatures": "管理Host特性" } -} \ No newline at end of file +} diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/zh-Hant.json b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/zh-Hant.json index bc4dbf268f..7d68fd5bc2 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/zh-Hant.json +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/zh-Hant.json @@ -2,6 +2,8 @@ "culture": "zh-Hant", "texts": { "Features": "功能", - "NoFeatureFoundMessage": "沒有可用的功能." + "NoFeatureFoundMessage": "沒有可用的功能.", + "Permission:FeatureManagement": "功能管理", + "Permission:FeatureManagement.ManageHostFeatures": "管理Host功能" } -} \ No newline at end of file +} diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/AbpFeatureManagementDomainModule.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/AbpFeatureManagementDomainModule.cs index e8e961d3b4..38a2fa3c56 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/AbpFeatureManagementDomainModule.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/AbpFeatureManagementDomainModule.cs @@ -1,10 +1,8 @@ using Volo.Abp.Caching; using Volo.Abp.FeatureManagement.Localization; using Volo.Abp.Features; -using Volo.Abp.Localization; using Volo.Abp.Localization.ExceptionHandling; using Volo.Abp.Modularity; -using Volo.Abp.VirtualFileSystem; namespace Volo.Abp.FeatureManagement { diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi/Volo/Abp/FeatureManagement/FeaturesController.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi/Volo/Abp/FeatureManagement/FeaturesController.cs index cc00fb370b..c7dff4d8a3 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi/Volo/Abp/FeatureManagement/FeaturesController.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.HttpApi/Volo/Abp/FeatureManagement/FeaturesController.cs @@ -28,4 +28,4 @@ namespace Volo.Abp.FeatureManagement return FeatureAppService.UpdateAsync(providerName, providerKey, input); } } -} \ No newline at end of file +} diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml.cs index 1464a1fc9b..367268019c 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Pages/FeatureManagement/FeatureManagementModal.cshtml.cs @@ -16,7 +16,6 @@ namespace Volo.Abp.FeatureManagement.Web.Pages.FeatureManagement [BindProperty(SupportsGet = true)] public string ProviderName { get; set; } - [Required] [HiddenInput] [BindProperty(SupportsGet = true)] public string ProviderKey { get; set; } @@ -83,8 +82,6 @@ namespace Volo.Abp.FeatureManagement.Web.Pages.FeatureManagement public string Value { get; set; } - public string ProviderName { get; set; } - public bool BoolValue { get; set; } public string Type { get; set; } diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/en.json b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/en.json index d6d1d7c155..ba4109c392 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/en.json +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/en.json @@ -10,13 +10,14 @@ "ConnectionStrings": "Connection Strings", "DisplayName:DefaultConnectionString": "Default Connection String", "DisplayName:UseSharedDatabase": "Use the Shared Database", + "ManageHostFeatures": "Manage Host features", "Permission:TenantManagement": "Tenant management", "Permission:Create": "Create", "Permission:Edit": "Edit", "Permission:Delete": "Delete", "Permission:ManageConnectionStrings": "Manage connection strings", "Permission:ManageFeatures": "Manage features", - "DisplayName:AdminEmailAddress": "Admin Email Address", - "DisplayName:AdminPassword": "Admin Password" + "DisplayName:AdminEmailAddress": "Admin Email Address", + "DisplayName:AdminPassword": "Admin Password" } -} \ No newline at end of file +} diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/tr.json b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/tr.json index 72b570f3f9..7315cccc3f 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/tr.json +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/tr.json @@ -10,6 +10,7 @@ "ConnectionStrings": "Bağlantı cümlesi", "DisplayName:DefaultConnectionString": "Varsayılan bağlantı cümlesi", "DisplayName:UseSharedDatabase": "Paylaşılan veritabanını kullan", + "ManageHostFeatures": "Toplantı Sahibi özelliklerini yönetin", "Permission:TenantManagement": "Müşteri yönetimi", "Permission:Create": "Oluşturma", "Permission:Edit": "Düzenleme", @@ -19,4 +20,4 @@ "DisplayName:AdminEmailAddress": "Admin Eposta Adresi", "DisplayName:AdminPassword": "Admin Şifresi" } -} \ No newline at end of file +} diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/zh-Hans.json b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/zh-Hans.json index b60c68e2e0..f85f6cf638 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/zh-Hans.json +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/zh-Hans.json @@ -10,6 +10,7 @@ "ConnectionStrings": "连接字符串", "DisplayName:DefaultConnectionString": "默认连接字符串", "DisplayName:UseSharedDatabase": "使用共享数据库", + "ManageHostFeatures": "管理Host特性", "Permission:TenantManagement": "租户管理", "Permission:Create": "创建", "Permission:Edit": "编辑", @@ -17,4 +18,4 @@ "Permission:ManageConnectionStrings": "管理连接字符串", "Permission:ManageFeatures": "管理功能" } -} \ No newline at end of file +} diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/zh-Hant.json b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/zh-Hant.json index ea8be8ae0e..6950a1ca00 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/zh-Hant.json +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/zh-Hant.json @@ -10,13 +10,14 @@ "ConnectionStrings": "資料庫連線字串", "DisplayName:DefaultConnectionString": "預設資料庫連線字串", "DisplayName:UseSharedDatabase": "使用共用資料庫", + "ManageHostFeatures": "管理Host功能", "Permission:TenantManagement": "租戶管理", "Permission:Create": "新增", "Permission:Edit": "編輯", "Permission:Delete": "刪除", "Permission:ManageConnectionStrings": "管理資料庫連線字串", "Permission:ManageFeatures": "管理功能", - "DisplayName:AdminEmailAddress": "管理者信箱", + "DisplayName:AdminEmailAddress": "管理者信箱", "DisplayName:AdminPassword": "管理者密碼" } } diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/Index.cshtml b/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/Index.cshtml index eabc75c786..bb972b02d8 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/Index.cshtml +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/Index.cshtml @@ -2,6 +2,7 @@ @using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Mvc.Localization @using Volo.Abp.AspNetCore.Mvc.UI.Layout +@using Volo.Abp.FeatureManagement @using Volo.Abp.TenantManagement @using Volo.Abp.TenantManagement.Localization @using Volo.Abp.TenantManagement.Web.Navigation @@ -29,9 +30,13 @@ @L["Tenants"] + @if (await Authorization.IsGrantedAsync(FeatureManagementPermissions.ManageHostFeatures)) + { + + } @if (await Authorization.IsGrantedAsync(TenantManagementPermissions.Tenants.Create)) { - + } @@ -39,4 +44,4 @@ - \ No newline at end of file + diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/Index.js b/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/Index.js index 4b19d0bbb7..69bbb0b955 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/Index.js +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Pages/TenantManagement/Tenants/Index.js @@ -100,7 +100,7 @@ }, 0 //adds as the first contributor ); - + $(function () { var _$wrapper = $('#TenantsWrapper'); @@ -128,5 +128,12 @@ e.preventDefault(); _createModal.open(); }); + + _$wrapper.find('button[name=ManageHostFeatures]').click(function (e) { + e.preventDefault(); + _featuresModal.open({ + providerName: 'T' + }); + }); }); })();