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 grants = await permissionChecker.IsGrantedAsync([.. candidates.Distinct(StringComparer.Ordinal)]); var missing = grants.Result .Where(result => result.Value != PermissionGrantResult.Granted) .Select(result => McpPermissionText.Describe(localizer, result.Key)) .ToList(); var target = toolName ?? McpConsts.EndpointPath; return missing.Count == 0 ? localizer[McpErrorCodes.PermissionDeniedUnspecified, target] : localizer[McpErrorCodes.PermissionDenied, target, string.Join(", ", missing)]; } }