59 lines
2.6 KiB
C#
59 lines
2.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.Extensions.Localization;
|
|
using Sozsoft.Platform.Localization;
|
|
using Volo.Abp;
|
|
using Volo.Abp.Authorization;
|
|
using Volo.Abp.Authorization.Permissions;
|
|
using Volo.Abp.DependencyInjection;
|
|
|
|
namespace Sozsoft.Mcp;
|
|
|
|
/// <summary>
|
|
/// Aracin arkasindaki platform servislerinden (wizard, custom component, ListForm verisi) ve sinif
|
|
/// duzeyindeki <c>[Authorize]</c>'dan gelen istisnalari istemcinin gorebilecegi mesaja cevirir. MCP'nin
|
|
/// kendi reddi istisna degildir, <see cref="McpProblem"/> olarak doner. SDK cevrilmemis istisnayi
|
|
/// "An error occurred invoking" olarak iletir ve model neden reddedildigini bilemez. Yetki reddinde
|
|
/// eksik yetkiler adiyla, is kurali hatasinda (<see cref="UserFriendlyException"/>) zaten
|
|
/// yerellestirilmis mesaj iletilir. Diger istisnalar cevrilmez: ic ayrinti (SQL, yigin) istemciye sizmaz.
|
|
/// </summary>
|
|
public class McpToolErrorTranslator(
|
|
IPermissionChecker permissionChecker,
|
|
IStringLocalizer<PlatformResource> localizer) : ITransientDependency
|
|
{
|
|
public static bool CanTranslate(Exception exception)
|
|
=> exception is AbpAuthorizationException or UserFriendlyException;
|
|
|
|
public async Task<string> TranslateAsync(Exception exception, string? toolName)
|
|
=> exception is AbpAuthorizationException authorization
|
|
? await DescribeMissingPermissionsAsync(authorization, toolName)
|
|
: exception.Message;
|
|
|
|
/// <summary>
|
|
/// <c>CheckAsync("...")</c> reddi yetki adini tasir; <c>[Authorize]</c> attribute'u tasimaz. Ikinci
|
|
/// durumda aracin adi bilinen yetkileri kullanicinin yetkileriyle karsilastirilir.
|
|
/// </summary>
|
|
private async Task<string> DescribeMissingPermissionsAsync(AbpAuthorizationException exception, string? toolName)
|
|
{
|
|
var candidates = new List<string>(McpToolNames.KnownPermissionsOf(toolName));
|
|
if (exception.Data["PolicyName"] is string policyName && !string.IsNullOrWhiteSpace(policyName))
|
|
{
|
|
candidates.Add(policyName);
|
|
}
|
|
|
|
var granted = await permissionChecker.GetGrantedNamesAsync(candidates);
|
|
var missing = candidates
|
|
.Distinct(StringComparer.Ordinal)
|
|
.Where(permission => !granted.Contains(permission))
|
|
.Select(permission => McpPermissionText.Describe(localizer, permission))
|
|
.ToList();
|
|
|
|
var target = toolName ?? McpConsts.EndpointPath;
|
|
|
|
return missing.Count == 0
|
|
? localizer[McpErrorCodes.PermissionDeniedUnspecified, target]
|
|
: localizer[McpErrorCodes.PermissionDenied, target, string.Join(", ", missing)];
|
|
}
|
|
}
|