From 5d33393cbd995f3532874c2cd3ff5a6676da1082 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Thu, 13 Jan 2022 06:26:35 -0800 Subject: [PATCH] Add target resource listing to default roles (#1803) This addresses the issue of a user being created in a normal or dev environment that is given access to authorize sessions against specific targets but the permission hasn't been configured for the UI clients to actually list them. Resolves #1791 --- CHANGELOG.md | 13 +++++++++++-- internal/iam/repository_scope.go | 6 ++++++ internal/iam/testing.go | 22 +++++++++++++++++++--- internal/tests/api/targets/target_test.go | 20 ++++++++++++++++++++ 4 files changed, 56 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 562e04f45b..af8b91e7fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ Canonical reference for changes, improvements, and bugfixes for Boundary. ## Next +### Deprecations/Changes + +* In newly-created scopes, if default role creation is not disabled, the roles + will now contain a grant to allow listing targets. This will still be subject + to listing visibility rules, so only targets the user is granted some action + on (such as `authorize-session`) will be returned. + ### New and Improved * config: The `description` field for workers now supports being set @@ -23,11 +30,13 @@ Canonical reference for changes, improvements, and bugfixes for Boundary. as well as files. ([PR](https://github.com/hashicorp/boundary/pull/1758)) * config: Add support for go-sockaddr templates to Worker and Controller addresses. ([PR](https://github.com/hashicorp/boundary/pull/1731)) +* controllers/workers: Add client IP to inbound request information which is included in + Boundary events ([PR](https://github.com/hashicorp/boundary/pull/1678)) * host: Plugin-based host catalogs will now schedule updates for all of its host sets when its attributes are updated. ([PR](https://github.com/hashicorp/boundary/pull/1736)) -* controllers/workers: Add client IP to inbound request information which is included in - Boundary events ([PR](https://github.com/hashicorp/boundary/pull/1678)) +* scopes: Default roles in newly-created scopes now contain a grant to allow + listing targets. ([PR](https://github.com/hashicorp/boundary/pull/1803)) * plugins/aws: AWS plugin based hosts now include DNS names in addition to the IP addresses they already provide. diff --git a/internal/iam/repository_scope.go b/internal/iam/repository_scope.go index 466b436eeb..6aa8832364 100644 --- a/internal/iam/repository_scope.go +++ b/internal/iam/repository_scope.go @@ -295,6 +295,12 @@ func (r *Repository) CreateScope(ctx context.Context, s *Scope, userId string, o } grants = append(grants, roleGrant) + roleGrant, err = NewRoleGrant(defaultRolePublicId, "type=target;actions=list") + if err != nil { + return errors.Wrap(ctx, err, op, errors.WithMsg("unable to create in memory role grant")) + } + grants = append(grants, roleGrant) + default: roleGrant, err := NewRoleGrant(defaultRolePublicId, "id=*;type=scope;actions=list,no-op") if err != nil { diff --git a/internal/iam/testing.go b/internal/iam/testing.go index 3e693a9a59..84c3bd21a0 100644 --- a/internal/iam/testing.go +++ b/internal/iam/testing.go @@ -77,7 +77,7 @@ func TestScopes(t *testing.T, repo *Repository, opt ...Option) (org *Scope, prj return } -func TestOrg(t *testing.T, repo *Repository, opt ...Option) (org *Scope) { +func TestOrg(t *testing.T, repo *Repository, opt ...Option) *Scope { t.Helper() require := require.New(t) @@ -85,12 +85,28 @@ func TestOrg(t *testing.T, repo *Repository, opt ...Option) (org *Scope) { org, err := NewOrg(opt...) require.NoError(err) - org, err = repo.CreateScope(context.Background(), org, opts.withUserId) + org, err = repo.CreateScope(context.Background(), org, opts.withUserId, opt...) require.NoError(err) require.NotNil(org) require.NotEmpty(org.GetPublicId()) - return + return org +} + +func TestProject(t *testing.T, repo *Repository, orgId string, opt ...Option) *Scope { + t.Helper() + require := require.New(t) + + opts := getOpts(opt...) + + proj, err := NewProject(orgId, opt...) + require.NoError(err) + proj, err = repo.CreateScope(context.Background(), proj, opts.withUserId, opt...) + require.NoError(err) + require.NotNil(proj) + require.NotEmpty(proj.GetPublicId()) + + return proj } func testOrg(t *testing.T, repo *Repository, name, description string) (org *Scope) { diff --git a/internal/tests/api/targets/target_test.go b/internal/tests/api/targets/target_test.go index bcad5e1fa6..855b176e63 100644 --- a/internal/tests/api/targets/target_test.go +++ b/internal/tests/api/targets/target_test.go @@ -3,6 +3,7 @@ package targets_test import ( "fmt" "net/http" + "strings" "testing" "github.com/hashicorp/boundary/api" @@ -10,6 +11,7 @@ import ( "github.com/hashicorp/boundary/api/credentialstores" "github.com/hashicorp/boundary/api/hostcatalogs" "github.com/hashicorp/boundary/api/hostsets" + "github.com/hashicorp/boundary/api/roles" "github.com/hashicorp/boundary/api/targets" "github.com/hashicorp/boundary/internal/credential/vault" "github.com/hashicorp/boundary/internal/iam" @@ -130,6 +132,24 @@ func TestList(t *testing.T) { client.SetToken(token.Token) _, proj := iam.TestScopes(t, tc.IamRepo(), iam.WithUserId(token.UserId)) + // Add unpriv user to default role in new project. Also add create grant as + // it will be needed later in the test and no-op for listing visibility. + rls, err := roles.NewClient(client).List(tc.Context(), proj.GetPublicId()) + require.NoError(err) + var defaultRoleId string + for _, rl := range rls.Items { + if strings.Contains(rl.Name, "Default") { + defaultRoleId = rl.Id + break + } + } + require.NotEmpty(defaultRoleId) + unprivToken := tc.UnprivilegedToken() + iam.TestUserRole(t, tc.DbConn(), defaultRoleId, unprivToken.UserId) + iam.TestRoleGrant(t, tc.DbConn(), defaultRoleId, "type=target;actions=create") + iam.TestRoleGrant(t, tc.DbConn(), defaultRoleId, "id=*;type=target;actions=no-op") + + client.SetToken(unprivToken.Token) tarClient := targets.NewClient(client) ul, err := tarClient.List(tc.Context(), proj.GetPublicId()) require.NoError(err)