226 lines
5.4 KiB
Go
226 lines
5.4 KiB
Go
package usecase
|
|
|
|
import (
|
|
"backend/pkg/library/errs/code"
|
|
"backend/pkg/permission/domain/permission"
|
|
"backend/pkg/permission/utils"
|
|
"context"
|
|
|
|
"backend/pkg/library/errs"
|
|
"backend/pkg/permission/domain/entity"
|
|
"backend/pkg/permission/domain/repository"
|
|
"backend/pkg/permission/domain/usecase"
|
|
)
|
|
|
|
type UserRoleUseCaseParam struct {
|
|
UserRoleRepo repository.UserRoleRepository
|
|
RoleRepo repository.RoleRepository
|
|
}
|
|
|
|
type UserRoleUseCase struct {
|
|
userRoleRepo repository.UserRoleRepository
|
|
roleRepo repository.RoleRepository
|
|
}
|
|
|
|
// MustUserRoleUseCase 創建用戶角色用例實例
|
|
func MustUserRoleUseCase(param UserRoleUseCaseParam) usecase.UserRoleUseCase {
|
|
return &UserRoleUseCase{
|
|
userRoleRepo: param.UserRoleRepo,
|
|
roleRepo: param.RoleRepo,
|
|
}
|
|
}
|
|
|
|
func (uc *UserRoleUseCase) AssignRole(ctx context.Context, req usecase.AssignRoleRequest) (*entity.UserRole, error) {
|
|
// 驗證請求
|
|
if req.UID == "" {
|
|
return nil, errs.InvalidFormat("uid is required")
|
|
}
|
|
if req.RoleUID == "" {
|
|
return nil, errs.InvalidFormat("role_uid is required")
|
|
}
|
|
if req.Brand == "" {
|
|
return nil, errs.InvalidFormat("brand is required")
|
|
}
|
|
|
|
// 檢查角色是否存在
|
|
role, err := uc.roleRepo.GetByUID(ctx, req.RoleUID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if !utils.IsActive(role.Status) {
|
|
return nil, errs.InvalidFormat("role is not active")
|
|
}
|
|
|
|
// 檢查用戶是否已經有此角色
|
|
existingUserRole, err := uc.userRoleRepo.GetByUserAndRole(ctx, req.UID, req.RoleUID)
|
|
if err == nil && existingUserRole != nil && utils.IsActive(existingUserRole.Status) {
|
|
return nil, errs.ResourceAlreadyExistWithScope(code.CloudEPPermission, req.UID+":"+req.RoleUID)
|
|
}
|
|
|
|
userRole := &entity.UserRole{
|
|
Brand: req.Brand,
|
|
UID: req.UID,
|
|
RoleUID: req.RoleUID,
|
|
Status: permission.StatusActive,
|
|
}
|
|
|
|
if err := uc.userRoleRepo.Create(ctx, userRole); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return userRole, nil
|
|
}
|
|
|
|
func (uc *UserRoleUseCase) RevokeRole(ctx context.Context, uid, roleUID string) error {
|
|
// 驗證參數
|
|
if uid == "" {
|
|
return errs.InvalidFormat("uid is required")
|
|
}
|
|
if roleUID == "" {
|
|
return errs.InvalidFormat("role_uid is required")
|
|
}
|
|
|
|
return uc.userRoleRepo.DeleteByUserAndRole(ctx, uid, roleUID)
|
|
}
|
|
|
|
func (uc *UserRoleUseCase) GetUserRole(ctx context.Context, id string) (*entity.UserRole, error) {
|
|
return uc.userRoleRepo.GetByID(ctx, id)
|
|
}
|
|
|
|
func (uc *UserRoleUseCase) UpdateUserRole(ctx context.Context, req usecase.UpdateUserRoleRequest) (*entity.UserRole, error) {
|
|
// 獲取現有用戶角色
|
|
userRole, err := uc.userRoleRepo.GetByID(ctx, req.ID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 更新狀態
|
|
if req.Status != nil {
|
|
userRole.Status = *req.Status
|
|
}
|
|
|
|
if err := uc.userRoleRepo.Update(ctx, req.ID, userRole); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return userRole, nil
|
|
}
|
|
|
|
func (uc *UserRoleUseCase) ListUserRoles(ctx context.Context, req usecase.ListUserRolesRequest) ([]*entity.UserRole, error) {
|
|
filter := repository.UserRoleFilter{
|
|
Brand: req.Brand,
|
|
UID: req.UID,
|
|
RoleUID: req.RoleUID,
|
|
Status: req.Status,
|
|
Limit: req.Limit,
|
|
Skip: req.Skip,
|
|
}
|
|
|
|
return uc.userRoleRepo.List(ctx, filter)
|
|
}
|
|
|
|
func (uc *UserRoleUseCase) GetUserRoles(ctx context.Context, uid string) ([]*entity.UserRole, error) {
|
|
if uid == "" {
|
|
return nil, errs.InvalidFormat("uid is required")
|
|
}
|
|
|
|
return uc.userRoleRepo.GetUserRolesByUID(ctx, uid)
|
|
}
|
|
|
|
func (uc *UserRoleUseCase) GetUserRoleDetails(ctx context.Context, uid string) ([]*usecase.UserRoleDetail, error) {
|
|
// 獲取用戶角色
|
|
userRoles, err := uc.GetUserRoles(ctx, uid)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var details []*usecase.UserRoleDetail
|
|
for _, userRole := range userRoles {
|
|
if !utils.IsActive(userRole.Status) {
|
|
continue
|
|
}
|
|
|
|
// 獲取角色詳情
|
|
role, err := uc.roleRepo.GetByUID(ctx, userRole.RoleUID)
|
|
if err != nil {
|
|
continue // 忽略獲取失敗的角色
|
|
}
|
|
|
|
detail := &usecase.UserRoleDetail{
|
|
UserRole: userRole,
|
|
Role: role,
|
|
}
|
|
details = append(details, detail)
|
|
}
|
|
|
|
return details, nil
|
|
}
|
|
|
|
func (uc *UserRoleUseCase) BatchAssignRoles(ctx context.Context, uid string, roleUIDs []string, brand string) error {
|
|
if uid == "" {
|
|
return errs.InvalidFormat("uid is required")
|
|
}
|
|
if brand == "" {
|
|
return errs.InvalidFormat("brand is required")
|
|
}
|
|
|
|
// 逐個分配角色
|
|
for _, roleUID := range roleUIDs {
|
|
req := usecase.AssignRoleRequest{
|
|
Brand: brand,
|
|
UID: uid,
|
|
RoleUID: roleUID,
|
|
}
|
|
|
|
_, err := uc.AssignRole(ctx, req)
|
|
if err != nil {
|
|
// 如果是已存在錯誤,忽略繼續
|
|
e := errs.FromError(err)
|
|
if e.Is(errs.ResourceAlreadyExist()) {
|
|
continue
|
|
}
|
|
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (uc *UserRoleUseCase) BatchRevokeRoles(ctx context.Context, uid string, roleUIDs []string) error {
|
|
if uid == "" {
|
|
return errs.InvalidFormat("uid is required")
|
|
}
|
|
|
|
// 逐個撤銷角色
|
|
for _, roleUID := range roleUIDs {
|
|
err := uc.RevokeRole(ctx, uid, roleUID)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (uc *UserRoleUseCase) ReplaceUserRoles(ctx context.Context, uid string, roleUIDs []string, brand string) error {
|
|
// 獲取用戶當前的所有角色
|
|
currentUserRoles, err := uc.GetUserRoles(ctx, uid)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// 撤銷所有現有角色
|
|
for _, userRole := range currentUserRoles {
|
|
if utils.IsActive(userRole.Status) {
|
|
if err := uc.RevokeRole(ctx, uid, userRole.RoleUID); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
|
|
// 分配新角色
|
|
return uc.BatchAssignRoles(ctx, uid, roleUIDs, brand)
|
|
}
|