fix: align admin behavior and Kratos integrations
This commit is contained in:
+98
-19
@@ -2,6 +2,7 @@ package biz
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -13,9 +14,28 @@ type API struct {
|
||||
Description string
|
||||
APIGroup string
|
||||
Method string
|
||||
OrderKey string
|
||||
Desc bool
|
||||
StrictAll bool
|
||||
}
|
||||
|
||||
type AccessRepo interface {
|
||||
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
|
||||
@@ -26,21 +46,9 @@ type AccessRepo interface {
|
||||
SetDataScope(context.Context, uint, int, []uint) error
|
||||
DataScopeDepartmentIDs(context.Context, uint) ([]uint, error)
|
||||
ResolveDataScope(context.Context, uint, uint) (DataScope, error)
|
||||
}
|
||||
|
||||
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, uint) ([]uint, error)
|
||||
SetAPIRoles(context.Context, uint, []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 PermissionRepo interface {
|
||||
Buttons(context.Context, uint) ([]*MenuButton, error)
|
||||
SetAuthorityButtons(context.Context, uint, map[uint][]uint) error
|
||||
AuthorityButtonIDs(context.Context, uint) ([]uint, error)
|
||||
@@ -49,14 +57,85 @@ type AccessRepo interface {
|
||||
CanRemoveButton(context.Context, uint) (bool, error)
|
||||
}
|
||||
|
||||
type AccessUsecase struct{ repo AccessRepo }
|
||||
type AccessRepo interface {
|
||||
AuthorityAccessRepo
|
||||
APIRepo
|
||||
PermissionRepo
|
||||
}
|
||||
|
||||
func NewAccessUsecase(repo AccessRepo) *AccessUsecase { return &AccessUsecase{repo: repo} }
|
||||
type AccessUsecase struct{ AccessRepo }
|
||||
|
||||
func NewAccessUsecase(repo AccessRepo) *AccessUsecase { return &AccessUsecase{AccessRepo: repo} }
|
||||
|
||||
func (uc *AccessUsecase) Repo() AccessRepo { return uc.repo }
|
||||
func (uc *AccessUsecase) Authorize(ctx context.Context, authorityID uint, path, method string) (bool, error) {
|
||||
if authorityID == 888 {
|
||||
return true, nil
|
||||
}
|
||||
return uc.repo.Authorize(ctx, authorityID, path, method)
|
||||
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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user