Files
KinginfoGateway/src/Admin/ThingsGateway.Admin.Application/Services/ApiPermission/ApiPermissionService.cs

175 lines
7.6 KiB
C#
Raw Normal View History

2025-01-24 22:42:26 +08:00
// ------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://thingsgateway.cn/
// QQ群605534569
// ------------------------------------------------------------------------------
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.AspNetCore.Mvc.Controllers;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Reflection;
2025-07-13 22:47:14 +08:00
using ThingsGateway.Common.Extension;
2025-01-24 22:42:26 +08:00
namespace ThingsGateway.Admin.Application;
internal sealed class ApiPermissionService : IApiPermissionService
{
private readonly IApiDescriptionGroupCollectionProvider _apiDescriptionGroupCollectionProvider;
public ApiPermissionService(
IOptions<SwaggerGeneratorOptions> generatorOptions,
IApiDescriptionGroupCollectionProvider apiDescriptionGroupCollectionProvider)
{
_apiDescriptionGroupCollectionProvider = apiDescriptionGroupCollectionProvider;
}
/// <inheritdoc />
public List<OpenApiPermissionTreeSelector> ApiPermissionTreeSelector()
{
var cacheKey = $"{nameof(ApiPermissionTreeSelector)}-{CultureInfo.CurrentUICulture.Name}";
var permissions = App.CacheService.Get<List<OpenApiPermissionTreeSelector>>(cacheKey);
if (permissions == null)
{
permissions = new();
Dictionary<string, OpenApiPermissionTreeSelector> groupOpenApis = new();
2025-05-12 10:21:41 +08:00
var apiDescriptions = _apiDescriptionGroupCollectionProvider.ApiDescriptionGroups.Items;
foreach (var item1 in apiDescriptions)
2025-01-24 22:42:26 +08:00
{
2025-05-12 10:21:41 +08:00
foreach (var item in item1.Items)
{
if (item.ActionDescriptor is ControllerActionDescriptor controllerActionDescriptor)
{
OpenApiPermissionTreeSelector openApiPermissionTreeSelector = new() { ApiName = controllerActionDescriptor.ControllerName ?? "Default" };
groupOpenApis.TryAdd(openApiPermissionTreeSelector.ApiName, openApiPermissionTreeSelector);
}
}
2025-01-24 22:42:26 +08:00
}
// 获取所有需要数据权限的控制器
var controllerTypes =
App.EffectiveTypes.Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass && u.IsDefined(typeof(RolePermissionAttribute), false));
2025-05-12 10:21:41 +08:00
//foreach (var groupOpenApi in groupOpenApis)
2025-01-24 22:42:26 +08:00
{
foreach (var apiDescriptionGroup in apiDescriptions)
{
var routes = apiDescriptionGroup.Items.Where(api => api.ActionDescriptor is ControllerActionDescriptor);
Dictionary<string, OpenApiPermissionTreeSelector> openApiPermissionTreeSelectorDict = new();
foreach (var route in routes)
{
var actionDesc = (ControllerActionDescriptor)route.ActionDescriptor;
if (!actionDesc.ControllerTypeInfo.CustomAttributes.Any(a => a.AttributeType == typeof(RolePermissionAttribute)))
continue;
var controllerDescription = actionDesc.ControllerTypeInfo.GetTypeDisplayName();
if (openApiPermissionTreeSelectorDict.TryGetValue(actionDesc.ControllerName, out var openApiControllerGroup))
{
}
else
{
openApiControllerGroup = new() { ApiName = controllerDescription, ApiRoute = actionDesc.ControllerName };
openApiPermissionTreeSelectorDict.Add(actionDesc.ControllerName, openApiControllerGroup);
}
var ignoreRolePermission = actionDesc.MethodInfo.CustomAttributes.Any(a => a.AttributeType == typeof(IgnoreRolePermissionAttribute));
if (ignoreRolePermission)
continue;
var routePath = route.RelativePath;
var methodDesc = actionDesc.MethodInfo.DeclaringType.GetMethodDisplayName(actionDesc.MethodInfo.Name);
//添加到权限列表
openApiControllerGroup.Children ??= new();
openApiControllerGroup.Children.Add(new OpenApiPermissionTreeSelector
{
ApiName = methodDesc,
ApiRoute = routePath,
});
}
2025-05-12 10:21:41 +08:00
if (openApiPermissionTreeSelectorDict.Values.Any(a => a.Children.Count > 0))
permissions.AddRange(openApiPermissionTreeSelectorDict.Values);
2025-01-24 22:42:26 +08:00
}
}
App.CacheService.Set(cacheKey, permissions);
}
return permissions;
}
/// <summary>
/// 获取路由地址名称
/// </summary>
/// <param name="controllerName">控制器地址</param>
/// <param name="template">路由名称</param>
/// <returns></returns>
public string GetRouteName(string controllerName, string template)
{
if (!template.StartsWith('/'))
template = "/" + template;//如果路由名称不是/开头则加上/防止控制器没写
if (template.Contains("[controller]"))
{
controllerName = controllerName.Replace("Controller", "");//去掉Controller
controllerName = controllerName.ToLowerCamelCase();//转首字母小写写
template = template.Replace("[controller]", controllerName);//替换[controller]
}
return template;
}
/// <inheritdoc />
public IEnumerable<PermissionTreeSelector> PermissionTreeSelector(IEnumerable<string> routes)
{
List<PermissionTreeSelector> permissions = PermissionTreeSelector();
var hashSet = routes.ToHashSet();
return permissions.Where(a => hashSet.Contains(a.ApiRoute));
2025-01-24 22:42:26 +08:00
}
/// <inheritdoc />
public List<PermissionTreeSelector> PermissionTreeSelector()
{
var cacheKey = $"{nameof(PermissionTreeSelector)}-{CultureInfo.CurrentUICulture.Name}";
var permissions = App.CacheService.GetOrAdd(cacheKey, entry =>
{
List<PermissionTreeSelector> permissions = new();//权限列表
// 获取所有需要数据权限的控制器
var controllerTypes = App.EffectiveTypes.Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass
&& u.IsDefined(typeof(AuthorizeAttribute), false)
&& u.IsDefined(typeof(Microsoft.AspNetCore.Components.RouteAttribute), false));
foreach (var controller in controllerTypes)
{
//获取数据权限特性
var route = controller.GetCustomAttributes<Microsoft.AspNetCore.Components.RouteAttribute>().FirstOrDefault();
if (route == null) continue;
var apiRoute = GetRouteName(controller.Name, route.Template);//赋值路由名称
var desc = controller.GetTypeDisplayName();
//添加到权限列表
permissions.Add(new PermissionTreeSelector
{
ApiName = desc,
ApiRoute = apiRoute,
});
}
return permissions;
});
return permissions;
}
}