From d2eef4f1f63aa7dad9e01fbed2e86d4d9d3dee49 Mon Sep 17 00:00:00 2001 From: maliming Date: Sat, 12 Apr 2025 17:48:43 +0800 Subject: [PATCH 1/4] Add `EditionId` to `TenantConfiguration` and use it in `EditionFeatureValueProvider`. --- .../Features/EditionFeatureValueProvider.cs | 37 +++++++++++++++++-- .../Abp/MultiTenancy/TenantConfiguration.cs | 5 ++- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/EditionFeatureValueProvider.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/EditionFeatureValueProvider.cs index 94822284f5e..e252bc31f09 100644 --- a/framework/src/Volo.Abp.Features/Volo/Abp/Features/EditionFeatureValueProvider.cs +++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/EditionFeatureValueProvider.cs @@ -1,5 +1,7 @@ -using System.Security.Principal; +using System; +using System.Security.Principal; using System.Threading.Tasks; +using Volo.Abp.MultiTenancy; using Volo.Abp.Security.Claims; namespace Volo.Abp.Features; @@ -12,15 +14,25 @@ public class EditionFeatureValueProvider : FeatureValueProvider protected ICurrentPrincipalAccessor PrincipalAccessor; - public EditionFeatureValueProvider(IFeatureStore featureStore, ICurrentPrincipalAccessor principalAccessor) + protected ITenantStore TenantStore { get; } + + protected ICurrentTenant CurrentTenant { get; } + + public EditionFeatureValueProvider( + IFeatureStore featureStore, + ICurrentPrincipalAccessor principalAccessor, + ITenantStore tenantStore, + ICurrentTenant currentTenant) : base(featureStore) { PrincipalAccessor = principalAccessor; + TenantStore = tenantStore; + CurrentTenant = currentTenant; } - public override async Task GetOrNullAsync(FeatureDefinition feature) + public async override Task GetOrNullAsync(FeatureDefinition feature) { - var editionId = PrincipalAccessor.Principal?.FindEditionId(); + var editionId = await GetEditionIdAsync(); if (editionId == null) { return null; @@ -28,4 +40,21 @@ public EditionFeatureValueProvider(IFeatureStore featureStore, ICurrentPrincipal return await FeatureStore.GetOrNullAsync(feature.Name, Name, editionId.Value.ToString()); } + + protected virtual async Task GetEditionIdAsync() + { + var editionId = PrincipalAccessor.Principal?.FindEditionId(); + if (editionId != null) + { + return editionId; + } + + if (CurrentTenant.Id == null) + { + return null; + } + + var tenant = await TenantStore.FindAsync(CurrentTenant.Id.Value); + return tenant?.EditionId; + } } diff --git a/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/TenantConfiguration.cs b/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/TenantConfiguration.cs index 29b0971708a..674bce6e94f 100644 --- a/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/TenantConfiguration.cs +++ b/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/TenantConfiguration.cs @@ -17,6 +17,8 @@ public class TenantConfiguration public bool IsActive { get; set; } + public Guid? EditionId { get; set; } + public TenantConfiguration() { IsActive = true; @@ -33,11 +35,12 @@ public TenantConfiguration(Guid id, [NotNull] string name) ConnectionStrings = new ConnectionStrings(); } - public TenantConfiguration(Guid id, [NotNull] string name, [NotNull] string normalizedName) + public TenantConfiguration(Guid id, [NotNull] string name, [NotNull] string normalizedName, Guid? editionId = null) : this(id, name) { Check.NotNull(normalizedName, nameof(normalizedName)); NormalizedName = normalizedName; + EditionId = editionId; } } From 556817e45c2e9d54efa1643843cfb94d4521f0a5 Mon Sep 17 00:00:00 2001 From: maliming Date: Sat, 12 Apr 2025 18:07:20 +0800 Subject: [PATCH 2/4] Ignore `EditionId` mapping in `AbpTenantManagementDomainMappingProfile` --- .../AbpTenantManagementDomainMappingProfile.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/AbpTenantManagementDomainMappingProfile.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/AbpTenantManagementDomainMappingProfile.cs index 496095c8072..6fe1edafc64 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/AbpTenantManagementDomainMappingProfile.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/AbpTenantManagementDomainMappingProfile.cs @@ -28,7 +28,8 @@ public AbpTenantManagementDomainMappingProfile() return connStrings; }); }) - .ForMember(x => x.IsActive, x => x.Ignore()); + .ForMember(x => x.IsActive, x => x.Ignore()) + .ForMember(x => x.EditionId, x => x.Ignore()); CreateMap(); } From 5003614b0c5ff976614f3056d7132385b039b2b5 Mon Sep 17 00:00:00 2001 From: maliming Date: Thu, 17 Apr 2025 10:20:48 +0800 Subject: [PATCH 3/4] Try to get tenant's `EditionId` in `EditionFeatureManagementProvider`. --- .../Features/EditionFeatureValueProvider.cs | 4 +- .../EditionFeatureManagementProvider.cs | 50 ++++++++++++++++--- 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/EditionFeatureValueProvider.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/EditionFeatureValueProvider.cs index e252bc31f09..cdab8e74c86 100644 --- a/framework/src/Volo.Abp.Features/Volo/Abp/Features/EditionFeatureValueProvider.cs +++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/EditionFeatureValueProvider.cs @@ -32,7 +32,7 @@ public EditionFeatureValueProvider( public async override Task GetOrNullAsync(FeatureDefinition feature) { - var editionId = await GetEditionIdAsync(); + var editionId = await FindEditionIdAsync(); if (editionId == null) { return null; @@ -41,7 +41,7 @@ public EditionFeatureValueProvider( return await FeatureStore.GetOrNullAsync(feature.Name, Name, editionId.Value.ToString()); } - protected virtual async Task GetEditionIdAsync() + protected virtual async Task FindEditionIdAsync() { var editionId = PrincipalAccessor.Principal?.FindEditionId(); if (editionId != null) diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/EditionFeatureManagementProvider.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/EditionFeatureManagementProvider.cs index 82c1c98cb97..f9de4cbd1f0 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/EditionFeatureManagementProvider.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/EditionFeatureManagementProvider.cs @@ -1,7 +1,9 @@ -using System.Security.Principal; +using System; +using System.Security.Principal; using System.Threading.Tasks; using Volo.Abp.DependencyInjection; using Volo.Abp.Features; +using Volo.Abp.MultiTenancy; using Volo.Abp.Security.Claims; namespace Volo.Abp.FeatureManagement; @@ -11,22 +13,58 @@ public class EditionFeatureManagementProvider : FeatureManagementProvider, ITran public override string Name => EditionFeatureValueProvider.ProviderName; protected ICurrentPrincipalAccessor PrincipalAccessor { get; } + protected ITenantStore TenantStore { get; } + protected ICurrentTenant CurrentTenant { get; } + protected string CurrentCompatibleProviderName { get; set; } public EditionFeatureManagementProvider( IFeatureManagementStore store, - ICurrentPrincipalAccessor principalAccessor) + ICurrentPrincipalAccessor principalAccessor, + ITenantStore tenantStore, + ICurrentTenant currentTenant) : base(store) { PrincipalAccessor = principalAccessor; + TenantStore = tenantStore; + CurrentTenant = currentTenant; } - protected override Task NormalizeProviderKeyAsync(string providerKey) + public override bool Compatible(string providerName) { - if (providerKey != null) + CurrentCompatibleProviderName = providerName; + return providerName == TenantFeatureValueProvider.ProviderName || base.Compatible(providerName); + } + + protected async override Task NormalizeProviderKeyAsync(string providerKey) + { + return (await FindEditionIdAsync(providerKey))?.ToString(); + } + + protected virtual async Task FindEditionIdAsync(string providerKey) + { + if (Guid.TryParse(providerKey, out var parsedEditionOrTenantId)) + { + if (CurrentCompatibleProviderName == TenantFeatureValueProvider.ProviderName) + { + var tenant = await TenantStore.FindAsync(parsedEditionOrTenantId); + if (tenant != null) + { + return tenant?.EditionId; + } + } + + return parsedEditionOrTenantId; + } + + if (CurrentTenant.Id.HasValue) { - return Task.FromResult(providerKey); + var tenant = await TenantStore.FindAsync(CurrentTenant.GetId()); + if (tenant != null) + { + return tenant?.EditionId; + } } - return Task.FromResult(PrincipalAccessor.Principal?.FindEditionId()?.ToString("N")); + return PrincipalAccessor.Principal?.FindEditionId(); } } From 00ce0a79b4cb3f90fc87d6a1fe53671b1dfc5f39 Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 18 Apr 2025 19:33:22 +0800 Subject: [PATCH 4/4] Update build-and-test.yml --- .github/workflows/build-and-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 7073e826e37..8ebcc32bfc9 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -48,7 +48,7 @@ permissions: jobs: build-test: runs-on: ubuntu-22.04 - timeout-minutes: 40 + timeout-minutes: 50 if: ${{ !github.event.pull_request.draft }} steps: - uses: actions/checkout@v2