- 生效规则统一为「后台填了用后台的,没填回落环境变量」,老部署不改 env 照常跑 - config.Resolver:短缓存解析有效配置,存储后端按配置签名热重建;后台保存主动失效 - 秘密项(client secret / bot token / R2 密钥 / 管理员密码)接口永不回显明文, 只报「是否已配置、来自哪里」;留空保存 = 保持现值 - 管理员密码 bcrypt 入库,DB 哈希优先、显式设置的 env 密码作解锁后路; 后台改过密码后 admin/admin 开发模式立即失效 - 设置页新增「登录与存储」标签,基础信息加站点地址;秘密项带来源提示 - 监听地址 / 数据库 / 目录 / ONE_SECRET / Passkey 仍留环境变量(启动期依赖)
54 lines
1.5 KiB
Go
54 lines
1.5 KiB
Go
package config
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"oneblog/internal/model"
|
|
)
|
|
|
|
func TestOverlayDBWinsEnvFallsBack(t *testing.T) {
|
|
env := &Config{
|
|
SiteURL: "https://env.example",
|
|
GitHubClientID: "env-id",
|
|
GitHubClientSecret: "env-sec",
|
|
UploadsPublicBase: "https://cdn.example/",
|
|
}
|
|
st := model.Settings{
|
|
SiteURL: "https://db.example",
|
|
GitHubClientSecret: "db-sec",
|
|
}
|
|
got := env.Overlay(st)
|
|
if got.SiteURL != "https://db.example" {
|
|
t.Errorf("SiteURL = %q, want db value", got.SiteURL)
|
|
}
|
|
if got.GitHubClientID != "env-id" {
|
|
t.Errorf("GitHubClientID = %q, want env fallback", got.GitHubClientID)
|
|
}
|
|
if got.GitHubClientSecret != "db-sec" {
|
|
t.Errorf("GitHubClientSecret = %q, want db value", got.GitHubClientSecret)
|
|
}
|
|
// env 原件不能被改掉
|
|
if env.SiteURL != "https://env.example" {
|
|
t.Error("Overlay must not mutate the env config")
|
|
}
|
|
}
|
|
|
|
// 存储端按凭据齐全与否重新判定,与 config.Load 的规则一致。
|
|
func TestOverlayStorageCompleteness(t *testing.T) {
|
|
env := &Config{DataDir: "/tmp/one"}
|
|
full := model.Settings{
|
|
S3Endpoint: "https://acct.r2.cloudflarestorage.com",
|
|
R2Bucket: "b",
|
|
R2AccessKey: "ak",
|
|
R2SecretKey: "sk",
|
|
}
|
|
if c := env.Overlay(full); c.StorageDriver != "r2" {
|
|
t.Errorf("complete R2 set: driver = %q, want r2", c.StorageDriver)
|
|
}
|
|
partial := full
|
|
partial.R2SecretKey = ""
|
|
if c := env.Overlay(partial); c.StorageDriver != "local" {
|
|
t.Errorf("incomplete R2 set: driver = %q, want local", c.StorageDriver)
|
|
}
|
|
}
|