agent-orchestrator/backend/internal/adapters/agent/qwen/auth.go

117 lines
2.7 KiB
Go

package qwen
import (
"context"
"encoding/json"
"os"
"path/filepath"
"strings"
"github.com/aoagents/agent-orchestrator/backend/internal/adapters/agent/authprobe"
"github.com/aoagents/agent-orchestrator/backend/internal/ports"
)
var _ ports.AgentAuthChecker = (*Plugin)(nil)
// AuthStatus returns the plugin's local authentication status.
func (p *Plugin) AuthStatus(ctx context.Context) (ports.AgentAuthStatus, error) {
binary, err := p.ResolveBinary(ctx)
if err != nil {
return ports.AgentAuthStatusUnknown, err
}
if status, ok, err := qwenLocalAuthStatus(ctx); err != nil {
return ports.AgentAuthStatusUnknown, err
} else if ok {
return status, nil
}
return authprobe.CLIStatus(ctx, binary, nil)
}
var qwenAPIKeyEnvVars = []string{
"QWEN_API_KEY",
"BAILIAN_CODING_PLAN_API_KEY",
"OPENAI_API_KEY",
"OPENROUTER_API_KEY",
"REQUESTY_API_KEY",
"DASHSCOPE_API_KEY",
"ZAI_API_KEY",
}
func qwenLocalAuthStatus(ctx context.Context) (ports.AgentAuthStatus, bool, error) {
if err := ctx.Err(); err != nil {
return ports.AgentAuthStatusUnknown, false, err
}
for _, name := range qwenAPIKeyEnvVars {
if strings.TrimSpace(os.Getenv(name)) != "" {
return ports.AgentAuthStatusAuthorized, true, nil
}
}
home, err := os.UserHomeDir()
if err != nil {
return ports.AgentAuthStatusUnknown, false, err
}
if home == "" {
return ports.AgentAuthStatusUnknown, false, nil
}
return qwenAuthStatusFromSettings(filepath.Join(home, ".qwen", "settings.json"))
}
func qwenAuthStatusFromSettings(path string) (ports.AgentAuthStatus, bool, error) {
data, err := os.ReadFile(path)
if os.IsNotExist(err) {
return ports.AgentAuthStatusUnknown, false, nil
}
if err != nil {
return ports.AgentAuthStatusUnknown, false, err
}
if strings.TrimSpace(string(data)) == "" {
return ports.AgentAuthStatusUnknown, false, nil
}
var root any
if err := json.Unmarshal(data, &root); err != nil {
return ports.AgentAuthStatusUnknown, false, err
}
if containsQwenAPIKey(root) {
return ports.AgentAuthStatusAuthorized, true, nil
}
return ports.AgentAuthStatusUnknown, false, nil
}
func containsQwenAPIKey(value any) bool {
switch v := value.(type) {
case map[string]any:
for key, child := range v {
if strings.EqualFold(key, "apiKey") || strings.EqualFold(key, "apikey") {
if stringSetting(child) != "" {
return true
}
continue
}
if containsQwenAPIKey(child) {
return true
}
}
case []any:
for _, child := range v {
if containsQwenAPIKey(child) {
return true
}
}
}
return false
}
func stringSetting(value any) string {
text, ok := value.(string)
if !ok {
return ""
}
text = strings.TrimSpace(text)
if text == "" || strings.EqualFold(text, "null") || strings.EqualFold(text, "none") {
return ""
}
return text
}