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

119 lines
2.7 KiB
Go

package useCases
import (
"RenewCMS/internal/domain/contenttype"
"RenewCMS/internal/domain/role"
"RenewCMS/internal/domain/user"
"slices"
"time"
)
type RoleEditor struct {
ID uint32
Name string
}
type RoleView struct {
role.Role
Members int
UpdatedAt *time.Time
UpdatedBy *RoleEditor
}
type roleViewer struct {
roles role.Repository
users user.Repository
contentTypes contenttype.Repository
}
func (v roleViewer) liveGrants(grants []role.Grant) ([]role.Grant, error) {
typeKeys, err := allowedTypeKeys(v.contentTypes)
if err != nil {
return nil, err
}
live := make([]role.Grant, 0, len(grants))
for _, grant := range grants {
if _, typeKey, parseErr := role.ParseTypedKey(grant.Key); parseErr == nil && !slices.Contains(typeKeys, typeKey) {
continue
}
live = append(live, grant)
}
return live, nil
}
func (v roleViewer) views(found []role.Role) ([]RoleView, error) {
counts, err := v.roles.MemberCounts()
if err != nil {
return nil, err
}
editors, err := v.editors(found)
if err != nil {
return nil, err
}
views := make([]RoleView, 0, len(found))
for _, item := range found {
view := toRoleView(item, counts[item.ID], editors)
if view.Grants, err = v.liveGrants(view.Grants); err != nil {
return nil, err
}
views = append(views, view)
}
return views, nil
}
func (v roleViewer) one(found role.Role, members int) (RoleView, error) {
editors, err := v.editors([]role.Role{found})
if err != nil {
return RoleView{}, err
}
view := toRoleView(found, members, editors)
if view.Grants, err = v.liveGrants(view.Grants); err != nil {
return RoleView{}, err
}
return view, nil
}
func (v roleViewer) members(roleID uint32) (int, error) {
counts, err := v.roles.MemberCounts()
if err != nil {
return 0, err
}
return counts[roleID], nil
}
func (v roleViewer) editors(found []role.Role) (map[uint32]string, error) {
ids := []uint32{}
for _, item := range found {
if item.UpdatedBy != nil {
ids = append(ids, *item.UpdatedBy)
}
}
names := map[uint32]string{}
if len(ids) == 0 {
return names, nil
}
editors, err := v.users.FindByIDs(ids)
if err != nil {
return nil, err
}
for _, editor := range editors {
names[editor.ID] = editor.NameOrUsername()
}
return names, nil
}
func toRoleView(found role.Role, members int, editors map[uint32]string) RoleView {
view := RoleView{Role: found, Members: members}
view.Grants = found.EffectiveGrants()
if !found.UpdatedAt.IsZero() {
stamp := found.UpdatedAt.UTC()
view.UpdatedAt = &stamp
}
if found.UpdatedBy != nil {
if name, present := editors[*found.UpdatedBy]; present {
view.UpdatedBy = &RoleEditor{ID: *found.UpdatedBy, Name: name}
}
}
return view
}