feat(auth): implement session-based token management with revocation support
Add Session model, SessionService, and SessionRepository to track user login sessions and enable token revocation on auth-critical events. - Introduce explicit TokenType (access/refresh) in JWT claims to prevent refresh token misuse via access token endpoints - Add SessionID field to JWT claims, enabling stateless JWT validation against revoked sessions - Replace legacy Auth middleware with RequireAuth/OptionalAuth pipeline that validates token type, account status, and session validity - Implement session revocation on password change, reset, user ban/inactive, and explicit logout - Add Principal cache with active invalidation for banned/role-changed users - Fix IDOR vulnerability: GetMessagesByCursor now validates currentUserID is conversation participant via GetParticipantStrict - Add group member visibility checks: announcements, group info, member list now require group membership - Simplify Casbin policy: remove g grouping, use r.sub == p.sub matcher with globMatch; user_roles table is single source of truth for roles - Add migration logic to clean legacy casbin g rules and migrate old p rules from path-style to admin/<domain> resource naming
This commit is contained in:
@@ -3,9 +3,9 @@ package router
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"with_you/internal/cache"
|
||||
"with_you/internal/handler"
|
||||
"with_you/internal/middleware"
|
||||
"with_you/internal/model"
|
||||
"with_you/internal/repository"
|
||||
"with_you/internal/service"
|
||||
)
|
||||
@@ -49,6 +49,9 @@ type RouterDeps struct {
|
||||
TradeHandler *handler.TradeHandler
|
||||
WSHandler *handler.WSHandler
|
||||
JWTService service.JWTService
|
||||
SessionService service.SessionService
|
||||
IdentityProvider middleware.IdentityProvider
|
||||
Cache cache.Cache
|
||||
LogService *service.LogService
|
||||
ActivityService service.UserActivityService
|
||||
CasbinService service.CasbinService
|
||||
@@ -67,6 +70,8 @@ type Router struct {
|
||||
func New(deps RouterDeps) *Router {
|
||||
deps.UserHandler.SetJWTService(deps.JWTService)
|
||||
deps.UserHandler.SetActivityService(deps.ActivityService)
|
||||
deps.UserHandler.SetSessionService(deps.SessionService)
|
||||
deps.UserHandler.SetCache(deps.Cache)
|
||||
|
||||
r := &Router{
|
||||
RouterDeps: &deps,
|
||||
@@ -92,17 +97,17 @@ func (r *Router) setupRoutes() {
|
||||
v1 := r.engine.Group("/api/v1")
|
||||
{
|
||||
// 认证路由(公开,按接口类型设置不同速率限制)
|
||||
auth := v1.Group("/auth")
|
||||
auth.Use(middleware.GlobalAuthRateLimit())
|
||||
auth.Use(middleware.IPBanMiddleware())
|
||||
// 注意:登出端点在下面 authMiddleware 定义后单独挂载,避免前向引用。
|
||||
authPublic := v1.Group("/auth")
|
||||
authPublic.Use(middleware.GlobalAuthRateLimit())
|
||||
authPublic.Use(middleware.IPBanMiddleware())
|
||||
{
|
||||
auth.POST("/register", middleware.RegisterRateLimit(), r.UserHandler.Register)
|
||||
auth.POST("/register/send-code", middleware.SendCodeRateLimit(), r.UserHandler.SendRegisterCode)
|
||||
auth.POST("/login", middleware.LoginRateLimit(), r.UserHandler.Login)
|
||||
auth.POST("/password/send-code", middleware.PasswordResetRateLimit(), r.UserHandler.SendPasswordResetCode)
|
||||
auth.POST("/password/reset", middleware.PasswordResetRateLimit(), r.UserHandler.ResetPassword)
|
||||
auth.POST("/logout", r.UserHandler.Logout)
|
||||
auth.POST("/refresh", r.UserHandler.RefreshToken)
|
||||
authPublic.POST("/register", middleware.RegisterRateLimit(), r.UserHandler.Register)
|
||||
authPublic.POST("/register/send-code", middleware.SendCodeRateLimit(), r.UserHandler.SendRegisterCode)
|
||||
authPublic.POST("/login", middleware.LoginRateLimit(), r.UserHandler.Login)
|
||||
authPublic.POST("/password/send-code", middleware.PasswordResetRateLimit(), r.UserHandler.SendPasswordResetCode)
|
||||
authPublic.POST("/password/reset", middleware.PasswordResetRateLimit(), r.UserHandler.ResetPassword)
|
||||
authPublic.POST("/refresh", r.UserHandler.RefreshToken)
|
||||
}
|
||||
|
||||
// 初始化超级管理员(公开接口,只能使用一次)
|
||||
@@ -111,14 +116,21 @@ func (r *Router) setupRoutes() {
|
||||
}
|
||||
|
||||
// 需要认证的路由
|
||||
authMiddleware := middleware.Auth(r.JWTService)
|
||||
// 统一认证管道:令牌解析 → 加载 Principal → 校验账户状态 → 校验会话有效性。
|
||||
// 取代旧 middleware.Auth,避免 refresh token 误当 access token、封禁用户旧 token 仍可用等问题。
|
||||
// 注入 cache.Cache 启用 Principal/Session 缓存(30s TTL),封禁/改密/登出时由 auth.InvalidatePrincipalCache 主动失效。
|
||||
authMiddleware := middleware.RequireAuth(r.JWTService, r.IdentityProvider, r.Cache)
|
||||
optionalAuth := middleware.OptionalAuth(r.JWTService, r.IdentityProvider, r.Cache)
|
||||
|
||||
// 登出挂在公开 auth 组上,但单独加认证中间件。
|
||||
v1.POST("/auth/logout", authMiddleware, r.UserHandler.Logout)
|
||||
|
||||
// === 访问日志中间件 ===
|
||||
if r.AdminLogHandler != nil && r.LogService != nil {
|
||||
accessLogConfig := &middleware.AccessLogConfig{
|
||||
Enable: true,
|
||||
SkipPaths: []string{"/health", "/api/v1/health"},
|
||||
ServerIP: "0.0.0.0",
|
||||
Enable: true,
|
||||
SkipPaths: []string{"/health", "/api/v1/health"},
|
||||
ServerIP: "0.0.0.0",
|
||||
ServerPort: 8080,
|
||||
}
|
||||
r.engine.Use(middleware.AccessLogMiddleware(
|
||||
@@ -155,10 +167,10 @@ func (r *Router) setupRoutes() {
|
||||
}
|
||||
|
||||
// 搜索用户
|
||||
users.GET("/search", middleware.OptionalAuth(r.JWTService), r.UserHandler.Search)
|
||||
users.GET("/search", optionalAuth, r.UserHandler.Search)
|
||||
|
||||
// 其他用户
|
||||
users.GET("/:id", middleware.OptionalAuth(r.JWTService), r.UserHandler.GetUserByID)
|
||||
users.GET("/:id", optionalAuth, r.UserHandler.GetUserByID)
|
||||
users.POST("/:id/follow", authMiddleware, r.UserHandler.FollowUser)
|
||||
users.DELETE("/:id/follow", authMiddleware, r.UserHandler.UnfollowUser)
|
||||
users.POST("/:id/block", authMiddleware, r.UserHandler.BlockUser)
|
||||
@@ -169,8 +181,8 @@ func (r *Router) setupRoutes() {
|
||||
users.GET("/:id/followers", authMiddleware, r.UserHandler.GetFollowersList)
|
||||
|
||||
// 用户帖子 - 使用 OptionalAuth 获取当前用户点赞/收藏状态
|
||||
users.GET("/:id/posts", middleware.OptionalAuth(r.JWTService), r.PostHandler.GetUserPosts)
|
||||
users.GET("/:id/favorites", middleware.OptionalAuth(r.JWTService), r.PostHandler.GetFavorites)
|
||||
users.GET("/:id/posts", optionalAuth, r.PostHandler.GetUserPosts)
|
||||
users.GET("/:id/favorites", optionalAuth, r.PostHandler.GetFavorites)
|
||||
}
|
||||
|
||||
// 身份认证路由
|
||||
@@ -203,32 +215,32 @@ func (r *Router) setupRoutes() {
|
||||
}
|
||||
|
||||
// 认证路由(公开)
|
||||
authPublic := v1.Group("/auth")
|
||||
authPublicCheck := v1.Group("/auth")
|
||||
{
|
||||
authPublic.GET("/check-username", r.UserHandler.CheckUsername)
|
||||
authPublicCheck.GET("/check-username", r.UserHandler.CheckUsername)
|
||||
}
|
||||
|
||||
// 帖子路由
|
||||
posts := v1.Group("/posts")
|
||||
{
|
||||
// 使用 OptionalAuth 中间件来获取用户登录状态
|
||||
posts.GET("", middleware.OptionalAuth(r.JWTService), r.PostHandler.List)
|
||||
posts.GET("/search", middleware.OptionalAuth(r.JWTService), r.PostHandler.Search)
|
||||
posts.GET("/suggest", middleware.OptionalAuth(r.JWTService), r.PostHandler.Suggest)
|
||||
posts.GET("/:id", middleware.OptionalAuth(r.JWTService), r.PostHandler.GetByID)
|
||||
posts.GET("", optionalAuth, r.PostHandler.List)
|
||||
posts.GET("/search", optionalAuth, r.PostHandler.Search)
|
||||
posts.GET("/suggest", optionalAuth, r.PostHandler.Suggest)
|
||||
posts.GET("/:id", optionalAuth, r.PostHandler.GetByID)
|
||||
posts.POST("", authMiddleware, middleware.RequireVerified(r.UserService), r.PostHandler.Create)
|
||||
posts.PUT("/:id", authMiddleware, middleware.RequireVerified(r.UserService), r.PostHandler.Update)
|
||||
posts.DELETE("/:id", authMiddleware, middleware.RequireVerified(r.UserService), r.PostHandler.Delete)
|
||||
|
||||
// 浏览量记录(可选认证,允许游客浏览)
|
||||
posts.POST("/:id/view", middleware.OptionalAuth(r.JWTService), r.PostHandler.RecordView)
|
||||
posts.POST("/:id/view", optionalAuth, r.PostHandler.RecordView)
|
||||
// 分享计数(可选认证;仅已发布帖子生效)
|
||||
posts.POST("/:id/share", middleware.OptionalAuth(r.JWTService), r.PostHandler.RecordShare)
|
||||
posts.POST("/:id/share", optionalAuth, r.PostHandler.RecordShare)
|
||||
|
||||
// 内链相关路由
|
||||
posts.GET("/:id/related", middleware.OptionalAuth(r.JWTService), r.PostHandler.GetRelatedPosts)
|
||||
posts.GET("/:id/refs", middleware.OptionalAuth(r.JWTService), r.PostHandler.GetReferencedPosts)
|
||||
posts.POST("/:id/ref-click", middleware.OptionalAuth(r.JWTService), r.PostHandler.RecordRefClick)
|
||||
posts.GET("/:id/related", optionalAuth, r.PostHandler.GetRelatedPosts)
|
||||
posts.GET("/:id/refs", optionalAuth, r.PostHandler.GetReferencedPosts)
|
||||
posts.POST("/:id/ref-click", optionalAuth, r.PostHandler.RecordRefClick)
|
||||
|
||||
// 点赞
|
||||
posts.POST("/:id/like", authMiddleware, middleware.RequireVerified(r.UserService), r.PostHandler.Like)
|
||||
@@ -240,7 +252,7 @@ func (r *Router) setupRoutes() {
|
||||
|
||||
// 投票相关路由
|
||||
posts.POST("/vote", authMiddleware, middleware.RequireVerified(r.UserService), r.VoteHandler.CreateVotePost) // 创建投票帖子
|
||||
posts.GET("/:id/vote", middleware.OptionalAuth(r.JWTService), r.VoteHandler.GetVoteResult) // 获取投票结果
|
||||
posts.GET("/:id/vote", optionalAuth, r.VoteHandler.GetVoteResult) // 获取投票结果
|
||||
posts.POST("/:id/vote", authMiddleware, middleware.RequireVerified(r.UserService), r.VoteHandler.Vote) // 投票
|
||||
posts.DELETE("/:id/vote", authMiddleware, middleware.RequireVerified(r.UserService), r.VoteHandler.Unvote) // 取消投票
|
||||
}
|
||||
@@ -257,13 +269,13 @@ func (r *Router) setupRoutes() {
|
||||
if r.TradeHandler != nil {
|
||||
trade := v1.Group("/trade")
|
||||
{
|
||||
trade.GET("", middleware.OptionalAuth(r.JWTService), r.TradeHandler.List)
|
||||
trade.GET("/:id", middleware.OptionalAuth(r.JWTService), r.TradeHandler.GetByID)
|
||||
trade.GET("", optionalAuth, r.TradeHandler.List)
|
||||
trade.GET("/:id", optionalAuth, r.TradeHandler.GetByID)
|
||||
trade.POST("", authMiddleware, middleware.RequireVerified(r.UserService), r.TradeHandler.Create)
|
||||
trade.PUT("/:id", authMiddleware, middleware.RequireVerified(r.UserService), r.TradeHandler.Update)
|
||||
trade.DELETE("/:id", authMiddleware, middleware.RequireVerified(r.UserService), r.TradeHandler.Delete)
|
||||
trade.PUT("/:id/status", authMiddleware, middleware.RequireVerified(r.UserService), r.TradeHandler.UpdateStatus)
|
||||
trade.POST("/:id/view", middleware.OptionalAuth(r.JWTService), r.TradeHandler.RecordView)
|
||||
trade.POST("/:id/view", optionalAuth, r.TradeHandler.RecordView)
|
||||
trade.POST("/:id/favorite", authMiddleware, middleware.RequireVerified(r.UserService), r.TradeHandler.Favorite)
|
||||
trade.DELETE("/:id/favorite", authMiddleware, middleware.RequireVerified(r.UserService), r.TradeHandler.Unfavorite)
|
||||
}
|
||||
@@ -337,15 +349,15 @@ func (r *Router) setupRoutes() {
|
||||
// 评论路由
|
||||
comments := v1.Group("/comments")
|
||||
{
|
||||
comments.GET("/post/:id", middleware.OptionalAuth(r.JWTService), r.CommentHandler.GetByPostID)
|
||||
comments.GET("/post/:id/cursor", middleware.OptionalAuth(r.JWTService), r.CommentHandler.GetByPostIDByCursor) // 帖子评论游标分页
|
||||
comments.GET("/:id", middleware.OptionalAuth(r.JWTService), r.CommentHandler.GetByID)
|
||||
comments.GET("/post/:id", optionalAuth, r.CommentHandler.GetByPostID)
|
||||
comments.GET("/post/:id/cursor", optionalAuth, r.CommentHandler.GetByPostIDByCursor) // 帖子评论游标分页
|
||||
comments.GET("/:id", optionalAuth, r.CommentHandler.GetByID)
|
||||
comments.POST("", authMiddleware, middleware.RequireVerified(r.UserService), r.CommentHandler.Create)
|
||||
comments.PUT("/:id", authMiddleware, middleware.RequireVerified(r.UserService), r.CommentHandler.Update)
|
||||
comments.DELETE("/:id", authMiddleware, middleware.RequireVerified(r.UserService), r.CommentHandler.Delete)
|
||||
comments.GET("/:id/replies", middleware.OptionalAuth(r.JWTService), r.CommentHandler.GetReplies)
|
||||
comments.GET("/:id/replies/flat", middleware.OptionalAuth(r.JWTService), r.CommentHandler.GetRepliesByRootID) // 扁平化分页获取回复
|
||||
comments.GET("/:id/replies/cursor", middleware.OptionalAuth(r.JWTService), r.CommentHandler.GetRepliesByRootIDByCursor) // 回复游标分页
|
||||
comments.GET("/:id/replies", optionalAuth, r.CommentHandler.GetReplies)
|
||||
comments.GET("/:id/replies/flat", optionalAuth, r.CommentHandler.GetRepliesByRootID) // 扁平化分页获取回复
|
||||
comments.GET("/:id/replies/cursor", optionalAuth, r.CommentHandler.GetRepliesByRootIDByCursor) // 回复游标分页
|
||||
// 评论点赞
|
||||
comments.POST("/:id/like", authMiddleware, middleware.RequireVerified(r.UserService), r.CommentHandler.Like)
|
||||
comments.DELETE("/:id/like", authMiddleware, middleware.RequireVerified(r.UserService), r.CommentHandler.Unlike)
|
||||
@@ -527,129 +539,129 @@ func (r *Router) setupRoutes() {
|
||||
}
|
||||
}
|
||||
|
||||
// 管理路由(需要管理员权限)
|
||||
// 管理路由
|
||||
// 鉴权链:RequireAuth → RequireActive(拒绝 pending_deletion 访问 admin)→ 路由级 Authorize。
|
||||
// 不再使用 RequireRole 粗粒度,改用每路由 Authorize(casbin, resource, action),
|
||||
// super_admin 通过 admin.* 通配策略获得所有能力,admin 仅获得业务管理能力,
|
||||
// 角色与权限管理(admin.roles.*、admin.users.roles.*)与日志导出(admin.logs.export)仅 super_admin 拥有。
|
||||
if r.RoleHandler != nil {
|
||||
admin := v1.Group("/admin")
|
||||
admin.Use(authMiddleware)
|
||||
admin.Use(middleware.RequireRole(r.CasbinService, model.RoleAdmin, model.RoleSuperAdmin))
|
||||
{
|
||||
// 角色管理
|
||||
admin.GET("/roles", r.RoleHandler.GetAllRoles)
|
||||
admin.GET("/roles/:name", r.RoleHandler.GetRoleDetail)
|
||||
admin.GET("/roles/:name/permissions", r.RoleHandler.GetRolePermissions)
|
||||
admin.PUT("/roles/:name/permissions", r.RoleHandler.UpdateRolePermissions)
|
||||
admin.GET("/permissions", r.RoleHandler.GetAllPermissions)
|
||||
admin.GET("/users/:id/roles", r.RoleHandler.GetUserRoles)
|
||||
admin.POST("/users/:id/roles", r.RoleHandler.AssignRole)
|
||||
admin.DELETE("/users/:id/roles/:role", r.RoleHandler.RemoveRole)
|
||||
admin.Use(middleware.RequireActive())
|
||||
|
||||
// 用户管理
|
||||
if r.AdminUserHandler != nil {
|
||||
admin.GET("/users", r.AdminUserHandler.GetUserList)
|
||||
admin.GET("/users/:id", r.AdminUserHandler.GetUserDetail)
|
||||
admin.PUT("/users/:id/status", r.AdminUserHandler.UpdateUserStatus)
|
||||
admin.GET("/users/:id/devices", r.AdminUserHandler.GetUserDevices)
|
||||
}
|
||||
// 角色与权限管理(仅 super_admin)
|
||||
admin.GET("/roles", middleware.Authorize(r.CasbinService, "admin/roles", "read"), r.RoleHandler.GetAllRoles)
|
||||
admin.GET("/roles/:name", middleware.Authorize(r.CasbinService, "admin/roles", "read"), r.RoleHandler.GetRoleDetail)
|
||||
admin.GET("/roles/:name/permissions", middleware.Authorize(r.CasbinService, "admin/roles/permissions", "read"), r.RoleHandler.GetRolePermissions)
|
||||
admin.PUT("/roles/:name/permissions", middleware.Authorize(r.CasbinService, "admin/roles/permissions", "write"), r.RoleHandler.UpdateRolePermissions)
|
||||
admin.GET("/permissions", middleware.Authorize(r.CasbinService, "admin/roles", "read"), r.RoleHandler.GetAllPermissions)
|
||||
admin.GET("/users/:id/roles", middleware.Authorize(r.CasbinService, "admin/users/roles", "read"), r.RoleHandler.GetUserRoles)
|
||||
admin.POST("/users/:id/roles", middleware.Authorize(r.CasbinService, "admin/users/roles", "write"), r.RoleHandler.AssignRole)
|
||||
admin.DELETE("/users/:id/roles/:role", middleware.Authorize(r.CasbinService, "admin/users/roles", "write"), r.RoleHandler.RemoveRole)
|
||||
|
||||
// 帖子管理
|
||||
if r.AdminPostHandler != nil {
|
||||
admin.GET("/posts", r.AdminPostHandler.GetPostList)
|
||||
admin.GET("/posts/:id", r.AdminPostHandler.GetPostDetail)
|
||||
admin.DELETE("/posts/:id", r.AdminPostHandler.DeletePost)
|
||||
admin.PUT("/posts/:id/moderate", r.AdminPostHandler.ModeratePost)
|
||||
admin.POST("/posts/batch-delete", r.AdminPostHandler.BatchDeletePosts)
|
||||
admin.POST("/posts/batch-moderate", r.AdminPostHandler.BatchModeratePosts)
|
||||
admin.PUT("/posts/:id/pin", r.AdminPostHandler.SetPostPin)
|
||||
admin.PUT("/posts/:id/feature", r.AdminPostHandler.SetPostFeature)
|
||||
}
|
||||
// 用户管理
|
||||
if r.AdminUserHandler != nil {
|
||||
admin.GET("/users", middleware.Authorize(r.CasbinService, "admin/users", "read"), r.AdminUserHandler.GetUserList)
|
||||
admin.GET("/users/:id", middleware.Authorize(r.CasbinService, "admin/users", "read"), r.AdminUserHandler.GetUserDetail)
|
||||
admin.PUT("/users/:id/status", middleware.Authorize(r.CasbinService, "admin/users/status", "write"), r.AdminUserHandler.UpdateUserStatus)
|
||||
admin.GET("/users/:id/devices", middleware.Authorize(r.CasbinService, "admin/users/devices", "read"), r.AdminUserHandler.GetUserDevices)
|
||||
}
|
||||
|
||||
// 频道管理
|
||||
if r.ChannelHandler != nil {
|
||||
admin.GET("/channels", r.ChannelHandler.AdminList)
|
||||
admin.POST("/channels", r.ChannelHandler.AdminCreate)
|
||||
admin.PUT("/channels/:id", r.ChannelHandler.AdminUpdate)
|
||||
admin.DELETE("/channels/:id", r.ChannelHandler.AdminDelete)
|
||||
}
|
||||
// 帖子管理
|
||||
if r.AdminPostHandler != nil {
|
||||
admin.GET("/posts", middleware.Authorize(r.CasbinService, "admin/posts", "read"), r.AdminPostHandler.GetPostList)
|
||||
admin.GET("/posts/:id", middleware.Authorize(r.CasbinService, "admin/posts", "read"), r.AdminPostHandler.GetPostDetail)
|
||||
admin.DELETE("/posts/:id", middleware.Authorize(r.CasbinService, "admin/posts", "write"), r.AdminPostHandler.DeletePost)
|
||||
admin.PUT("/posts/:id/moderate", middleware.Authorize(r.CasbinService, "admin/posts", "write"), r.AdminPostHandler.ModeratePost)
|
||||
admin.POST("/posts/batch-delete", middleware.Authorize(r.CasbinService, "admin/posts", "write"), r.AdminPostHandler.BatchDeletePosts)
|
||||
admin.POST("/posts/batch-moderate", middleware.Authorize(r.CasbinService, "admin/posts", "write"), r.AdminPostHandler.BatchModeratePosts)
|
||||
admin.PUT("/posts/:id/pin", middleware.Authorize(r.CasbinService, "admin/posts", "write"), r.AdminPostHandler.SetPostPin)
|
||||
admin.PUT("/posts/:id/feature", middleware.Authorize(r.CasbinService, "admin/posts", "write"), r.AdminPostHandler.SetPostFeature)
|
||||
}
|
||||
|
||||
// 评论管理
|
||||
if r.AdminCommentHandler != nil {
|
||||
admin.GET("/comments", r.AdminCommentHandler.GetCommentList)
|
||||
admin.GET("/comments/:id", r.AdminCommentHandler.GetCommentDetail)
|
||||
admin.DELETE("/comments/:id", r.AdminCommentHandler.DeleteComment)
|
||||
admin.PUT("/comments/:id/moderate", r.AdminCommentHandler.ModerateComment)
|
||||
admin.POST("/comments/batch-delete", r.AdminCommentHandler.BatchDeleteComments)
|
||||
admin.POST("/comments/batch-moderate", r.AdminCommentHandler.BatchModerateComments)
|
||||
admin.GET("/comments/post/:postId", r.AdminCommentHandler.GetPostComments)
|
||||
}
|
||||
// 频道管理
|
||||
if r.ChannelHandler != nil {
|
||||
admin.GET("/channels", middleware.Authorize(r.CasbinService, "admin/channels", "read"), r.ChannelHandler.AdminList)
|
||||
admin.POST("/channels", middleware.Authorize(r.CasbinService, "admin/channels", "write"), r.ChannelHandler.AdminCreate)
|
||||
admin.PUT("/channels/:id", middleware.Authorize(r.CasbinService, "admin/channels", "write"), r.ChannelHandler.AdminUpdate)
|
||||
admin.DELETE("/channels/:id", middleware.Authorize(r.CasbinService, "admin/channels", "write"), r.ChannelHandler.AdminDelete)
|
||||
}
|
||||
|
||||
// 群组管理
|
||||
if r.AdminGroupHandler != nil {
|
||||
admin.GET("/groups", r.AdminGroupHandler.GetGroupList)
|
||||
admin.GET("/groups/:id", r.AdminGroupHandler.GetGroupDetail)
|
||||
admin.GET("/groups/:id/members", r.AdminGroupHandler.GetGroupMembers)
|
||||
admin.DELETE("/groups/:id", r.AdminGroupHandler.DeleteGroup)
|
||||
admin.PUT("/groups/:id/status", r.AdminGroupHandler.UpdateGroupStatus)
|
||||
admin.DELETE("/groups/:id/members/:userId", r.AdminGroupHandler.RemoveMember)
|
||||
admin.PUT("/groups/:id/transfer", r.AdminGroupHandler.TransferOwner)
|
||||
}
|
||||
// 评论管理
|
||||
if r.AdminCommentHandler != nil {
|
||||
admin.GET("/comments", middleware.Authorize(r.CasbinService, "admin/comments", "read"), r.AdminCommentHandler.GetCommentList)
|
||||
admin.GET("/comments/:id", middleware.Authorize(r.CasbinService, "admin/comments", "read"), r.AdminCommentHandler.GetCommentDetail)
|
||||
admin.DELETE("/comments/:id", middleware.Authorize(r.CasbinService, "admin/comments", "write"), r.AdminCommentHandler.DeleteComment)
|
||||
admin.PUT("/comments/:id/moderate", middleware.Authorize(r.CasbinService, "admin/comments", "write"), r.AdminCommentHandler.ModerateComment)
|
||||
admin.POST("/comments/batch-delete", middleware.Authorize(r.CasbinService, "admin/comments", "write"), r.AdminCommentHandler.BatchDeleteComments)
|
||||
admin.POST("/comments/batch-moderate", middleware.Authorize(r.CasbinService, "admin/comments", "write"), r.AdminCommentHandler.BatchModerateComments)
|
||||
admin.GET("/comments/post/:postId", middleware.Authorize(r.CasbinService, "admin/comments", "read"), r.AdminCommentHandler.GetPostComments)
|
||||
}
|
||||
|
||||
// 仪表盘
|
||||
if r.AdminDashboardHandler != nil {
|
||||
admin.GET("/dashboard/stats", r.AdminDashboardHandler.GetStats)
|
||||
admin.GET("/dashboard/user-activity", r.AdminDashboardHandler.GetUserActivityTrend)
|
||||
admin.GET("/dashboard/content-stats", r.AdminDashboardHandler.GetContentStats)
|
||||
admin.GET("/dashboard/pending-content", r.AdminDashboardHandler.GetPendingContent)
|
||||
admin.GET("/dashboard/online-users", r.AdminDashboardHandler.GetOnlineUsers)
|
||||
}
|
||||
// 群组管理
|
||||
if r.AdminGroupHandler != nil {
|
||||
admin.GET("/groups", middleware.Authorize(r.CasbinService, "admin/groups", "read"), r.AdminGroupHandler.GetGroupList)
|
||||
admin.GET("/groups/:id", middleware.Authorize(r.CasbinService, "admin/groups", "read"), r.AdminGroupHandler.GetGroupDetail)
|
||||
admin.GET("/groups/:id/members", middleware.Authorize(r.CasbinService, "admin/groups", "read"), r.AdminGroupHandler.GetGroupMembers)
|
||||
admin.DELETE("/groups/:id", middleware.Authorize(r.CasbinService, "admin/groups", "write"), r.AdminGroupHandler.DeleteGroup)
|
||||
admin.PUT("/groups/:id/status", middleware.Authorize(r.CasbinService, "admin/groups", "write"), r.AdminGroupHandler.UpdateGroupStatus)
|
||||
admin.DELETE("/groups/:id/members/:userId", middleware.Authorize(r.CasbinService, "admin/groups", "write"), r.AdminGroupHandler.RemoveMember)
|
||||
admin.PUT("/groups/:id/transfer", middleware.Authorize(r.CasbinService, "admin/groups", "write"), r.AdminGroupHandler.TransferOwner)
|
||||
}
|
||||
|
||||
// 日志管理
|
||||
if r.AdminLogHandler != nil {
|
||||
logs := admin.Group("/logs")
|
||||
{
|
||||
logs.GET("/operations", r.AdminLogHandler.GetOperationLogs)
|
||||
logs.GET("/logins", r.AdminLogHandler.GetLoginLogs)
|
||||
logs.GET("/data-changes", r.AdminLogHandler.GetDataChangeLogs)
|
||||
logs.GET("/statistics", r.AdminLogHandler.GetLogStatistics)
|
||||
logs.GET("/export", r.AdminLogHandler.ExportLogs)
|
||||
}
|
||||
}
|
||||
// 仪表盘
|
||||
if r.AdminDashboardHandler != nil {
|
||||
admin.GET("/dashboard/stats", middleware.Authorize(r.CasbinService, "admin/dashboard", "read"), r.AdminDashboardHandler.GetStats)
|
||||
admin.GET("/dashboard/user-activity", middleware.Authorize(r.CasbinService, "admin/dashboard", "read"), r.AdminDashboardHandler.GetUserActivityTrend)
|
||||
admin.GET("/dashboard/content-stats", middleware.Authorize(r.CasbinService, "admin/dashboard", "read"), r.AdminDashboardHandler.GetContentStats)
|
||||
admin.GET("/dashboard/pending-content", middleware.Authorize(r.CasbinService, "admin/dashboard", "read"), r.AdminDashboardHandler.GetPendingContent)
|
||||
admin.GET("/dashboard/online-users", middleware.Authorize(r.CasbinService, "admin/dashboard", "read"), r.AdminDashboardHandler.GetOnlineUsers)
|
||||
}
|
||||
|
||||
// 学习资料管理
|
||||
if r.MaterialHandler != nil {
|
||||
// 学科管理
|
||||
admin.GET("/materials/subjects", r.MaterialHandler.AdminListSubjects)
|
||||
admin.POST("/materials/subjects", r.MaterialHandler.AdminCreateSubject)
|
||||
admin.PUT("/materials/subjects/:id", r.MaterialHandler.AdminUpdateSubject)
|
||||
admin.DELETE("/materials/subjects/:id", r.MaterialHandler.AdminDeleteSubject)
|
||||
// 资料管理
|
||||
admin.GET("/materials", r.MaterialHandler.AdminListMaterials)
|
||||
admin.GET("/materials/:id", r.MaterialHandler.AdminGetMaterial)
|
||||
admin.POST("/materials", r.MaterialHandler.AdminCreateMaterial)
|
||||
admin.PUT("/materials/:id", r.MaterialHandler.AdminUpdateMaterial)
|
||||
admin.DELETE("/materials/:id", r.MaterialHandler.AdminDeleteMaterial)
|
||||
}
|
||||
// 日志管理(导出仅 super_admin)
|
||||
if r.AdminLogHandler != nil {
|
||||
admin.GET("/logs/operations", middleware.Authorize(r.CasbinService, "admin/logs", "read"), r.AdminLogHandler.GetOperationLogs)
|
||||
admin.GET("/logs/logins", middleware.Authorize(r.CasbinService, "admin/logs", "read"), r.AdminLogHandler.GetLoginLogs)
|
||||
admin.GET("/logs/data-changes", middleware.Authorize(r.CasbinService, "admin/logs", "read"), r.AdminLogHandler.GetDataChangeLogs)
|
||||
admin.GET("/logs/statistics", middleware.Authorize(r.CasbinService, "admin/logs", "read"), r.AdminLogHandler.GetLogStatistics)
|
||||
admin.GET("/logs/export", middleware.Authorize(r.CasbinService, "admin/logs/export", "read"), r.AdminLogHandler.ExportLogs)
|
||||
}
|
||||
|
||||
// 举报管理
|
||||
if r.AdminReportHandler != nil {
|
||||
admin.GET("/reports", r.AdminReportHandler.List)
|
||||
admin.GET("/reports/:id", r.AdminReportHandler.Detail)
|
||||
admin.PUT("/reports/:id/handle", r.AdminReportHandler.Handle)
|
||||
admin.POST("/reports/batch-handle", r.AdminReportHandler.BatchHandle)
|
||||
}
|
||||
// 学习资料管理
|
||||
if r.MaterialHandler != nil {
|
||||
// 学科管理
|
||||
admin.GET("/materials/subjects", middleware.Authorize(r.CasbinService, "admin/materials", "read"), r.MaterialHandler.AdminListSubjects)
|
||||
admin.POST("/materials/subjects", middleware.Authorize(r.CasbinService, "admin/materials", "write"), r.MaterialHandler.AdminCreateSubject)
|
||||
admin.PUT("/materials/subjects/:id", middleware.Authorize(r.CasbinService, "admin/materials", "write"), r.MaterialHandler.AdminUpdateSubject)
|
||||
admin.DELETE("/materials/subjects/:id", middleware.Authorize(r.CasbinService, "admin/materials", "write"), r.MaterialHandler.AdminDeleteSubject)
|
||||
// 资料管理
|
||||
admin.GET("/materials", middleware.Authorize(r.CasbinService, "admin/materials", "read"), r.MaterialHandler.AdminListMaterials)
|
||||
admin.GET("/materials/:id", middleware.Authorize(r.CasbinService, "admin/materials", "read"), r.MaterialHandler.AdminGetMaterial)
|
||||
admin.POST("/materials", middleware.Authorize(r.CasbinService, "admin/materials", "write"), r.MaterialHandler.AdminCreateMaterial)
|
||||
admin.PUT("/materials/:id", middleware.Authorize(r.CasbinService, "admin/materials", "write"), r.MaterialHandler.AdminUpdateMaterial)
|
||||
admin.DELETE("/materials/:id", middleware.Authorize(r.CasbinService, "admin/materials", "write"), r.MaterialHandler.AdminDeleteMaterial)
|
||||
}
|
||||
|
||||
// 身份认证管理
|
||||
if r.AdminVerificationHandler != nil {
|
||||
admin.GET("/verifications", r.AdminVerificationHandler.ListVerifications)
|
||||
admin.GET("/verifications/:id", r.AdminVerificationHandler.GetVerificationDetail)
|
||||
admin.PUT("/verifications/:id/review", r.AdminVerificationHandler.ReviewVerification)
|
||||
}
|
||||
// 举报管理
|
||||
if r.AdminReportHandler != nil {
|
||||
admin.GET("/reports", middleware.Authorize(r.CasbinService, "admin/reports", "read"), r.AdminReportHandler.List)
|
||||
admin.GET("/reports/:id", middleware.Authorize(r.CasbinService, "admin/reports", "read"), r.AdminReportHandler.Detail)
|
||||
admin.PUT("/reports/:id/handle", middleware.Authorize(r.CasbinService, "admin/reports", "write"), r.AdminReportHandler.Handle)
|
||||
admin.POST("/reports/batch-handle", middleware.Authorize(r.CasbinService, "admin/reports", "write"), r.AdminReportHandler.BatchHandle)
|
||||
}
|
||||
|
||||
// 用户资料审核管理
|
||||
if r.AdminProfileAuditHandler != nil {
|
||||
admin.GET("/profile-audits", r.AdminProfileAuditHandler.GetPendingList)
|
||||
admin.PUT("/profile-audits/:id/moderate", r.AdminProfileAuditHandler.ModerateAudit)
|
||||
admin.POST("/profile-audits/batch-moderate", r.AdminProfileAuditHandler.BatchModerate)
|
||||
}
|
||||
// 身份认证管理
|
||||
if r.AdminVerificationHandler != nil {
|
||||
admin.GET("/verifications", middleware.Authorize(r.CasbinService, "admin/verifications", "read"), r.AdminVerificationHandler.ListVerifications)
|
||||
admin.GET("/verifications/:id", middleware.Authorize(r.CasbinService, "admin/verifications", "read"), r.AdminVerificationHandler.GetVerificationDetail)
|
||||
admin.PUT("/verifications/:id/review", middleware.Authorize(r.CasbinService, "admin/verifications", "write"), r.AdminVerificationHandler.ReviewVerification)
|
||||
}
|
||||
|
||||
// 用户资料审核管理
|
||||
if r.AdminProfileAuditHandler != nil {
|
||||
admin.GET("/profile-audits", middleware.Authorize(r.CasbinService, "admin/profile_audits", "read"), r.AdminProfileAuditHandler.GetPendingList)
|
||||
admin.PUT("/profile-audits/:id/moderate", middleware.Authorize(r.CasbinService, "admin/profile_audits", "write"), r.AdminProfileAuditHandler.ModerateAudit)
|
||||
admin.POST("/profile-audits/batch-moderate", middleware.Authorize(r.CasbinService, "admin/profile_audits", "write"), r.AdminProfileAuditHandler.BatchModerate)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user