Files
gott/Services/KeyPatterns.cs
T
Meleki e61f3ef082 feat: DB-Explorer, Scanner-KeyTypes-Setting, Stripe-Checker, Anthropic-Auth-Fix, Progress-Tracking
Backend:
- Neuer Database Explorer Endpoint (GET /api/admin/db/tables, GET /api/admin/db/tables/{name})
- DatabaseService: public GetConnection() Methode
- StripeKeyChecker: 2-Schritt-Check (/v1/balance + /v1/account), erkennt Live/Test, Balance, Account-Details
- AnthropicKeyChecker: Auth-Header fix (x-api-key für API-Keys, Bearer für OAuth), 400-Handler für credit balance
- KeyPatterns: Stripe einkommentiert, Krea AI Pattern, AllTypes-Array, MinLength 4
- ServerSettingsService: string_array Typ (Get/SetStringArray), ScannerKeyTypes Setting mit Checkbox-Optionen
- ServerSettingsEndpoint: string_array Speichern (Array/CSV)
- KeyScannerService: GetActiveSearchPatterns() filtert nach ScannerKeyTypes, Progress-Tracking
- GitHubEventScannerService: CheckNewKeys nur für aktuelle Poll-Keys (statt alle unchecked), klarere Log-Meldung

Frontend:
- Database Explorer Page: Tabellenliste mit Klick -> Tabelleninhalt, Pagination, sticky Header
- Server Settings: Checkbox-Gruppe für string_array (Alle/Keine Buttons)
- API Keys: adoptedApiKeyId Fix (leerer String == null)
- Dashboard: DB-Explorer Link für Admins
- Scan-Progress: Live-Fortschritt mit Phase/Detail/Counter
2026-03-14 16:19:13 +01:00

131 lines
5.5 KiB
C#

