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 }