105 lines
3.0 KiB
Go
105 lines
3.0 KiB
Go
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")
|
||
}
|
||
}
|