93 lines
3.1 KiB
Go
93 lines
3.1 KiB
Go
package scopeids
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/hashicorp/boundary/internal/auth"
|
|
"github.com/hashicorp/boundary/internal/gen/controller/api/resources/scopes"
|
|
"github.com/hashicorp/boundary/internal/perms"
|
|
"github.com/hashicorp/boundary/internal/servers/controller/common"
|
|
"github.com/hashicorp/boundary/internal/types/action"
|
|
"github.com/hashicorp/boundary/internal/types/resource"
|
|
)
|
|
|
|
// GetScopeIds, given common parameters for List calls, returns the set of scope
|
|
// IDs in which to search for resources. It also returns a memoized map of the
|
|
// scopes to their info for populating returned values.
|
|
//
|
|
// Note: This was originally pulled out 1:1 from the role service. It and other
|
|
// tests in the other service handlers test this function extensively as it
|
|
// forms the basis for all recursive listing tests; see those tests for list
|
|
// functionality in the various service handlers.
|
|
func GetScopeIds(
|
|
// The context to use when listing in the DB, if required
|
|
ctx context.Context,
|
|
// An IAM repo function to use for a listing call, if required
|
|
repoFn common.IamRepoFactory,
|
|
// The original auth results from the list command
|
|
authResults auth.VerifyResults,
|
|
// The scope ID to use, or to use as the starting point for a recursive
|
|
// search
|
|
rootScopeId string,
|
|
// Whether or not the search should be recursive
|
|
recursive bool) ([]string, map[string]*scopes.ScopeInfo, error) {
|
|
// Get the list of scope IDs. If it's recursive, check ACLs.
|
|
var scopeIds []string
|
|
// This will be used to memoize scope info so we can put the right scope
|
|
// info for each returned value
|
|
scopeInfoMap := map[string]*scopes.ScopeInfo{
|
|
rootScopeId: authResults.Scope,
|
|
}
|
|
switch recursive {
|
|
case true:
|
|
repo, err := repoFn()
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
// Get all scopes recursively
|
|
scps, err := repo.ListScopesRecursively(ctx, rootScopeId)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
scopeIds = make([]string, 0, len(scps))
|
|
res := perms.Resource{
|
|
Type: resource.Role,
|
|
}
|
|
// For each scope, see if we have permission to list on that scope
|
|
for _, scp := range scps {
|
|
scpId := scp.GetPublicId()
|
|
// We already checked the incoming ID so we can definitely add it
|
|
if scpId == authResults.Scope.Id {
|
|
scopeIds = append(scopeIds, scp.GetPublicId())
|
|
continue
|
|
}
|
|
res.ScopeId = scpId
|
|
aSet := authResults.FetchActionSetForType(ctx,
|
|
resource.Role,
|
|
action.ActionSet{action.List},
|
|
auth.WithResource(&res),
|
|
)
|
|
// We only passed one action in, so anything other than that one
|
|
// action back should not be included. Assuming it's correct, add
|
|
// the scope ID for lookup and memoize the scope info if needed.
|
|
if len(aSet) == 1 && aSet[0] == action.List {
|
|
scopeIds = append(scopeIds, scpId)
|
|
if scopeInfoMap[scpId] == nil {
|
|
scopeInfo := &scopes.ScopeInfo{
|
|
Id: scp.GetPublicId(),
|
|
Type: scp.GetType(),
|
|
Name: scp.GetName(),
|
|
Description: scp.GetDescription(),
|
|
}
|
|
scopeInfoMap[scpId] = scopeInfo
|
|
}
|
|
}
|
|
}
|
|
|
|
default:
|
|
scopeIds = []string{rootScopeId}
|
|
}
|
|
|
|
return scopeIds, scopeInfoMap, nil
|
|
}
|