Scout/internal/access/store_test.go
2026-08-31 21:19:15 +08:00

105 lines
3.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package access
import (
"path/filepath"
"testing"
"time"
)
func TestStorePersistsMembersAndTokens(t *testing.T) {
path := filepath.Join(t.TempDir(), "project-access.json")
store, err := New(path)
if err != nil {
t.Fatal(err)
}
member, err := store.AddMember("ssl", "user-1", RoleDeveloper)
if err != nil {
t.Fatal(err)
}
if member.Role != RoleDeveloper || !store.HasAccessControl("ssl") {
t.Fatalf("项目成员保存错误:%+v", member)
}
expiresAt := time.Now().UTC().Add(time.Hour)
token, secret, err := store.CreateToken("ssl", "客户端令牌", RoleViewer, &expiresAt)
if err != nil {
t.Fatal(err)
}
if secret == "" || token.SecretHash != "" || token.Prefix == "" {
t.Fatalf("项目令牌返回错误:%+v,明文长度:%d", token, len(secret))
}
matched, ok := store.AuthenticateToken("ssl", secret)
if !ok || matched.ID != token.ID {
t.Fatalf("项目令牌认证失败:%+v,%v", matched, ok)
}
if _, ok := store.AuthenticateToken("smail", secret); ok {
t.Fatal("项目令牌不应访问其他项目")
}
reloaded, err := New(path)
if err != nil {
t.Fatal(err)
}
if len(reloaded.ListMembers("ssl")) != 1 || len(reloaded.ListTokens("ssl")) != 1 {
t.Fatal("项目权限数据重新加载失败")
}
if _, ok := reloaded.AuthenticateToken("ssl", secret); !ok {
t.Fatal("重新加载后项目令牌认证失败")
}
}
func TestStoreRevokesTokenAndUpdatesMember(t *testing.T) {
store, err := New(filepath.Join(t.TempDir(), "access.json"))
if err != nil {
t.Fatal(err)
}
if _, err := store.AddMember("ssl", "user-1", RoleViewer); err != nil {
t.Fatal(err)
}
if _, err := store.UpdateMember("ssl", "user-1", RoleAdmin); err != nil {
t.Fatal(err)
}
member, ok := store.GetMember("ssl", "user-1")
if !ok || member.Role != RoleAdmin {
t.Fatalf("项目成员更新错误:%+v,%v", member, ok)
}
_, secret, err := store.CreateToken("ssl", "令牌", RoleDeveloper, nil)
if err != nil {
t.Fatal(err)
}
tokens := store.ListTokens("ssl")
if len(tokens) != 1 {
t.Fatal("项目令牌列表数量错误")
}
if _, err := store.RevokeToken("ssl", tokens[0].ID); err != nil {
t.Fatal(err)
}
if _, ok := store.AuthenticateToken("ssl", secret); ok {
t.Fatal("已吊销项目令牌仍可认证")
}
}
func TestStoreKeepsLastProjectAdmin(t *testing.T) {
store, err := New(filepath.Join(t.TempDir(), "access.json"))
if err != nil {
t.Fatal(err)
}
if _, err := store.AddMember("ssl", "admin-1", RoleAdmin); err != nil {
t.Fatal(err)
}
if _, err := store.UpdateMember("ssl", "admin-1", RoleViewer); err == nil {
t.Fatal("demoting the last project admin should fail")
}
if err := store.DeleteMember("ssl", "admin-1"); err == nil {
t.Fatal("deleting the last project admin should fail")
}
if _, err := store.AddMember("ssl", "admin-2", RoleAdmin); err != nil {
t.Fatal(err)
}
if err := store.DeleteMember("ssl", "admin-2"); err != nil {
t.Fatal(err)
}
if _, err := store.UpdateMember("ssl", "admin-1", RoleViewer); err == nil {
t.Fatal("demoting the last project admin should fail")
}
}