csharpdeeb25a2 | 1 | using System.Text.Json; |
| 2 | |
| 3 | namespace CascadeIDE.Features.Forge.Infrastructure; |
| 4 | |
| 5 | /// <summary>Interop с <c>forge auth login</c> → <c>~/.forge/credentials.json</c> (FORGE-ADR-0010).</summary> |
| 6 | public static class ForgeSharedCredentialReader |
| 7 | { |
| 8 | private static readonly JsonSerializerOptions JsonOptions = new() { PropertyNameCaseInsensitive = true }; |
| 9 | |
| 10 | public static string? TryGetToken(string baseUrl) |
| 11 | { |
| 12 | try |
| 13 | { |
| 14 | var path = Path.Combine( |
| 15 | Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), |
| 16 | ".forge", |
| 17 | "credentials.json"); |
| 18 | if (!File.Exists(path)) |
| 19 | return null; |
| 20 | |
| 21 | var json = File.ReadAllText(path); |
| 22 | var file = JsonSerializer.Deserialize<ForgeSharedCredentialsFile>(json, JsonOptions); |
| 23 | if (file?.Hosts is null) |
| 24 | return null; |
| 25 | |
| 26 | var key = ForgeLensHostUrl.NormalizeKey(baseUrl); |
| 27 | return file.Hosts.TryGetValue(key, out var entry) |
| 28 | && !string.IsNullOrWhiteSpace(entry.Token) |
| 29 | ? entry.Token.Trim() |
| 30 | : null; |
| 31 | } |
| 32 | catch |
| 33 | { |
| 34 | return null; |
| 35 | } |
| 36 | } |
| 37 | |
| 38 | private sealed class ForgeSharedCredentialsFile |
| 39 | { |
| 40 | public Dictionary<string, ForgeSharedHostCredential> Hosts { get; set; } = |
| 41 | new(StringComparer.OrdinalIgnoreCase); |
| 42 | } |
| 43 | |
| 44 | private sealed class ForgeSharedHostCredential |
| 45 | { |
| 46 | public string Token { get; set; } = ""; |
| 47 | } |
| 48 | } |
| 49 | |
View only · write via MCP/CIDE