package auth import ( "errors" "testing" "hfb_sys/backend/internal/model" "gorm.io/driver/sqlite" "gorm.io/gorm" ) func TestUserTokenVersionRevokesAccessAndRefreshTokens(t *testing.T) { db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{}) if err != nil { t.Fatalf("打开测试数据库失败:%v", err) } if err := db.AutoMigrate(&model.User{}); err != nil { t.Fatalf("数据库迁移失败:%v", err) } user := model.User{Phone: "13900000001", Status: "active", TokenVersion: 0} if err := db.Create(&user).Error; err != nil { t.Fatalf("创建用户失败:%v", err) } repo := NewUserRepository(db) manager := NewJWTManager("test-secret") pair, err := manager.GenerateSubjectPairWithVersion(user.ID, user.Phone, "user", user.TokenVersion) if err != nil { t.Fatalf("生成令牌失败:%v", err) } _, err = repo.FindActiveForToken(t.Context(), user.ID, 0) if err != nil { t.Fatalf("有效令牌校验失败:%v", err) } if err := db.Model(&model.User{}).Where("id = ?", user.ID).Updates(map[string]any{ "status": "frozen", "token_version": 1, }).Error; err != nil { t.Fatalf("冻结用户失败:%v", err) } _, err = repo.FindActiveForToken(t.Context(), user.ID, 0) if !errors.Is(err, ErrUserDisabled) { t.Fatalf("冻结用户校验错误 = %v, want %v", err, ErrUserDisabled) } service := NewService(repo, nil, manager, nil, nil) _, err = service.RefreshToken(t.Context(), pair.RefreshToken) if !errors.Is(err, ErrUserDisabled) { t.Fatalf("冻结用户刷新错误 = %v, want %v", err, ErrUserDisabled) } // 解冻后版本仍然不同,冻结前签发的 token 不能恢复使用。 if err := db.Model(&model.User{}).Where("id = ?", user.ID).Updates(map[string]any{ "status": "active", "token_version": 2, }).Error; err != nil { t.Fatalf("解冻用户失败:%v", err) } _, err = repo.FindActiveForToken(t.Context(), user.ID, 0) if !errors.Is(err, ErrTokenVersionMismatch) { t.Fatalf("旧令牌版本校验错误 = %v, want %v", err, ErrTokenVersionMismatch) } _, err = repo.FindActiveForToken(t.Context(), user.ID, 2) if err != nil { t.Fatalf("新令牌版本校验失败:%v", err) } }