mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-07-02 09:44:25 +08:00
- Introduced `AuthKind` and `AuthSourceKind` methods for improved credential type and source classification. - Replaced legacy fallback logic with normalized attribute-based handling in `AuthKind`. - Consolidated metadata inspection for both API key and OAuth attributes. - Updated calls to replace direct `AccountInfo` usage with `AuthKind` and `AuthSourceKind`. - Enhanced unit tests to validate explicit and fallback credential resolution scenarios.
139 lines
3.4 KiB
Go
139 lines
3.4 KiB
Go
package auth
|
|
|
|
import "strings"
|
|
|
|
const (
|
|
AuthKindAPIKey = "apikey"
|
|
AuthKindOAuth = "oauth"
|
|
|
|
AuthSourceConfig = "config"
|
|
AuthSourceFile = "file"
|
|
AuthSourceGit = "git"
|
|
AuthSourceMemory = "memory"
|
|
AuthSourceObjectStore = "objectstore"
|
|
AuthSourcePostgres = "postgres"
|
|
|
|
AttributeAPIKey = "api_key"
|
|
AttributeAuthKind = "auth_kind"
|
|
AttributePath = "path"
|
|
AttributeRuntimeOnly = "runtime_only"
|
|
AttributeSource = "source"
|
|
AttributeSourceBackend = "source_backend"
|
|
)
|
|
|
|
// AuthKind returns the credential kind using explicit metadata first and legacy
|
|
// field-shape fallbacks second.
|
|
func (a *Auth) AuthKind() string {
|
|
if a == nil {
|
|
return ""
|
|
}
|
|
if kind := normalizeAuthKind(authAttribute(a, AttributeAuthKind)); kind != "" {
|
|
return kind
|
|
}
|
|
if kind := normalizeAuthKind(authMetadataString(a, AttributeAuthKind)); kind != "" {
|
|
return kind
|
|
}
|
|
if authAttribute(a, AttributeAPIKey) != "" {
|
|
return AuthKindAPIKey
|
|
}
|
|
if authHasOAuthMetadata(a) {
|
|
return AuthKindOAuth
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// AuthSourceKind returns where the Auth entry came from at runtime.
|
|
func (a *Auth) AuthSourceKind() string {
|
|
if a == nil {
|
|
return ""
|
|
}
|
|
if strings.EqualFold(authAttribute(a, AttributeRuntimeOnly), "true") {
|
|
return AuthSourceMemory
|
|
}
|
|
if source := normalizeAuthSourceKind(authAttribute(a, AttributeSourceBackend)); source != "" {
|
|
return source
|
|
}
|
|
source := authAttribute(a, AttributeSource)
|
|
if source != "" {
|
|
sourceLower := strings.ToLower(source)
|
|
if strings.HasPrefix(sourceLower, AuthSourceConfig+":") {
|
|
return AuthSourceConfig
|
|
}
|
|
if normalized := normalizeAuthSourceKind(source); normalized != "" {
|
|
return normalized
|
|
}
|
|
return AuthSourceFile
|
|
}
|
|
if authAttribute(a, AttributePath) != "" {
|
|
return AuthSourceFile
|
|
}
|
|
if strings.TrimSpace(a.FileName) != "" {
|
|
return AuthSourceFile
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func normalizeAuthKind(kind string) string {
|
|
switch strings.ToLower(strings.TrimSpace(kind)) {
|
|
case AuthKindAPIKey, "api_key", "api-key":
|
|
return AuthKindAPIKey
|
|
case AuthKindOAuth, "oauth2":
|
|
return AuthKindOAuth
|
|
default:
|
|
return ""
|
|
}
|
|
}
|
|
|
|
func normalizeAuthSourceKind(source string) string {
|
|
switch strings.ToLower(strings.TrimSpace(source)) {
|
|
case AuthSourceConfig:
|
|
return AuthSourceConfig
|
|
case AuthSourceFile, "filesystem":
|
|
return AuthSourceFile
|
|
case AuthSourceGit:
|
|
return AuthSourceGit
|
|
case AuthSourceMemory, "runtime", "runtime_only":
|
|
return AuthSourceMemory
|
|
case AuthSourceObjectStore, "object-store":
|
|
return AuthSourceObjectStore
|
|
case AuthSourcePostgres, "postgresql", "database", "db":
|
|
return AuthSourcePostgres
|
|
default:
|
|
return ""
|
|
}
|
|
}
|
|
|
|
func authHasOAuthMetadata(auth *Auth) bool {
|
|
if auth == nil || len(auth.Metadata) == 0 {
|
|
return false
|
|
}
|
|
for _, key := range []string{"access_token", "refresh_token", "id_token", "email", "token_type", "expires_at", "expired"} {
|
|
if authMetadataString(auth, key) != "" {
|
|
return true
|
|
}
|
|
}
|
|
if token, ok := auth.Metadata["token"].(map[string]any); ok && len(token) > 0 {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func authAttribute(auth *Auth, key string) string {
|
|
if auth == nil || auth.Attributes == nil {
|
|
return ""
|
|
}
|
|
return strings.TrimSpace(auth.Attributes[key])
|
|
}
|
|
|
|
func authMetadataString(auth *Auth, key string) string {
|
|
if auth == nil || auth.Metadata == nil {
|
|
return ""
|
|
}
|
|
switch value := auth.Metadata[key].(type) {
|
|
case string:
|
|
return strings.TrimSpace(value)
|
|
default:
|
|
return ""
|
|
}
|
|
}
|