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

54
internal/wire/casbin.go Normal file
View File

@@ -0,0 +1,54 @@
package wire
import (
"log"
"carrot_bbs/internal/cache"
"carrot_bbs/internal/config"
"carrot_bbs/internal/repository"
"carrot_bbs/internal/service"
"github.com/casbin/casbin/v2"
"github.com/google/wire"
"gorm.io/gorm"
)
// CasbinSet Casbin 相关 Provider Set
var CasbinSet = wire.NewSet(
ProvideCasbinEnforcer,
ProvideCasbinService,
ProvideRoleRepository,
)
// ProvideCasbinEnforcer 提供 Casbin Enforcer
func ProvideCasbinEnforcer(cfg *config.Config, db *gorm.DB) *casbin.Enforcer {
// 创建 Casbin Enforcer
// 注意:这里使用文件适配器作为示例,实际使用时需要替换为数据库适配器
enforcer, err := casbin.NewEnforcer(cfg.Casbin.ModelPath)
if err != nil {
log.Fatalf("Failed to create Casbin enforcer: %v", err)
}
// 加载策略
if err := enforcer.LoadPolicy(); err != nil {
log.Printf("[WARNING] Failed to load Casbin policy: %v", err)
}
log.Println("[Wire] Initialized Casbin enforcer")
return enforcer
}
// ProvideCasbinService 提供 Casbin 服务
func ProvideCasbinService(
enforcer *casbin.Enforcer,
cache cache.Cache,
roleRepo repository.RoleRepository,
cfg *config.Config,
) service.CasbinService {
return service.NewCasbinService(enforcer, cache, roleRepo, &cfg.Casbin)
}
// ProvideRoleRepository 提供角色仓储
func ProvideRoleRepository(db *gorm.DB) repository.RoleRepository {
return repository.NewRoleRepository(db)
}

View File

@@ -15,15 +15,16 @@ import (
// HandlerSet Handler 层 Provider Set
var HandlerSet = wire.NewSet(
// 直接使用构造函数的 Handler
handler.NewUserHandler,
handler.NewCommentHandler,
handler.NewNotificationHandler,
handler.NewUploadHandler,
handler.NewPushHandler,
handler.NewStickerHandler,
handler.NewVoteHandler,
handler.NewRoleHandler,
// 需要特殊处理的 Handler
ProvideUserHandler,
ProvidePostHandler,
ProvideMessageHandler,
ProvideSystemMessageHandler,
@@ -32,6 +33,14 @@ var HandlerSet = wire.NewSet(
ProvideScheduleHandler,
)
// ProvideUserHandler 提供用户处理器
func ProvideUserHandler(
userService service.UserService,
activityService service.UserActivityService,
) *handler.UserHandler {
return handler.NewUserHandler(userService, activityService)
}
// ProvidePostHandler 提供帖子处理器
func ProvidePostHandler(
postService service.PostService,

View File

@@ -5,6 +5,7 @@ import "github.com/google/wire"
// AllSet 包含所有 Provider Set
var AllSet = wire.NewSet(
InfrastructureSet,
CasbinSet,
RepositorySet,
ServiceSet,
HandlerSet,

View File

@@ -1,9 +1,11 @@
package wire
import (
"carrot_bbs/internal/cache"
"carrot_bbs/internal/repository"
"github.com/google/wire"
"gorm.io/gorm"
)
// RepositorySet Repository 层 Provider Set
@@ -20,8 +22,14 @@ var RepositorySet = wire.NewSet(
repository.NewStickerRepository,
repository.NewVoteRepository,
repository.NewScheduleRepository,
ProvideUserActivityRepository,
)
// ProvideUserActivityRepository 提供用户活跃数据仓储
func ProvideUserActivityRepository(db *gorm.DB, cache cache.Cache) *repository.UserActivityRepository {
return repository.NewUserActivityRepository(db, cache)
}
// Note: 以下 Repository 返回接口类型而非指针,需要单独处理
// - ScheduleRepository (repository.ScheduleRepository)
// - StickerRepository (repository.StickerRepository)

View File

@@ -41,6 +41,8 @@ var ServiceSet = wire.NewSet(
ProvideScheduleSyncService,
ProvideGroupService,
ProvideUploadService,
ProvideUserActivityService,
ProvideRoleService,
)
// ProvideJWTService 提供 JWT 服务
@@ -199,3 +201,16 @@ func ProvideUploadService(
) *service.UploadService {
return service.NewUploadService(s3Client, userService)
}
// ProvideUserActivityService 提供用户活跃统计服务
func ProvideUserActivityService(repo *repository.UserActivityRepository) service.UserActivityService {
return service.NewUserActivityService(repo)
}
// ProvideRoleService 提供角色管理服务
func ProvideRoleService(
roleRepo repository.RoleRepository,
casbinSvc service.CasbinService,
) service.RoleService {
return service.NewRoleService(roleRepo, casbinSvc)
}