backend/pkg/permission/usecase/role.go

190 lines
4.8 KiB
Go

package usecase
import (
"backend/pkg/library/errs/code"
"backend/pkg/permission/domain/permission"
"context"
"backend/pkg/library/errs"
"backend/pkg/permission/domain/entity"
"backend/pkg/permission/domain/repository"
"backend/pkg/permission/domain/usecase"
)
type RoleUseCaseParam struct {
RoleRepo repository.RoleRepository
UserRoleRepo repository.UserRoleRepository
}
type RoleUseCase struct {
roleRepo repository.RoleRepository
userRoleRepo repository.UserRoleRepository
}
// MustRoleUseCase 創建角色用例實例
func MustRoleUseCase(param RoleUseCaseParam) usecase.RoleUseCase {
return &RoleUseCase{
roleRepo: param.RoleRepo,
userRoleRepo: param.UserRoleRepo,
}
}
func (uc *RoleUseCase) CreateRole(ctx context.Context, req usecase.CreateRoleRequest) (*entity.Role, error) {
// 驗證請求
if req.ClientID == "" {
return nil, errs.InvalidFormat("client_id is required")
}
if req.Name == "" {
return nil, errs.InvalidFormat("role name is required")
}
// 檢查角色名稱是否已存在
existingRole, err := uc.roleRepo.GetByClientAndName(ctx, req.ClientID, req.Name)
if err == nil && existingRole != nil {
return nil, errs.ResourceAlreadyExistWithScope(code.CloudEPPermission, req.ClientID+":"+req.Name)
}
role := &entity.Role{
ClientID: req.ClientID,
UID: req.UID,
Name: req.Name,
Status: req.Status,
Permissions: req.Permissions,
}
if err := uc.roleRepo.Create(ctx, role); err != nil {
return nil, err
}
return role, nil
}
func (uc *RoleUseCase) GetRole(ctx context.Context, id string) (*entity.Role, error) {
return uc.roleRepo.GetByID(ctx, id)
}
func (uc *RoleUseCase) GetRoleByUID(ctx context.Context, uid string) (*entity.Role, error) {
return uc.roleRepo.GetByUID(ctx, uid)
}
func (uc *RoleUseCase) UpdateRole(ctx context.Context, req usecase.UpdateRoleRequest) (*entity.Role, error) {
// 獲取現有角色
role, err := uc.roleRepo.GetByID(ctx, req.ID)
if err != nil {
return nil, err
}
// 更新字段
if req.Name != nil {
// 檢查新名稱是否已存在
existingRole, err := uc.roleRepo.GetByClientAndName(ctx, role.ClientID, *req.Name)
if err == nil && existingRole != nil && existingRole.ID != role.ID {
return nil, errs.ResourceAlreadyExistWithScope(code.CloudEPPermission, role.ClientID+":"+*req.Name)
}
role.Name = *req.Name
}
if req.Status != nil {
role.Status = *req.Status
}
if req.Permissions != nil {
role.Permissions = *req.Permissions
}
if err := uc.roleRepo.Update(ctx, req.ID, role); err != nil {
return nil, err
}
return role, nil
}
func (uc *RoleUseCase) DeleteRole(ctx context.Context, id string) error {
// 獲取角色信息
role, err := uc.roleRepo.GetByID(ctx, id)
if err != nil {
return err
}
status := permission.StatusActive
// 檢查是否有用戶使用此角色
userRoles, err := uc.userRoleRepo.List(ctx, repository.UserRoleFilter{
RoleUID: role.UID,
Status: &status,
})
if err != nil {
return err
}
if len(userRoles) > 0 {
return errs.InvalidFormat("cannot delete role that is assigned to users")
}
return uc.roleRepo.Delete(ctx, id)
}
func (uc *RoleUseCase) ListRoles(ctx context.Context, req usecase.ListRolesRequest) ([]*entity.Role, error) {
filter := repository.RoleFilter{
ClientID: req.ClientID,
Status: req.Status,
Limit: req.Limit,
Skip: req.Skip,
}
return uc.roleRepo.List(ctx, filter)
}
func (uc *RoleUseCase) AddPermissionToRole(ctx context.Context, roleID string, permissionKey string) error {
// 獲取角色
role, err := uc.roleRepo.GetByID(ctx, roleID)
if err != nil {
return err
}
// 添加權限
role.AddPermission(permissionKey)
return uc.roleRepo.Update(ctx, role.ID.Hex(), role)
}
func (uc *RoleUseCase) RemovePermissionFromRole(ctx context.Context, roleID string, permissionKey string) error {
// 獲取角色
role, err := uc.roleRepo.GetByID(ctx, roleID)
if err != nil {
return err
}
// 移除權限
role.RemovePermission(permissionKey)
return uc.roleRepo.Update(ctx, role.ID.Hex(), role)
}
func (uc *RoleUseCase) BatchUpdateRolePermissions(ctx context.Context, roleID string, permissions entity.Permissions) error {
// 獲取角色
role, err := uc.roleRepo.GetByID(ctx, roleID)
if err != nil {
return err
}
// 批量更新權限
role.Permissions = permissions
return uc.roleRepo.Update(ctx, role.ID.Hex(), role)
}
func (uc *RoleUseCase) GetRolesByClientID(ctx context.Context, clientID string) ([]*entity.Role, error) {
return uc.roleRepo.GetRolesByClientID(ctx, clientID)
}
func (uc *RoleUseCase) CopyRole(ctx context.Context, sourceRoleID string, req usecase.CreateRoleRequest) (*entity.Role, error) {
// 獲取源角色
sourceRole, err := uc.roleRepo.GetByID(ctx, sourceRoleID)
if err != nil {
return nil, err
}
// 創建新角色,複製權限
newReq := req
newReq.Permissions = sourceRole.Permissions
return uc.CreateRole(ctx, newReq)
}