using System;
using System.Linq;
using System.Text.RegularExpressions;
namespace Gott.Services;
/// <summary>
/// Zentrale Definition aller Key-Patterns für den Secret Scanner.
/// Wird von KeyScannerService und GitHubEventScannerService gemeinsam genutzt.
/// </summary>
public static class KeyPatterns
{
// ── Pattern-Definitionen ──
// (Regex-Pattern, Suchbegriff für GitHub Code Search / Serper, Key-Typ)
public static readonly (string Pattern, string SearchTerm, string Type)[] All =
{
// Anthropic
(@"sk-ant-oat01-[A-Za-z0-9_\-]{95}", "sk-ant-oat01", "anthropic_oauth"),
(@"sk-ant-api03-[A-Za-z0-9_\-]{95}", "sk-ant-api03", "anthropic_api"),
// Krea AI (UUID:Base32Token)
(@"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}:[A-Za-z0-9]{32}", "krea", "krea_ai"),
// OpenAI
(@"sk-proj-[A-Za-z0-9_\-]{80,200}", "sk-proj-", "openai_project"),
(@"sk-svcacct-[A-Za-z0-9_\-]{80,200}", "sk-svcacct-", "openai_service"),
(@"sk-[A-Za-z0-9]{48}", "sk-", "openai_legacy"),
// Google / Gemini
(@"AIza[0-9A-Za-z_\-]{35}", "AIzaSy", "google_api"),
// AWS
(@"AKIA[0-9A-Z]{16}", "AKIA", "aws_access_key"),
// GitHub
(@"ghp_[A-Za-z0-9]{36}", "ghp_", "github_pat"),
(@"gho_[A-Za-z0-9]{36}", "gho_", "github_oauth"),
// GitLab
(@"glpat-[A-Za-z0-9_\-]{20}", "glpat-", "gitlab_pat"),
// HuggingFace
(@"hf_[A-Za-z0-9]{34}", "hf_", "huggingface"),
// Stripe
(@"sk_live_[0-9a-zA-Z]{24,}", "sk_live_", "stripe_live"),
(@"sk_test_[0-9a-zA-Z]{24,}", "sk_test_", "stripe_test"),
// SendGrid
(@"SG\.[A-Za-z0-9_\-]{22}\.[A-Za-z0-9_\-]{43}", "SG.", "sendgrid"),
// Slack (xoxb ist häufigster Typ)
(@"xoxb-[0-9]{10,13}-[A-Za-z0-9\-]{20,}", "xoxb-", "slack"),
};
/// <summary>
/// Patterns die für GitHub Code Search / Serper geeignet sind.
/// Filtert zu generische Suchterme aus (z.B. "sk-", "SG.", "SK").
/// </summary>
public static readonly (string Pattern, string SearchTerm, string Type)[] ForCodeSearch =
All.Where(p => p.SearchTerm.Length >= 4).ToArray();
// ── Kompilierte Regexe (einmalig, alle Patterns) ──
public static readonly Regex[] Compiled = All
.Select(p => new Regex(p.Pattern, RegexOptions.Compiled))
.ToArray();
/// <summary>Alle verfügbaren Key-Typ-IDs (für Settings).</summary>
public static readonly string[] AllTypes = All.Select(p => p.Type).Distinct().ToArray();
/// <summary>Erkennt den Key-Typ anhand des Prefixes.</summary>
public static string DetectType(string key)
{
// Spezifischere Patterns zuerst prüfen (Reihenfolge wichtig!)
if (key.StartsWith("sk-ant-oat01-", StringComparison.Ordinal)) return "anthropic_oauth";
if (key.StartsWith("sk-ant-api03-", StringComparison.Ordinal)) return "anthropic_api";
if (key.StartsWith("sk-ant-", StringComparison.Ordinal)) return "anthropic_unknown";
if (key.StartsWith("sk-proj-", StringComparison.Ordinal)) return "openai_project";
if (key.StartsWith("sk-svcacct-", StringComparison.Ordinal)) return "openai_service";
if (key.StartsWith("sk_live_", StringComparison.Ordinal)) return "stripe_live";
if (key.StartsWith("sk_test_", StringComparison.Ordinal)) return "stripe_test";
if (key.StartsWith("sk-", StringComparison.Ordinal)) return "openai_legacy";
if (key.StartsWith("AIza", StringComparison.Ordinal)) return "google_api";
if (key.StartsWith("AKIA", StringComparison.Ordinal)) return "aws_access_key";
if (key.StartsWith("ghp_", StringComparison.Ordinal)) return "github_pat";
if (key.StartsWith("gho_", StringComparison.Ordinal)) return "github_oauth";
if (key.StartsWith("glpat-", StringComparison.Ordinal)) return "gitlab_pat";
if (key.StartsWith("hf_", StringComparison.Ordinal)) return "huggingface";
if (key.StartsWith("SG.", StringComparison.Ordinal)) return "sendgrid";
if (key.StartsWith("xoxb-", StringComparison.Ordinal)) return "slack";
// Krea AI: UUID:Token Format
if (key.Length == 69 && key[8] == '-' && key[13] == '-' && key[18] == '-' && key[23] == '-' && key[36] == ':')
return "krea_ai";
return "unknown";
}
/// <summary>Prüft ob ein Key-Typ zu Anthropic gehört (für automatische Validierung).</summary>
public static bool IsAnthropic(string type)
{
return type == "anthropic_oauth" || type == "anthropic_api" || type == "anthropic_unknown";
}
/// <summary>Menschenlesbarer Name für den Key-Typ.</summary>
public static string DisplayName(string type)
{
return type switch
{
"anthropic_oauth" => "Anthropic OAuth",
"anthropic_api" => "Anthropic API",
"anthropic_unknown" => "Anthropic",
"openai_project" => "OpenAI Project",
"openai_service" => "OpenAI Service",
"openai_legacy" => "OpenAI Legacy",
"google_api" => "Google / Gemini",
"aws_access_key" => "AWS Access Key",
"github_pat" => "GitHub PAT",
"github_oauth" => "GitHub OAuth",
"gitlab_pat" => "GitLab PAT",
"huggingface" => "HuggingFace",
"stripe_live" => "Stripe Live",
"stripe_test" => "Stripe Test",
"sendgrid" => "SendGrid",
"slack" => "Slack",
"krea_ai" => "Krea AI",
_ => type
};
}
}