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; /// /// Aracin arkasindaki platform servislerinden (wizard, custom component, ListForm verisi) ve sinif /// duzeyindeki [Authorize]'dan gelen istisnalari istemcinin gorebilecegi mesaja cevirir. MCP'nin /// kendi reddi istisna degildir, olarak doner. SDK cevrilmemis istisnayi /// "An error occurred invoking" olarak iletir ve model neden reddedildigini bilemez. Yetki reddinde /// eksik yetkiler adiyla, is kurali hatasinda () zaten /// yerellestirilmis mesaj iletilir. Diger istisnalar cevrilmez: ic ayrinti (SQL, yigin) istemciye sizmaz. /// public class McpToolErrorTranslator( IPermissionChecker permissionChecker, IStringLocalizer localizer) : ITransientDependency { public static bool CanTranslate(Exception exception) => exception is AbpAuthorizationException or UserFriendlyException; public async Task TranslateAsync(Exception exception, string? toolName) => exception is AbpAuthorizationException authorization ? await DescribeMissingPermissionsAsync(authorization, toolName) : exception.Message; /// /// CheckAsync("...") reddi yetki adini tasir; [Authorize] attribute'u tasimaz. Ikinci /// durumda aracin adi bilinen yetkileri kullanicinin yetkileriyle karsilastirilir. /// private async Task DescribeMissingPermissionsAsync(AbpAuthorizationException exception, string? toolName) { var candidates = new List(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)]; } }