119 lines
2.7 KiB
Go
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
|
|
}
|