Open Closed

IPermissionStore can't override. #8030


User avatar
0
cetin.sahin created
  • ABP Framework version: v8.3.1
  • UI Type:Blazor Server
  • Database System: EF Core (SQL Server,
  • Tiered (for MVC) or Auth Server Separated (for Angular): yes
  • Exception message and full stack trace:
  • Steps to reproduce the issue:

we overrided IPermissionStore in Application project . but after login IPermissionStore dont working Our code:

using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Volo.Abp; using Volo.Abp.Authorization.Permissions; using Volo.Abp.Caching; using Volo.Abp.DependencyInjection; using Volo.Abp.PermissionManagement; using EnzimWeb.Helpers; using Volo.Abp.Identity; using Volo.Abp.Users; using Volo.Abp.Data; using System.Reflection; using IdentityModel; using System.Security.Claims; using Veri.Temel; using System; using Veri.Temel.Sabitler; using EnzimWeb.Permissions; using EnzimWeb.CrmKurums; using EnzimWeb.Rols; using Microsoft.Extensions.Configuration;

namespace EnzimWeb.Overrides { [Dependency(ReplaceServices = true)] [ExposeServices(typeof(IPermissionStore))] public class MyPermissionStore : IPermissionStore, ITransientDependency { public ILogger<PermissionStore> Logger { get; set; }

    protected  IPermissionGrantRepository PermissionGrantRepository { get; }

    protected  IPermissionDefinitionManager PermissionDefinitionManager { get; }

    protected IDistributedCache&lt;PermissionGrantCacheItem&gt; Cache { get; }
    protected IRoleHelperRepository _roleHelperRepository { get; }
    protected IdentityUserManager _identityUserManager { get; }
    protected ICurrentUser _currentUser { get; }
    protected IIdentityRoleRepository _roleRepository;
    private readonly IConfiguration _configuration;
    public MyPermissionStore(
    IPermissionGrantRepository permissionGrantRepository,
    IDistributedCache&lt;PermissionGrantCacheItem&gt; cache,
    IPermissionDefinitionManager permissionDefinitionManager,
    IRoleHelperRepository roleHelperRepository,
    IdentityUserManager userManager,
    ICurrentUser currentUser,
    IIdentityRoleRepository roleRepository,
    IConfiguration configuration)
    {
        PermissionGrantRepository = permissionGrantRepository;
        Cache = cache;
        PermissionDefinitionManager = permissionDefinitionManager;
        Logger = NullLogger&lt;PermissionStore&gt;.Instance;
        _roleHelperRepository = roleHelperRepository;
        _identityUserManager = userManager;
        _currentUser = currentUser;
        _roleRepository = roleRepository;
        _configuration = configuration;
    }




    public virtual async Task&lt;bool&gt; IsGrantedAsync(string name, string providerName, string providerKey)
    {
        return (await GetCacheItemAsync(name, providerName, providerKey)).IsGranted;
    }

    protected virtual async Task&lt;PermissionGrantCacheItem&gt; GetCacheItemAsync(
    string name,
    string providerName,
    string providerKey)
    {
       
        var cacheKey = CalculateCacheKey(name, providerName, providerKey);

        Logger.LogInformation($"PermissionStore.GetCacheItemAsync: {cacheKey}");

        var cacheItem = await Cache.GetAsync(cacheKey);

        if (cacheItem != null)
        {
            Logger.LogInformation($"Found in the cache: {cacheKey}");
            return cacheItem;
        }

        Logger.LogInformation($"Not found in the cache: {cacheKey}");

        cacheItem = new PermissionGrantCacheItem(false);

        await SetCacheItemsAsync(providerName, providerKey, name, cacheItem);

        return cacheItem;
    }

    protected virtual async Task SetCacheItemsAsync(
    string providerName,
    string providerKey,
    string currentName,
    PermissionGrantCacheItem currentCacheItem)
    {
        var permissions = await PermissionDefinitionManager.GetPermissionsAsync();

        Logger.LogInformation($"Getting all granted permissions from the repository for this provider name,key: {providerName},{providerKey}");

        var grantedPermissionsHashSet = new HashSet&lt;string&gt;(
        (await PermissionGrantRepository.GetListAsync(providerName, providerKey)).Select(p => p.Name)
        );
        foreach (var item in await GetEnzimPermissions(providerName, providerKey))
        {
            grantedPermissionsHashSet.AddIfNotContains(item);
        }
        Logger.LogInformation($"Setting the cache items. Count: {permissions.Count}");

        var cacheItems = new List&lt;KeyValuePair&lt;string, PermissionGrantCacheItem&gt;>();

        foreach (var permission in permissions)
        {
            var isGranted = grantedPermissionsHashSet.Contains(permission.Name);

            cacheItems.Add(new KeyValuePair&lt;string, PermissionGrantCacheItem&gt;(
            CalculateCacheKey(permission.Name, providerName, providerKey),
            new PermissionGrantCacheItem(isGranted))
            );

            if (permission.Name == currentName)
            {
                currentCacheItem.IsGranted = isGranted;
            }
        }
        await Cache.SetManyAsync(cacheItems);

        Logger.LogInformation($"Finished setting the cache items. Count: {permissions.Count}");
    }
    public virtual async Task&lt;MultiplePermissionGrantResult&gt; IsGrantedAsync(string[] names, string providerName, string providerKey)
    {
        Check.NotNullOrEmpty(names, nameof(names));

        var result = new MultiplePermissionGrantResult();

        if (names.Length == 1)
        {
            var name = names.First();
            result.Result.Add(name,
            await IsGrantedAsync(names.First(), providerName, providerKey)
            ? PermissionGrantResult.Granted
            : PermissionGrantResult.Undefined);
            return result;
        }

        var cacheItems = await GetCacheItemsAsync(names, providerName, providerKey);
        foreach (var item in cacheItems)
        {
            result.Result.Add(GetPermissionNameFormCacheKeyOrNull(item.Key),
            item.Value != null && item.Value.IsGranted
            ? PermissionGrantResult.Granted
            : PermissionGrantResult.Undefined);
        }

        return result;
    }

    protected virtual async Task&lt;List&lt;KeyValuePair&lt;string, PermissionGrantCacheItem&gt;>> GetCacheItemsAsync(
    string[] names,
    string providerName,
    string providerKey)
    {
        var cacheKeys = names.Select(x => CalculateCacheKey(x, providerName, providerKey)).ToList();

        Logger.LogInformation($"PermissionStore.GetCacheItemAsync: {string.Join(",", cacheKeys)}");

        var cacheItems = (await Cache.GetManyAsync(cacheKeys)).ToList();
        if (cacheItems.All(x => x.Value != null))
        {
            Logger.LogInformation($"Found in the cache: {string.Join(",", cacheKeys)}");
            return cacheItems;
        }

        var notCacheKeys = cacheItems.Where(x => x.Value == null).Select(x => x.Key).ToList();

        Logger.LogInformation($"Not found in the cache: {string.Join(",", notCacheKeys)}");

        var newCacheItems = await SetCacheItemsAsync(providerName, providerKey, notCacheKeys);

        var result = new List&lt;KeyValuePair&lt;string, PermissionGrantCacheItem&gt;>();
        foreach (var key in cacheKeys)
        {
            var item = newCacheItems.FirstOrDefault(x => x.Key == key);
            if (item.Value == null)
            {
                item = cacheItems.FirstOrDefault(x => x.Key == key);
            }

            result.Add(new KeyValuePair&lt;string, PermissionGrantCacheItem&gt;(key, item.Value));
        }

        return result;
    }

    protected virtual async Task&lt;List&lt;KeyValuePair&lt;string, PermissionGrantCacheItem&gt;>> SetCacheItemsAsync(
    string providerName,
    string providerKey,
    List&lt;string&gt; notCacheKeys)
    {
        var permissions = (await PermissionDefinitionManager.GetPermissionsAsync())
        .Where(x => notCacheKeys.Any(k => GetPermissionNameFormCacheKeyOrNull(k) == x.Name)).ToList();

        Logger.LogInformation($"Getting not cache granted permissions from the repository for this provider name,key: {providerName},{providerKey}");

        var grantedPermissionsHashSet = new HashSet&lt;string&gt;(
        (await PermissionGrantRepository.GetListAsync(notCacheKeys.Select(GetPermissionNameFormCacheKeyOrNull).ToArray(), providerName, providerKey)).Select(p => p.Name)
        );
        var nCacheKeys = notCacheKeys.Select(GetPermissionNameFormCacheKeyOrNull).ToArray();

        foreach (var item in await GetEnzimPermissions(providerName, providerKey))
        {
            grantedPermissionsHashSet.AddIfNotContains(item);
        }
        Logger.LogInformation($"Setting the cache items. Count: {permissions.Count}");

        var cacheItems = new List&lt;KeyValuePair&lt;string, PermissionGrantCacheItem&gt;>();

        foreach (var permission in permissions)
        {
            var isGranted = grantedPermissionsHashSet.Contains(permission.Name);

            cacheItems.Add(new KeyValuePair&lt;string, PermissionGrantCacheItem&gt;(
            CalculateCacheKey(permission.Name, providerName, providerKey),
            new PermissionGrantCacheItem(isGranted))
            );
        }

        await Cache.SetManyAsync(cacheItems);

        Logger.LogInformation($"Finished setting the cache items. Count: {permissions.Count}");

        return cacheItems;
    }

    protected virtual string CalculateCacheKey(string name, string providerName, string providerKey)
    {
        return PermissionGrantCacheItem.CalculateCacheKey(name, providerName, providerKey);
    }

    protected virtual string GetPermissionNameFormCacheKeyOrNull(string key)
    {
        //TODO: throw ex when name is null?
        return PermissionGrantCacheItem.GetPermissionNameFormCacheKeyOrNull(key);
    }

    private async Task&lt;List&lt;string&gt;> GetEnzimPermissions(string providerName, string providerKey)
    {
        List&lt;string&gt; permissions = new List&lt;string&gt;();
        
        return permissions;
    }
}

}

and we added Application project's ConfigureServices

    context.Services.Replace(
    ServiceDescriptor.Transient&lt;IPermissionStore, MyPermissionStore&gt;()
    );

27 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    What is the instance of IPermissionStore if you get it from DI?

  • User Avatar
    0
    cetin.sahin created

    I don't understand your question. we shared code . we want to override IPermissionStore ? how can I implement abp version 8.3.1 this code worked on abp version 8.1.4

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    You can inject the IPermissionStore and set a breakpoint to see its instance. Or you can share a test project with your PermissionStore. I will download and check it. liming.ma@volosoft.com

    Thanks

  • User Avatar
    0
    cetin.sahin created

    can you share default tiered blazor server project with override IPermissionStore

    cetin.sahin@iberteknoloji.com.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    No problem. Please create a template project and share it via https://wetransfer.com/

    I will download and change code.

    liming.ma@volosoft.com

    Thanks.

  • User Avatar
    0
    cetin.sahin created

    I think I wasn't able to explain our issue clearly.

    What we want is to override the IPermissionStore in the most up-to-date abp.io Blazor Server tiered project. We want to make additional custom developments on the IPermissionStore side.

    We want to replace the service with the following annotations.

    I don't understand why we need to create the template project ourselves for this.

    [Dependency(ReplaceServices = true)]
    [ExposeServices(typeof(IPermissionStore ))]
    
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    ok, I see your point.

    I don't understand why we need to create the template project ourselves for this.

    Because the template project contains the license info, that's why you need to create it and share it. Then, I will add the code for you.

    Thanks.

  • User Avatar
    0
    cetin.sahin created

    I sent we transfer code in e-mail can you check IPermissionStore run after log in

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    I added the MyPermissionStore to Domain module.

    Then I can get it in API and AuthServer project.

  • User Avatar
    0
    cetin.sahin created

    we want to override IPermissionStore with this code [Dependency(ReplaceServices = true)] [ExposeServices(typeof(IPermissionStore))] I set break point on IsGrantedAsyncmethod in MyPermissionStore class but the break point doesn't trigger.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Can you try the code I provided?

    then inject the IPermissionStore and see it type. should be MyPermissionStore

  • User Avatar
    0
    cetin.sahin created

    I injected IPermissionStore . it change MyPermissionStore. auth project call IPermissionStore . but api host doesn't call IPermissionStore . Did you change api host authorize annotiation in abp 8.3.1 version.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    but api host doesn't call IPermissionStore .

    IPermissionStore is only called when checking permissions.

    Can you reproduce this in a template project? That way I can check.

    Thanks

  • User Avatar
    0
    cetin.sahin created

    Hi; we cant triggered IPermissionStore IsGrantedAsync method. can you recommend another procedure for override Permission save and get method

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    Your MyPermissionStore has already replaced the built-in PermissionStore.

    I don't understand what your problem is with it.

    Can you reproduce your problem in a template project? That way I can check.

    Thanks

  • User Avatar
    0
    cetin.sahin created

    Our project cant trigger PermissionStore.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Can you reproduce your problem in a template project? That way I can check.

  • User Avatar
    0
    cetin.sahin created

    our code run 8.1.4 version succesfully But 8.3.1 version cant trigger PermissionStore. Did you change the Permission Stored structure in version 8.3.1?

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    There is no such change in the new version.

  • User Avatar
    0
    cetin.sahin created

    we overrided IPermissionStore in Application project. is it wrong

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    You can try to override IPermissionStore in Domain project.

  • User Avatar
    0
    cetin.sahin created

    can we get online meeting ?

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Can you try override IPermissionStore in Domain project and get it from DI in your API and AuthServer projects?

    https://abp.io/support/questions/8030/IPermissionStore-can%27t-override#answer-3a157857-26ea-3344-dee9-0d9807a137fd

  • User Avatar
    0
    cetin.sahin created

    I made the changes as you requested, but unfortunately the permission store is not triggered.

    Also, even if we do not override IPermissionStore, abp.io permission store does not work. Menus are not loaded. Authorizations are not received. The values ​​of permissions pulled from the redis appear to be null.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    Override IPermissionStore may not be the solution to your problem.

    Also, even if we do not override IPermissionStore, abp.io permission store does not work. Menus are not loaded. Authorizations are not received. The values ​​of permissions pulled from the redis appear to be null.

    In this case, it would be better if you could share a project that reproduces the problem, and I will check it locally, it will be difficult to check your code in a remote meeting.

    liming.ma@volosoft.com

    Thanks

Made with ❤️ on ABP v9.1.0-preview. Updated on November 11, 2024, 11:11