92 lines
2.6 KiB
Go
92 lines
2.6 KiB
Go
package useCases
|
|
|
|
import (
|
|
"RenewCMS/internal/domain/audit"
|
|
"RenewCMS/internal/domain/contenttype"
|
|
"RenewCMS/internal/domain/role"
|
|
"RenewCMS/internal/domain/user"
|
|
"context"
|
|
"errors"
|
|
)
|
|
|
|
type ReassignRoleMembersUseCase struct {
|
|
roles role.Repository
|
|
users user.Repository
|
|
contentTypes contenttype.Repository
|
|
recorder audit.Recorder
|
|
}
|
|
|
|
type ReassignRoleMembersCommand struct {
|
|
Caller ContentCaller
|
|
SourceID uint32
|
|
TargetID uint32
|
|
}
|
|
|
|
func NewReassignRoleMembersUseCase(roles role.Repository, users user.Repository, contentTypes contenttype.Repository, recorder audit.Recorder) *ReassignRoleMembersUseCase {
|
|
return &ReassignRoleMembersUseCase{roles, users, contentTypes, recorder}
|
|
}
|
|
|
|
func (u *ReassignRoleMembersUseCase) Reassign(ctx context.Context, command ReassignRoleMembersCommand) (int, error) {
|
|
source, err := u.roles.Get(command.SourceID)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
if err := u.checkSource(command.Caller, source); err != nil {
|
|
return 0, err
|
|
}
|
|
target, err := u.checkTarget(command, source)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
event := audit.NewEvent(audit.ActionRoleReassign, audit.CategoryRoles)
|
|
event.Target = roleTarget(source)
|
|
event.Params[audit.ParamFrom] = source.ID
|
|
event.Params[audit.ParamTo] = command.TargetID
|
|
event.Params[audit.ParamToName] = target.Name
|
|
event.Params[audit.ParamMoved] = 0
|
|
moved, err := u.roles.ReassignMembers(source.ID, command.TargetID)
|
|
if err != nil {
|
|
recordRoleWriteFailure(ctx, u.recorder, event, err)
|
|
return 0, err
|
|
}
|
|
if moved > 0 {
|
|
event.Params[audit.ParamMoved] = moved
|
|
u.recorder.Record(ctx, event)
|
|
}
|
|
return moved, nil
|
|
}
|
|
|
|
func (u *ReassignRoleMembersUseCase) checkSource(caller ContentCaller, source role.Role) error {
|
|
if err := ensureEditable(source); err != nil {
|
|
return err
|
|
}
|
|
if err := ensureNotBuiltIn(source); err != nil {
|
|
return err
|
|
}
|
|
if err := ensureNotOwnRole(u.roles, u.users, caller, source); err != nil {
|
|
return err
|
|
}
|
|
return ensureCovered(caller, u.contentTypes, source)
|
|
}
|
|
|
|
func (u *ReassignRoleMembersUseCase) checkTarget(command ReassignRoleMembersCommand, source role.Role) (role.Role, error) {
|
|
if command.TargetID == 0 || command.TargetID == source.ID {
|
|
return role.Role{}, role.ErrInvalidReassign
|
|
}
|
|
target, err := u.roles.Get(command.TargetID)
|
|
if errors.Is(err, role.ErrRoleNotFound) {
|
|
return role.Role{}, role.ErrReassignTargetNotFound
|
|
}
|
|
if err != nil {
|
|
return role.Role{}, err
|
|
}
|
|
if target.Locked {
|
|
return role.Role{}, role.ErrInvalidReassign
|
|
}
|
|
if err := ensureCovered(command.Caller, u.contentTypes, target); err != nil {
|
|
return role.Role{}, err
|
|
}
|
|
return target, nil
|
|
}
|