using Microsoft.Extensions.Logging;
using OrpaonVision.Core.Results;
using OrpaonVision.Model.Security;
using OrpaonVision.ConfigApp.Infrastructure.Services;
namespace OrpaonVision.ConfigApp.Infrastructure.Services;
///
/// 权限验证服务实现。
///
public sealed class AuthorizationService : IAuthorizationService
{
private readonly ILogger _logger;
private readonly IUserService _userService;
private readonly IUserRoleService _userRoleService;
private readonly IRolePermissionService _rolePermissionService;
// 缓存用户权限
private readonly Dictionary> _userPermissionCache = new();
private readonly Dictionary> _userRoleCache = new();
private readonly Dictionary _cacheTimestamps = new();
///
/// 构造函数。
///
public AuthorizationService(
ILogger logger,
IUserService userService,
IUserRoleService userRoleService,
IRolePermissionService rolePermissionService)
{
_logger = logger;
_userService = userService;
_userRoleService = userRoleService;
_rolePermissionService = rolePermissionService;
}
///
public Result CheckUserHasPermission(Guid userId, string permissionCode)
{
try
{
_logger.LogDebug("检查用户权限: {UserId} - {PermissionCode}", userId, permissionCode);
// 获取用户权限
var permissionsResult = GetUserPermissions(userId);
if (!permissionsResult.Succeeded)
{
return Result.Fail(permissionsResult.Code, permissionsResult.Message, permissionsResult.Errors.ToArray());
}
var hasPermission = permissionsResult.Data.Any(p => p.Code.Equals(permissionCode, StringComparison.OrdinalIgnoreCase));
_logger.LogDebug("用户权限检查结果: {UserId} - {PermissionCode} - {HasPermission}", userId, permissionCode, hasPermission);
return Result.Success(hasPermission, message: hasPermission ? "用户拥有指定权限" : "用户不拥有指定权限");
}
catch (Exception ex)
{
var traceId = Guid.NewGuid().ToString("N");
_logger.LogError(ex, "检查用户权限失败。TraceId: {TraceId}", traceId);
var result = Result.FromException(ex, "CHECK_PERMISSION_FAILED", "检查用户权限失败。", traceId);
return Result.FailWithTrace(result.Code, result.Message, result.TraceId ?? traceId, result.Errors.ToArray());
}
}
///
public Result CheckUserHasPermission(Guid userId, Guid permissionId)
{
try
{
_logger.LogDebug("检查用户权限: {UserId} - {PermissionId}", userId, permissionId);
// 获取用户权限
var permissionsResult = GetUserPermissions(userId);
if (!permissionsResult.Succeeded)
{
return Result.Fail(permissionsResult.Code, permissionsResult.Message, permissionsResult.Errors.ToArray());
}
var hasPermission = permissionsResult.Data.Any(p => p.Id == permissionId);
_logger.LogDebug("用户权限检查结果: {UserId} - {PermissionId} - {HasPermission}", userId, permissionId, hasPermission);
return Result.Success(hasPermission, message: hasPermission ? "用户拥有指定权限" : "用户不拥有指定权限");
}
catch (Exception ex)
{
var traceId = Guid.NewGuid().ToString("N");
_logger.LogError(ex, "检查用户权限失败。TraceId: {TraceId}", traceId);
var result = Result.FromException(ex, "CHECK_PERMISSION_FAILED", "检查用户权限失败。", traceId);
return Result.FailWithTrace(result.Code, result.Message, result.TraceId ?? traceId, result.Errors.ToArray());
}
}
///
public Result CheckUserHasRole(Guid userId, string roleName)
{
try
{
_logger.LogDebug("检查用户角色: {UserId} - {RoleName}", userId, roleName);
// 获取用户角色
var rolesResult = GetUserRoles(userId);
if (!rolesResult.Succeeded)
{
return Result.Fail(rolesResult.Code, rolesResult.Message, rolesResult.Errors.ToArray());
}
var hasRole = rolesResult.Data.Any(r => r.Name.Equals(roleName, StringComparison.OrdinalIgnoreCase));
_logger.LogDebug("用户角色检查结果: {UserId} - {RoleName} - {HasRole}", userId, roleName, hasRole);
return Result.Success(hasRole, message: hasRole ? "用户拥有指定角色" : "用户不拥有指定角色");
}
catch (Exception ex)
{
var traceId = Guid.NewGuid().ToString("N");
_logger.LogError(ex, "检查用户角色失败。TraceId: {TraceId}", traceId);
var result = Result.FromException(ex, "CHECK_ROLE_FAILED", "检查用户角色失败。", traceId);
return Result.FailWithTrace(result.Code, result.Message, result.TraceId ?? traceId, result.Errors.ToArray());
}
}
///
public Result> GetUserPermissions(Guid userId)
{
try
{
// 检查缓存
if (_userPermissionCache.TryGetValue(userId, out var cachedPermissions) &&
_cacheTimestamps.TryGetValue(userId, out var cacheTime) &&
DateTime.UtcNow.Subtract(cacheTime).TotalMinutes < 5) // 5分钟缓存
{
_logger.LogDebug("从缓存获取用户权限: {UserId}", userId);
return Result>.Success(cachedPermissions, message: "从缓存获取用户权限成功。");
}
_logger.LogDebug("重新计算用户权限: {UserId}", userId);
// 获取用户角色
var rolesResult = _userRoleService.GetUserRoles(userId).Result;
if (!rolesResult.Succeeded)
{
return Result>.Fail(rolesResult.Code, rolesResult.Message, rolesResult.Errors.ToArray());
}
var allPermissions = new List();
// 获取每个角色的权限
foreach (var role in rolesResult.Data)
{
var rolePermissionsResult = _rolePermissionService.GetRolePermissions(role.Id).Result;
if (rolePermissionsResult.Succeeded)
{
allPermissions.AddRange(rolePermissionsResult.Data);
}
}
// 去重
var uniquePermissions = allPermissions
.GroupBy(p => p.Id)
.Select(g => g.First())
.ToList();
// 更新缓存
_userPermissionCache[userId] = uniquePermissions;
_cacheTimestamps[userId] = DateTime.UtcNow;
_logger.LogDebug("用户权限计算完成: {UserId} - {PermissionCount}", userId, uniquePermissions.Count);
return Result>.Success(uniquePermissions, message: "获取用户权限成功。");
}
catch (Exception ex)
{
var traceId = Guid.NewGuid().ToString("N");
_logger.LogError(ex, "获取用户权限失败。TraceId: {TraceId}", traceId);
var result = Result.FromException(ex, "GET_USER_PERMISSIONS_FAILED", "获取用户权限失败。", traceId);
return Result>.FailWithTrace(result.Code, result.Message, result.TraceId ?? traceId, result.Errors.ToArray());
}
}
///
public Result> GetUserRoles(Guid userId)
{
try
{
// 检查缓存
if (_userRoleCache.TryGetValue(userId, out var cachedRoles) &&
_cacheTimestamps.TryGetValue(userId, out var cacheTime) &&
DateTime.UtcNow.Subtract(cacheTime).TotalMinutes < 5) // 5分钟缓存
{
_logger.LogDebug("从缓存获取用户角色: {UserId}", userId);
return Result>.Success(cachedRoles, message: "从缓存获取用户角色成功。");
}
_logger.LogDebug("重新获取用户角色: {UserId}", userId);
var rolesResult = _userRoleService.GetUserRoles(userId).Result;
if (!rolesResult.Succeeded)
{
return Result>.Fail(rolesResult.Code, rolesResult.Message, rolesResult.Errors.ToArray());
}
// 更新缓存
_userRoleCache[userId] = rolesResult.Data.ToList();
_cacheTimestamps[userId] = DateTime.UtcNow;
_logger.LogDebug("用户角色获取完成: {UserId} - {RoleCount}", userId, rolesResult.Data.Count);
return Result>.Success(rolesResult.Data.ToList(), message: "获取用户角色成功。");
}
catch (Exception ex)
{
var traceId = Guid.NewGuid().ToString("N");
_logger.LogError(ex, "获取用户角色失败。TraceId: {TraceId}", traceId);
var result = Result.FromException(ex, "GET_USER_ROLES_FAILED", "获取用户角色失败。", traceId);
return Result>.FailWithTrace(result.Code, result.Message, result.TraceId ?? traceId, result.Errors.ToArray());
}
}
///
public Result Authorize(Guid userId, string module, string action)
{
try
{
_logger.LogDebug("权限验证: {UserId} - {Module}.{Action}", userId, module, action);
// 构建权限编码
var permissionCode = $"{module}.{action}";
// 检查用户权限
var checkResult = CheckUserHasPermission(userId, permissionCode);
if (!checkResult.Succeeded)
{
return Result.Fail(checkResult.Code, checkResult.Message, checkResult.Errors.ToArray());
}
_logger.LogDebug("权限验证结果: {UserId} - {Module}.{Action} - {Authorized}", userId, module, action, checkResult.Data);
return Result.Success(checkResult.Data, message: checkResult.Data ? "权限验证通过" : "权限验证失败");
}
catch (Exception ex)
{
var traceId = Guid.NewGuid().ToString("N");
_logger.LogError(ex, "权限验证失败。TraceId: {TraceId}", traceId);
var result = Result.FromException(ex, "AUTHORIZE_FAILED", "权限验证失败。", traceId);
return Result.FailWithTrace(result.Code, result.Message, result.TraceId ?? traceId, result.Errors.ToArray());
}
}
///
public Result> BatchCheckPermissions(Guid userId, List permissionCodes)
{
try
{
if (permissionCodes == null || !permissionCodes.Any())
{
return Result>.Success(new Dictionary(), message: "权限代码列表为空。");
}
_logger.LogDebug("批量权限检查: {UserId} - {Count}个权限", userId, permissionCodes.Count);
// 获取用户权限
var permissionsResult = GetUserPermissions(userId);
if (!permissionsResult.Succeeded)
{
return Result>.Fail(permissionsResult.Code, permissionsResult.Message, permissionsResult.Errors.ToArray());
}
var userPermissions = permissionsResult.Data;
var results = new Dictionary();
foreach (var permissionCode in permissionCodes)
{
var hasPermission = userPermissions.Any(p => p.Code.Equals(permissionCode, StringComparison.OrdinalIgnoreCase));
results[permissionCode] = hasPermission;
}
_logger.LogDebug("批量权限检查完成: {UserId} - {Count}个权限", userId, results.Count);
return Result>.Success(results, message: "批量权限检查成功。");
}
catch (Exception ex)
{
var traceId = Guid.NewGuid().ToString("N");
_logger.LogError(ex, "批量权限检查失败。TraceId: {TraceId}", traceId);
var result = Result.FromException(ex, "BATCH_CHECK_PERMISSIONS_FAILED", "批量权限检查失败。", traceId);
return Result>.FailWithTrace(result.Code, result.Message, result.TraceId ?? traceId, result.Errors.ToArray());
}
}
///
/// 清除用户缓存。
///
public void ClearUserCache(Guid userId)
{
_userPermissionCache.Remove(userId);
_userRoleCache.Remove(userId);
_cacheTimestamps.Remove(userId);
_logger.LogDebug("已清除用户缓存: {UserId}", userId);
}
///
/// 清除所有缓存。
///
public void ClearAllCache()
{
_userPermissionCache.Clear();
_userRoleCache.Clear();
_cacheTimestamps.Clear();
_logger.LogDebug("已清除所有权限缓存");
}
}