Open Closed

Features availability based on editions not working well #2698


User avatar
0
christophe.baille created
  • ABP Framework version: v5.0.0
  • UI type: Blazor
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): no

In my solution, I want to manage my tenants features based on Editions. To do so, I created some Editions which have features, then I assign editions to Tenants. All seems OK, until I update edition information on tenant table:

EditionEndDateUtc: When I change the EditionEndDateUtc on a tenant from future to past, I can see when login as host/admin user, then go to Tenant/Saas and features, they get disabled. If I change this date from past to future, they become enable, which is good. The update is done right away, no need to close the application, logout or anything.

Now I want to check features for my tenant user to let him use them or not,

from the menu contributor to show or not the menu: var currentFeature = context.ServiceProvider.GetRequiredService<IFeatureChecker>();

fron my applicationservice to let the user make the action or not: await _featureChecker.IsEnabledAsync("AIGeneratorFeatures." + item)

My problem is, in both cases, that the EditionEndDateUtc change will be effective only after the user logout and login again.

Is it a normal behave? For now I am checking EditionEndDateUtc of the tenant but it is not so great, any other possibility to do?

I then notice something a bit strange, the tenant has possibility to change edition, I then check from host/tenant and see features changed based on the edition. However, I met the issue that 2 tenants with the same edition do not have the same features, one of them have no features available anymore, then whatever I put another feature or anything, it remains empty... One here, "payno" do not have any features, but "daypayno" has. whatever I change the Edition for "payno", he is still without feature. Is there any other datas than EditionId and EditionEnd that could affect this?


11 Answer(s)
  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    We will check it.

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    HI,

    Can you check this? https://support.abp.io/QA/Questions/2090/How-to-clear-cache-for-features

  • User Avatar
    0
    christophe.baille created

    I tried this but nothing changed. I still need to logout and login to see changes.

    I added the class they said on my blazor server project, then call it after app.UseAuthorization();

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    Sorry, I bad, Blazor server will not call middleware. you can try this:

    public class AbpRefreshEditionIdFilter : IHubFilter
    {
        public virtual async ValueTask<object> InvokeMethodAsync(HubInvocationContext invocationContext,
            Func<HubInvocationContext, ValueTask<object>> next)
    
        {
            var currentTenant = invocationContext.ServiceProvider.GetRequiredService<ICurrentTenant>();
            var currentUser = invocationContext.ServiceProvider.GetRequiredService<ICurrentUser>();
    
            if (!currentUser.IsAuthenticated || !currentUser.TenantId.HasValue)
            {
                return await next(invocationContext);
            }
    
            var tenantStore = invocationContext.ServiceProvider.GetRequiredService<ITenantRepository>();
            var currentPrincipalAccessor = invocationContext.ServiceProvider.GetRequiredService<ICurrentPrincipalAccessor>();
            var tenant = await tenantStore.FindAsync(currentTenant.GetId());
            var claims = currentPrincipalAccessor.Principal.Claims.ToList();
    
            claims.ReplaceOne(x => x.Type == AbpClaimTypes.EditionId,
                new Claim(AbpClaimTypes.EditionId, tenant.EditionId?.ToString() ?? string.Empty));
    
            using (currentPrincipalAccessor.Change(claims))
            {
                return await next(invocationContext);
            }
        }
    }
    
    Configure<HubOptions>(options =>
    {
        options.AddFilter<AbpRefreshEditionIdFilter>();
    });
    

  • User Avatar
    0
    christophe.baille created

    I do not have access on changing the edition for my tenants, because it is managed by payment provider as they said?

    I then tried to disable and enable features, it show/hide the menus successfully for my tenant

    I then edit the EditionEndDateUtc on the database but still no work, it will not show/hide my menus as I would like without login.

    Another thing I just noticed, in case I check/uncheck a feature for a tenant manually, then the EditionEndDateUtc change will not update feature for this tenant anymore

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    I then edit the EditionEndDateUtc on the database but still no work

    Please try update the AbpRefreshEditionIdFilter:

    public class AbpRefreshEditionIdFilter : IHubFilter
    {
        public virtual async ValueTask<object> InvokeMethodAsync(HubInvocationContext invocationContext,
            Func<HubInvocationContext, ValueTask<object>> next)
    
        {
            var currentTenant = invocationContext.ServiceProvider.GetRequiredService<ICurrentTenant>();
            var currentUser = invocationContext.ServiceProvider.GetRequiredService<ICurrentUser>();
    
            if (!currentUser.IsAuthenticated || !currentUser.TenantId.HasValue)
            {
                return await next(invocationContext);
            }
    
            var tenantStore = invocationContext.ServiceProvider.GetRequiredService<ITenantRepository>();
            var currentPrincipalAccessor = invocationContext.ServiceProvider.GetRequiredService<ICurrentPrincipalAccessor>();
            var tenant = await tenantStore.FindAsync(currentTenant.GetId());
            var claims = currentPrincipalAccessor.Principal.Claims.ToList();
    
            var editionId = tenant.GetActiveEditionId();
            if (editionId != null)
            {
                claims.ReplaceOne(x => x.Type == AbpClaimTypes.EditionId,
                    new Claim(AbpClaimTypes.EditionId, editionId.Value.ToString()));
            }
            else
            {
                claims.RemoveAll(x => x.Type == AbpClaimTypes.EditionId);
            }
    
            using (currentPrincipalAccessor.Change(claims))
            {
                return await next(invocationContext);
            }
        }
    }
    
  • User Avatar
    0
    christophe.baille created

    It works perfectly, thanks a lot.

    Just one more question, regarding the issue I got:

    In case I change features of the tenant manually (from host admin UI), then when I change the tenant editionId, it does not interact with features anymore. I guess it is because when change manually I write it somewhere else manually? However I do not find on which table, could you tell me?

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    I will check it.

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Will solved by : https://github.com/abpframework/abp/pull/11895#event-6222634134

  • User Avatar
    0
    christophe.baille created

    Thanks, in which release will it be?

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    Should be version 5.1.5.

Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
Do you need assistance from an ABP expert?
Schedule a Meeting
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v9.2.0-preview. Updated on March 25, 2025, 11:10