diff --git a/CHANGELOG.md b/CHANGELOG.md index e1ab0eea00..ccafe151ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,16 +6,23 @@ Canonical reference for changes, improvements, and bugfixes for Boundary. ### New and Improved -* cli/api/sdk: New User's attributes for: +* actions: The new `no-op` action allows a grant to be given to a principals + without conveying any actionable result. Since resources do not appear in list + results if the principal has no actions granted on that resource, this can be + used to allow principals to see values in list results without also giving + `read` or other capabilities on the resources. The default scope permissions + have been updated to convey `no-op,list` instead of `read,list`. + [PR](https://github.com/hashicorp/boundary/pull/1138) +* cli/api/sdk: User resources have new attributes for: * Primary Account ID * Login Name * Full Name * Email - These new user attributes correspond to attributes - from the user's primary auth method account. These attributes will be empty - when the user has no account in the primary auth method for their scope, or - there is no designated primary auth method for their scope. + These new user attributes correspond to attributes from the user's primary + auth method account. These attributes will be empty when the user has no + account in the primary auth method for their scope, or there is no designated + primary auth method for their scope. ### Bug Fixes diff --git a/internal/cmd/base/initial_resources.go b/internal/cmd/base/initial_resources.go index b2f2adc1fc..a951f307fa 100644 --- a/internal/cmd/base/initial_resources.go +++ b/internal/cmd/base/initial_resources.go @@ -59,7 +59,7 @@ func (b *Server) CreateInitialLoginRole(ctx context.Context) (*iam.Role, error) return nil, fmt.Errorf("error creating role for default generated grants: %w", err) } if _, err := iamRepo.AddRoleGrants(cancelCtx, role.PublicId, role.Version, []string{ - "id=*;type=scope;actions=list,read", + "id=*;type=scope;actions=list,no-op", "id=*;type=auth-method;actions=authenticate,list", "id={{account.id}};actions=read,change-password", }); err != nil { diff --git a/internal/iam/repository_scope.go b/internal/iam/repository_scope.go index b4ce107fce..7711b7e6da 100644 --- a/internal/iam/repository_scope.go +++ b/internal/iam/repository_scope.go @@ -296,7 +296,7 @@ func (r *Repository) CreateScope(ctx context.Context, s *Scope, userId string, o grants = append(grants, roleGrant) default: - roleGrant, err := NewRoleGrant(defaultRolePublicId, "id=*;type=scope;actions=list,read") + roleGrant, err := NewRoleGrant(defaultRolePublicId, "id=*;type=scope;actions=list,no-op") if err != nil { return errors.Wrap(err, op, errors.WithMsg("unable to create in memory role grant")) } diff --git a/internal/servers/controller/common/scopeids/scope_ids_test.go b/internal/servers/controller/common/scopeids/scope_ids_test.go index 71a9b940b3..cc01904a95 100644 --- a/internal/servers/controller/common/scopeids/scope_ids_test.go +++ b/internal/servers/controller/common/scopeids/scope_ids_test.go @@ -79,24 +79,24 @@ func TestListingScopeIds(t *testing.T) { }, { name: "perms on global, no groups", - globalGrants: []string{"id=*;type=group;actions=list,read"}, + globalGrants: []string{"id=*;type=group;actions=list,no-op"}, projGrants: []string{"id=*;type=group;actions=read"}, recurseFrom: "global", }, { name: "perms on org, no groups", - orgGrants: []string{"id=*;type=group;actions=list,read"}, + orgGrants: []string{"id=*;type=group;actions=list,no-op"}, projGrants: []string{"id=*;type=group;actions=read"}, recurseFrom: "org", }, { name: "perms on project, no groups", - projGrants: []string{"id=*;type=group;actions=list,read"}, + projGrants: []string{"id=*;type=group;actions=list,no-op"}, recurseFrom: "project", }, { name: "perms on global, none in org", - globalGrants: []string{"id=*;type=group;actions=list,read"}, + globalGrants: []string{"id=*;type=group;actions=list,no-op"}, projGrants: []string{"id=*;type=group;actions=read"}, globalGroups: 1, orgGroups: 3, @@ -106,7 +106,7 @@ func TestListingScopeIds(t *testing.T) { }, { name: "perms on global, none in org, start at org", - globalGrants: []string{"id=*;type=group;actions=list,read"}, + globalGrants: []string{"id=*;type=group;actions=list,no-op"}, projGrants: []string{"id=*;type=group;actions=read"}, globalGroups: 1, orgGroups: 3, @@ -116,7 +116,7 @@ func TestListingScopeIds(t *testing.T) { }, { name: "perms on global, with org", - globalGrants: []string{"id=*;type=group;actions=list,read"}, + globalGrants: []string{"id=*;type=group;actions=list,no-op"}, orgGrants: []string{"id=*;type=group;actions=read"}, projGrants: []string{"id=*;type=group;actions=read"}, globalGroups: 1, @@ -127,7 +127,7 @@ func TestListingScopeIds(t *testing.T) { }, { name: "perms on global, with org, start at org", - globalGrants: []string{"id=*;type=group;actions=list,read"}, + globalGrants: []string{"id=*;type=group;actions=list,no-op"}, orgGrants: []string{"id=*;type=group;actions=read"}, projGrants: []string{"id=*;type=group;actions=read"}, globalGroups: 1, @@ -138,7 +138,7 @@ func TestListingScopeIds(t *testing.T) { }, { name: "perms on global, start at project", - globalGrants: []string{"id=*;type=group;actions=list,read"}, + globalGrants: []string{"id=*;type=group;actions=list,no-op"}, orgGrants: []string{"id=*;type=group;actions=read"}, projGrants: []string{"id=*;type=group;actions=read"}, globalGroups: 1, @@ -159,7 +159,7 @@ func TestListingScopeIds(t *testing.T) { }, { name: "perms on org, start at global, read on org", - orgGrants: []string{"id=*;type=group;actions=list,read"}, + orgGrants: []string{"id=*;type=group;actions=list,no-op"}, projGrants: []string{"id=*;type=group;actions=read"}, globalGroups: 1, orgGroups: 3, @@ -169,7 +169,7 @@ func TestListingScopeIds(t *testing.T) { }, { name: "perms on org, start at org", - orgGrants: []string{"id=*;type=group;actions=list,read"}, + orgGrants: []string{"id=*;type=group;actions=list,no-op"}, projGrants: []string{"id=*;type=group;actions=read"}, globalGroups: 1, orgGroups: 3, @@ -179,7 +179,7 @@ func TestListingScopeIds(t *testing.T) { }, { name: "perms on org, start at project", - orgGrants: []string{"id=*;type=group;actions=list,read"}, + orgGrants: []string{"id=*;type=group;actions=list,no-op"}, projGrants: []string{"id=*;type=group;actions=read"}, globalGroups: 1, orgGroups: 3, @@ -189,7 +189,7 @@ func TestListingScopeIds(t *testing.T) { }, { name: "perms on proj", - projGrants: []string{"id=*;type=group;actions=list,read"}, + projGrants: []string{"id=*;type=group;actions=list,no-op"}, globalGroups: 1, orgGroups: 3, projGroups: 5, @@ -198,7 +198,7 @@ func TestListingScopeIds(t *testing.T) { }, { name: "perms on proj, start at org", - projGrants: []string{"id=*;type=group;actions=list,read"}, + projGrants: []string{"id=*;type=group;actions=list,no-op"}, globalGroups: 1, orgGroups: 3, projGroups: 5, @@ -207,7 +207,7 @@ func TestListingScopeIds(t *testing.T) { }, { name: "perms on proj, start at global", - projGrants: []string{"id=*;type=group;actions=list,read"}, + projGrants: []string{"id=*;type=group;actions=list,no-op"}, globalGroups: 1, orgGroups: 3, projGroups: 5, diff --git a/internal/servers/controller/handlers/accounts/account_service.go b/internal/servers/controller/handlers/accounts/account_service.go index 97a4ee252b..8f0444e906 100644 --- a/internal/servers/controller/handlers/accounts/account_service.go +++ b/internal/servers/controller/handlers/accounts/account_service.go @@ -52,6 +52,7 @@ var ( // individual resources IdActions = map[auth.SubType]action.ActionSet{ auth.PasswordSubtype: { + action.NoOp, action.Read, action.Update, action.Delete, @@ -59,6 +60,7 @@ var ( action.ChangePassword, }, auth.OidcSubtype: { + action.NoOp, action.Read, action.Update, action.Delete, diff --git a/internal/servers/controller/handlers/accounts/account_service_test.go b/internal/servers/controller/handlers/accounts/account_service_test.go index 12f87e811a..2c1221f3ad 100644 --- a/internal/servers/controller/handlers/accounts/account_service_test.go +++ b/internal/servers/controller/handlers/accounts/account_service_test.go @@ -36,6 +36,7 @@ import ( var ( pwAuthorizedActions = []string{ + action.NoOp.String(), action.Read.String(), action.Update.String(), action.Delete.String(), @@ -43,6 +44,7 @@ var ( action.ChangePassword.String(), } oidcAuthorizedActions = []string{ + action.NoOp.String(), action.Read.String(), action.Update.String(), action.Delete.String(), diff --git a/internal/servers/controller/handlers/authmethods/authmethod_service_test.go b/internal/servers/controller/handlers/authmethods/authmethod_service_test.go index 863d236e1b..076bb625f2 100644 --- a/internal/servers/controller/handlers/authmethods/authmethod_service_test.go +++ b/internal/servers/controller/handlers/authmethods/authmethod_service_test.go @@ -40,12 +40,14 @@ const ( var ( pwAuthorizedActions = []string{ + action.NoOp.String(), action.Read.String(), action.Update.String(), action.Delete.String(), action.Authenticate.String(), } oidcAuthorizedActions = []string{ + action.NoOp.String(), action.Read.String(), action.Update.String(), action.Delete.String(), diff --git a/internal/servers/controller/handlers/authmethods/oidc.go b/internal/servers/controller/handlers/authmethods/oidc.go index 45b08de683..6c96a94a8c 100644 --- a/internal/servers/controller/handlers/authmethods/oidc.go +++ b/internal/servers/controller/handlers/authmethods/oidc.go @@ -52,6 +52,7 @@ func init() { } IdActions[auth.OidcSubtype] = action.ActionSet{ + action.NoOp, action.Read, action.Update, action.Delete, diff --git a/internal/servers/controller/handlers/authmethods/password.go b/internal/servers/controller/handlers/authmethods/password.go index ef6253061c..56309c137b 100644 --- a/internal/servers/controller/handlers/authmethods/password.go +++ b/internal/servers/controller/handlers/authmethods/password.go @@ -33,6 +33,7 @@ func init() { } IdActions[auth.PasswordSubtype] = action.ActionSet{ + action.NoOp, action.Read, action.Update, action.Delete, diff --git a/internal/servers/controller/handlers/authtokens/authtoken_service.go b/internal/servers/controller/handlers/authtokens/authtoken_service.go index 632b9636d6..e08bff06d8 100644 --- a/internal/servers/controller/handlers/authtokens/authtoken_service.go +++ b/internal/servers/controller/handlers/authtokens/authtoken_service.go @@ -22,6 +22,7 @@ var ( // IdActions contains the set of actions that can be performed on // individual resources IdActions = action.ActionSet{ + action.NoOp, action.Read, action.Delete, } diff --git a/internal/servers/controller/handlers/authtokens/authtoken_service_test.go b/internal/servers/controller/handlers/authtokens/authtoken_service_test.go index 26ca95805f..ad4f76c025 100644 --- a/internal/servers/controller/handlers/authtokens/authtoken_service_test.go +++ b/internal/servers/controller/handlers/authtokens/authtoken_service_test.go @@ -24,6 +24,8 @@ import ( "github.com/stretchr/testify/require" ) +var testAuthorizedActions = []string{"no-op", "read", "delete"} + func TestGet(t *testing.T) { conn, _ := db.TestSetup(t, "postgres") rw := db.New(conn) @@ -53,7 +55,7 @@ func TestGet(t *testing.T) { ApproximateLastUsedTime: at.GetApproximateLastAccessTime().GetTimestamp(), ExpirationTime: at.GetExpirationTime().GetTimestamp(), Scope: &scopes.ScopeInfo{Id: org.GetPublicId(), Type: scope.Org.String(), ParentScopeId: scope.Global.String()}, - AuthorizedActions: []string{"read", "delete"}, + AuthorizedActions: testAuthorizedActions, } cases := []struct { @@ -128,7 +130,7 @@ func TestList(t *testing.T) { ApproximateLastUsedTime: at.GetApproximateLastAccessTime().GetTimestamp(), ExpirationTime: at.GetExpirationTime().GetTimestamp(), Scope: &scopes.ScopeInfo{Id: scope.Global.String(), Type: scope.Global.String(), Name: scope.Global.String(), Description: "Global Scope"}, - AuthorizedActions: []string{"read", "delete"}, + AuthorizedActions: testAuthorizedActions, }) } @@ -147,7 +149,7 @@ func TestList(t *testing.T) { ApproximateLastUsedTime: at.GetApproximateLastAccessTime().GetTimestamp(), ExpirationTime: at.GetExpirationTime().GetTimestamp(), Scope: &scopes.ScopeInfo{Id: orgWithSomeTokens.GetPublicId(), Type: scope.Org.String(), ParentScopeId: scope.Global.String()}, - AuthorizedActions: []string{"read", "delete"}, + AuthorizedActions: testAuthorizedActions, }) } @@ -166,7 +168,7 @@ func TestList(t *testing.T) { ApproximateLastUsedTime: at.GetApproximateLastAccessTime().GetTimestamp(), ExpirationTime: at.GetExpirationTime().GetTimestamp(), Scope: &scopes.ScopeInfo{Id: orgWithOtherTokens.GetPublicId(), Type: scope.Org.String(), ParentScopeId: scope.Global.String()}, - AuthorizedActions: []string{"read", "delete"}, + AuthorizedActions: testAuthorizedActions, }) } diff --git a/internal/servers/controller/handlers/groups/group_service.go b/internal/servers/controller/handlers/groups/group_service.go index a41b0f4053..45153e772f 100644 --- a/internal/servers/controller/handlers/groups/group_service.go +++ b/internal/servers/controller/handlers/groups/group_service.go @@ -28,6 +28,7 @@ var ( // IdActions contains the set of actions that can be performed on // individual resources IdActions = action.ActionSet{ + action.NoOp, action.Read, action.Update, action.Delete, diff --git a/internal/servers/controller/handlers/groups/group_service_test.go b/internal/servers/controller/handlers/groups/group_service_test.go index 88a4fc740e..333b4163b5 100644 --- a/internal/servers/controller/handlers/groups/group_service_test.go +++ b/internal/servers/controller/handlers/groups/group_service_test.go @@ -7,7 +7,6 @@ import ( "strings" "testing" - "github.com/golang/protobuf/ptypes" "github.com/google/go-cmp/cmp" "github.com/hashicorp/boundary/internal/auth" "github.com/hashicorp/boundary/internal/db" @@ -23,12 +22,15 @@ import ( "google.golang.org/grpc/status" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/testing/protocmp" + "google.golang.org/protobuf/types/known/timestamppb" "google.golang.org/protobuf/types/known/wrapperspb" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) +var testAuthorizedActions = []string{"no-op", "read", "update", "delete", "add-members", "set-members", "remove-members"} + // Creates an org scoped group and a project scoped group. func createDefaultGroupsAndRepo(t *testing.T) (*iam.Group, *iam.Group, func() (*iam.Repository, error)) { t.Helper() @@ -106,7 +108,7 @@ func TestGet(t *testing.T) { ScopeId: u.GetScopeId(), }, }, - AuthorizedActions: []string{"read", "update", "delete", "add-members", "set-members", "remove-members"}, + AuthorizedActions: testAuthorizedActions, } wantProjGroup := &pb.Group{ @@ -125,7 +127,7 @@ func TestGet(t *testing.T) { ScopeId: u.GetScopeId(), }, }, - AuthorizedActions: []string{"read", "update", "delete", "add-members", "set-members", "remove-members"}, + AuthorizedActions: testAuthorizedActions, } cases := []struct { @@ -227,7 +229,7 @@ func TestList(t *testing.T) { CreatedTime: og.GetCreateTime().GetTimestamp(), UpdatedTime: og.GetUpdateTime().GetTimestamp(), Version: 1, - AuthorizedActions: []string{"read", "update", "delete", "add-members", "set-members", "remove-members"}, + AuthorizedActions: testAuthorizedActions, }) totalGroups = append(totalGroups, wantOrgGroups[i]) pg := iam.TestGroup(t, conn, pWithGroups.GetPublicId()) @@ -238,7 +240,7 @@ func TestList(t *testing.T) { CreatedTime: pg.GetCreateTime().GetTimestamp(), UpdatedTime: pg.GetUpdateTime().GetTimestamp(), Version: 1, - AuthorizedActions: []string{"read", "update", "delete", "add-members", "set-members", "remove-members"}, + AuthorizedActions: testAuthorizedActions, }) totalGroups = append(totalGroups, wantProjGroups[i]) } @@ -425,8 +427,7 @@ func TestDelete_twice(t *testing.T) { func TestCreate(t *testing.T) { defaultOGroup, defaultPGroup, repoFn := createDefaultGroupsAndRepo(t) - defaultCreated, err := ptypes.Timestamp(defaultOGroup.GetCreateTime().GetTimestamp()) - require.NoError(t, err, "Error converting proto to timestamp.") + defaultCreated := defaultOGroup.GetCreateTime().GetTimestamp().AsTime() toMerge := &pbs.CreateGroupRequest{} cases := []struct { @@ -450,7 +451,7 @@ func TestCreate(t *testing.T) { Name: &wrapperspb.StringValue{Value: "name"}, Description: &wrapperspb.StringValue{Value: "desc"}, Version: 1, - AuthorizedActions: []string{"read", "update", "delete", "add-members", "set-members", "remove-members"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -469,7 +470,7 @@ func TestCreate(t *testing.T) { Name: &wrapperspb.StringValue{Value: "name"}, Description: &wrapperspb.StringValue{Value: "desc"}, Version: 1, - AuthorizedActions: []string{"read", "update", "delete", "add-members", "set-members", "remove-members"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -490,7 +491,7 @@ func TestCreate(t *testing.T) { Name: &wrapperspb.StringValue{Value: "name"}, Description: &wrapperspb.StringValue{Value: "desc"}, Version: 1, - AuthorizedActions: []string{"read", "update", "delete", "add-members", "set-members", "remove-members"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -505,7 +506,7 @@ func TestCreate(t *testing.T) { { name: "Can't specify Created Time", req: &pbs.CreateGroupRequest{Item: &pb.Group{ - CreatedTime: ptypes.TimestampNow(), + CreatedTime: timestamppb.Now(), }}, res: nil, err: handlers.ApiErrorWithCode(codes.InvalidArgument), @@ -513,7 +514,7 @@ func TestCreate(t *testing.T) { { name: "Can't specify Update Time", req: &pbs.CreateGroupRequest{Item: &pb.Group{ - UpdatedTime: ptypes.TimestampNow(), + UpdatedTime: timestamppb.Now(), }}, res: nil, err: handlers.ApiErrorWithCode(codes.InvalidArgument), @@ -536,10 +537,8 @@ func TestCreate(t *testing.T) { if got != nil { assert.Contains(got.GetUri(), tc.res.Uri) assert.True(strings.HasPrefix(got.GetItem().GetId(), iam.GroupPrefix+"_")) - gotCreateTime, err := ptypes.Timestamp(got.GetItem().GetCreatedTime()) - require.NoError(err, "Error converting proto to timestamp.") - gotUpdateTime, err := ptypes.Timestamp(got.GetItem().GetUpdatedTime()) - require.NoError(err, "Error converting proto to timestamp.") + gotCreateTime := got.GetItem().GetCreatedTime().AsTime() + gotUpdateTime := got.GetItem().GetUpdatedTime().AsTime() // Verify it is a group created after the test setup's default group assert.True(gotCreateTime.After(defaultCreated), "New group should have been created after default group. Was created %v, which is after %v", gotCreateTime, defaultCreated) assert.True(gotUpdateTime.After(defaultCreated), "New group should have been updated after default group. Was updated %v, which is after %v", gotUpdateTime, defaultCreated) @@ -590,8 +589,7 @@ func TestUpdate(t *testing.T) { } } - created, err := ptypes.Timestamp(og.GetCreateTime().GetTimestamp()) - require.NoError(t, err, "Error converting proto to timestamp") + created := og.GetCreateTime().GetTimestamp().AsTime() toMerge := &pbs.UpdateGroupRequest{ Id: og.GetPublicId(), } @@ -632,7 +630,7 @@ func TestUpdate(t *testing.T) { ScopeId: u.GetScopeId(), }, }, - AuthorizedActions: []string{"read", "update", "delete", "add-members", "set-members", "remove-members"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -663,7 +661,7 @@ func TestUpdate(t *testing.T) { ScopeId: u.GetScopeId(), }, }, - AuthorizedActions: []string{"read", "update", "delete", "add-members", "set-members", "remove-members"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -695,7 +693,7 @@ func TestUpdate(t *testing.T) { ScopeId: u.GetScopeId(), }, }, - AuthorizedActions: []string{"read", "update", "delete", "add-members", "set-members", "remove-members"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -727,7 +725,7 @@ func TestUpdate(t *testing.T) { ScopeId: u.GetScopeId(), }, }, - AuthorizedActions: []string{"read", "update", "delete", "add-members", "set-members", "remove-members"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -790,7 +788,7 @@ func TestUpdate(t *testing.T) { ScopeId: u.GetScopeId(), }, }, - AuthorizedActions: []string{"read", "update", "delete", "add-members", "set-members", "remove-members"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -821,7 +819,7 @@ func TestUpdate(t *testing.T) { ScopeId: u.GetScopeId(), }, }, - AuthorizedActions: []string{"read", "update", "delete", "add-members", "set-members", "remove-members"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -852,7 +850,7 @@ func TestUpdate(t *testing.T) { ScopeId: u.GetScopeId(), }, }, - AuthorizedActions: []string{"read", "update", "delete", "add-members", "set-members", "remove-members"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -893,7 +891,7 @@ func TestUpdate(t *testing.T) { Paths: []string{"created_time"}, }, Item: &pb.Group{ - CreatedTime: ptypes.TimestampNow(), + CreatedTime: timestamppb.Now(), }, }, res: nil, @@ -906,7 +904,7 @@ func TestUpdate(t *testing.T) { Paths: []string{"updated_time"}, }, Item: &pb.Group{ - UpdatedTime: ptypes.TimestampNow(), + UpdatedTime: timestamppb.Now(), }, }, res: nil, @@ -946,8 +944,7 @@ func TestUpdate(t *testing.T) { if got != nil { assert.NotNilf(tc.res, "Expected UpdateGroup response to be nil, but was %v", got) - gotUpdateTime, err := ptypes.Timestamp(got.GetItem().GetUpdatedTime()) - require.NoError(err, "Error converting proto to timestamp") + gotUpdateTime := got.GetItem().GetUpdatedTime().AsTime() // Verify it is a group updated after it was created assert.True(gotUpdateTime.After(created), "Updated group should have been updated after it's creation. Was updated %v, which is after %v", gotUpdateTime, created) diff --git a/internal/servers/controller/handlers/host_catalogs/host_catalog_service.go b/internal/servers/controller/handlers/host_catalogs/host_catalog_service.go index f58c37a49a..e0b176331c 100644 --- a/internal/servers/controller/handlers/host_catalogs/host_catalog_service.go +++ b/internal/servers/controller/handlers/host_catalogs/host_catalog_service.go @@ -32,6 +32,7 @@ var ( // IdActions contains the set of actions that can be performed on // individual resources IdActions = action.ActionSet{ + action.NoOp, action.Read, action.Update, action.Delete, diff --git a/internal/servers/controller/handlers/host_catalogs/host_catalog_service_test.go b/internal/servers/controller/handlers/host_catalogs/host_catalog_service_test.go index 9760050972..54062e8e69 100644 --- a/internal/servers/controller/handlers/host_catalogs/host_catalog_service_test.go +++ b/internal/servers/controller/handlers/host_catalogs/host_catalog_service_test.go @@ -7,7 +7,6 @@ import ( "strings" "testing" - "github.com/golang/protobuf/ptypes" "github.com/golang/protobuf/ptypes/wrappers" "github.com/google/go-cmp/cmp" "github.com/hashicorp/boundary/internal/auth" @@ -27,6 +26,7 @@ import ( "google.golang.org/protobuf/proto" "google.golang.org/protobuf/testing/protocmp" "google.golang.org/protobuf/types/known/structpb" + "google.golang.org/protobuf/types/known/timestamppb" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -47,6 +47,8 @@ var authorizedCollectionActions = map[string]*structpb.ListValue{ }, } +var testAuthorizedActions = []string{"no-op", "read", "update", "delete"} + func createDefaultHostCatalogAndRepo(t *testing.T) (*static.HostCatalog, *iam.Scope, common.StaticRepoFactory, common.IamRepoFactory) { t.Helper() require := require.New(t) @@ -90,7 +92,7 @@ func TestGet(t *testing.T) { CreatedTime: hc.CreateTime.GetTimestamp(), UpdatedTime: hc.UpdateTime.GetTimestamp(), Type: "static", - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, AuthorizedCollectionActions: authorizedCollectionActions, } @@ -174,7 +176,7 @@ func TestList(t *testing.T) { Scope: &scopepb.ScopeInfo{Id: pWithCatalogs.GetPublicId(), Type: scope.Project.String(), ParentScopeId: oWithCatalogs.GetPublicId()}, Version: 1, Type: "static", - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, AuthorizedCollectionActions: authorizedCollectionActions, }) } @@ -189,7 +191,7 @@ func TestList(t *testing.T) { Scope: &scopepb.ScopeInfo{Id: pWithOtherCatalogs.GetPublicId(), Type: scope.Project.String(), ParentScopeId: oWithOtherCatalogs.GetPublicId()}, Version: 1, Type: "static", - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, AuthorizedCollectionActions: authorizedCollectionActions, }) } @@ -340,8 +342,7 @@ func TestDelete_twice(t *testing.T) { func TestCreate(t *testing.T) { t.Parallel() defaultHc, proj, repo, iamRepoFn := createDefaultHostCatalogAndRepo(t) - defaultHcCreated, err := ptypes.Timestamp(defaultHc.GetCreateTime().GetTimestamp()) - require.NoError(t, err, "Error converting proto to timestamp.") + defaultHcCreated := defaultHc.GetCreateTime().GetTimestamp().AsTime() toMerge := &pbs.CreateHostCatalogRequest{} cases := []struct { @@ -366,7 +367,7 @@ func TestCreate(t *testing.T) { Name: &wrappers.StringValue{Value: "name"}, Description: &wrappers.StringValue{Value: "desc"}, Type: "static", - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, AuthorizedCollectionActions: authorizedCollectionActions, }, }, @@ -419,7 +420,7 @@ func TestCreate(t *testing.T) { { name: "Can't specify Created Time", req: &pbs.CreateHostCatalogRequest{Item: &pb.HostCatalog{ - CreatedTime: ptypes.TimestampNow(), + CreatedTime: timestamppb.Now(), }}, res: nil, err: handlers.ApiErrorWithCode(codes.InvalidArgument), @@ -427,7 +428,7 @@ func TestCreate(t *testing.T) { { name: "Can't specify Update Time", req: &pbs.CreateHostCatalogRequest{Item: &pb.HostCatalog{ - UpdatedTime: ptypes.TimestampNow(), + UpdatedTime: timestamppb.Now(), }}, res: nil, err: handlers.ApiErrorWithCode(codes.InvalidArgument), @@ -450,9 +451,9 @@ func TestCreate(t *testing.T) { if got != nil { assert.Contains(got.GetUri(), tc.res.GetUri()) assert.True(strings.HasPrefix(got.GetItem().GetId(), static.HostCatalogPrefix)) - gotCreateTime, err := ptypes.Timestamp(got.GetItem().GetCreatedTime()) + gotCreateTime := got.GetItem().GetCreatedTime().AsTime() require.NoError(err, "Error converting proto to timestamp.") - gotUpdateTime, err := ptypes.Timestamp(got.GetItem().GetUpdatedTime()) + gotUpdateTime := got.GetItem().GetUpdatedTime().AsTime() require.NoError(err, "Error converting proto to timestamp") // Verify it is a catalog created after the test setup's default catalog assert.True(gotCreateTime.After(defaultHcCreated), "New catalog should have been created after default catalog. Was created %v, which is after %v", gotCreateTime, defaultHcCreated) @@ -488,8 +489,7 @@ func TestUpdate(t *testing.T) { version++ } - hcCreated, err := ptypes.Timestamp(hc.GetCreateTime().GetTimestamp()) - require.NoError(t, err, "Failed to convert proto to timestamp") + hcCreated := hc.GetCreateTime().GetTimestamp().AsTime() toMerge := &pbs.UpdateHostCatalogRequest{ Id: hc.GetPublicId(), } @@ -521,7 +521,7 @@ func TestUpdate(t *testing.T) { Description: &wrappers.StringValue{Value: "desc"}, CreatedTime: hc.GetCreateTime().GetTimestamp(), Type: "static", - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, AuthorizedCollectionActions: authorizedCollectionActions, }, }, @@ -547,7 +547,7 @@ func TestUpdate(t *testing.T) { Description: &wrappers.StringValue{Value: "desc"}, CreatedTime: hc.GetCreateTime().GetTimestamp(), Type: "static", - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, AuthorizedCollectionActions: authorizedCollectionActions, }, }, @@ -602,7 +602,7 @@ func TestUpdate(t *testing.T) { Description: &wrappers.StringValue{Value: "default"}, CreatedTime: hc.GetCreateTime().GetTimestamp(), Type: "static", - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, AuthorizedCollectionActions: authorizedCollectionActions, }, }, @@ -625,7 +625,7 @@ func TestUpdate(t *testing.T) { Name: &wrappers.StringValue{Value: "default"}, CreatedTime: hc.GetCreateTime().GetTimestamp(), Type: "static", - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, AuthorizedCollectionActions: authorizedCollectionActions, }, }, @@ -650,7 +650,7 @@ func TestUpdate(t *testing.T) { Description: &wrappers.StringValue{Value: "default"}, CreatedTime: hc.GetCreateTime().GetTimestamp(), Type: "static", - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, AuthorizedCollectionActions: authorizedCollectionActions, }, }, @@ -675,7 +675,7 @@ func TestUpdate(t *testing.T) { Description: &wrappers.StringValue{Value: "notignored"}, CreatedTime: hc.GetCreateTime().GetTimestamp(), Type: "static", - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, AuthorizedCollectionActions: authorizedCollectionActions, }, }, @@ -732,7 +732,7 @@ func TestUpdate(t *testing.T) { Paths: []string{"created_time"}, }, Item: &pb.HostCatalog{ - CreatedTime: ptypes.TimestampNow(), + CreatedTime: timestamppb.Now(), }, }, res: nil, @@ -745,7 +745,7 @@ func TestUpdate(t *testing.T) { Paths: []string{"updated_time"}, }, Item: &pb.HostCatalog{ - UpdatedTime: ptypes.TimestampNow(), + UpdatedTime: timestamppb.Now(), }, }, res: nil, @@ -794,7 +794,7 @@ func TestUpdate(t *testing.T) { if got != nil { assert.NotNilf(tc.res, "Expected UpdateHostCatalog response to be nil, but was %v", got) - gotUpdateTime, err := ptypes.Timestamp(got.GetItem().GetUpdatedTime()) + gotUpdateTime := got.GetItem().GetUpdatedTime().AsTime() require.NoError(err, "Failed to convert proto to timestamp") // Verify it is a catalog updated after it was created // TODO: This is currently failing. diff --git a/internal/servers/controller/handlers/host_sets/host_set_service.go b/internal/servers/controller/handlers/host_sets/host_set_service.go index b8240fa175..f3a32e7edc 100644 --- a/internal/servers/controller/handlers/host_sets/host_set_service.go +++ b/internal/servers/controller/handlers/host_sets/host_set_service.go @@ -27,6 +27,7 @@ var ( // IdActions contains the set of actions that can be performed on // individual resources IdActions = action.ActionSet{ + action.NoOp, action.Read, action.Update, action.Delete, diff --git a/internal/servers/controller/handlers/host_sets/host_set_service_test.go b/internal/servers/controller/handlers/host_sets/host_set_service_test.go index 88e7985d32..6eeaf1a8c2 100644 --- a/internal/servers/controller/handlers/host_sets/host_set_service_test.go +++ b/internal/servers/controller/handlers/host_sets/host_set_service_test.go @@ -7,7 +7,6 @@ import ( "strings" "testing" - "github.com/golang/protobuf/ptypes" "github.com/golang/protobuf/ptypes/wrappers" "github.com/google/go-cmp/cmp" "github.com/hashicorp/boundary/internal/auth" @@ -29,8 +28,11 @@ import ( "google.golang.org/grpc/status" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/testing/protocmp" + "google.golang.org/protobuf/types/known/timestamppb" ) +var testAuthorizedActions = []string{"no-op", "read", "update", "delete", "add-hosts", "set-hosts", "remove-hosts"} + func TestGet(t *testing.T) { t.Parallel() conn, _ := db.TestSetup(t, "postgres") @@ -65,7 +67,7 @@ func TestGet(t *testing.T) { Scope: &scopes.ScopeInfo{Id: proj.GetPublicId(), Type: scope.Project.String(), ParentScopeId: org.GetPublicId()}, Type: "static", HostIds: hIds, - AuthorizedActions: []string{"read", "update", "delete", "add-hosts", "set-hosts", "remove-hosts"}, + AuthorizedActions: testAuthorizedActions, } cases := []struct { @@ -150,7 +152,7 @@ func TestList(t *testing.T) { UpdatedTime: h.GetUpdateTime().GetTimestamp(), Version: h.GetVersion(), Type: host.StaticSubtype.String(), - AuthorizedActions: []string{"read", "update", "delete", "add-hosts", "set-hosts", "remove-hosts"}, + AuthorizedActions: testAuthorizedActions, }) } @@ -333,8 +335,7 @@ func TestCreate(t *testing.T) { } hc := static.TestCatalogs(t, conn, proj.GetPublicId(), 1)[0] - defaultHcCreated, err := ptypes.Timestamp(hc.GetCreateTime().GetTimestamp()) - require.NoError(t, err) + defaultHcCreated := hc.GetCreateTime().GetTimestamp().AsTime() cases := []struct { name string @@ -358,7 +359,7 @@ func TestCreate(t *testing.T) { Name: &wrappers.StringValue{Value: "name"}, Description: &wrappers.StringValue{Value: "desc"}, Type: "static", - AuthorizedActions: []string{"read", "update", "delete", "add-hosts", "set-hosts", "remove-hosts"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -387,7 +388,7 @@ func TestCreate(t *testing.T) { Name: &wrappers.StringValue{Value: "no type name"}, Description: &wrappers.StringValue{Value: "no type desc"}, Type: "static", - AuthorizedActions: []string{"read", "update", "delete", "add-hosts", "set-hosts", "remove-hosts"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -404,7 +405,7 @@ func TestCreate(t *testing.T) { name: "Can't specify Created Time", req: &pbs.CreateHostSetRequest{Item: &pb.HostSet{ HostCatalogId: hc.GetPublicId(), - CreatedTime: ptypes.TimestampNow(), + CreatedTime: timestamppb.Now(), }}, res: nil, err: handlers.ApiErrorWithCode(codes.InvalidArgument), @@ -413,7 +414,7 @@ func TestCreate(t *testing.T) { name: "Can't specify Update Time", req: &pbs.CreateHostSetRequest{Item: &pb.HostSet{ HostCatalogId: hc.GetPublicId(), - UpdatedTime: ptypes.TimestampNow(), + UpdatedTime: timestamppb.Now(), }}, res: nil, err: handlers.ApiErrorWithCode(codes.InvalidArgument), @@ -434,9 +435,9 @@ func TestCreate(t *testing.T) { if got != nil { assert.Contains(got.GetUri(), tc.res.GetUri()) assert.True(strings.HasPrefix(got.GetItem().GetId(), static.HostSetPrefix), got.GetItem().GetId()) - gotCreateTime, err := ptypes.Timestamp(got.GetItem().GetCreatedTime()) + gotCreateTime := got.GetItem().GetCreatedTime().AsTime() require.NoError(err, "Error converting proto to timestamp.") - gotUpdateTime, err := ptypes.Timestamp(got.GetItem().GetUpdatedTime()) + gotUpdateTime := got.GetItem().GetUpdatedTime().AsTime() require.NoError(err, "Error converting proto to timestamp") // Verify it is a set created after the test setup's default set assert.True(gotCreateTime.After(defaultHcCreated), "New set should have been created after default set. Was created %v, which is after %v", gotCreateTime, defaultHcCreated) @@ -496,8 +497,7 @@ func TestUpdate(t *testing.T) { version++ } - hCreated, err := ptypes.Timestamp(hs.GetCreateTime().GetTimestamp()) - require.NoError(t, err, "Failed to convert proto to timestamp") + hCreated := hs.GetCreateTime().GetTimestamp().AsTime() toMerge := &pbs.UpdateHostSetRequest{ Id: hs.GetPublicId(), } @@ -533,7 +533,7 @@ func TestUpdate(t *testing.T) { CreatedTime: hs.GetCreateTime().GetTimestamp(), Type: "static", HostIds: hIds, - AuthorizedActions: []string{"read", "update", "delete", "add-hosts", "set-hosts", "remove-hosts"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -559,7 +559,7 @@ func TestUpdate(t *testing.T) { CreatedTime: hs.GetCreateTime().GetTimestamp(), Type: "static", HostIds: hIds, - AuthorizedActions: []string{"read", "update", "delete", "add-hosts", "set-hosts", "remove-hosts"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -628,7 +628,7 @@ func TestUpdate(t *testing.T) { CreatedTime: hs.GetCreateTime().GetTimestamp(), Type: "static", HostIds: hIds, - AuthorizedActions: []string{"read", "update", "delete", "add-hosts", "set-hosts", "remove-hosts"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -651,7 +651,7 @@ func TestUpdate(t *testing.T) { CreatedTime: hs.GetCreateTime().GetTimestamp(), Type: "static", HostIds: hIds, - AuthorizedActions: []string{"read", "update", "delete", "add-hosts", "set-hosts", "remove-hosts"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -676,7 +676,7 @@ func TestUpdate(t *testing.T) { CreatedTime: hs.GetCreateTime().GetTimestamp(), Type: "static", HostIds: hIds, - AuthorizedActions: []string{"read", "update", "delete", "add-hosts", "set-hosts", "remove-hosts"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -701,7 +701,7 @@ func TestUpdate(t *testing.T) { CreatedTime: hs.GetCreateTime().GetTimestamp(), Type: "static", HostIds: hIds, - AuthorizedActions: []string{"read", "update", "delete", "add-hosts", "set-hosts", "remove-hosts"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -744,7 +744,7 @@ func TestUpdate(t *testing.T) { Paths: []string{"created_time"}, }, Item: &pb.HostSet{ - CreatedTime: ptypes.TimestampNow(), + CreatedTime: timestamppb.Now(), }, }, res: nil, @@ -757,7 +757,7 @@ func TestUpdate(t *testing.T) { Paths: []string{"updated_time"}, }, Item: &pb.HostSet{ - UpdatedTime: ptypes.TimestampNow(), + UpdatedTime: timestamppb.Now(), }, }, res: nil, @@ -806,8 +806,7 @@ func TestUpdate(t *testing.T) { if got != nil { assert.NotNilf(tc.res, "Expected UpdateHost response to be nil, but was %v", got) - gotUpdateTime, err := ptypes.Timestamp(got.GetItem().GetUpdatedTime()) - require.NoError(err, "Failed to convert proto to timestamp") + gotUpdateTime := got.GetItem().GetUpdatedTime().AsTime() // Verify it is a set updated after it was created // TODO: This is currently failing. assert.True(gotUpdateTime.After(hCreated), "Updated set should have been updated after it's creation. Was updated %v, which is after %v", gotUpdateTime, hCreated) diff --git a/internal/servers/controller/handlers/hosts/host_service.go b/internal/servers/controller/handlers/hosts/host_service.go index 49052ec65d..a5521e5ac9 100644 --- a/internal/servers/controller/handlers/hosts/host_service.go +++ b/internal/servers/controller/handlers/hosts/host_service.go @@ -28,6 +28,7 @@ var ( // IdActions contains the set of actions that can be performed on // individual resources IdActions = action.ActionSet{ + action.NoOp, action.Read, action.Update, action.Delete, diff --git a/internal/servers/controller/handlers/hosts/host_service_test.go b/internal/servers/controller/handlers/hosts/host_service_test.go index 328ec00e34..2a35d40147 100644 --- a/internal/servers/controller/handlers/hosts/host_service_test.go +++ b/internal/servers/controller/handlers/hosts/host_service_test.go @@ -7,7 +7,6 @@ import ( "strings" "testing" - "github.com/golang/protobuf/ptypes" "github.com/golang/protobuf/ptypes/wrappers" "github.com/google/go-cmp/cmp" "github.com/hashicorp/boundary/internal/auth" @@ -29,8 +28,11 @@ import ( "google.golang.org/protobuf/proto" "google.golang.org/protobuf/testing/protocmp" "google.golang.org/protobuf/types/known/structpb" + "google.golang.org/protobuf/types/known/timestamppb" ) +var testAuthorizedActions = []string{"no-op", "read", "update", "delete"} + func TestGet(t *testing.T) { t.Parallel() conn, _ := db.TestSetup(t, "postgres") @@ -61,7 +63,7 @@ func TestGet(t *testing.T) { Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{ "address": structpb.NewStringValue(h.GetAddress()), }}, - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, } cases := []struct { @@ -145,7 +147,7 @@ func TestList(t *testing.T) { Type: host.StaticSubtype.String(), Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{ "address": structpb.NewStringValue(h.GetAddress()), }}, - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, }) } @@ -320,8 +322,7 @@ func TestCreate(t *testing.T) { } hc := static.TestCatalogs(t, conn, proj.GetPublicId(), 1)[0] - defaultHcCreated, err := ptypes.Timestamp(hc.GetCreateTime().GetTimestamp()) - require.NoError(t, err) + defaultHcCreated := hc.GetCreateTime().GetTimestamp().AsTime() cases := []struct { name string @@ -351,7 +352,7 @@ func TestCreate(t *testing.T) { Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{ "address": structpb.NewStringValue("123.456.789"), }}, - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -410,7 +411,7 @@ func TestCreate(t *testing.T) { Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{ "address": structpb.NewStringValue("123.456.789"), }}, - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -427,7 +428,7 @@ func TestCreate(t *testing.T) { name: "Can't specify Created Time", req: &pbs.CreateHostRequest{Item: &pb.Host{ HostCatalogId: hc.GetPublicId(), - CreatedTime: ptypes.TimestampNow(), + CreatedTime: timestamppb.Now(), }}, res: nil, err: handlers.ApiErrorWithCode(codes.InvalidArgument), @@ -435,7 +436,7 @@ func TestCreate(t *testing.T) { { name: "Can't specify Update Time", req: &pbs.CreateHostRequest{Item: &pb.Host{ - UpdatedTime: ptypes.TimestampNow(), + UpdatedTime: timestamppb.Now(), }}, res: nil, err: handlers.ApiErrorWithCode(codes.InvalidArgument), @@ -455,10 +456,8 @@ func TestCreate(t *testing.T) { if got != nil { assert.Contains(got.GetUri(), tc.res.GetUri()) assert.True(strings.HasPrefix(got.GetItem().GetId(), static.HostPrefix)) - gotCreateTime, err := ptypes.Timestamp(got.GetItem().GetCreatedTime()) - require.NoError(err, "Error converting proto to timestamp.") - gotUpdateTime, err := ptypes.Timestamp(got.GetItem().GetUpdatedTime()) - require.NoError(err, "Error converting proto to timestamp") + gotCreateTime := got.GetItem().GetCreatedTime().AsTime() + gotUpdateTime := got.GetItem().GetUpdatedTime().AsTime() // Verify it is a set created after the test setup's default set assert.True(gotCreateTime.After(defaultHcCreated), "New host should have been created after default host. Was created %v, which is after %v", gotCreateTime, defaultHcCreated) assert.True(gotUpdateTime.After(defaultHcCreated), "New host should have been updated after default host. Was updated %v, which is after %v", gotUpdateTime, defaultHcCreated) @@ -512,8 +511,7 @@ func TestUpdate(t *testing.T) { version++ } - hCreated, err := ptypes.Timestamp(h.GetCreateTime().GetTimestamp()) - require.NoError(t, err, "Failed to convert proto to timestamp") + hCreated := h.GetCreateTime().GetTimestamp().AsTime() toMerge := &pbs.UpdateHostRequest{ Id: h.GetPublicId(), } @@ -551,7 +549,7 @@ func TestUpdate(t *testing.T) { Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{ "address": structpb.NewStringValue("defaultaddress"), }}, - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -579,7 +577,7 @@ func TestUpdate(t *testing.T) { Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{ "address": structpb.NewStringValue("defaultaddress"), }}, - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -649,7 +647,7 @@ func TestUpdate(t *testing.T) { Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{ "address": structpb.NewStringValue("defaultaddress"), }}, - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -674,7 +672,7 @@ func TestUpdate(t *testing.T) { Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{ "address": structpb.NewStringValue("defaultaddress"), }}, - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -701,7 +699,7 @@ func TestUpdate(t *testing.T) { Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{ "address": structpb.NewStringValue("defaultaddress"), }}, - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -728,7 +726,7 @@ func TestUpdate(t *testing.T) { Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{ "address": structpb.NewStringValue("defaultaddress"), }}, - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -803,7 +801,7 @@ func TestUpdate(t *testing.T) { Paths: []string{"created_time"}, }, Item: &pb.Host{ - CreatedTime: ptypes.TimestampNow(), + CreatedTime: timestamppb.Now(), }, }, res: nil, @@ -816,7 +814,7 @@ func TestUpdate(t *testing.T) { Paths: []string{"updated_time"}, }, Item: &pb.Host{ - UpdatedTime: ptypes.TimestampNow(), + UpdatedTime: timestamppb.Now(), }, }, res: nil, @@ -865,8 +863,7 @@ func TestUpdate(t *testing.T) { if got != nil { assert.NotNilf(tc.res, "Expected UpdateHost response to be nil, but was %v", got) - gotUpdateTime, err := ptypes.Timestamp(got.GetItem().GetUpdatedTime()) - require.NoError(err, "Failed to convert proto to timestamp") + gotUpdateTime := got.GetItem().GetUpdatedTime().AsTime() // Verify it is a set updated after it was created // TODO: This is currently failing. assert.True(gotUpdateTime.After(hCreated), "Updated set should have been updated after it's creation. Was updated %v, which is after %v", gotUpdateTime, hCreated) diff --git a/internal/servers/controller/handlers/roles/role_service.go b/internal/servers/controller/handlers/roles/role_service.go index 0451eb6897..a11deffbd0 100644 --- a/internal/servers/controller/handlers/roles/role_service.go +++ b/internal/servers/controller/handlers/roles/role_service.go @@ -28,6 +28,7 @@ var ( // IdActions contains the set of actions that can be performed on // individual resources IdActions = action.ActionSet{ + action.NoOp, action.Read, action.Update, action.Delete, diff --git a/internal/servers/controller/handlers/roles/role_service_test.go b/internal/servers/controller/handlers/roles/role_service_test.go index 1d736e244f..b04f532944 100644 --- a/internal/servers/controller/handlers/roles/role_service_test.go +++ b/internal/servers/controller/handlers/roles/role_service_test.go @@ -7,7 +7,6 @@ import ( "strings" "testing" - "github.com/golang/protobuf/ptypes" "github.com/google/go-cmp/cmp" "github.com/hashicorp/boundary/internal/auth" "github.com/hashicorp/boundary/internal/db" @@ -24,12 +23,15 @@ import ( "google.golang.org/grpc/status" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/testing/protocmp" + "google.golang.org/protobuf/types/known/timestamppb" "google.golang.org/protobuf/types/known/wrapperspb" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) +var testAuthorizedActions = []string{"no-op", "read", "update", "delete", "add-principals", "set-principals", "remove-principals", "add-grants", "set-grants", "remove-grants"} + func createDefaultRolesAndRepo(t *testing.T) (*iam.Role, *iam.Role, func() (*iam.Repository, error)) { t.Helper() conn, _ := db.TestSetup(t, "postgres") @@ -86,7 +88,7 @@ func TestGet(t *testing.T) { CreatedTime: or.CreateTime.GetTimestamp(), UpdatedTime: or.UpdateTime.GetTimestamp(), Version: or.GetVersion(), - AuthorizedActions: []string{"read", "update", "delete", "add-principals", "set-principals", "remove-principals", "add-grants", "set-grants", "remove-grants"}, + AuthorizedActions: testAuthorizedActions, } wantProjRole := &pb.Role{ @@ -99,7 +101,7 @@ func TestGet(t *testing.T) { CreatedTime: pr.CreateTime.GetTimestamp(), UpdatedTime: pr.UpdateTime.GetTimestamp(), Version: pr.GetVersion(), - AuthorizedActions: []string{"read", "update", "delete", "add-principals", "set-principals", "remove-principals", "add-grants", "set-grants", "remove-grants"}, + AuthorizedActions: testAuthorizedActions, } cases := []struct { @@ -201,7 +203,7 @@ func TestList(t *testing.T) { UpdatedTime: or.GetUpdateTime().GetTimestamp(), GrantScopeId: &wrapperspb.StringValue{Value: or.GetGrantScopeId()}, Version: or.GetVersion(), - AuthorizedActions: []string{"read", "update", "delete", "add-principals", "set-principals", "remove-principals", "add-grants", "set-grants", "remove-grants"}, + AuthorizedActions: testAuthorizedActions, }) totalRoles = append(totalRoles, wantOrgRoles[i]) pr := iam.TestRole(t, conn, pWithRoles.GetPublicId()) @@ -213,7 +215,7 @@ func TestList(t *testing.T) { UpdatedTime: pr.GetUpdateTime().GetTimestamp(), GrantScopeId: &wrapperspb.StringValue{Value: pr.GetGrantScopeId()}, Version: pr.GetVersion(), - AuthorizedActions: []string{"read", "update", "delete", "add-principals", "set-principals", "remove-principals", "add-grants", "set-grants", "remove-grants"}, + AuthorizedActions: testAuthorizedActions, }) totalRoles = append(totalRoles, wantProjRoles[i]) } @@ -400,8 +402,7 @@ func TestDelete_twice(t *testing.T) { func TestCreate(t *testing.T) { defaultOrgRole, defaultProjRole, repoFn := createDefaultRolesAndRepo(t) - defaultCreated, err := ptypes.Timestamp(defaultOrgRole.GetCreateTime().GetTimestamp()) - require.NoError(t, err, "Error converting proto to timestamp.") + defaultCreated := defaultOrgRole.GetCreateTime().GetTimestamp().AsTime() toMerge := &pbs.CreateRoleRequest{} cases := []struct { @@ -427,7 +428,7 @@ func TestCreate(t *testing.T) { Description: &wrapperspb.StringValue{Value: "desc"}, GrantScopeId: &wrapperspb.StringValue{Value: defaultProjRole.ScopeId}, Version: 1, - AuthorizedActions: []string{"read", "update", "delete", "add-principals", "set-principals", "remove-principals", "add-grants", "set-grants", "remove-grants"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -448,7 +449,7 @@ func TestCreate(t *testing.T) { Description: &wrapperspb.StringValue{Value: "desc"}, GrantScopeId: &wrapperspb.StringValue{Value: defaultProjRole.ScopeId}, Version: 1, - AuthorizedActions: []string{"read", "update", "delete", "add-principals", "set-principals", "remove-principals", "add-grants", "set-grants", "remove-grants"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -470,7 +471,7 @@ func TestCreate(t *testing.T) { Description: &wrapperspb.StringValue{Value: "desc"}, GrantScopeId: &wrapperspb.StringValue{Value: defaultProjRole.ScopeId}, Version: 1, - AuthorizedActions: []string{"read", "update", "delete", "add-principals", "set-principals", "remove-principals", "add-grants", "set-grants", "remove-grants"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -500,7 +501,7 @@ func TestCreate(t *testing.T) { name: "Can't specify Created Time", req: &pbs.CreateRoleRequest{Item: &pb.Role{ ScopeId: defaultProjRole.GetScopeId(), - CreatedTime: ptypes.TimestampNow(), + CreatedTime: timestamppb.Now(), }}, res: nil, err: handlers.ApiErrorWithCode(codes.InvalidArgument), @@ -509,7 +510,7 @@ func TestCreate(t *testing.T) { name: "Can't specify Update Time", req: &pbs.CreateRoleRequest{Item: &pb.Role{ ScopeId: defaultProjRole.GetScopeId(), - UpdatedTime: ptypes.TimestampNow(), + UpdatedTime: timestamppb.Now(), }}, res: nil, err: handlers.ApiErrorWithCode(codes.InvalidArgument), @@ -532,10 +533,8 @@ func TestCreate(t *testing.T) { if got != nil { assert.Contains(got.GetUri(), tc.res.Uri) assert.True(strings.HasPrefix(got.GetItem().GetId(), iam.RolePrefix+"_"), "Expected %q to have the prefix %q", got.GetItem().GetId(), iam.RolePrefix+"_") - gotCreateTime, err := ptypes.Timestamp(got.GetItem().GetCreatedTime()) - require.NoError(err, "Error converting proto to timestamp.") - gotUpdateTime, err := ptypes.Timestamp(got.GetItem().GetUpdatedTime()) - require.NoError(err, "Error converting proto to timestamp.") + gotCreateTime := got.GetItem().GetCreatedTime().AsTime() + gotUpdateTime := got.GetItem().GetUpdatedTime().AsTime() // Verify it is a role created after the test setup's default role assert.True(gotCreateTime.After(defaultCreated), "New role should have been created after default role. Was created %v, which is after %v", gotCreateTime, defaultCreated) assert.True(gotUpdateTime.After(defaultCreated), "New role should have been updated after default role. Was updated %v, which is after %v", gotUpdateTime, defaultCreated) @@ -610,8 +609,7 @@ func TestUpdate(t *testing.T) { } } - created, err := ptypes.Timestamp(or.GetCreateTime().GetTimestamp()) - require.NoError(t, err, "Error converting proto to timestamp") + created := or.GetCreateTime().GetTimestamp().AsTime() toMerge := &pbs.UpdateRoleRequest{ Id: or.GetPublicId(), } @@ -649,7 +647,7 @@ func TestUpdate(t *testing.T) { Grants: []*pb.Grant{grant}, PrincipalIds: []string{u.GetPublicId()}, Principals: []*pb.Principal{principal}, - AuthorizedActions: []string{"read", "update", "delete", "add-principals", "set-principals", "remove-principals", "add-grants", "set-grants", "remove-grants"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -678,7 +676,7 @@ func TestUpdate(t *testing.T) { Grants: []*pb.Grant{grant}, PrincipalIds: []string{u.GetPublicId()}, Principals: []*pb.Principal{principal}, - AuthorizedActions: []string{"read", "update", "delete", "add-principals", "set-principals", "remove-principals", "add-grants", "set-grants", "remove-grants"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -708,7 +706,7 @@ func TestUpdate(t *testing.T) { Grants: []*pb.Grant{grant}, PrincipalIds: []string{u.GetPublicId()}, Principals: []*pb.Principal{principal}, - AuthorizedActions: []string{"read", "update", "delete", "add-principals", "set-principals", "remove-principals", "add-grants", "set-grants", "remove-grants"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -738,7 +736,7 @@ func TestUpdate(t *testing.T) { Grants: []*pb.Grant{grant}, PrincipalIds: []string{u.GetPublicId()}, Principals: []*pb.Principal{principal}, - AuthorizedActions: []string{"read", "update", "delete", "add-principals", "set-principals", "remove-principals", "add-grants", "set-grants", "remove-grants"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -799,7 +797,7 @@ func TestUpdate(t *testing.T) { Grants: []*pb.Grant{grant}, PrincipalIds: []string{u.GetPublicId()}, Principals: []*pb.Principal{principal}, - AuthorizedActions: []string{"read", "update", "delete", "add-principals", "set-principals", "remove-principals", "add-grants", "set-grants", "remove-grants"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -828,7 +826,7 @@ func TestUpdate(t *testing.T) { Grants: []*pb.Grant{grant}, PrincipalIds: []string{u.GetPublicId()}, Principals: []*pb.Principal{principal}, - AuthorizedActions: []string{"read", "update", "delete", "add-principals", "set-principals", "remove-principals", "add-grants", "set-grants", "remove-grants"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -857,7 +855,7 @@ func TestUpdate(t *testing.T) { Grants: []*pb.Grant{grant}, PrincipalIds: []string{u.GetPublicId()}, Principals: []*pb.Principal{principal}, - AuthorizedActions: []string{"read", "update", "delete", "add-principals", "set-principals", "remove-principals", "add-grants", "set-grants", "remove-grants"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -897,7 +895,7 @@ func TestUpdate(t *testing.T) { Paths: []string{"created_time"}, }, Item: &pb.Role{ - CreatedTime: ptypes.TimestampNow(), + CreatedTime: timestamppb.Now(), }, }, res: nil, @@ -910,7 +908,7 @@ func TestUpdate(t *testing.T) { Paths: []string{"updated_time"}, }, Item: &pb.Role{ - UpdatedTime: ptypes.TimestampNow(), + UpdatedTime: timestamppb.Now(), }, }, res: nil, @@ -976,7 +974,7 @@ func TestUpdate(t *testing.T) { if got != nil { assert.NotNilf(tc.res, "Expected UpdateRole response to be nil, but was %v", got) - gotUpdateTime, err := ptypes.Timestamp(got.GetItem().GetUpdatedTime()) + gotUpdateTime := got.GetItem().GetUpdatedTime().AsTime() require.NoError(err, "Error converting proto to timestamp") // Verify it is a role updated after it was created assert.True(gotUpdateTime.After(created), "Updated role should have been updated after it's creation. Was updated %v, which is after %v", gotUpdateTime, created) diff --git a/internal/servers/controller/handlers/scopes/scope_service.go b/internal/servers/controller/handlers/scopes/scope_service.go index 5547011c5a..3e4af80998 100644 --- a/internal/servers/controller/handlers/scopes/scope_service.go +++ b/internal/servers/controller/handlers/scopes/scope_service.go @@ -41,6 +41,7 @@ var ( // IdActions contains the set of actions that can be performed on // individual resources IdActions = action.ActionSet{ + action.NoOp, action.Read, action.Update, action.Delete, diff --git a/internal/servers/controller/handlers/scopes/scope_service_test.go b/internal/servers/controller/handlers/scopes/scope_service_test.go index 3e78c86e3d..da546bb30b 100644 --- a/internal/servers/controller/handlers/scopes/scope_service_test.go +++ b/internal/servers/controller/handlers/scopes/scope_service_test.go @@ -29,6 +29,8 @@ import ( "github.com/stretchr/testify/require" ) +var testAuthorizedActions = []string{"no-op", "read", "update", "delete"} + func createDefaultScopesAndRepo(t *testing.T) (*iam.Scope, *iam.Scope, func() (*iam.Repository, error)) { t.Helper() conn, _ := db.TestSetup(t, "postgres") @@ -185,7 +187,7 @@ func TestGet(t *testing.T) { UpdatedTime: org.UpdateTime.GetTimestamp(), Version: 2, Type: scope.Org.String(), - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, AuthorizedCollectionActions: orgAuthorizedCollectionActions, } @@ -199,7 +201,7 @@ func TestGet(t *testing.T) { UpdatedTime: proj.UpdateTime.GetTimestamp(), Version: 2, Type: scope.Project.String(), - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, AuthorizedCollectionActions: projectAuthorizedCollectionActions, } @@ -292,11 +294,11 @@ func TestList(t *testing.T) { globalScope := &pb.ScopeInfo{Id: "global", Type: scope.Global.String(), Name: scope.Global.String(), Description: "Global Scope"} oNoProjectsProto := scopes.ToProto(oNoProjects) oNoProjectsProto.Scope = globalScope - oNoProjectsProto.AuthorizedActions = []string{"read", "update", "delete"} + oNoProjectsProto.AuthorizedActions = testAuthorizedActions oNoProjectsProto.AuthorizedCollectionActions = orgAuthorizedCollectionActions oWithProjectsProto := scopes.ToProto(oWithProjects) oWithProjectsProto.Scope = globalScope - oWithProjectsProto.AuthorizedActions = []string{"read", "update", "delete"} + oWithProjectsProto.AuthorizedActions = testAuthorizedActions oWithProjectsProto.AuthorizedCollectionActions = orgAuthorizedCollectionActions initialOrgs = append(initialOrgs, oNoProjectsProto, oWithProjectsProto) scopes.SortScopes(initialOrgs) @@ -373,7 +375,7 @@ func TestList(t *testing.T) { UpdatedTime: o.GetUpdateTime().GetTimestamp(), Version: 1, Type: scope.Org.String(), - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, AuthorizedCollectionActions: orgAuthorizedCollectionActions, }) } @@ -394,7 +396,7 @@ func TestList(t *testing.T) { UpdatedTime: p.GetUpdateTime().GetTimestamp(), Version: 1, Type: scope.Project.String(), - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, AuthorizedCollectionActions: projectAuthorizedCollectionActions, }) } @@ -619,7 +621,7 @@ func TestCreate(t *testing.T) { Description: &wrapperspb.StringValue{Value: "desc"}, Version: 1, Type: scope.Project.String(), - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, AuthorizedCollectionActions: projectAuthorizedCollectionActions, }, }, @@ -643,7 +645,7 @@ func TestCreate(t *testing.T) { Description: &wrapperspb.StringValue{Value: "desc"}, Version: 1, Type: scope.Org.String(), - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, AuthorizedCollectionActions: orgAuthorizedCollectionActions, }, }, @@ -666,7 +668,7 @@ func TestCreate(t *testing.T) { Description: &wrapperspb.StringValue{Value: "desc"}, Version: 1, Type: scope.Project.String(), - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, AuthorizedCollectionActions: projectAuthorizedCollectionActions, }, }, @@ -689,7 +691,7 @@ func TestCreate(t *testing.T) { Description: &wrapperspb.StringValue{Value: "desc"}, Version: 1, Type: scope.Org.String(), - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, AuthorizedCollectionActions: orgAuthorizedCollectionActions, }, }, @@ -918,7 +920,7 @@ func TestUpdate(t *testing.T) { Description: &wrapperspb.StringValue{Value: "desc"}, CreatedTime: proj.GetCreateTime().GetTimestamp(), Type: scope.Project.String(), - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, AuthorizedCollectionActions: projectAuthorizedCollectionActions, }, }, @@ -945,7 +947,7 @@ func TestUpdate(t *testing.T) { Description: &wrapperspb.StringValue{Value: "desc"}, CreatedTime: org.GetCreateTime().GetTimestamp(), Type: scope.Org.String(), - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, AuthorizedCollectionActions: orgAuthorizedCollectionActions, }, }, @@ -971,7 +973,7 @@ func TestUpdate(t *testing.T) { Description: &wrapperspb.StringValue{Value: "desc"}, CreatedTime: global.GetCreateTime().GetTimestamp(), Type: scope.Global.String(), - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, AuthorizedCollectionActions: globalAuthorizedCollectionActions, }, }, @@ -997,7 +999,7 @@ func TestUpdate(t *testing.T) { Description: &wrapperspb.StringValue{Value: "desc"}, CreatedTime: proj.GetCreateTime().GetTimestamp(), Type: scope.Project.String(), - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, AuthorizedCollectionActions: projectAuthorizedCollectionActions, }, }, @@ -1070,7 +1072,7 @@ func TestUpdate(t *testing.T) { Description: &wrapperspb.StringValue{Value: "defaultProj"}, CreatedTime: proj.GetCreateTime().GetTimestamp(), Type: scope.Project.String(), - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, AuthorizedCollectionActions: projectAuthorizedCollectionActions, }, }, @@ -1094,7 +1096,7 @@ func TestUpdate(t *testing.T) { Name: &wrappers.StringValue{Value: "defaultProj"}, CreatedTime: proj.GetCreateTime().GetTimestamp(), Type: scope.Project.String(), - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, AuthorizedCollectionActions: projectAuthorizedCollectionActions, }, }, @@ -1120,7 +1122,7 @@ func TestUpdate(t *testing.T) { Description: &wrapperspb.StringValue{Value: "defaultProj"}, CreatedTime: proj.GetCreateTime().GetTimestamp(), Type: scope.Project.String(), - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, AuthorizedCollectionActions: projectAuthorizedCollectionActions, }, }, @@ -1146,7 +1148,7 @@ func TestUpdate(t *testing.T) { Description: &wrapperspb.StringValue{Value: "notignored"}, CreatedTime: proj.GetCreateTime().GetTimestamp(), Type: scope.Project.String(), - AuthorizedActions: []string{"read", "update", "delete"}, + AuthorizedActions: testAuthorizedActions, AuthorizedCollectionActions: projectAuthorizedCollectionActions, }, }, diff --git a/internal/servers/controller/handlers/sessions/session_service.go b/internal/servers/controller/handlers/sessions/session_service.go index 88692d4bf5..97e12f9cc7 100644 --- a/internal/servers/controller/handlers/sessions/session_service.go +++ b/internal/servers/controller/handlers/sessions/session_service.go @@ -24,6 +24,7 @@ var ( // IdActions contains the set of actions that can be performed on // individual resources IdActions = action.ActionSet{ + action.NoOp, action.Read, action.ReadSelf, action.Cancel, diff --git a/internal/servers/controller/handlers/sessions/session_service_test.go b/internal/servers/controller/handlers/sessions/session_service_test.go index a5421882cb..d4c330a3d7 100644 --- a/internal/servers/controller/handlers/sessions/session_service_test.go +++ b/internal/servers/controller/handlers/sessions/session_service_test.go @@ -31,6 +31,8 @@ import ( "google.golang.org/protobuf/testing/protocmp" ) +var testAuthorizedActions = []string{"no-op", "read", "read:self", "cancel", "cancel:self"} + func TestGetSession(t *testing.T) { conn, _ := db.TestSetup(t, "postgres") wrap := db.TestWrapper(t) @@ -86,7 +88,7 @@ func TestGetSession(t *testing.T) { States: []*pb.SessionState{{Status: session.StatusPending.String(), StartTime: sess.CreateTime.GetTimestamp()}}, Certificate: sess.Certificate, Type: target.TcpSubType.String(), - AuthorizedActions: []string{"read", "read:self", "cancel", "cancel:self"}, + AuthorizedActions: testAuthorizedActions, } cases := []struct { @@ -299,7 +301,7 @@ func TestList(t *testing.T) { States: states, Certificate: sess.Certificate, Type: target.TcpSubType.String(), - AuthorizedActions: []string{"read", "read:self", "cancel", "cancel:self"}, + AuthorizedActions: testAuthorizedActions, }) totalSession = append(totalSession, wantSession[i]) @@ -334,7 +336,7 @@ func TestList(t *testing.T) { States: states, Certificate: sess.Certificate, Type: target.TcpSubType.String(), - AuthorizedActions: []string{"read", "read:self", "cancel", "cancel:self"}, + AuthorizedActions: testAuthorizedActions, }) } @@ -477,7 +479,7 @@ func TestCancel(t *testing.T) { Status: session.StatusCanceling.String(), Certificate: sess.Certificate, Type: target.TcpSubType.String(), - AuthorizedActions: []string{"read", "read:self", "cancel", "cancel:self"}, + AuthorizedActions: testAuthorizedActions, } version := wireSess.GetVersion() diff --git a/internal/servers/controller/handlers/targets/target_service.go b/internal/servers/controller/handlers/targets/target_service.go index de3d6e4bcd..8407119c7c 100644 --- a/internal/servers/controller/handlers/targets/target_service.go +++ b/internal/servers/controller/handlers/targets/target_service.go @@ -44,6 +44,7 @@ var ( // IdActions contains the set of actions that can be performed on // individual resources IdActions = action.ActionSet{ + action.NoOp, action.Read, action.Update, action.Delete, diff --git a/internal/servers/controller/handlers/targets/target_service_test.go b/internal/servers/controller/handlers/targets/target_service_test.go index 07e8cff43f..67b79df6fe 100644 --- a/internal/servers/controller/handlers/targets/target_service_test.go +++ b/internal/servers/controller/handlers/targets/target_service_test.go @@ -7,7 +7,6 @@ import ( "strings" "testing" - "github.com/golang/protobuf/ptypes" "github.com/google/go-cmp/cmp" "github.com/hashicorp/boundary/internal/auth" "github.com/hashicorp/boundary/internal/db" @@ -33,9 +32,12 @@ import ( "google.golang.org/protobuf/proto" "google.golang.org/protobuf/testing/protocmp" "google.golang.org/protobuf/types/known/structpb" + "google.golang.org/protobuf/types/known/timestamppb" "google.golang.org/protobuf/types/known/wrapperspb" ) +var testAuthorizedActions = []string{"no-op", "read", "update", "delete", "add-host-sets", "set-host-sets", "remove-host-sets", "authorize-session"} + func testService(t *testing.T, conn *gorm.DB, kms *kms.Kms, wrapper wrapping.Wrapper) (targets.Service, error) { rw := db.New(conn) repoFn := func() (*target.Repository, error) { @@ -86,7 +88,7 @@ func TestGet(t *testing.T) { Attributes: new(structpb.Struct), SessionMaxSeconds: wrapperspb.UInt32(28800), SessionConnectionLimit: wrapperspb.Int32(1), - AuthorizedActions: targets.IdActions.Strings(), + AuthorizedActions: testAuthorizedActions, } for _, ihs := range hs { pTar.HostSets = append(pTar.HostSets, &pb.HostSet{Id: ihs.GetPublicId(), HostCatalogId: ihs.GetCatalogId()}) @@ -178,7 +180,7 @@ func TestList(t *testing.T) { Attributes: new(structpb.Struct), SessionMaxSeconds: wrapperspb.UInt32(28800), SessionConnectionLimit: wrapperspb.Int32(1), - AuthorizedActions: targets.IdActions.Strings(), + AuthorizedActions: testAuthorizedActions, }) totalTars = append(totalTars, wantTars[i]) tar = target.TestTcpTarget(t, conn, otherProj.GetPublicId(), name, target.WithHostSets([]string{otherHss[0].GetPublicId(), otherHss[1].GetPublicId()})) @@ -194,7 +196,7 @@ func TestList(t *testing.T) { Attributes: new(structpb.Struct), SessionMaxSeconds: wrapperspb.UInt32(28800), SessionConnectionLimit: wrapperspb.Int32(1), - AuthorizedActions: targets.IdActions.Strings(), + AuthorizedActions: testAuthorizedActions, }) } @@ -388,7 +390,7 @@ func TestCreate(t *testing.T) { }}, SessionMaxSeconds: wrapperspb.UInt32(28800), SessionConnectionLimit: wrapperspb.Int32(1), - AuthorizedActions: targets.IdActions.Strings(), + AuthorizedActions: testAuthorizedActions, WorkerFilter: wrapperspb.String(`type == "bar"`), }, }, @@ -433,7 +435,7 @@ func TestCreate(t *testing.T) { { name: "Can't specify Created Time", req: &pbs.CreateTargetRequest{Item: &pb.Target{ - CreatedTime: ptypes.TimestampNow(), + CreatedTime: timestamppb.Now(), }}, res: nil, err: handlers.ApiErrorWithCode(codes.InvalidArgument), @@ -441,7 +443,7 @@ func TestCreate(t *testing.T) { { name: "Can't specify Update Time", req: &pbs.CreateTargetRequest{Item: &pb.Target{ - UpdatedTime: ptypes.TimestampNow(), + UpdatedTime: timestamppb.Now(), }}, res: nil, err: handlers.ApiErrorWithCode(codes.InvalidArgument), @@ -531,8 +533,7 @@ func TestUpdate(t *testing.T) { version++ } - hCreated, err := ptypes.Timestamp(tar.GetCreateTime().GetTimestamp()) - require.NoError(t, err, "Failed to convert proto to timestamp") + hCreated := tar.GetCreateTime().GetTimestamp().AsTime() toMerge := &pbs.UpdateTargetRequest{ Id: tar.GetPublicId(), } @@ -576,7 +577,7 @@ func TestUpdate(t *testing.T) { HostSets: hostSets, SessionMaxSeconds: wrapperspb.UInt32(3600), SessionConnectionLimit: wrapperspb.Int32(5), - AuthorizedActions: targets.IdActions.Strings(), + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -608,7 +609,7 @@ func TestUpdate(t *testing.T) { HostSets: hostSets, SessionMaxSeconds: wrapperspb.UInt32(3600), SessionConnectionLimit: wrapperspb.Int32(5), - AuthorizedActions: targets.IdActions.Strings(), + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -693,7 +694,7 @@ func TestUpdate(t *testing.T) { HostSets: hostSets, SessionMaxSeconds: wrapperspb.UInt32(3600), SessionConnectionLimit: wrapperspb.Int32(5), - AuthorizedActions: targets.IdActions.Strings(), + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -724,7 +725,7 @@ func TestUpdate(t *testing.T) { HostSets: hostSets, SessionMaxSeconds: wrapperspb.UInt32(3600), SessionConnectionLimit: wrapperspb.Int32(5), - AuthorizedActions: targets.IdActions.Strings(), + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -755,7 +756,7 @@ func TestUpdate(t *testing.T) { HostSets: hostSets, SessionMaxSeconds: wrapperspb.UInt32(3600), SessionConnectionLimit: wrapperspb.Int32(5), - AuthorizedActions: targets.IdActions.Strings(), + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -798,7 +799,7 @@ func TestUpdate(t *testing.T) { Paths: []string{"created_time"}, }, Item: &pb.Target{ - CreatedTime: ptypes.TimestampNow(), + CreatedTime: timestamppb.Now(), }, }, res: nil, @@ -811,7 +812,7 @@ func TestUpdate(t *testing.T) { Paths: []string{"updated_time"}, }, Item: &pb.Target{ - UpdatedTime: ptypes.TimestampNow(), + UpdatedTime: timestamppb.Now(), }, }, res: nil, @@ -838,8 +839,7 @@ func TestUpdate(t *testing.T) { if got != nil { assert.NotNilf(tc.res, "Expected UpdateHost response to be nil, but was %v", got) - gotUpdateTime, err := ptypes.Timestamp(got.GetItem().GetUpdatedTime()) - require.NoError(err, "Failed to convert proto to timestamp") + gotUpdateTime := got.GetItem().GetUpdatedTime().AsTime() // Verify it is a set updated after it was created // TODO: This is currently failing. assert.True(gotUpdateTime.After(hCreated), "Updated target should have been updated after it's creation. Was updated %v, which is after %v", gotUpdateTime, hCreated) diff --git a/internal/servers/controller/handlers/users/user_service.go b/internal/servers/controller/handlers/users/user_service.go index f6eef1c4ca..9b4d816232 100644 --- a/internal/servers/controller/handlers/users/user_service.go +++ b/internal/servers/controller/handlers/users/user_service.go @@ -30,6 +30,7 @@ var ( // IdActions contains the set of actions that can be performed on // individual resources IdActions = action.ActionSet{ + action.NoOp, action.Read, action.Update, action.Delete, diff --git a/internal/servers/controller/handlers/users/user_service_test.go b/internal/servers/controller/handlers/users/user_service_test.go index 0ce9700206..fd07293a44 100644 --- a/internal/servers/controller/handlers/users/user_service_test.go +++ b/internal/servers/controller/handlers/users/user_service_test.go @@ -32,6 +32,8 @@ import ( "github.com/stretchr/testify/require" ) +var testAuthorizedActions = []string{"no-op", "read", "update", "delete", "add-accounts", "set-accounts", "remove-accounts"} + func createDefaultUserAndRepo(t *testing.T, withAccts bool) (*iam.User, []string, func() (*iam.Repository, error)) { t.Helper() conn, _ := db.TestSetup(t, "postgres") @@ -92,7 +94,7 @@ func TestGet(t *testing.T) { CreatedTime: u.CreateTime.GetTimestamp(), UpdatedTime: u.UpdateTime.GetTimestamp(), Version: u.Version, - AuthorizedActions: []string{"read", "update", "delete", "add-accounts", "set-accounts", "remove-accounts"}, + AuthorizedActions: testAuthorizedActions, LoginName: u.LoginName, FullName: u.GetFullName(), Email: u.GetEmail(), @@ -216,7 +218,7 @@ func TestList(t *testing.T) { CreatedTime: u.GetCreateTime().GetTimestamp(), UpdatedTime: u.GetUpdateTime().GetTimestamp(), Version: 2, - AuthorizedActions: []string{"read", "update", "delete", "add-accounts", "set-accounts", "remove-accounts"}, + AuthorizedActions: testAuthorizedActions, LoginName: oidcAcct.GetSubject(), FullName: oidcAcct.GetFullName(), Email: oidcAcct.GetEmail(), @@ -396,7 +398,7 @@ func TestCreate(t *testing.T) { Name: &wrapperspb.StringValue{Value: "name"}, Description: &wrapperspb.StringValue{Value: "desc"}, Version: 1, - AuthorizedActions: []string{"read", "update", "delete", "add-accounts", "set-accounts", "remove-accounts"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -415,7 +417,7 @@ func TestCreate(t *testing.T) { Name: &wrapperspb.StringValue{Value: "name"}, Description: &wrapperspb.StringValue{Value: "desc"}, Version: 1, - AuthorizedActions: []string{"read", "update", "delete", "add-accounts", "set-accounts", "remove-accounts"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -523,7 +525,7 @@ func TestUpdate(t *testing.T) { Name: &wrapperspb.StringValue{Value: "new"}, Description: &wrapperspb.StringValue{Value: "desc"}, CreatedTime: u.GetCreateTime().GetTimestamp(), - AuthorizedActions: []string{"read", "update", "delete", "add-accounts", "set-accounts", "remove-accounts"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -546,7 +548,7 @@ func TestUpdate(t *testing.T) { Name: &wrapperspb.StringValue{Value: "new"}, Description: &wrapperspb.StringValue{Value: "desc"}, CreatedTime: u.GetCreateTime().GetTimestamp(), - AuthorizedActions: []string{"read", "update", "delete", "add-accounts", "set-accounts", "remove-accounts"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -599,7 +601,7 @@ func TestUpdate(t *testing.T) { Scope: &scopes.ScopeInfo{Id: u.GetScopeId(), Type: scope.Org.String(), ParentScopeId: scope.Global.String()}, Description: &wrapperspb.StringValue{Value: "default"}, CreatedTime: u.GetCreateTime().GetTimestamp(), - AuthorizedActions: []string{"read", "update", "delete", "add-accounts", "set-accounts", "remove-accounts"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -622,7 +624,7 @@ func TestUpdate(t *testing.T) { Name: &wrapperspb.StringValue{Value: "updated"}, Description: &wrapperspb.StringValue{Value: "default"}, CreatedTime: u.GetCreateTime().GetTimestamp(), - AuthorizedActions: []string{"read", "update", "delete", "add-accounts", "set-accounts", "remove-accounts"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -645,7 +647,7 @@ func TestUpdate(t *testing.T) { Name: &wrapperspb.StringValue{Value: "default"}, Description: &wrapperspb.StringValue{Value: "notignored"}, CreatedTime: u.GetCreateTime().GetTimestamp(), - AuthorizedActions: []string{"read", "update", "delete", "add-accounts", "set-accounts", "remove-accounts"}, + AuthorizedActions: testAuthorizedActions, }, }, }, @@ -981,7 +983,8 @@ func TestSetAccount(t *testing.T) { t.Run(tc.name, func(t *testing.T) { usr := iam.TestUser(t, iamRepo, o.GetPublicId()) defer func() { - _, _ = iamRepo.DeleteUser(context.Background(), usr.GetPublicId()) + _, err := iamRepo.DeleteUser(context.Background(), usr.GetPublicId()) + require.NoError(t, err) }() tc.setup(usr) @@ -1060,7 +1063,6 @@ func TestRemoveAccount(t *testing.T) { databaseWrapper, err := kmsCache.GetWrapper(context.Background(), o.PublicId, kms.KeyPurposeDatabase) require.NoError(t, err) - oidcAm := oidc.TestAuthMethod( t, conn, databaseWrapper, o.PublicId, oidc.ActivePrivateState, "alice-rp", "fido", @@ -1143,7 +1145,8 @@ func TestRemoveAccount(t *testing.T) { t.Run(tc.name, func(t *testing.T) { usr := iam.TestUser(t, iamRepo, o.GetPublicId()) defer func() { - _, _ = iamRepo.DeleteUser(context.Background(), usr.GetPublicId()) + _, err := iamRepo.DeleteUser(context.Background(), usr.GetPublicId()) + require.NoError(t, err) }() tc.setup(usr) req := &pbs.RemoveUserAccountsRequest{ diff --git a/internal/types/action/action.go b/internal/types/action/action.go index 1869627d5f..b6edf97f19 100644 --- a/internal/types/action/action.go +++ b/internal/types/action/action.go @@ -40,6 +40,7 @@ const ( ReadSelf Type = 31 CancelSelf Type = 32 ChangeState Type = 33 + NoOp Type = 34 ) var Map = map[string]Type{ @@ -76,6 +77,7 @@ var Map = map[string]Type{ ReadSelf.String(): ReadSelf, CancelSelf.String(): CancelSelf, ChangeState.String(): ChangeState, + NoOp.String(): NoOp, } func (a Type) String() string { @@ -114,6 +116,7 @@ func (a Type) String() string { "read:self", "cancel:self", "change-state", + "no-op", }[a] } diff --git a/internal/types/action/action_test.go b/internal/types/action/action_test.go index 52620acd83..ebd5c6303f 100644 --- a/internal/types/action/action_test.go +++ b/internal/types/action/action_test.go @@ -87,6 +87,10 @@ func TestAction(t *testing.T) { action: ChangeState, want: "change-state", }, + { + action: NoOp, + want: "no-op", + }, } for _, tt := range tests { t.Run(tt.want, func(t *testing.T) { diff --git a/website/content/docs/common-workflows/manage-roles.mdx b/website/content/docs/common-workflows/manage-roles.mdx index 4a0833031d..a9a75dbf7d 100644 --- a/website/content/docs/common-workflows/manage-roles.mdx +++ b/website/content/docs/common-workflows/manage-roles.mdx @@ -139,7 +139,7 @@ In this example we give a role read and list permissions to all resources. ```bash -boundary roles add-grants -id $role_id -grant 'id=*;type=*;actions=read,list' +boundary roles add-grants -id $role_id -grant 'id=*;type=*;actions=no-op,list' Role information: Created Time: Fri, 09 Oct 2020 14:45:47 PDT @@ -162,7 +162,7 @@ Role information: Scope ID: o_1234567890 Canonical Grants: - id=*;type=*;actions=list,read + id=*;type=*;actions=list,no-op ``` diff --git a/website/content/docs/concepts/security/permissions.mdx b/website/content/docs/concepts/security/permissions.mdx index 0760cb5576..6fab029d32 100644 --- a/website/content/docs/concepts/security/permissions.mdx +++ b/website/content/docs/concepts/security/permissions.mdx @@ -36,6 +36,21 @@ level action infers being granted all subactions. Thus, if a grant conveys grant conveys `read:self`, it will match the API action `read:self` but will not match `read`. +## The `no-op` Action + +Starting in Boundary 0.2.1 there is an action that can be granted called +`no-op`. As might be apparent, `no-op` is not used for any real action in +Boundary; the purpose of this action is for listing visibility. Boundary only +shows resources in the output of a `list` action for which a user has at least +one granted action. Thus, without `no-op`, in order for a resource to be visible +in a list, a different action such as `read` would have to be granted to a user. +This could result in exposing more information than desired, especially in the +case of listing scopes and authentication methods so that users can perform +initial authentication to Boundary (that is, granting access to `u_anon`). + +By granting the `no-op` action to users, they can see the resources in the +output of a list command without needing other capability grants as well. + ## Applicable Resource Types Boundary's [domain model](/docs/concepts/domain-model) is based on resource