using System;
using System.Linq;
using System.Text.RegularExpressions;
namespace Gott.Services;
///
/// Zentrale Definition aller Key-Patterns für den Secret Scanner.
/// Wird von KeyScannerService und GitHubEventScannerService gemeinsam genutzt.
///
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"),
// 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"),
};
///
/// Patterns die für GitHub Code Search / Serper geeignet sind.
/// Filtert zu generische Suchterme aus (z.B. "sk-", "SG.", "SK").
///
public static readonly (string Pattern, string SearchTerm, string Type)[] ForCodeSearch =
All.Where(p => p.SearchTerm.Length >= 5).ToArray();
// ── Kompilierte Regexe (einmalig, alle Patterns) ──
public static readonly Regex[] Compiled = All
.Select(p => new Regex(p.Pattern, RegexOptions.Compiled))
.ToArray();
/// Erkennt den Key-Typ anhand des Prefixes.
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";
return "unknown";
}
/// Prüft ob ein Key-Typ zu Anthropic gehört (für automatische Validierung).
public static bool IsAnthropic(string type)
{
return type == "anthropic_oauth" || type == "anthropic_api" || type == "anthropic_unknown";
}
/// Menschenlesbarer Name für den Key-Typ.
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",
_ => type
};
}
}