发布 0.1.0:通知渠道、告警规则、令牌版本与安全加固
CI / test (push) Successful in 30s
Release / release (push) Successful in 49s

This commit is contained in:
Wang Defa
2026-07-10 17:38:34 +08:00
parent 4af6a0ca92
commit dbba1f4905
78 changed files with 6898 additions and 551 deletions
+65 -8
View File
@@ -109,7 +109,7 @@ func TestTokenRoundTrip(t *testing.T) {
if expires.IsZero() {
t.Error("expires is zero, want future time")
}
username, err := auth.ParseToken(token)
username, err := auth.ParseToken(context.Background(), token)
if err != nil {
t.Fatalf("ParseToken: %v", err)
}
@@ -129,35 +129,92 @@ func TestParseTokenRejectsForged(t *testing.T) {
if err != nil {
t.Fatalf("Login: %v", err)
}
if _, err := auth.ParseToken(forged); err == nil {
if _, err := auth.ParseToken(context.Background(), forged); err == nil {
t.Error("ParseToken(forged): got nil error, want failure")
}
if _, err := auth.ParseToken("not.a.token"); err == nil {
if _, err := auth.ParseToken(context.Background(), "not.a.token"); err == nil {
t.Error("ParseToken(garbage): got nil error, want failure")
}
}
func TestLogoutRevokesToken(t *testing.T) {
auth := newTestAuth(t)
token, _, err := auth.signToken("admin")
// ParseToken 现校验令牌版本,须存在对应账号
if err := auth.EnsureAdmin("admin", "pass123"); err != nil {
t.Fatalf("EnsureAdmin: %v", err)
}
token, _, err := auth.signToken("admin", 0)
if err != nil {
t.Fatalf("signToken: %v", err)
}
if _, err := auth.ParseToken(token); err != nil {
if _, err := auth.ParseToken(context.Background(), token); err != nil {
t.Fatalf("ParseToken before logout: %v", err)
}
auth.Logout(token)
if _, err := auth.ParseToken(token); err == nil {
if _, err := auth.ParseToken(context.Background(), token); err == nil {
t.Error("ParseToken after logout: got nil error, want revoked")
}
// 幂等:重复登出与无效令牌登出都不应 panic,也不影响其他令牌
auth.Logout(token)
auth.Logout("not.a.token")
fresh, _, err := auth.signToken("admin")
fresh, _, err := auth.signToken("admin", 0)
if err != nil {
t.Fatalf("signToken fresh: %v", err)
}
if _, err := auth.ParseToken(fresh); err != nil {
if _, err := auth.ParseToken(context.Background(), fresh); err != nil {
t.Errorf("ParseToken(fresh) after revoking old: %v", err)
}
}
// TestTokenVersionInvalidatesOldToken 凭据变更递增令牌版本,旧 JWT 立即失效,
// 重签的新令牌可用(审计 S-02 动态复现序列的反向断言)。
func TestTokenVersionInvalidatesOldToken(t *testing.T) {
auth := newTestAuth(t)
if err := auth.EnsureAdmin("admin", "pass123"); err != nil {
t.Fatalf("EnsureAdmin: %v", err)
}
ctx := context.Background()
old, _, err := auth.Login(ctx, "admin", "pass123", "127.0.0.1", "")
if err != nil {
t.Fatalf("Login: %v", err)
}
finalName, err := auth.UpdateCredentials(ctx, "admin", UpdateCredentialsInput{
NewPassword: "changed-456", CurrentPassword: "pass123",
})
if err != nil {
t.Fatalf("UpdateCredentials: %v", err)
}
if _, err := auth.ParseToken(ctx, old); err == nil {
t.Error("旧 token 在凭据变更后仍有效, want 失效")
}
fresh, _, err := auth.IssueToken(ctx, finalName)
if err != nil {
t.Fatalf("IssueToken: %v", err)
}
if name, err := auth.ParseToken(ctx, fresh); err != nil || name != "admin" {
t.Errorf("重签 token 应有效: name=%q err=%v", name, err)
}
}
// TestRevokeSessions 撤销全部会话:旧 token 失效,返回的新 token 有效。
func TestRevokeSessions(t *testing.T) {
auth := newTestAuth(t)
if err := auth.EnsureAdmin("admin", "pass123"); err != nil {
t.Fatalf("EnsureAdmin: %v", err)
}
ctx := context.Background()
old, _, err := auth.Login(ctx, "admin", "pass123", "127.0.0.1", "")
if err != nil {
t.Fatalf("Login: %v", err)
}
fresh, _, err := auth.RevokeSessions(ctx, "admin")
if err != nil {
t.Fatalf("RevokeSessions: %v", err)
}
if _, err := auth.ParseToken(ctx, old); err == nil {
t.Error("撤销后旧 token 仍有效, want 失效")
}
if name, err := auth.ParseToken(ctx, fresh); err != nil || name != "admin" {
t.Errorf("撤销后新 token 应有效: name=%q err=%v", name, err)
}
}