- resolveSecrets 统一所有部署形态的零配置体验:显式 env 优先 → DATA_DIR/.secrets.env → 自动生成随机密钥持久化(0600,重启不变);无法持久化才拒绝启动(单测覆盖生成/复用/显式优先) - install.md 重写为三方式各一条命令(K8s install.sh / docker compose up -d / release 包), 密钥与数据说明收敛到统一「说明」一节;README Docker 段同步精简
51 lines
1.6 KiB
Go
51 lines
1.6 KiB
Go
package config
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// TestResolveSecretsAutoGenerate 零配置:未设置环境变量时自动生成随机密钥并持久化,二次调用复用
|
|
func TestResolveSecretsAutoGenerate(t *testing.T) {
|
|
dir := t.TempDir()
|
|
t.Setenv("JWT_SECRET", "")
|
|
t.Setenv("ENCRYPTION_KEY", "")
|
|
|
|
jwt1, enc1 := resolveSecrets(dir)
|
|
if len(jwt1) != 64 || len(enc1) != 64 {
|
|
t.Fatalf("生成的密钥长度异常: %d/%d", len(jwt1), len(enc1))
|
|
}
|
|
data, err := os.ReadFile(filepath.Join(dir, ".secrets.env"))
|
|
if err != nil {
|
|
t.Fatalf("密钥未持久化: %v", err)
|
|
}
|
|
if !strings.Contains(string(data), jwt1) || !strings.Contains(string(data), enc1) {
|
|
t.Fatal("持久化内容与返回值不一致")
|
|
}
|
|
info, _ := os.Stat(filepath.Join(dir, ".secrets.env"))
|
|
if info.Mode().Perm() != 0o600 {
|
|
t.Fatalf("密钥文件权限应为 0600,实际 %v", info.Mode().Perm())
|
|
}
|
|
// 二次调用复用
|
|
jwt2, enc2 := resolveSecrets(dir)
|
|
if jwt1 != jwt2 || enc1 != enc2 {
|
|
t.Fatal("二次解析应复用持久化密钥")
|
|
}
|
|
}
|
|
|
|
// TestResolveSecretsExplicitEnvWins 显式环境变量优先,不读不写持久化文件
|
|
func TestResolveSecretsExplicitEnvWins(t *testing.T) {
|
|
dir := t.TempDir()
|
|
t.Setenv("JWT_SECRET", "explicit-jwt-secret-0123456789abcdef")
|
|
t.Setenv("ENCRYPTION_KEY", "explicit-enc-secret-0123456789abcdef")
|
|
jwt, enc := resolveSecrets(dir)
|
|
if jwt != "explicit-jwt-secret-0123456789abcdef" || enc != "explicit-enc-secret-0123456789abcdef" {
|
|
t.Fatal("显式环境变量必须原样生效")
|
|
}
|
|
if _, err := os.Stat(filepath.Join(dir, ".secrets.env")); !os.IsNotExist(err) {
|
|
t.Fatal("显式提供时不应写持久化文件")
|
|
}
|
|
}
|