feat(auth): add Casbin RBAC and user activity tracking

Integrate Casbin for role-based access control with admin routes for role management. Add user activity logging service to track login and refresh events. Refactor audit service to use AI-based content moderation.
This commit is contained in:
2026-03-14 02:09:38 +08:00
parent c561a0bb0c
commit ae5b997924
27 changed files with 2197 additions and 691 deletions

View File

@@ -1,25 +1,29 @@
package handler
import (
"context"
"strconv"
"github.com/gin-gonic/gin"
"carrot_bbs/internal/dto"
"carrot_bbs/internal/model"
"carrot_bbs/internal/pkg/response"
"carrot_bbs/internal/service"
)
// UserHandler 用户处理器
type UserHandler struct {
userService service.UserService
jwtService *service.JWTService
userService service.UserService
activityService service.UserActivityService // 用户活跃统计服务
jwtService *service.JWTService
}
// NewUserHandler 创建用户处理器
func NewUserHandler(userService service.UserService) *UserHandler {
func NewUserHandler(userService service.UserService, activityService service.UserActivityService) *UserHandler {
return &UserHandler{
userService: userService,
userService: userService,
activityService: activityService,
}
}
@@ -90,6 +94,17 @@ func (h *UserHandler) Login(c *gin.Context) {
accessToken, _ := h.jwtService.GenerateAccessToken(user.ID, user.Username)
refreshToken, _ := h.jwtService.GenerateRefreshToken(user.ID, user.Username)
// 记录用户活跃
if h.activityService != nil {
go func() {
ctx := context.Background()
loginType := model.LoginTypeLogin
ip := c.ClientIP()
userAgent := c.GetHeader("User-Agent")
h.activityService.RecordUserActive(ctx, user.ID, loginType, ip, userAgent)
}()
}
response.Success(c, gin.H{
"user": dto.ConvertUserToResponse(user),
"token": accessToken,
@@ -353,6 +368,17 @@ func (h *UserHandler) RefreshToken(c *gin.Context) {
accessToken, _ := h.jwtService.GenerateAccessToken(claims.UserID, claims.Username)
refreshToken, _ := h.jwtService.GenerateRefreshToken(claims.UserID, claims.Username)
// 记录用户活跃
if h.activityService != nil {
go func() {
ctx := context.Background()
loginType := model.LoginTypeRefresh
ip := c.ClientIP()
userAgent := c.GetHeader("User-Agent")
h.activityService.RecordUserActive(ctx, claims.UserID, loginType, ip, userAgent)
}()
}
response.Success(c, gin.H{
"token": accessToken,
"refresh_token": refreshToken,
@@ -364,6 +390,11 @@ func (h *UserHandler) SetJWTService(jwtSvc *service.JWTService) {
h.jwtService = jwtSvc
}
// SetActivityService 设置活跃统计服务
func (h *UserHandler) SetActivityService(activityService service.UserActivityService) {
h.activityService = activityService
}
// FollowUser 关注用户
func (h *UserHandler) FollowUser(c *gin.Context) {
userID := c.Param("id")