From 3370bf70aec03c3ef2c0d95786757acd3c1054fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Scout=E5=BC=80=E5=8F=91=E8=80=85?= Date: Thu, 17 Sep 2026 00:15:47 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=A4=B1=E6=95=88=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E4=BB=A4=E7=89=8C=E7=9A=84=E6=9D=83=E9=99=90=E6=8E=A7?= =?UTF-8?q?=E5=88=B6=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/access/store.go | 3 ++- internal/access/store_test.go | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/internal/access/store.go b/internal/access/store.go index 685f63a..7e07bc4 100644 --- a/internal/access/store.go +++ b/internal/access/store.go @@ -103,8 +103,9 @@ func (s *Store) HasAccessControl(projectID string) bool { if len(s.members[projectID]) > 0 { return true } + now := time.Now().UTC() for _, token := range s.tokens { - if token.ProjectID == projectID { + if token.ProjectID == projectID && token.RevokedAt == nil && (token.ExpiresAt == nil || now.Before(*token.ExpiresAt)) { return true } } diff --git a/internal/access/store_test.go b/internal/access/store_test.go index 555e419..e967241 100644 --- a/internal/access/store_test.go +++ b/internal/access/store_test.go @@ -102,3 +102,35 @@ func TestStoreKeepsLastProjectAdmin(t *testing.T) { t.Fatal("demoting the last project admin should fail") } } + +func TestStoreIgnoresExpiredAndRevokedTokensForAccessControl(t *testing.T) { + store, err := New(filepath.Join(t.TempDir(), "access.json")) + if err != nil { + t.Fatal(err) + } + expired := time.Now().UTC().Add(-time.Minute) + _, _, err = store.CreateToken("ssl", "过期令牌", RoleViewer, &expired) + if err != nil { + t.Fatal(err) + } + if store.HasAccessControl("ssl") { + t.Fatal("过期项目令牌不应启用项目权限控制") + } + _, secret, err := store.CreateToken("ssl", "待吊销令牌", RoleViewer, nil) + if err != nil { + t.Fatal(err) + } + tokens := store.ListTokens("ssl") + if len(tokens) != 2 { + t.Fatalf("项目令牌数量错误:%d", len(tokens)) + } + if _, err := store.RevokeToken("ssl", tokens[1].ID); err != nil { + t.Fatal(err) + } + if store.HasAccessControl("ssl") { + t.Fatal("仅剩过期或吊销令牌时不应启用项目权限控制") + } + if _, ok := store.AuthenticateToken("ssl", secret); ok { + t.Fatal("已吊销项目令牌仍可认证") + } +}