Files
backend/internal/service/role_service.go
lan ae5b997924 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.
2026-03-14 02:09:38 +08:00

117 lines
2.9 KiB
Go

package service
import (
"context"
apperrors "carrot_bbs/internal/errors"
"carrot_bbs/internal/model"
"carrot_bbs/internal/repository"
)
// RoleService 角色管理服务接口
type RoleService interface {
// GetUserRoles 获取用户的所有角色
GetUserRoles(ctx context.Context, userID string) ([]model.Role, error)
// AssignRole 为用户分配角色
AssignRole(ctx context.Context, operatorID, targetUserID, role string) error
// RemoveRole 移除用户的角色
RemoveRole(ctx context.Context, operatorID, targetUserID, role string) error
// GetAllRoles 获取所有角色定义
GetAllRoles(ctx context.Context) ([]model.Role, error)
// GetRole 获取角色详情
GetRole(ctx context.Context, name string) (*model.Role, error)
}
type roleService struct {
roleRepo repository.RoleRepository
casbinSvc CasbinService
}
// NewRoleService 创建角色管理服务
func NewRoleService(
roleRepo repository.RoleRepository,
casbinSvc CasbinService,
) RoleService {
return &roleService{
roleRepo: roleRepo,
casbinSvc: casbinSvc,
}
}
func (s *roleService) GetUserRoles(ctx context.Context, userID string) ([]model.Role, error) {
roleNames, err := s.casbinSvc.GetRolesForUser(ctx, userID)
if err != nil {
return nil, err
}
var roles []model.Role
for _, name := range roleNames {
role, err := s.roleRepo.GetRole(ctx, name)
if err != nil {
continue // 忽略找不到的角色
}
roles = append(roles, *role)
}
return roles, nil
}
func (s *roleService) AssignRole(ctx context.Context, operatorID, targetUserID, role string) error {
// 不能修改自己的角色
if operatorID == targetUserID {
return apperrors.ErrCannotModifyOwnRole
}
// 检查目标用户是否已有该角色
hasRole, err := s.casbinSvc.HasRoleForUser(ctx, targetUserID, role)
if err != nil {
return err
}
if hasRole {
return apperrors.ErrRoleAlreadyAssigned
}
// 检查角色是否存在
_, err = s.roleRepo.GetRole(ctx, role)
if err != nil {
return apperrors.ErrRoleNotFound
}
// 添加角色
return s.casbinSvc.AddRoleForUser(ctx, targetUserID, role)
}
func (s *roleService) RemoveRole(ctx context.Context, operatorID, targetUserID, role string) error {
// 不能修改自己的角色
if operatorID == targetUserID {
return apperrors.ErrCannotModifyOwnRole
}
// 不能修改超级管理员角色
if role == model.RoleSuperAdmin {
return apperrors.ErrCannotModifySuperAdmin
}
// 检查用户是否有该角色
hasRole, err := s.casbinSvc.HasRoleForUser(ctx, targetUserID, role)
if err != nil {
return err
}
if !hasRole {
return apperrors.ErrRoleNotAssigned
}
return s.casbinSvc.DeleteRoleForUser(ctx, targetUserID, role)
}
func (s *roleService) GetAllRoles(ctx context.Context) ([]model.Role, error) {
return s.roleRepo.GetAllRoles(ctx)
}
func (s *roleService) GetRole(ctx context.Context, name string) (*model.Role, error) {
return s.roleRepo.GetRole(ctx, name)
}