gcli2api / internal /auth /realm_test.go
a3216's picture
chore: 同步到上游 1.12.0-panel + 凭证同步/独立启动器/保活
6d60378 verified
Raw History Blame Contribute Delete
8.8 kB
package auth
import (
"os"
"path/filepath"
"testing"
)
// withGlobalEnabled 临时打开 global realm 开关(生产缺省即开,此辅助仅显式确保),
// 测试结束复位为开启态(缺省)。
func withGlobalEnabled(t *testing.T) {
t.Helper()
globalEnabled.Store(true)
t.Cleanup(func() { globalEnabled.Store(true) })
}
// withGlobalDisabled 临时关闭 global realm 开关(逃生门),测试结束复位为开启态(缺省)。
func withGlobalDisabled(t *testing.T) {
t.Helper()
globalEnabled.Store(false)
t.Cleanup(func() { globalEnabled.Store(true) })
}
func TestRealmExplicitGlobal(t *testing.T) {
withGlobalEnabled(t)
a := &Auth{realm: "global"}
if got := a.Realm(); got != "global" {
t.Errorf("Realm()=%q want global", got)
}
if !a.IsGlobal() {
t.Error("IsGlobal()=false want true")
}
}
func TestRealmExplicitCN(t *testing.T) {
a := &Auth{realm: "cn"}
if got := a.Realm(); got != "cn" {
t.Errorf("Realm()=%q want cn", got)
}
if a.IsGlobal() {
t.Error("IsGlobal()=true want false")
}
}
func TestRealmDomainFallback(t *testing.T) {
withGlobalEnabled(t)
cases := []struct{ domain, want string }{
{"www.workbuddy.ai", "global"},
{"workbuddy.ai", "global"},
{"sub.workbuddy.ai", "global"},
{"www.codebuddy.cn", "cn"},
{"", "cn"},
}
for _, c := range cases {
a := &Auth{Domain: c.domain}
if got := a.Realm(); got != c.want {
t.Errorf("Domain=%q Realm()=%q want %q", c.domain, got, c.want)
}
}
}
func TestRealmEmptyFallsBackToCN(t *testing.T) {
// 开关缺省开启(零回归前提):空 realm + 空 domain → cn(老 CN 凭证的核心)。
a := &Auth{}
if got := a.Realm(); got != "cn" {
t.Errorf("Realm()=%q want cn", got)
}
// 显式 global → global(缺省开启,Realm() 不再因"未配置"而恒 cn)。
ag := &Auth{realm: "global"}
if got := ag.Realm(); got != "global" {
t.Errorf("Realm()=%q want global", got)
}
// domain 回落照常(缺省开启识别 workbuddy.ai)。
ad := &Auth{Domain: "www.workbuddy.ai"}
if got := ad.Realm(); got != "global" {
t.Errorf("Realm()=%q want global", got)
}
}
// TestRealmDefaultOnForCNZeroRegression 开关缺省开启时,老 CN 凭证(无 realm、无 domain)
// Realm() 恒为 cn——「默认开启」不影响纯 CN 部署行为。
func TestRealmDefaultOnForCNZeroRegression(t *testing.T) {
withGlobalEnabled(t)
cases := []*Auth{
{},
{Domain: "www.codebuddy.cn"},
{Domain: "codebuddy.cn"},
{realm: "cn"},
{realm: "cn", Domain: "www.codebuddy.cn"},
}
for _, a := range cases {
if got := a.Realm(); got != "cn" {
t.Errorf("%+v Realm()=%q want cn", a, got)
}
if a.IsGlobal() {
t.Errorf("%+v IsGlobal()=true want false", a)
}
}
}
// TestRealmExplicitOffEscapeHatch 逃生门:SetGlobalEnabled(false) 后恒 cn,
// 即便 realm=global / domain=workbuddy.ai(纯 CN 锁定,与旧缺省行为等价)。
func TestRealmExplicitOffEscapeHatch(t *testing.T) {
withGlobalDisabled(t)
cases := []struct {
auth *Auth
}{
{&Auth{realm: "global"}},
{&Auth{realm: "global", Domain: "www.workbuddy.ai"}},
{&Auth{Domain: "www.workbuddy.ai"}},
}
for _, tc := range cases {
if got := tc.auth.Realm(); got != "cn" {
t.Errorf("%+v Realm()=%q want cn (switch off)", tc.auth, got)
}
if tc.auth.IsGlobal() {
t.Errorf("%+v IsGlobal()=true want false (switch off)", tc.auth)
}
}
}
func TestParseNestedRealm(t *testing.T) {
raw := []byte(`{"auth":{"accessToken":"at","refreshToken":"rt","expiresAt":1,"domain":"www.workbuddy.ai","realm":"global"},"account":{"uid":"u1"}}`)
sa, err := Parse(raw)
if err != nil {
t.Fatalf("nested parse err: %v", err)
}
if sa.realm != "global" {
t.Errorf("nested realm=%q want global", sa.realm)
}
// 嵌套形显式 realm 空 → 读不到,靠 domain 回落。
raw2 := []byte(`{"auth":{"accessToken":"at","refreshToken":"rt","expiresAt":1},"account":{"uid":"u1"}}`)
sa2, err := Parse(raw2)
if err != nil {
t.Fatalf("nested no-realm parse err: %v", err)
}
if sa2.realm != "" {
t.Errorf("nested missing realm key should be zero, got %q", sa2.realm)
}
}
func TestParseFlatRealm(t *testing.T) {
withGlobalEnabled(t)
raw := []byte(`{"accessToken":"at","refreshToken":"rt","expiresAt":1,"uid":"u2","realm":"global"}`)
fa, err := Parse(raw)
if err != nil {
t.Fatalf("flat parse err: %v", err)
}
if fa.realm != "global" {
t.Errorf("flat realm=%q want global", fa.realm)
}
if !fa.IsGlobal() {
t.Error("flat global account IsGlobal()=false want true")
}
// 扁平形缺 realm 键 → 零值 → CN。
flatCN := []byte(`{"accessToken":"at","refreshToken":"rt","expiresAt":1,"uid":"u3"}`)
fc, err := Parse(flatCN)
if err != nil {
t.Fatalf("flat cn parse err: %v", err)
}
if fc.realm != "" {
t.Errorf("flat missing realm should be zero, got %q", fc.realm)
}
}
func TestSaveAtomicWritesRealm(t *testing.T) {
withGlobalEnabled(t)
dir := t.TempDir()
fp := filepath.Join(dir, "workbuddy-global.json")
a := &Auth{AccessToken: "at", RefreshToken: "rt", ExpiresAt: 1,
UID: "g1", realm: "global", FilePath: fp}
if err := a.SaveAtomic(); err != nil {
t.Fatalf("save: %v", err)
}
raw, err := os.ReadFile(fp)
if err != nil {
t.Fatalf("read: %v", err)
}
b, err := Parse(raw)
if err != nil {
t.Fatalf("reparse: %v", err)
}
if b.realm != "global" {
t.Errorf("roundtrip realm=%q want global", b.realm)
}
if !b.IsGlobal() {
t.Error("roundtrip global account IsGlobal()=false")
}
}
// TestBackfillRealmDomain CN/global 按原始 domain 推断(backfill 为导出空 realm 字段服务)。
func TestBackfillRealmDomain(t *testing.T) {
t.Parallel() // 不触碰全局开关
cases := []struct {
domain string
want string
}{
{"www.workbuddy.ai", "global"},
{"workbuddy.ai", "global"},
{"sub.workbuddy.ai", "global"},
{"www.codebuddy.cn", "cn"},
{"codebuddy.cn", "cn"},
{"", "cn"}, // 空 domain + 空 realm → cn(老 CN 凭证核心)
}
for _, c := range cases {
a := &Auth{Domain: c.domain}
changed, got := a.BackfillRealm()
if !changed {
t.Errorf("Domain=%q backfill changed=false want true", c.domain)
}
assertRealmStored(a, c.want, t)
if got != c.want {
t.Errorf("Domain=%q backfill got realm=%q want %q", c.domain, got, c.want)
}
}
}
// TestBackfillRealmEscapeHatchFree 逃生门关闭时 backfill 仍按原始 domain 推断(不受 Realm() 降级影响)。
func TestBackfillRealmEscapeHatchFree(t *testing.T) {
withGlobalDisabled(t) // 逃生门关闭:Realm() 恒 cn,但 backfill 不得被污染
a := &Auth{Domain: "www.workbuddy.ai"}
if g := a.Realm(); g != "cn" {
t.Fatalf("precondition Realm()=%q want cn (escape hatch on)", g)
}
changed, got := a.BackfillRealm()
if !changed {
t.Fatal("backfill changed=false want true (escape hatch free)")
}
assertRealmStored(a, "global", t)
if got != "global" {
t.Errorf("backfill got=%q want global (escape hatch must not corrupt backfill)", got)
}
}
// TestBackfillRealmIdempotent 已有 realm 标识的文件不做修改(幂等)。
func TestBackfillRealmIdempotent(t *testing.T) {
t.Parallel()
a := &Auth{Domain: "www.workbuddy.ai", realm: "cn"} // 已有 cn,domain 会推断 global——绝不覆盖
changed, got := a.BackfillRealm()
if changed {
t.Errorf("backfill changed=true want false (existing realm must win)")
}
if got != "cn" {
t.Errorf("backfill got=%q want cn (existing realm preserved)", got)
}
assertRealmStored(a, "cn", t)
}
func assertRealmStored(a *Auth, want string, t *testing.T) {
t.Helper()
if a.realm != want {
t.Errorf("stored realm field=%q want %q", a.realm, want)
}
}
// TestResolveRealm 纯函数归一化显式 realm,缺失时按 domain 推断(与 BackfillRealm
// 共用同一来源;不受逃生门影响)。显式值优先于 domain 推断。
func TestResolveRealm(t *testing.T) {
t.Parallel() // 纯函数:不触碰全局开关
cases := []struct {
explicit, domain, want string
}{
{"global", "www.codebuddy.cn", "global"}, // 显式优先:cn domain 也写 global
{"cn", "www.workbuddy.ai", "cn"}, // 显式优先:global domain 也写 cn
{"", "www.workbuddy.ai", "global"}, // 缺省按 domain 推断
{"", "workbuddy.ai", "global"},
{"", "codebuddy.cn", "cn"},
{"", "", "cn"}, // 空 domain → cn(老 CN 凭证零回归)
}
for _, c := range cases {
if got := ResolveRealm(c.explicit, c.domain); got != c.want {
t.Errorf("ResolveRealm(%q,%q)=%q want %q", c.explicit, c.domain, got, c.want)
}
}
}