using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Volo.Abp; using Volo.Abp.Application.Services; using Volo.Abp.Authorization.Permissions; using Volo.Abp.Caching; using Volo.Abp.DependencyInjection; using Volo.Abp.PermissionManagement; using PermissionGrantCacheItem = WinIn.FasterZ.InterfaceDash.Permissions.PermissionGrantCacheItem; namespace WinIn.FasterZ.AuthSiteCenter.Permissions { public class PermissionStoreAppService : ApplicationService, IPermissionStore, ITransientDependency { public ILogger Logger { get; set; } protected IPermissionGrantRepository PermissionGrantRepository { get; } protected IPermissionDefinitionManager PermissionDefinitionManager { get; } protected IDistributedCache Cache { get; } public PermissionStoreAppService(IPermissionGrantRepository permissionGrantRepository, IDistributedCache cache, IPermissionDefinitionManager permissionDefinitionManager) { PermissionGrantRepository = permissionGrantRepository; Cache = cache; PermissionDefinitionManager = permissionDefinitionManager; Logger = NullLogger.Instance; } [HttpPost] [Route("api/permissions/get-isGranted")] public virtual async Task IsGrantedAsync(string name, string providerName, string providerKey) { return (await GetCacheItemAsync(name, providerName, providerKey).ConfigureAwait(continueOnCapturedContext: false)).IsGranted; } protected virtual async Task GetCacheItemAsync(string name, string providerName, string providerKey) { string cacheKey = CalculateCacheKey(name, providerName, providerKey); Logger.LogDebug("PermissionStore.GetCacheItemAsync: " + cacheKey); PermissionGrantCacheItem cacheItem2 = await Cache.GetAsync(cacheKey).ConfigureAwait(continueOnCapturedContext: false); if (cacheItem2 != null) { Logger.LogDebug("Found in the cache: " + cacheKey); return cacheItem2; } Logger.LogDebug("Not found in the cache: " + cacheKey); cacheItem2 = new PermissionGrantCacheItem(isGranted: false); await SetCacheItemsAsync(providerName, providerKey, name, cacheItem2).ConfigureAwait(continueOnCapturedContext: false); return cacheItem2; } protected virtual async Task SetCacheItemsAsync(string providerName, string providerKey, string currentName, PermissionGrantCacheItem currentCacheItem) { IReadOnlyList permissions = PermissionDefinitionManager.GetPermissionsAsync().Result.ToList(); Logger.LogDebug("Getting all granted permissions from the repository for this provider name,key: " + providerName + "," + providerKey); HashSet hashSet = new HashSet((await PermissionGrantRepository.GetListAsync(providerName, providerKey).ConfigureAwait(continueOnCapturedContext: false)).Select((PermissionGrant p) => p.Name)); Logger.LogDebug($"Setting the cache items. Count: {permissions.Count}"); List> list = new List>(); foreach (PermissionDefinition item in permissions) { bool isGranted = hashSet.Contains(item.Name); list.Add(new KeyValuePair(CalculateCacheKey(item.Name, providerName, providerKey), new PermissionGrantCacheItem(isGranted))); if (item.Name == currentName) { currentCacheItem.IsGranted = isGranted; } } await Cache.SetManyAsync(list).ConfigureAwait(continueOnCapturedContext: false); Logger.LogDebug($"Finished setting the cache items. Count: {permissions.Count}"); } public virtual async Task IsGrantedAsync(string[] names, string providerName, string providerKey) { Check.NotNullOrEmpty(names, "names"); MultiplePermissionGrantResult result = new MultiplePermissionGrantResult(); if (names.Length == 1) { string text = names.First(); Dictionary result2 = result.Result; string key = text; result2.Add(key, (await IsGrantedAsync(names.First(), providerName, providerKey).ConfigureAwait(continueOnCapturedContext: false)) ? PermissionGrantResult.Granted : PermissionGrantResult.Undefined); return result; } foreach (KeyValuePair item in await GetCacheItemsAsync(names, providerName, providerKey).ConfigureAwait(continueOnCapturedContext: false)) { result.Result.Add(GetPermissionNameFormCacheKeyOrNull(item.Key), (item.Value != null && item.Value.IsGranted) ? PermissionGrantResult.Granted : PermissionGrantResult.Undefined); } return result; } protected virtual async Task>> GetCacheItemsAsync(string[] names, string providerName, string providerKey) { List cacheKeys = names.Select((string x) => CalculateCacheKey(x, providerName, providerKey)).ToList(); Logger.LogDebug("PermissionStore.GetCacheItemAsync: " + string.Join(",", cacheKeys)); List> cacheItems = (await Cache.GetManyAsync(cacheKeys).ConfigureAwait(continueOnCapturedContext: false)).ToList(); if (cacheItems.All((KeyValuePair x) => x.Value != null)) { Logger.LogDebug("Found in the cache: " + string.Join(",", cacheKeys)); return cacheItems; } List list = (from x in cacheItems where x.Value == null select x.Key).ToList(); Logger.LogDebug("Not found in the cache: " + string.Join(",", list)); List> source = await SetCacheItemsAsync(providerName, providerKey, list).ConfigureAwait(continueOnCapturedContext: false); List> list2 = new List>(); foreach (string key in cacheKeys) { KeyValuePair keyValuePair = source.FirstOrDefault((KeyValuePair x) => x.Key == key); if (keyValuePair.Value == null) { keyValuePair = cacheItems.FirstOrDefault((KeyValuePair x) => x.Key == key); } list2.Add(new KeyValuePair(key, keyValuePair.Value)); } return list2; } protected virtual async Task>> SetCacheItemsAsync(string providerName, string providerKey, List notCacheKeys) { List permissions = PermissionDefinitionManager.GetPermissionsAsync().Result.ToList(); Logger.LogDebug("Getting not cache granted permissions from the repository for this provider name,key: " + providerName + "," + providerKey); HashSet hashSet = new HashSet((await PermissionGrantRepository.GetListAsync(notCacheKeys.Select(new Func(GetPermissionNameFormCacheKeyOrNull)).ToArray(), providerName, providerKey).ConfigureAwait(continueOnCapturedContext: false)).Select((PermissionGrant p) => p.Name)); Logger.LogDebug($"Setting the cache items. Count: {permissions.Count}"); List> cacheItems = new List>(); foreach (PermissionDefinition item in permissions) { bool isGranted = hashSet.Contains(item.Name); cacheItems.Add(new KeyValuePair(CalculateCacheKey(item.Name, providerName, providerKey), new PermissionGrantCacheItem(isGranted))); } await Cache.SetManyAsync(cacheItems).ConfigureAwait(continueOnCapturedContext: false); Logger.LogDebug($"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) { return PermissionGrantCacheItem.GetPermissionNameFormCacheKeyOrNull(key); } } }