|
|
@ -1,37 +1,28 @@ |
|
|
using System; |
|
|
using System.Threading.Tasks; |
|
|
using System.Threading.Tasks; |
|
|
|
|
|
using Microsoft.Extensions.Caching.Distributed; |
|
|
|
|
|
using Volo.Abp.Authorization.Permissions; |
|
|
using Volo.Abp.Authorization.Permissions; |
|
|
|
|
|
using Volo.Abp.Caching; |
|
|
using Volo.Abp.DependencyInjection; |
|
|
using Volo.Abp.DependencyInjection; |
|
|
using Volo.Abp.Domain.Entities.Events; |
|
|
using Volo.Abp.Domain.Entities.Events; |
|
|
using Volo.Abp.EventBus; |
|
|
using Volo.Abp.EventBus; |
|
|
using Volo.Abp.Json; |
|
|
|
|
|
using Volo.Abp.MultiTenancy; |
|
|
using Volo.Abp.MultiTenancy; |
|
|
using Volo.Abp.Threading; |
|
|
|
|
|
|
|
|
|
|
|
namespace Volo.Abp.Permissions |
|
|
namespace Volo.Abp.Permissions |
|
|
{ |
|
|
{ |
|
|
//TODO: Extract cache invalidate logic to another class
|
|
|
//TODO: Extract cache invalidate logic to another class
|
|
|
public class PermissionStore : AbpServiceBase, IPermissionStore, IAsyncEventHandler<EntityChangedEventData<PermissionGrant>>, ITransientDependency |
|
|
public class PermissionStore : IPermissionStore, IAsyncEventHandler<EntityChangedEventData<PermissionGrant>>, ITransientDependency |
|
|
{ |
|
|
{ |
|
|
private readonly IPermissionGrantRepository _permissionGrantRepository; |
|
|
protected IPermissionGrantRepository PermissionGrantRepository { get; } |
|
|
private readonly ICurrentTenant _currentTenant; |
|
|
protected IDistributedCache<PermissionGrantCacheItem> Cache { get; } |
|
|
private readonly ICancellationTokenProvider _cancellationTokenProvider; |
|
|
protected ICurrentTenant CurrentTenant { get; } |
|
|
private readonly IDistributedCache _distributedCache; |
|
|
|
|
|
private readonly IJsonSerializer _jsonSerializer; |
|
|
|
|
|
|
|
|
|
|
|
public PermissionStore( |
|
|
public PermissionStore( |
|
|
IPermissionGrantRepository permissionGrantRepository, |
|
|
IPermissionGrantRepository permissionGrantRepository, |
|
|
IDistributedCache distributedCache, |
|
|
IDistributedCache<PermissionGrantCacheItem> cache, |
|
|
ICancellationTokenProvider cancellationTokenProvider, |
|
|
ICurrentTenant currentTenant) |
|
|
ICurrentTenant currentTenant, |
|
|
|
|
|
IJsonSerializer jsonSerializer) |
|
|
|
|
|
{ |
|
|
{ |
|
|
_permissionGrantRepository = permissionGrantRepository; |
|
|
PermissionGrantRepository = permissionGrantRepository; |
|
|
_distributedCache = distributedCache; |
|
|
Cache = cache; |
|
|
_cancellationTokenProvider = cancellationTokenProvider; |
|
|
CurrentTenant = currentTenant; |
|
|
_currentTenant = currentTenant; |
|
|
|
|
|
_jsonSerializer = jsonSerializer; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public async Task<bool> IsGrantedAsync(string name, string providerName, string providerKey) |
|
|
public async Task<bool> IsGrantedAsync(string name, string providerName, string providerKey) |
|
|
@ -39,53 +30,46 @@ namespace Volo.Abp.Permissions |
|
|
return (await GetCacheItemAsync(name, providerName, providerKey)).IsGranted; |
|
|
return (await GetCacheItemAsync(name, providerName, providerKey)).IsGranted; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public virtual Task HandleEventAsync(EntityChangedEventData<PermissionGrant> eventData) |
|
|
public virtual async Task HandleEventAsync(EntityChangedEventData<PermissionGrant> eventData) |
|
|
{ |
|
|
{ |
|
|
return _distributedCache.RemoveAsync( |
|
|
var cacheKey = CalculateCacheKey( |
|
|
CalculateCacheKey( |
|
|
eventData.Entity.Name, |
|
|
eventData.Entity.Name, |
|
|
eventData.Entity.ProviderName, |
|
|
eventData.Entity.ProviderName, |
|
|
eventData.Entity.ProviderKey |
|
|
eventData.Entity.ProviderKey, |
|
|
|
|
|
eventData.Entity.TenantId |
|
|
|
|
|
) |
|
|
|
|
|
); |
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
using (CurrentTenant.Change(eventData.Entity.TenantId)) |
|
|
|
|
|
{ |
|
|
|
|
|
await Cache.RemoveAsync(cacheKey); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
protected virtual async Task<PermissionGrantCacheItem> GetCacheItemAsync(string name, string providerName, string providerKey) |
|
|
protected virtual async Task<PermissionGrantCacheItem> GetCacheItemAsync(string name, string providerName, string providerKey) |
|
|
{ |
|
|
{ |
|
|
var cacheKey = CalculateCacheKey(name, providerName, providerKey, _currentTenant.Id); |
|
|
var cacheKey = CalculateCacheKey(name, providerName, providerKey); |
|
|
var cachedString = await _distributedCache.GetStringAsync(cacheKey, _cancellationTokenProvider.Token); |
|
|
var cacheItem = await Cache.GetAsync(cacheKey); |
|
|
|
|
|
|
|
|
if (cachedString != null) |
|
|
if (cacheItem != null) |
|
|
{ |
|
|
{ |
|
|
return _jsonSerializer.Deserialize<PermissionGrantCacheItem>(cachedString); |
|
|
return cacheItem; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
var cacheItem = new PermissionGrantCacheItem( |
|
|
cacheItem = new PermissionGrantCacheItem( |
|
|
name, |
|
|
name, |
|
|
await _permissionGrantRepository.FindAsync(name, providerName, providerKey) != null |
|
|
await PermissionGrantRepository.FindAsync(name, providerName, providerKey) != null |
|
|
); |
|
|
); |
|
|
|
|
|
|
|
|
await _distributedCache.SetStringAsync( |
|
|
await Cache.SetAsync( |
|
|
cacheKey, |
|
|
cacheKey, |
|
|
_jsonSerializer.Serialize(cacheItem), |
|
|
cacheItem |
|
|
new DistributedCacheEntryOptions { SlidingExpiration = TimeSpan.FromMinutes(20) }, |
|
|
|
|
|
_cancellationTokenProvider.Token |
|
|
|
|
|
); |
|
|
); |
|
|
|
|
|
|
|
|
return cacheItem; |
|
|
return cacheItem; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
protected virtual string CalculateCacheKey(string name, string providerName, string providerKey, Guid? tenantId) |
|
|
protected virtual string CalculateCacheKey(string name, string providerName, string providerKey) |
|
|
{ |
|
|
{ |
|
|
var key = "N:" + "PermissionGrant" + "#P:" + providerName + "#K:" + providerKey + "#N:" + name; |
|
|
return "pn:" + providerName + ",pk:" + providerKey + ",n:" + name; |
|
|
|
|
|
|
|
|
if (tenantId.HasValue) |
|
|
|
|
|
{ |
|
|
|
|
|
key += "#T:" + tenantId.Value; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return key; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|