Files
RenewCMS/internal/infrastructure/useCases/roleSupport.go
T

118 lines
2.8 KiB
Go

package useCases
import (
"RenewCMS/internal/domain/audit"
"RenewCMS/internal/domain/builtintype"
"RenewCMS/internal/domain/contenttype"
"RenewCMS/internal/domain/role"
"RenewCMS/internal/domain/user"
"context"
"errors"
"slices"
)
func roleTarget(found role.Role) audit.Target {
return audit.NewTarget(audit.TargetRole, found.ID, found.Name)
}
func allowedTypeKeys(contentTypes contenttype.Repository) ([]string, error) {
types, err := contentTypes.List()
if err != nil {
return nil, err
}
keys := []string{builtintype.KeyArticle}
for _, contentType := range types {
keys = append(keys, contentType.Key)
}
slices.Sort(keys)
return keys, nil
}
func ensureCovered(caller ContentCaller, contentTypes contenttype.Repository, candidate role.Role) error {
typeKeys, err := allowedTypeKeys(contentTypes)
if err != nil {
return err
}
return caller.Grants.Covers(candidate.GrantSet(), typeKeys)
}
func ensureNotOwnRole(roles role.Repository, users user.Repository, caller ContentCaller, target role.Role) error {
account, err := users.Get(caller.UserID)
if err != nil {
return err
}
own, err := resolveRole(roles, account)
if errors.Is(err, role.ErrRoleNotFound) {
return nil
}
if err != nil {
return err
}
if own.ID == target.ID {
return role.ErrOwnRole
}
return nil
}
func ensureEditable(target role.Role) error {
if target.Locked {
return role.ErrRoleLocked
}
return nil
}
func ensureNotBuiltIn(target role.Role) error {
if target.BuiltIn {
return role.ErrBuiltInRole
}
return nil
}
func ensureNameFree(roles role.Repository, name string, excludedID uint32) error {
existing, err := roles.List()
if err != nil {
return err
}
for _, other := range existing {
if other.ID != excludedID && role.SameName(other.Name, name) {
return role.ErrRoleNameTaken
}
}
return nil
}
func validateRoleGrants(contentTypes contenttype.Repository, grants []role.Grant) error {
if err := role.ValidateGrants(false, grants); err != nil {
return err
}
typeKeys, err := allowedTypeKeys(contentTypes)
if err != nil {
return err
}
return role.ValidateGrantTypes(grants, typeKeys)
}
func normalizedGrants(grants []role.Grant) []role.Grant {
return role.Role{Grants: grants}.EffectiveGrants()
}
var writeRefusals = []error{role.ErrRoleConflict, role.ErrRoleHasMembers, role.ErrRoleNotFound, role.ErrRoleNameTaken, role.ErrInvalidReassign}
func recordRoleWriteFailure(ctx context.Context, recorder audit.Recorder, event audit.Event, err error) {
for _, refusal := range writeRefusals {
if errors.Is(err, refusal) {
return
}
}
recordFailure(ctx, recorder, event, err)
}
func grantsParams(diff role.GrantDiff, members int) map[string]any {
return map[string]any{
audit.ParamAdded: diff.Added,
audit.ParamRemoved: diff.Removed,
audit.ParamChanged: diff.Changed,
audit.ParamMembers: members,
}
}