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

@@ -0,0 +1,97 @@
package repository
import (
"context"
"carrot_bbs/internal/model"
"gorm.io/gorm"
)
// RoleRepository 角色仓储接口
type RoleRepository interface {
// GetUserRoles 获取用户的所有角色
GetUserRoles(ctx context.Context, userID string) ([]string, error)
// AddRoleForUser 为用户添加角色
AddRoleForUser(ctx context.Context, userID, role string) error
// DeleteRoleForUser 移除用户的角色
DeleteRoleForUser(ctx context.Context, userID, role string) error
// DeleteAllRolesForUser 移除用户的所有角色
DeleteAllRolesForUser(ctx context.Context, userID string) error
// HasRole 检查用户是否拥有指定角色
HasRole(ctx context.Context, userID, role string) (bool, error)
// GetRole 获取角色信息
GetRole(ctx context.Context, name string) (*model.Role, error)
// GetAllRoles 获取所有角色
GetAllRoles(ctx context.Context) ([]model.Role, error)
}
type roleRepository struct {
db *gorm.DB
}
func NewRoleRepository(db *gorm.DB) RoleRepository {
return &roleRepository{db: db}
}
func (r *roleRepository) GetUserRoles(ctx context.Context, userID string) ([]string, error) {
var userRoles []model.UserRole
if err := r.db.WithContext(ctx).Where("user_id = ?", userID).Find(&userRoles).Error; err != nil {
return nil, err
}
roles := make([]string, len(userRoles))
for i, ur := range userRoles {
roles[i] = ur.Role
}
return roles, nil
}
func (r *roleRepository) AddRoleForUser(ctx context.Context, userID, role string) error {
userRole := model.UserRole{
UserID: userID,
Role: role,
}
return r.db.WithContext(ctx).Create(&userRole).Error
}
func (r *roleRepository) DeleteRoleForUser(ctx context.Context, userID, role string) error {
return r.db.WithContext(ctx).
Where("user_id = ? AND role = ?", userID, role).
Delete(&model.UserRole{}).Error
}
func (r *roleRepository) DeleteAllRolesForUser(ctx context.Context, userID string) error {
return r.db.WithContext(ctx).
Where("user_id = ?", userID).
Delete(&model.UserRole{}).Error
}
func (r *roleRepository) HasRole(ctx context.Context, userID, role string) (bool, error) {
var count int64
err := r.db.WithContext(ctx).
Model(&model.UserRole{}).
Where("user_id = ? AND role = ?", userID, role).
Count(&count).Error
return count > 0, err
}
func (r *roleRepository) GetRole(ctx context.Context, name string) (*model.Role, error) {
var role model.Role
err := r.db.WithContext(ctx).Where("name = ?", name).First(&role).Error
if err != nil {
return nil, err
}
return &role, nil
}
func (r *roleRepository) GetAllRoles(ctx context.Context) ([]model.Role, error) {
var roles []model.Role
err := r.db.WithContext(ctx).Order("priority DESC").Find(&roles).Error
return roles, err
}