perf(target): Use new Permissions object to determine resource access
Using the new Permissions object, we can build a list of the level of access a user should have based on the grants they've been given, meaining we don't need to fetch all resources from the database to then remove the ones the user shouldn't be able to see. This commit also removes some unused options in `ListTargets` for the sake of simplicity.
This commit is contained in:
1 parent
63196ee4ca
commit
bf263fbd7d
4 files changed
+263
-194
No files matched your search
@@ -15,7 +15,6 @@ import (
|
||||
"github.com/hashicorp/boundary/internal/credential/vault"
|
||||
"github.com/hashicorp/boundary/internal/daemon/controller/auth"
|
||||
"github.com/hashicorp/boundary/internal/daemon/controller/common"
|
||||
"github.com/hashicorp/boundary/internal/daemon/controller/common/scopeids"
|
||||
"github.com/hashicorp/boundary/internal/daemon/controller/handlers"
|
||||
"github.com/hashicorp/boundary/internal/db/timestamp"
|
||||
"github.com/hashicorp/boundary/internal/errors"
|
||||
@@ -33,6 +32,7 @@ import (
|
||||
"github.com/hashicorp/boundary/internal/types/resource"
|
||||
"github.com/hashicorp/boundary/internal/types/scope"
|
||||
"github.com/hashicorp/boundary/internal/types/subtypes"
|
||||
"github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/scopes"
|
||||
pb "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/targets"
|
||||
"github.com/hashicorp/go-bexpr"
|
||||
"github.com/hashicorp/go-secure-stdlib/strutil"
|
||||
@@ -183,34 +183,24 @@ func (s Service) ListTargets(ctx context.Context, req *pbs.ListTargetsRequest) (
|
||||
}
|
||||
}
|
||||
|
||||
repo, err := s.repoFn()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
var err error
|
||||
var authzScopes map[string]*scopes.ScopeInfo
|
||||
if req.GetRecursive() {
|
||||
authzScopes, err = authResults.ScopesAuthorizedForList(ctx, req.GetScopeId(), resource.Target)
|
||||
} else {
|
||||
authzScopes = map[string]*scopes.ScopeInfo{authResults.Scope.Id: authResults.Scope}
|
||||
}
|
||||
|
||||
scopeResourceInfo, err := scopeids.GetListingResourceInformation(
|
||||
ctx,
|
||||
scopeids.GetListingResourceInformationInput{
|
||||
IamRepoFn: s.iamRepoFn,
|
||||
AuthResults: authResults,
|
||||
RootScopeId: req.GetScopeId(),
|
||||
Type: resource.Target,
|
||||
Recursive: req.GetRecursive(),
|
||||
AuthzProtectedEntityProvider: repo,
|
||||
ActionSet: IdActions,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// If no scopes match, return an empty response
|
||||
if len(scopeResourceInfo.ScopeIds) == 0 ||
|
||||
len(scopeResourceInfo.ResourceIds) == 0 {
|
||||
// Get all user permissions for the requested scope(s).
|
||||
userPerms := authResults.ACL().ListPermissions(authzScopes, resource.Target, IdActions)
|
||||
if len(userPerms) == 0 {
|
||||
return &pbs.ListTargetsResponse{}, nil
|
||||
}
|
||||
|
||||
tl, err := s.listFromRepo(ctx, scopeResourceInfo.ResourceIds)
|
||||
tl, err := s.listFromRepo(ctx, userPerms)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -222,19 +212,21 @@ func (s Service) ListTargets(ctx context.Context, req *pbs.ListTargetsRequest) (
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
finalItems := make([]*pb.Target, 0, len(tl))
|
||||
res := perms.Resource{
|
||||
Type: resource.Target,
|
||||
}
|
||||
for _, item := range tl {
|
||||
outputFields := authResults.FetchOutputFields(res, action.List).SelfOrDefaults(authResults.UserId)
|
||||
pr := perms.Resource{Id: item.GetPublicId(), ScopeId: item.GetProjectId(), Type: resource.Target}
|
||||
outputFields := authResults.FetchOutputFields(pr, action.List).SelfOrDefaults(authResults.UserId)
|
||||
|
||||
outputOpts := make([]handlers.Option, 0, 3)
|
||||
outputOpts = append(outputOpts, handlers.WithOutputFields(&outputFields))
|
||||
|
||||
if outputFields.Has(globals.ScopeField) {
|
||||
outputOpts = append(outputOpts, handlers.WithScope(scopeResourceInfo.ScopeResourceMap[item.GetProjectId()].ScopeInfo))
|
||||
outputOpts = append(outputOpts, handlers.WithScope(authzScopes[item.GetProjectId()]))
|
||||
}
|
||||
if outputFields.Has(globals.AuthorizedActionsField) {
|
||||
outputOpts = append(outputOpts, handlers.WithAuthorizedActions(scopeResourceInfo.ScopeResourceMap[item.GetProjectId()].Resources[item.GetPublicId()].AuthorizedActions.Strings()))
|
||||
authorizedActions := authResults.FetchActionSetForId(ctx, item.GetPublicId(), IdActions, auth.WithResource(&pr)).Strings()
|
||||
outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authorizedActions))
|
||||
}
|
||||
|
||||
item, err := toProto(ctx, item, nil, nil, outputOpts...)
|
||||
@@ -250,6 +242,7 @@ func (s Service) ListTargets(ctx context.Context, req *pbs.ListTargetsRequest) (
|
||||
finalItems = append(finalItems, item)
|
||||
}
|
||||
}
|
||||
|
||||
return &pbs.ListTargetsResponse{Items: finalItems}, nil
|
||||
}
|
||||
|
||||
@@ -1233,12 +1226,12 @@ func (s Service) deleteFromRepo(ctx context.Context, id string) (bool, error) {
|
||||
return rows > 0, nil
|
||||
}
|
||||
|
||||
func (s Service) listFromRepo(ctx context.Context, targetIds []string) ([]target.Target, error) {
|
||||
repo, err := s.repoFn()
|
||||
func (s Service) listFromRepo(ctx context.Context, perms []perms.Permission) ([]target.Target, error) {
|
||||
repo, err := s.repoFn(target.WithPermissions(perms))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ul, err := repo.ListTargets(ctx, target.WithTargetIds(targetIds))
|
||||
ul, err := repo.ListTargets(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user