- ToolDefinitionOptions + ToolExecutionContext ersetzen lange Parameterlisten in ToolService - AppendToLastMessage-Helper in ChatService eliminiert 5x duplizierte Logik - OpenAiService: ResolveProviderConfig + BuildApiMessages + ConvertToOpenAiTools statt doppeltem Code - Tool-Definitionen aus einer Quelle (Anthropic→OpenAI Konvertierung statt hardcodierter Liste) - KeyCheckDispatcher zentralisiert Key-Check-Dispatch (ApiKeysEndpoint, KeyScanner, GitHubEventScanner) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
146 lines
6.1 KiB
C#
146 lines
6.1 KiB
C#
using System;
|
|
using System.Linq;
|
|
using System.Net.Http;
|
|
using System.Text.RegularExpressions;
|
|
using System.Threading.Tasks;
|
|
|
|
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>
|
|
/// Mappt einen Key-Typ auf den Provider-Namen für den Checker.
|
|
/// Gibt null zurück wenn kein Checker verfügbar ist.
|
|
/// </summary>
|
|
public static string GetCheckerProvider(string type)
|
|
{
|
|
if (IsAnthropic(type)) return "anthropic";
|
|
if (type == "openai_project" || type == "openai_service" || type == "openai_legacy") return "openai";
|
|
if (type == "google_api") return "google";
|
|
if (type == "stripe_live" || type == "stripe_test") return "stripe";
|
|
return null;
|
|
}
|
|
|
|
/// <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
|
|
};
|
|
}
|
|
}
|