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.
I sent we transfer code in e-mail can you check IPermissionStore run after log in
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 ))]
can you share default tiered blazor server project with override IPermissionStore
cetin.sahin@iberteknoloji.com.
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
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<PermissionGrantCacheItem> 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<PermissionGrantCacheItem> cache,
IPermissionDefinitionManager permissionDefinitionManager,
IRoleHelperRepository roleHelperRepository,
IdentityUserManager userManager,
ICurrentUser currentUser,
IIdentityRoleRepository roleRepository,
IConfiguration configuration)
{
PermissionGrantRepository = permissionGrantRepository;
Cache = cache;
PermissionDefinitionManager = permissionDefinitionManager;
Logger = NullLogger<PermissionStore>.Instance;
_roleHelperRepository = roleHelperRepository;
_identityUserManager = userManager;
_currentUser = currentUser;
_roleRepository = roleRepository;
_configuration = configuration;
}
public virtual async Task<bool> IsGrantedAsync(string name, string providerName, string providerKey)
{
return (await GetCacheItemAsync(name, providerName, providerKey)).IsGranted;
}
protected virtual async Task<PermissionGrantCacheItem> 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<string>(
(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<KeyValuePair<string, PermissionGrantCacheItem>>();
foreach (var permission in permissions)
{
var isGranted = grantedPermissionsHashSet.Contains(permission.Name);
cacheItems.Add(new KeyValuePair<string, PermissionGrantCacheItem>(
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<MultiplePermissionGrantResult> 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<List<KeyValuePair<string, PermissionGrantCacheItem>>> 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<KeyValuePair<string, PermissionGrantCacheItem>>();
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<string, PermissionGrantCacheItem>(key, item.Value));
}
return result;
}
protected virtual async Task<List<KeyValuePair<string, PermissionGrantCacheItem>>> SetCacheItemsAsync(
string providerName,
string providerKey,
List<string> 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<string>(
(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<KeyValuePair<string, PermissionGrantCacheItem>>();
foreach (var permission in permissions)
{
var isGranted = grantedPermissionsHashSet.Contains(permission.Name);
cacheItems.Add(new KeyValuePair<string, PermissionGrantCacheItem>(
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<List<string>> GetEnzimPermissions(string providerName, string providerKey)
{
List<string> permissions = new List<string>();
return permissions;
}
}
}
and we added Application project's ConfigureServices
context.Services.Replace(
ServiceDescriptor.Transient<IPermissionStore, MyPermissionStore>()
);
liangshiwei after this config i can override StaticPermissionSaver and also found the problem.
When running DbMigrator UpdateChangedPermissionsAsync method can not find deleted permission. because PermissionOptions.DeletedPermissions is always null. Also because of matching permissions with name, when permission name changes (in our scenario it changes) UpdateChangedPermissionsAsync thinks that it is new permission. so insert a new permission to database but in database old permission still exists.
The reason we want this is because our application becomes very slow when there are garbage permissions in our database. The system probably enters a loop because there is a difference between the permissions in Redis and the database.
Anyway i changed the StaticPermissionSaver. Thanks
"When we run the DbMigrator project, we want the permissions to be deleted. I don't understand the part with
Configure<AbpPermissionOptions>(options => { options.DeletedPermissions = ...; options.DeletedPermissionGroups = ...; });.
There is no configuration here, and DeletedPermissions and DeletedPermissionGroups are just lists. I tried to override the StaticPermissionSaver and customize it myself. I tried to override it in all layers, including DbMigrator, and when I run DbMigrator, it doesn't hit the breakpoint. So i failed. I need the permissions that have been removed or modified to also be deleted or updated in the database when I run the DbMigrator project. I need your support on this matter.
We wil try it and return
we request that the DB migrator project updates the relevant tables with the latest permissions from the code side when it runs.
What would your recommendation be on this issue?