- Remove BOM from all Go source files - Standardize import ordering and whitespace across handlers and services - Replace PostgreSQL full-text search with ILIKE pattern matching in post and user repositories - Enhance JPush client with TLS transport, rate limit monitoring, and simplified API - Refactor PushService to include userID in device management methods - Add MaxDevicesPerUser limit and extract helper functions for push payload construction
251 lines
6.4 KiB
Go
251 lines
6.4 KiB
Go
package service
|
||
|
||
import (
|
||
"context"
|
||
|
||
apperrors "with_you/internal/errors"
|
||
"with_you/internal/model"
|
||
"with_you/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)
|
||
}
|