You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

64 lines
2.3 KiB

package comm
import (
"os"
"testing"
"yunyan/lego/sys/log"
)
// applyDBValues 在解密失败时会 log.Errorf;lego 的 log 子系统若未初始化会 nil 解引用。
func TestMain(m *testing.M) {
_ = log.OnInit(nil)
os.Exit(m.Run())
}
// 事故回归:FIELD_ENCRYPT_KEY 与 console 不一致时,密钥字段解密失败。
// 此时**绝不能**把密文当明文写进 Sys 配置——历史上密文被当成微信商户私钥的文件路径去 open,
// 触发 log.Fatal 让 home 退出,5-in-1 容器整体 crash loop,全站 502。
func TestApplyDBValues_DecryptFailure_DoesNotLeakCiphertext(t *testing.T) {
const ciphertext = "HgIdj0m/9aV5CqoKQtj7Gi7yfnaCylNbGYztHF1fVKtwtfIM3UrD5jHP4khP6AI=" // 线上真实密文样本
sec := map[string]interface{}{
"PrivateKeyPath": "/app/certs/apiclient_key.pem", // yaml 默认值
}
rows := []*AppModuleConfig{
{Module: "wechatpay", Key: "PrivateKeyPath", Value: ciphertext, Encrypted: true},
}
applyDBValues(sec, rows, "wrong-key-not-matching-console")
got, _ := sec["PrivateKeyPath"].(string)
if got == ciphertext {
t.Fatal("解密失败后密文被当明文写进配置——这正是导致全站 502 的 fail-open 行为")
}
if got != "/app/certs/apiclient_key.pem" {
t.Errorf("解密失败应保留 yaml 默认值,实际=%q", got)
}
}
// 解密成功时正常覆盖。
func TestApplyDBValues_DecryptSuccess_Overrides(t *testing.T) {
const key = "test-key-consistent-with-console"
ct, err := Encrypt(key, "real-secret-value")
if err != nil {
t.Fatalf("Encrypt err: %v", err)
}
sec := map[string]interface{}{"ApiKey": "yaml-default"}
rows := []*AppModuleConfig{{Module: "sms", Key: "ApiKey", Value: ct, Encrypted: true}}
applyDBValues(sec, rows, key)
if got, _ := sec["ApiKey"].(string); got != "real-secret-value" {
t.Errorf("解密成功应覆盖为明文,实际=%q", got)
}
}
// 非加密字段照常覆盖,且按 yaml 原值类型还原。
func TestApplyDBValues_PlainField(t *testing.T) {
sec := map[string]interface{}{"Enabled": false}
rows := []*AppModuleConfig{{Module: "sms", Key: "Enabled", Value: "true", Encrypted: false}}
applyDBValues(sec, rows, "")
if got, _ := sec["Enabled"].(bool); !got {
t.Errorf("非加密字段应按原值类型还原为 bool true,实际=%#v", sec["Enabled"])
}
}