Files
backend/internal/service/role_service.go

251 lines
6.4 KiB
Go
Raw Normal View History

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)
// GetRoleDetail 获取角色详情(包含用户数量和权限)
GetRoleDetail(ctx context.Context, name string) (*RoleDetail, error)
// GetRolePermissions 获取角色的权限列表
GetRolePermissions(ctx context.Context, name string) ([]Permission, error)
// GetAllPermissions 获取系统中所有权限定义
GetAllPermissions(ctx context.Context) ([]Permission, error)
// UpdateRolePermissions 更新角色权限
UpdateRolePermissions(ctx context.Context, roleName string, permissions []Permission) error
}
// Permission 权限定义
type Permission struct {
Resource string `json:"resource"`
Action string `json:"action"`
}
// RoleDetail 角色详情
type RoleDetail struct {
Name string `json:"name"`
DisplayName string `json:"display_name"`
Description string `json:"description"`
ParentRole *string `json:"parent_role"`
Priority int `json:"priority"`
UserCount int64 `json:"user_count"`
Permissions []Permission `json:"permissions"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
}
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)
}
func (s *roleService) GetRoleDetail(ctx context.Context, name string) (*RoleDetail, error) {
role, err := s.roleRepo.GetRole(ctx, name)
if err != nil {
return nil, apperrors.ErrRoleNotFound
}
// 获取用户数量
userCount, err := s.roleRepo.GetRoleUserCount(ctx, name)
if err != nil {
userCount = 0
}
// 获取权限
permissions, err := s.casbinSvc.GetPermissionsForRole(ctx, name)
if err != nil {
return nil, err
}
perms := make([]Permission, 0)
for _, p := range permissions {
if len(p) >= 2 {
perms = append(perms, Permission{
Resource: p[0],
Action: p[1],
})
}
}
return &RoleDetail{
Name: role.Name,
DisplayName: role.DisplayName,
Description: role.Description,
ParentRole: role.ParentRole,
Priority: role.Priority,
UserCount: userCount,
Permissions: perms,
CreatedAt: role.CreatedAt.Format("2006-01-02T15:04:05Z07:00"),
UpdatedAt: role.UpdatedAt.Format("2006-01-02T15:04:05Z07:00"),
}, nil
}
func (s *roleService) GetRolePermissions(ctx context.Context, name string) ([]Permission, error) {
// 检查角色是否存在
_, err := s.roleRepo.GetRole(ctx, name)
if err != nil {
return nil, apperrors.ErrRoleNotFound
}
permissions, err := s.casbinSvc.GetPermissionsForRole(ctx, name)
if err != nil {
return nil, err
}
// 初始化为空数组,避免 JSON 序列化为 null
perms := make([]Permission, 0)
for _, p := range permissions {
if len(p) >= 2 {
perms = append(perms, Permission{
Resource: p[0],
Action: p[1],
})
}
}
return perms, nil
}
func (s *roleService) GetAllPermissions(ctx context.Context) ([]Permission, error) {
permissions := s.casbinSvc.GetAllPermissions(ctx)
perms := make([]Permission, 0)
for _, p := range permissions {
if len(p) >= 3 {
// p[0] 是角色名p[1] 是资源p[2] 是操作
perms = append(perms, Permission{
Resource: p[1],
Action: p[2],
})
}
}
return perms, nil
}
func (s *roleService) UpdateRolePermissions(ctx context.Context, roleName string, permissions []Permission) error {
// 检查角色是否存在
_, err := s.roleRepo.GetRole(ctx, roleName)
if err != nil {
return apperrors.ErrRoleNotFound
}
// 不能修改超级管理员权限
if roleName == model.RoleSuperAdmin {
return apperrors.ErrCannotModifySuperAdmin
}
// 转换权限格式
var perms [][]string
for _, p := range permissions {
perms = append(perms, []string{p.Resource, p.Action})
}
return s.casbinSvc.UpdatePermissionsForRole(ctx, roleName, perms)
}