142 lines
4.1 KiB
Go
142 lines
4.1 KiB
Go
package biz
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type API struct {
|
|
ID uint
|
|
CreatedAt time.Time
|
|
UpdatedAt time.Time
|
|
Path string
|
|
Description string
|
|
APIGroup string
|
|
Method string
|
|
OrderKey string
|
|
Desc bool
|
|
StrictAll bool
|
|
}
|
|
|
|
type APIRepo interface {
|
|
CreateAPI(context.Context, *API) error
|
|
UpdateAPI(context.Context, *API) error
|
|
DeleteAPIs(context.Context, []uint) error
|
|
FindAPI(context.Context, uint) (*API, error)
|
|
ListAPIs(context.Context, int, int, *API) ([]*API, int64, error)
|
|
APIRoleIDs(context.Context, string, string) ([]uint, error)
|
|
SetAPIRoles(context.Context, string, string, []uint) error
|
|
Authorize(context.Context, uint, string, string) (bool, error)
|
|
PolicyPaths(context.Context, uint) ([]*API, error)
|
|
SetPolicyPaths(context.Context, uint, []*API) error
|
|
IgnoredAPIs(context.Context) ([]*API, error)
|
|
SetAPIIgnored(context.Context, string, string, bool) error
|
|
ApplyAPISync(context.Context, []*API, []*API) error
|
|
}
|
|
|
|
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)
|
|
}
|
|
|
|
type PermissionRepo interface {
|
|
Buttons(context.Context, uint) ([]*MenuButton, error)
|
|
SetAuthorityButtons(context.Context, uint, map[uint][]uint) error
|
|
AuthorityButtonIDs(context.Context, uint) ([]uint, error)
|
|
SelectedButtons(context.Context, uint, uint) ([]uint, error)
|
|
SetSelectedButtons(context.Context, uint, uint, []uint) error
|
|
CanRemoveButton(context.Context, uint) (bool, error)
|
|
}
|
|
|
|
type AccessRepo interface {
|
|
AuthorityAccessRepo
|
|
APIRepo
|
|
PermissionRepo
|
|
}
|
|
|
|
type AccessUsecase struct{ AccessRepo }
|
|
|
|
func NewAccessUsecase(repo AccessRepo) *AccessUsecase { return &AccessUsecase{AccessRepo: repo} }
|
|
|
|
func (uc *AccessUsecase) Authorize(ctx context.Context, authorityID uint, path, method string) (bool, error) {
|
|
if authorityID == 888 {
|
|
return true, nil
|
|
}
|
|
return uc.AccessRepo.Authorize(ctx, authorityID, path, method)
|
|
}
|
|
|
|
type APISyncDiff struct {
|
|
Added []*API
|
|
Deleted []*API
|
|
Ignored []*API
|
|
}
|
|
|
|
func (uc *AccessUsecase) SyncAPIs(ctx context.Context, routes []*API) (*APISyncDiff, error) {
|
|
stored, _, err := uc.ListAPIs(ctx, 0, 0, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
ignored, err := uc.IgnoredAPIs(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
key := func(value *API) string { return strings.ToUpper(value.Method) + " " + value.Path }
|
|
ignoreSet := make(map[string]bool, len(ignored))
|
|
for _, item := range ignored {
|
|
ignoreSet[key(item)] = true
|
|
}
|
|
routeSet := make(map[string]*API, len(routes))
|
|
for _, item := range routes {
|
|
if !ignoreSet[key(item)] {
|
|
routeSet[key(item)] = item
|
|
}
|
|
}
|
|
storedSet := make(map[string]*API, len(stored))
|
|
for _, item := range stored {
|
|
storedSet[key(item)] = item
|
|
}
|
|
diff := &APISyncDiff{Ignored: ignored}
|
|
for routeKey, item := range routeSet {
|
|
if storedSet[routeKey] == nil {
|
|
diff.Added = append(diff.Added, item)
|
|
}
|
|
}
|
|
for storedKey, item := range storedSet {
|
|
if routeSet[storedKey] == nil && !ignoreSet[storedKey] {
|
|
diff.Deleted = append(diff.Deleted, item)
|
|
}
|
|
}
|
|
return diff, nil
|
|
}
|
|
|
|
func (uc *AccessUsecase) 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 {
|
|
roots = append(roots, item)
|
|
}
|
|
}
|
|
return roots, nil
|
|
}
|