Files
gott/Services/GoogleKeyChecker.cs
T
Meleki c8859a89d0 Multi-Provider Key Scanner + Checker (OpenAI, Google, 15 Key-Typen)
- KeyPatterns.cs: Zentrale Pattern-Klasse für 15 Key-Typen
  (Anthropic, OpenAI, Google, AWS, GitHub, GitLab, HuggingFace, Stripe, SendGrid, Slack)
- OpenAiKeyChecker.cs: Prüft sk-proj/sk-svcacct/sk- Keys via /v1/models
  (Org, Modelle, RPM/TPM, Tier-Erkennung Free bis 5+)
- GoogleKeyChecker.cs: Prüft AIza-Keys via Gemini /v1/models
  (Gemini-Modelle, Maps-Key-Erkennung)
- KeyScannerService + GitHubEventScannerService: Dispatch nach Key-Typ
- ApiKeysEndpoint: GET /scanned/summary + ?type= Filter
- Frontend: 2-stufige UI (Typ-Übersicht → Keys pro Typ)
2026-03-13 20:43:20 +01:00

94 lines
3.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Linq;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;
namespace Gott.Services
{
public class GoogleCheckResult
{
public string Status { get; set; } // "ok", "invalid", "disabled", "error"
public string Message { get; set; }
public string[] Models { get; set; }
}
public static class GoogleKeyChecker
{
public static async Task<GoogleCheckResult> CheckKeyAsync(IHttpClientFactory httpFactory, string apiKey)
{
try
{
var client = httpFactory.CreateClient();
client.Timeout = TimeSpan.FromSeconds(30);
// Gemini / Generative Language API – listet verfügbare Modelle
var url = "https://generativelanguage.googleapis.com/v1/models?key=" + apiKey;
var resp = await client.GetAsync(url);
var statusCode = (int)resp.StatusCode;
if (statusCode == 400)
return new GoogleCheckResult { Status = "invalid", Message = "API-Key ungültig (400)" };
if (statusCode == 403)
{
// Key gültig, aber Gemini API nicht aktiviert (z.B. Maps-Key)
var errorBody = await resp.Content.ReadAsStringAsync();
if (errorBody.Contains("API_KEY_INVALID", StringComparison.OrdinalIgnoreCase))
return new GoogleCheckResult { Status = "invalid", Message = "API-Key ungültig (403)" };
return new GoogleCheckResult { Status = "disabled", Message = "Key gültig, aber Gemini API nicht aktiviert (403)" };
}
if (statusCode == 429)
return new GoogleCheckResult { Status = "rate_limited", Message = "Rate Limited (429)" };
if (statusCode >= 400)
return new GoogleCheckResult { Status = "error", Message = "API-Fehler (" + statusCode + ")" };
// 200 OK → Key gültig + Gemini API aktiv
var body = await resp.Content.ReadAsStringAsync();
var doc = JsonDocument.Parse(body);
string[] models = Array.Empty<string>();
if (doc.RootElement.TryGetProperty("models", out var modelsArr))
{
var interestingPrefixes = new[] { "gemini" };
models = modelsArr.EnumerateArray()
.Where(m => m.TryGetProperty("name", out _))
.Select(m => m.GetProperty("name").GetString())
.Where(n => n != null)
.Select(n => n.StartsWith("models/", StringComparison.Ordinal) ? n.Substring(7) : n)
.Where(n => interestingPrefixes.Any(p => n.StartsWith(p, StringComparison.OrdinalIgnoreCase)))
.Distinct()
.OrderBy(x => x)
.ToArray();
}
// Plan-Erkennung
string plan;
if (models.Any(m => m.Contains("2.5", StringComparison.OrdinalIgnoreCase)
|| m.Contains("ultra", StringComparison.OrdinalIgnoreCase)))
plan = "Premium";
else if (models.Any(m => m.Contains("pro", StringComparison.OrdinalIgnoreCase)))
plan = "Standard";
else if (models.Any(m => m.Contains("flash", StringComparison.OrdinalIgnoreCase)))
plan = "Basic";
else
plan = "Free";
return new GoogleCheckResult
{
Status = "ok",
Message = models.Length + " Gemini-Modelle · " + plan,
Models = models
};
}
catch (Exception ex)
{
return new GoogleCheckResult { Status = "error", Message = ex.Message };
}
}
}
}