mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-07-10 14:28:43 +02:00
Add files via upload
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
@@ -41,6 +42,12 @@ type Config struct {
|
||||
Vision VisionConfig `yaml:"vision,omitempty" json:"vision,omitempty"`
|
||||
}
|
||||
|
||||
type EnsureLocalConfigResult struct {
|
||||
Created bool
|
||||
GeneratedPassword string
|
||||
ExamplePath string
|
||||
}
|
||||
|
||||
const (
|
||||
DefaultSummarizationUserIntentLedgerMaxRunes = 96000
|
||||
DefaultSummarizationUserIntentLedgerEntryMaxRunes = 16000
|
||||
@@ -1103,6 +1110,64 @@ func Load(path string) (*Config, error) {
|
||||
return &cfg, nil
|
||||
}
|
||||
|
||||
func EnsureLocalConfig(path string) (EnsureLocalConfigResult, error) {
|
||||
path = strings.TrimSpace(path)
|
||||
if path == "" {
|
||||
path = "config.yaml"
|
||||
}
|
||||
|
||||
if _, err := os.Stat(path); err == nil {
|
||||
return EnsureLocalConfigResult{}, nil
|
||||
} else if err != nil && !os.IsNotExist(err) {
|
||||
return EnsureLocalConfigResult{}, fmt.Errorf("检查配置文件失败: %w", err)
|
||||
}
|
||||
|
||||
examplePath := filepath.Join(filepath.Dir(path), "config.example.yaml")
|
||||
if _, err := os.Stat(examplePath); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
if alt := "config.example.yaml"; examplePath != alt {
|
||||
if _, altErr := os.Stat(alt); altErr == nil {
|
||||
examplePath = alt
|
||||
} else {
|
||||
return EnsureLocalConfigResult{}, fmt.Errorf("配置文件 %s 不存在,且未找到模板 %s", path, examplePath)
|
||||
}
|
||||
} else {
|
||||
return EnsureLocalConfigResult{}, fmt.Errorf("配置文件 %s 不存在,且未找到模板 %s", path, examplePath)
|
||||
}
|
||||
} else {
|
||||
return EnsureLocalConfigResult{}, fmt.Errorf("检查配置模板失败: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
data, err := os.ReadFile(examplePath)
|
||||
if err != nil {
|
||||
return EnsureLocalConfigResult{}, fmt.Errorf("读取配置模板失败: %w", err)
|
||||
}
|
||||
|
||||
if dir := filepath.Dir(path); dir != "." && dir != "" {
|
||||
if err := os.MkdirAll(dir, 0700); err != nil {
|
||||
return EnsureLocalConfigResult{}, fmt.Errorf("创建配置目录失败: %w", err)
|
||||
}
|
||||
}
|
||||
if err := os.WriteFile(path, data, fs.FileMode(0600)); err != nil {
|
||||
return EnsureLocalConfigResult{}, fmt.Errorf("创建配置文件失败: %w", err)
|
||||
}
|
||||
|
||||
password, err := generateStrongPassword(24)
|
||||
if err != nil {
|
||||
return EnsureLocalConfigResult{}, fmt.Errorf("生成默认密码失败: %w", err)
|
||||
}
|
||||
if err := PersistAuthPassword(path, password); err != nil {
|
||||
return EnsureLocalConfigResult{}, fmt.Errorf("写入默认密码失败: %w", err)
|
||||
}
|
||||
|
||||
return EnsureLocalConfigResult{
|
||||
Created: true,
|
||||
GeneratedPassword: password,
|
||||
ExamplePath: examplePath,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func generateStrongPassword(length int) (string, error) {
|
||||
if length <= 0 {
|
||||
length = 24
|
||||
|
||||
@@ -72,6 +72,56 @@ func TestPersistAuthPasswordDoesNotTreatQuotedHashAsComment(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnsureLocalConfigCreatesFromExampleWithGeneratedPassword(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
examplePath := filepath.Join(dir, "config.example.yaml")
|
||||
configPath := filepath.Join(dir, "config.yaml")
|
||||
|
||||
example := []byte(`auth:
|
||||
password: "change-me-use-a-long-random-password"
|
||||
session_duration_hours: 12
|
||||
server:
|
||||
host: 127.0.0.1
|
||||
port: 8080
|
||||
`)
|
||||
if err := os.WriteFile(examplePath, example, 0644); err != nil {
|
||||
t.Fatalf("write example: %v", err)
|
||||
}
|
||||
|
||||
result, err := EnsureLocalConfig(configPath)
|
||||
if err != nil {
|
||||
t.Fatalf("EnsureLocalConfig: %v", err)
|
||||
}
|
||||
if !result.Created {
|
||||
t.Fatal("Created = false, want true")
|
||||
}
|
||||
if result.GeneratedPassword == "" {
|
||||
t.Fatal("GeneratedPassword is empty")
|
||||
}
|
||||
if result.ExamplePath != examplePath {
|
||||
t.Fatalf("ExamplePath = %q, want %q", result.ExamplePath, examplePath)
|
||||
}
|
||||
|
||||
cfg, err := Load(configPath)
|
||||
if err != nil {
|
||||
t.Fatalf("Load generated config: %v", err)
|
||||
}
|
||||
if cfg.Auth.Password == "change-me-use-a-long-random-password" {
|
||||
t.Fatal("auth.password still contains the template placeholder")
|
||||
}
|
||||
if cfg.Auth.Password != result.GeneratedPassword {
|
||||
t.Fatalf("Auth.Password = %q, want generated password %q", cfg.Auth.Password, result.GeneratedPassword)
|
||||
}
|
||||
|
||||
second, err := EnsureLocalConfig(configPath)
|
||||
if err != nil {
|
||||
t.Fatalf("EnsureLocalConfig existing: %v", err)
|
||||
}
|
||||
if second.Created {
|
||||
t.Fatal("Created = true for existing config, want false")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHitlAuditModelEffectiveFallsBackToMainConfig(t *testing.T) {
|
||||
main := OpenAIConfig{
|
||||
Provider: "openai",
|
||||
|
||||
Reference in New Issue
Block a user