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.

Made with ❤️ on ABP v8.2.0-preview Updated on March 25, 2024, 15:11