80 lines
2.5 KiB
Go
80 lines
2.5 KiB
Go
package system
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
)
|
|
|
|
// SuperAdminAuthorityID is the seeded super-administrator role created by the
|
|
// bootstrap data in internal/data/system/seed.go. It is the fallback authority
|
|
// for new users and the recipient group for system-wide alerts.
|
|
const SuperAdminAuthorityID uint = 888
|
|
|
|
type AuthorityAccessRepo interface {
|
|
CreateAuthority(context.Context, *Authority) error
|
|
CopyAuthority(context.Context, uint, *Authority) error
|
|
UpdateAuthority(context.Context, *Authority) error
|
|
DeleteAuthority(context.Context, uint) error
|
|
ListAuthorities(context.Context) ([]*Authority, error)
|
|
SetAuthorityUsers(context.Context, uint, []uint) error
|
|
AuthorityUserIDs(context.Context, uint) ([]uint, error)
|
|
SetDataScope(context.Context, uint, int, []uint) error
|
|
DataScopeDepartmentIDs(context.Context, uint) ([]uint, error)
|
|
ResolveDataScope(context.Context, uint, uint) (DataScope, error)
|
|
}
|
|
|
|
// Authority is the domain representation of an administration role. Keep the
|
|
// audit timestamps because exports and API clients use them even though the
|
|
// administration screens do not display them.
|
|
type Authority struct {
|
|
CreatedAt time.Time
|
|
UpdatedAt time.Time
|
|
DeletedAt *time.Time
|
|
AuthorityID uint
|
|
AuthorityName string
|
|
ParentID *uint
|
|
DataScope int
|
|
DefaultRouter string
|
|
Children []*Authority
|
|
Menus []*Menu
|
|
}
|
|
|
|
type AuthorityUsecase struct{ AuthorityAccessRepo }
|
|
|
|
func NewAuthorityUsecase(repo AuthorityAccessRepo) *AuthorityUsecase {
|
|
return &AuthorityUsecase{AuthorityAccessRepo: repo}
|
|
}
|
|
|
|
func (uc *AuthorityUsecase) AuthorityTree(ctx context.Context) ([]*Authority, error) {
|
|
items, err := uc.ListAuthorities(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
byID := make(map[uint]*Authority, len(items))
|
|
for _, item := range items {
|
|
item.Children = nil
|
|
byID[item.AuthorityID] = item
|
|
}
|
|
roots := make([]*Authority, 0)
|
|
for _, item := range items {
|
|
if item.ParentID != nil && *item.ParentID != 0 && byID[*item.ParentID] != nil {
|
|
parent := byID[*item.ParentID]
|
|
parent.Children = append(parent.Children, item)
|
|
} else if item.ParentID != nil && *item.ParentID == 0 {
|
|
roots = append(roots, item)
|
|
}
|
|
}
|
|
// In strict-authority mode a non-root actor receives its direct
|
|
// children as the top-level result even though their parent is omitted.
|
|
if len(roots) == 0 {
|
|
if actor, ok := ActorFromContext(ctx); ok {
|
|
for _, item := range items {
|
|
if item.ParentID != nil && *item.ParentID == actor.AuthorityID {
|
|
roots = append(roots, item)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return roots, nil
|
|
}
|