mirror of https://github.com/hashicorp/boundary
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2183 lines
82 KiB
2183 lines
82 KiB
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
package groups_test
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"slices"
|
|
"testing"
|
|
|
|
"github.com/hashicorp/boundary/globals"
|
|
"github.com/hashicorp/boundary/internal/auth"
|
|
"github.com/hashicorp/boundary/internal/auth/ldap"
|
|
"github.com/hashicorp/boundary/internal/auth/oidc"
|
|
"github.com/hashicorp/boundary/internal/auth/password"
|
|
"github.com/hashicorp/boundary/internal/authtoken"
|
|
cauth "github.com/hashicorp/boundary/internal/daemon/controller/auth"
|
|
"github.com/hashicorp/boundary/internal/daemon/controller/handlers"
|
|
"github.com/hashicorp/boundary/internal/daemon/controller/handlers/groups"
|
|
"github.com/hashicorp/boundary/internal/db"
|
|
pbs "github.com/hashicorp/boundary/internal/gen/controller/api/services"
|
|
"github.com/hashicorp/boundary/internal/iam"
|
|
"github.com/hashicorp/boundary/internal/kms"
|
|
pb "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/groups"
|
|
"github.com/hashicorp/go-uuid"
|
|
"github.com/stretchr/testify/require"
|
|
"google.golang.org/protobuf/types/known/fieldmaskpb"
|
|
"google.golang.org/protobuf/types/known/wrapperspb"
|
|
)
|
|
|
|
func TestGrants_ListGroups(t *testing.T) {
|
|
ctx := context.Background()
|
|
conn, _ := db.TestSetup(t, "postgres")
|
|
rw := db.New(conn)
|
|
wrap := db.TestWrapper(t)
|
|
iamRepo := iam.TestRepo(t, conn, wrap)
|
|
kmsCache := kms.TestKms(t, conn, wrap)
|
|
atRepo, err := authtoken.NewRepository(ctx, rw, rw, kmsCache)
|
|
require.NoError(t, err)
|
|
|
|
repoFn := func() (*iam.Repository, error) {
|
|
return iamRepo, nil
|
|
}
|
|
s, err := groups.NewService(ctx, repoFn, 1000)
|
|
require.NoError(t, err)
|
|
org1, proj1 := iam.TestScopes(t, iamRepo)
|
|
org2, proj2 := iam.TestScopes(t, iamRepo)
|
|
proj3 := iam.TestProject(t, iamRepo, org2.GetPublicId())
|
|
|
|
globalGroup := iam.TestGroup(t, conn, globals.GlobalPrefix, iam.WithDescription("global"), iam.WithName("global"))
|
|
org1Group := iam.TestGroup(t, conn, org1.GetPublicId(), iam.WithDescription("org1"), iam.WithName("org1"))
|
|
org2Group := iam.TestGroup(t, conn, org2.GetPublicId(), iam.WithDescription("org2"), iam.WithName("org2"))
|
|
proj1Group := iam.TestGroup(t, conn, proj1.GetPublicId(), iam.WithDescription("proj1"), iam.WithName("proj1"))
|
|
proj2Group := iam.TestGroup(t, conn, proj2.GetPublicId(), iam.WithDescription("proj2"), iam.WithName("proj2"))
|
|
proj3Group := iam.TestGroup(t, conn, proj3.GetPublicId(), iam.WithDescription("proj3"), iam.WithName("proj3"))
|
|
testcases := []struct {
|
|
name string
|
|
input *pbs.ListGroupsRequest
|
|
userFunc func() (*iam.User, auth.Account)
|
|
wantErr error
|
|
wantIDs []string
|
|
}{
|
|
{
|
|
name: "global role grant this only returns in global groups",
|
|
wantErr: nil,
|
|
input: &pbs.ListGroupsRequest{
|
|
ScopeId: globals.GlobalPrefix,
|
|
Recursive: true,
|
|
},
|
|
userFunc: iam.TestUserDirectGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=*;actions=*"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
wantIDs: []string{globalGroup.PublicId},
|
|
},
|
|
{
|
|
name: "global role grant this and children returns global and org groups",
|
|
input: &pbs.ListGroupsRequest{
|
|
ScopeId: globals.GlobalPrefix,
|
|
Recursive: true,
|
|
},
|
|
userFunc: iam.TestUserDirectGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=list,read"},
|
|
GrantScopes: []string{globals.GrantScopeThis, globals.GrantScopeChildren},
|
|
},
|
|
}),
|
|
wantErr: nil,
|
|
wantIDs: []string{globalGroup.PublicId, org1Group.PublicId, org2Group.PublicId},
|
|
},
|
|
{
|
|
name: "global role grant via managed groups this and children returns org and proj groups",
|
|
input: &pbs.ListGroupsRequest{
|
|
ScopeId: org1.PublicId,
|
|
Recursive: true,
|
|
},
|
|
userFunc: iam.TestUserManagedGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, oidc.TestAuthMethodWithAccountInManagedGroup, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: org1.PublicId,
|
|
Grants: []string{"ids=*;type=group;actions=list,read"},
|
|
GrantScopes: []string{globals.GrantScopeThis, globals.GrantScopeChildren},
|
|
},
|
|
}),
|
|
wantErr: nil,
|
|
wantIDs: []string{org1Group.PublicId, proj1Group.PublicId},
|
|
},
|
|
{
|
|
name: "global role grant this and descendant returns all groups",
|
|
input: &pbs.ListGroupsRequest{
|
|
ScopeId: globals.GlobalPrefix,
|
|
Recursive: true,
|
|
},
|
|
userFunc: iam.TestUserDirectGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=*;actions=*"},
|
|
GrantScopes: []string{globals.GrantScopeThis, globals.GrantScopeDescendants},
|
|
},
|
|
}),
|
|
wantErr: nil,
|
|
wantIDs: []string{globalGroup.PublicId, org1Group.PublicId, org2Group.PublicId, proj1Group.PublicId, proj2Group.PublicId, proj3Group.PublicId},
|
|
},
|
|
{
|
|
name: "org role grant children IDs only org children",
|
|
input: &pbs.ListGroupsRequest{
|
|
ScopeId: org2.PublicId,
|
|
Recursive: true,
|
|
},
|
|
userFunc: iam.TestUserDirectGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=*;actions=*"},
|
|
GrantScopes: []string{globals.GrantScopeDescendants},
|
|
},
|
|
}),
|
|
wantErr: nil,
|
|
wantIDs: []string{org2Group.PublicId, proj2Group.PublicId, proj3Group.PublicId},
|
|
},
|
|
{
|
|
name: "LDAP org role grant children IDs only org children",
|
|
input: &pbs.ListGroupsRequest{
|
|
ScopeId: org2.PublicId,
|
|
Recursive: true,
|
|
},
|
|
userFunc: iam.TestUserManagedGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, ldap.TestAuthMethodWithAccountInManagedGroup, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: org2.PublicId,
|
|
Grants: []string{"ids=*;type=*;actions=*"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
wantErr: nil,
|
|
wantIDs: []string{org2Group.PublicId},
|
|
},
|
|
{
|
|
name: "no list permission returns error",
|
|
input: &pbs.ListGroupsRequest{
|
|
ScopeId: globals.GlobalPrefix,
|
|
Recursive: true,
|
|
},
|
|
userFunc: iam.TestUserDirectGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{
|
|
fmt.Sprintf("ids=%s;types=group;actions=read", proj1Group.PublicId),
|
|
},
|
|
GrantScopes: []string{globals.GrantScopeThis, globals.GrantScopeDescendants},
|
|
},
|
|
}),
|
|
wantErr: handlers.ForbiddenError(),
|
|
wantIDs: nil,
|
|
},
|
|
{
|
|
name: "global role scope specific grants only returns granted scopes",
|
|
input: &pbs.ListGroupsRequest{
|
|
ScopeId: globals.GlobalPrefix,
|
|
Recursive: true,
|
|
},
|
|
userFunc: iam.TestUserDirectGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=read,list"},
|
|
GrantScopes: []string{proj1.PublicId, proj2.PublicId, proj3.PublicId},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=read,list"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
wantErr: nil,
|
|
wantIDs: []string{globalGroup.PublicId, proj1Group.PublicId, proj2Group.PublicId, proj3Group.PublicId},
|
|
},
|
|
{
|
|
name: "global role not granted group resources returns error",
|
|
input: &pbs.ListGroupsRequest{
|
|
ScopeId: globals.GlobalPrefix,
|
|
Recursive: true,
|
|
},
|
|
userFunc: iam.TestUserDirectGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=target;actions=read,list"},
|
|
GrantScopes: []string{globals.GrantScopeThis, globals.GrantScopeDescendants},
|
|
},
|
|
}),
|
|
wantErr: handlers.ForbiddenError(),
|
|
wantIDs: nil,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testcases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
user, account := tc.userFunc()
|
|
tok, err := atRepo.CreateAuthToken(ctx, user, account.GetPublicId())
|
|
require.NoError(t, err)
|
|
fullGrantAuthCtx := cauth.TestAuthContextFromToken(t, conn, wrap, tok, iamRepo)
|
|
got, finalErr := s.ListGroups(fullGrantAuthCtx, tc.input)
|
|
if tc.wantErr != nil {
|
|
require.ErrorIs(t, finalErr, tc.wantErr)
|
|
return
|
|
}
|
|
require.NoError(t, finalErr)
|
|
var gotIDs []string
|
|
for _, g := range got.Items {
|
|
gotIDs = append(gotIDs, g.GetId())
|
|
}
|
|
require.ElementsMatch(t, tc.wantIDs, gotIDs)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGrants_GetGroup(t *testing.T) {
|
|
ctx := context.Background()
|
|
conn, _ := db.TestSetup(t, "postgres")
|
|
rw := db.New(conn)
|
|
wrap := db.TestWrapper(t)
|
|
iamRepo := iam.TestRepo(t, conn, wrap)
|
|
kmsCache := kms.TestKms(t, conn, wrap)
|
|
atRepo, err := authtoken.NewRepository(ctx, rw, rw, kmsCache)
|
|
require.NoError(t, err)
|
|
|
|
repoFn := func() (*iam.Repository, error) {
|
|
return iamRepo, nil
|
|
}
|
|
s, err := groups.NewService(ctx, repoFn, 1000)
|
|
require.NoError(t, err)
|
|
org1, proj1 := iam.TestScopes(t, iamRepo)
|
|
org2, proj2 := iam.TestScopes(t, iamRepo)
|
|
|
|
globalGroup := iam.TestGroup(t, conn, globals.GlobalPrefix, iam.WithDescription("global"), iam.WithName("global"))
|
|
org1Group := iam.TestGroup(t, conn, org1.GetPublicId(), iam.WithDescription("org1"), iam.WithName("org1"))
|
|
org2Group := iam.TestGroup(t, conn, org2.GetPublicId(), iam.WithDescription("org2"), iam.WithName("org2"))
|
|
proj1Group := iam.TestGroup(t, conn, proj1.GetPublicId(), iam.WithDescription("proj1"), iam.WithName("proj1"))
|
|
proj2Group := iam.TestGroup(t, conn, proj2.GetPublicId(), iam.WithDescription("proj2"), iam.WithName("proj2"))
|
|
|
|
testcases := []struct {
|
|
name string
|
|
userFunc func() (*iam.User, auth.Account)
|
|
inputWantErrMap map[*pbs.GetGroupRequest]error
|
|
}{
|
|
{
|
|
name: "global role group grant this scope with all permissions",
|
|
userFunc: iam.TestUserGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=*;actions=*"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
inputWantErrMap: map[*pbs.GetGroupRequest]error{
|
|
{Id: globalGroup.PublicId}: nil,
|
|
{Id: org1Group.PublicId}: handlers.ForbiddenError(),
|
|
{Id: proj1Group.PublicId}: handlers.ForbiddenError(),
|
|
{Id: org2Group.PublicId}: handlers.ForbiddenError(),
|
|
{Id: proj2Group.PublicId}: handlers.ForbiddenError(),
|
|
},
|
|
},
|
|
{
|
|
name: "global role group grant this scope with all permissions",
|
|
userFunc: iam.TestUserGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=*;actions=*"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
inputWantErrMap: map[*pbs.GetGroupRequest]error{
|
|
{Id: globalGroup.PublicId}: nil,
|
|
{Id: org1Group.PublicId}: handlers.ForbiddenError(),
|
|
{Id: proj1Group.PublicId}: handlers.ForbiddenError(),
|
|
{Id: org2Group.PublicId}: handlers.ForbiddenError(),
|
|
{Id: proj2Group.PublicId}: handlers.ForbiddenError(),
|
|
},
|
|
},
|
|
{
|
|
name: "global role grant children scopes with all permissions",
|
|
userFunc: iam.TestUserDirectGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=*;actions=*"},
|
|
GrantScopes: []string{globals.GrantScopeChildren},
|
|
},
|
|
}),
|
|
inputWantErrMap: map[*pbs.GetGroupRequest]error{
|
|
{Id: globalGroup.PublicId}: handlers.ForbiddenError(),
|
|
{Id: org1Group.PublicId}: nil,
|
|
{Id: proj1Group.PublicId}: handlers.ForbiddenError(),
|
|
{Id: org2Group.PublicId}: nil,
|
|
{Id: proj2Group.PublicId}: handlers.ForbiddenError(),
|
|
},
|
|
},
|
|
{
|
|
name: "global role grant descendant scopes with all permissions",
|
|
userFunc: iam.TestUserDirectGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=*;actions=*"},
|
|
GrantScopes: []string{globals.GrantScopeDescendants},
|
|
},
|
|
}),
|
|
inputWantErrMap: map[*pbs.GetGroupRequest]error{
|
|
{Id: globalGroup.PublicId}: handlers.ForbiddenError(),
|
|
{Id: org1Group.PublicId}: nil,
|
|
{Id: proj1Group.PublicId}: nil,
|
|
{Id: org2Group.PublicId}: nil,
|
|
{Id: proj2Group.PublicId}: nil,
|
|
},
|
|
},
|
|
{
|
|
name: "global role grant this and children scopes with all permissions",
|
|
userFunc: iam.TestUserDirectGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=*;actions=*"},
|
|
GrantScopes: []string{globals.GrantScopeThis, globals.GrantScopeChildren},
|
|
},
|
|
}),
|
|
inputWantErrMap: map[*pbs.GetGroupRequest]error{
|
|
{Id: globalGroup.PublicId}: nil,
|
|
{Id: org1Group.PublicId}: nil,
|
|
{Id: proj1Group.PublicId}: handlers.ForbiddenError(),
|
|
{Id: org2Group.PublicId}: nil,
|
|
{Id: proj2Group.PublicId}: handlers.ForbiddenError(),
|
|
},
|
|
},
|
|
{
|
|
name: "global role grant this and descendant scopes with all permissions",
|
|
userFunc: iam.TestUserDirectGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=*;actions=*"},
|
|
GrantScopes: []string{globals.GrantScopeThis, globals.GrantScopeDescendants},
|
|
},
|
|
}),
|
|
inputWantErrMap: map[*pbs.GetGroupRequest]error{
|
|
{Id: globalGroup.PublicId}: nil,
|
|
{Id: org1Group.PublicId}: nil,
|
|
{Id: proj1Group.PublicId}: nil,
|
|
{Id: org2Group.PublicId}: nil,
|
|
{Id: proj2Group.PublicId}: nil,
|
|
},
|
|
},
|
|
{
|
|
name: "org1 role grant this scope with all permissions",
|
|
userFunc: iam.TestUserDirectGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: org1.GetPublicId(),
|
|
Grants: []string{"ids=*;type=*;actions=*"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
inputWantErrMap: map[*pbs.GetGroupRequest]error{
|
|
{Id: globalGroup.PublicId}: handlers.ForbiddenError(),
|
|
{Id: org1Group.PublicId}: nil,
|
|
{Id: proj1Group.PublicId}: handlers.ForbiddenError(),
|
|
{Id: org2Group.PublicId}: handlers.ForbiddenError(),
|
|
{Id: proj2Group.PublicId}: handlers.ForbiddenError(),
|
|
},
|
|
},
|
|
{
|
|
name: "org1 role grant children scope with all permissions",
|
|
userFunc: iam.TestUserDirectGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: org1.GetPublicId(),
|
|
Grants: []string{"ids=*;type=*;actions=*"},
|
|
GrantScopes: []string{globals.GrantScopeChildren},
|
|
},
|
|
}),
|
|
inputWantErrMap: map[*pbs.GetGroupRequest]error{
|
|
{Id: globalGroup.PublicId}: handlers.ForbiddenError(),
|
|
{Id: org1Group.PublicId}: handlers.ForbiddenError(),
|
|
{Id: proj1Group.PublicId}: nil,
|
|
{Id: org2Group.PublicId}: handlers.ForbiddenError(),
|
|
{Id: proj2Group.PublicId}: handlers.ForbiddenError(),
|
|
},
|
|
},
|
|
{
|
|
name: "org1 role grant this and children scopes with all permissions",
|
|
userFunc: iam.TestUserDirectGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: org1.GetPublicId(),
|
|
Grants: []string{"ids=*;type=*;actions=*"},
|
|
GrantScopes: []string{globals.GrantScopeThis, globals.GrantScopeChildren},
|
|
},
|
|
}),
|
|
inputWantErrMap: map[*pbs.GetGroupRequest]error{
|
|
{Id: globalGroup.PublicId}: handlers.ForbiddenError(),
|
|
{Id: org1Group.PublicId}: nil,
|
|
{Id: proj1Group.PublicId}: nil,
|
|
{Id: org2Group.PublicId}: handlers.ForbiddenError(),
|
|
{Id: proj2Group.PublicId}: handlers.ForbiddenError(),
|
|
},
|
|
},
|
|
{
|
|
name: "proj1 role grant this scope with all permissions",
|
|
userFunc: iam.TestUserDirectGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: proj1.GetPublicId(),
|
|
Grants: []string{"ids=*;type=*;actions=*"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
inputWantErrMap: map[*pbs.GetGroupRequest]error{
|
|
{Id: globalGroup.PublicId}: handlers.ForbiddenError(),
|
|
{Id: org1Group.PublicId}: handlers.ForbiddenError(),
|
|
{Id: proj1Group.PublicId}: nil,
|
|
{Id: org2Group.PublicId}: handlers.ForbiddenError(),
|
|
{Id: proj2Group.PublicId}: handlers.ForbiddenError(),
|
|
},
|
|
},
|
|
{
|
|
name: "global role grant this and descendant scope with read permissions on specific group",
|
|
userFunc: iam.TestUserDirectGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{fmt.Sprintf("ids=%s;types=group ;actions=read", org1Group.PublicId)},
|
|
GrantScopes: []string{globals.GrantScopeThis, globals.GrantScopeDescendants},
|
|
},
|
|
}),
|
|
inputWantErrMap: map[*pbs.GetGroupRequest]error{
|
|
{Id: globalGroup.PublicId}: handlers.ForbiddenError(),
|
|
{Id: org1Group.PublicId}: nil,
|
|
{Id: proj1Group.PublicId}: handlers.ForbiddenError(),
|
|
{Id: org2Group.PublicId}: handlers.ForbiddenError(),
|
|
{Id: proj2Group.PublicId}: handlers.ForbiddenError(),
|
|
},
|
|
},
|
|
{
|
|
name: "global role grant this and specific scopes with read permissions on specific group",
|
|
userFunc: iam.TestUserDirectGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{
|
|
fmt.Sprintf("ids=%s;types=group;actions=read", org1Group.PublicId),
|
|
fmt.Sprintf("ids=%s;types=group;actions=read", proj1Group.PublicId),
|
|
},
|
|
GrantScopes: []string{org1.PublicId, proj1.PublicId},
|
|
},
|
|
}),
|
|
inputWantErrMap: map[*pbs.GetGroupRequest]error{
|
|
{Id: globalGroup.PublicId}: handlers.ForbiddenError(),
|
|
{Id: org1Group.PublicId}: nil,
|
|
{Id: proj1Group.PublicId}: nil,
|
|
{Id: org2Group.PublicId}: handlers.ForbiddenError(),
|
|
{Id: proj2Group.PublicId}: handlers.ForbiddenError(),
|
|
},
|
|
},
|
|
{
|
|
name: "union multiple role grant specific resources permissions",
|
|
userFunc: iam.TestUserDirectGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{
|
|
fmt.Sprintf("ids=%s;types=group;actions=read", globalGroup.PublicId),
|
|
},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: org1.GetPublicId(),
|
|
Grants: []string{
|
|
fmt.Sprintf("ids=%s;types=group;actions=read", org1Group.PublicId),
|
|
fmt.Sprintf("ids=%s;types=group;actions=read", proj1Group.PublicId),
|
|
},
|
|
GrantScopes: []string{globals.GrantScopeThis, globals.GrantScopeChildren},
|
|
},
|
|
}),
|
|
inputWantErrMap: map[*pbs.GetGroupRequest]error{
|
|
{Id: globalGroup.PublicId}: nil,
|
|
{Id: org1Group.PublicId}: nil,
|
|
{Id: proj1Group.PublicId}: nil,
|
|
{Id: org2Group.PublicId}: handlers.ForbiddenError(),
|
|
{Id: proj2Group.PublicId}: handlers.ForbiddenError(),
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testcases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
user, account := tc.userFunc()
|
|
tok, err := atRepo.CreateAuthToken(ctx, user, account.GetPublicId())
|
|
require.NoError(t, err)
|
|
fullGrantAuthCtx := cauth.TestAuthContextFromToken(t, conn, wrap, tok, iamRepo)
|
|
for input, wantErr := range tc.inputWantErrMap {
|
|
_, err := s.GetGroup(fullGrantAuthCtx, input)
|
|
// not found means expect error
|
|
if wantErr != nil {
|
|
require.ErrorIs(t, err, wantErr)
|
|
continue
|
|
}
|
|
require.NoError(t, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGrants_CreateGroup(t *testing.T) {
|
|
ctx := context.Background()
|
|
conn, _ := db.TestSetup(t, "postgres")
|
|
rw := db.New(conn)
|
|
wrap := db.TestWrapper(t)
|
|
kmsCache := kms.TestKms(t, conn, wrap)
|
|
iamRepo := iam.TestRepo(t, conn, wrap)
|
|
atRepo, err := authtoken.NewRepository(ctx, rw, rw, kmsCache)
|
|
require.NoError(t, err)
|
|
repoFn := func() (*iam.Repository, error) {
|
|
return iamRepo, nil
|
|
}
|
|
s, err := groups.NewService(ctx, repoFn, 1000)
|
|
require.NoError(t, err)
|
|
|
|
org1, proj1 := iam.TestScopes(t, iamRepo)
|
|
org2, proj2 := iam.TestScopes(t, iamRepo)
|
|
proj3 := iam.TestProject(t, iamRepo, org2.GetPublicId())
|
|
|
|
testcases := []struct {
|
|
name string
|
|
userFunc func() (*iam.User, auth.Account)
|
|
canCreateInScopes map[*pbs.CreateGroupRequest]error
|
|
}{
|
|
{
|
|
name: "direct grant all can create all",
|
|
userFunc: iam.TestUserDirectGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=*;actions=*"},
|
|
GrantScopes: []string{globals.GrantScopeThis, globals.GrantScopeDescendants},
|
|
},
|
|
}),
|
|
canCreateInScopes: map[*pbs.CreateGroupRequest]error{
|
|
{Item: &pb.Group{ScopeId: globals.GlobalPrefix}}: nil,
|
|
{Item: &pb.Group{ScopeId: org1.PublicId}}: nil,
|
|
{Item: &pb.Group{ScopeId: org2.PublicId}}: nil,
|
|
{Item: &pb.Group{ScopeId: proj1.PublicId}}: nil,
|
|
{Item: &pb.Group{ScopeId: proj2.PublicId}}: nil,
|
|
{Item: &pb.Group{ScopeId: proj3.PublicId}}: nil,
|
|
},
|
|
},
|
|
{
|
|
name: "groups grant all can create all",
|
|
userFunc: iam.TestUserGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=*;actions=*"},
|
|
GrantScopes: []string{globals.GrantScopeThis, globals.GrantScopeDescendants},
|
|
},
|
|
}),
|
|
canCreateInScopes: map[*pbs.CreateGroupRequest]error{
|
|
{Item: &pb.Group{ScopeId: globals.GlobalPrefix}}: nil,
|
|
{Item: &pb.Group{ScopeId: org1.PublicId}}: nil,
|
|
{Item: &pb.Group{ScopeId: org2.PublicId}}: nil,
|
|
{Item: &pb.Group{ScopeId: proj1.PublicId}}: nil,
|
|
{Item: &pb.Group{ScopeId: proj2.PublicId}}: nil,
|
|
{Item: &pb.Group{ScopeId: proj3.PublicId}}: nil,
|
|
},
|
|
},
|
|
{
|
|
name: "ldap grant all can create all",
|
|
userFunc: iam.TestUserManagedGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, ldap.TestAuthMethodWithAccountInManagedGroup, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=*;actions=*"},
|
|
GrantScopes: []string{globals.GrantScopeThis, globals.GrantScopeDescendants},
|
|
},
|
|
}),
|
|
canCreateInScopes: map[*pbs.CreateGroupRequest]error{
|
|
{Item: &pb.Group{ScopeId: globals.GlobalPrefix}}: nil,
|
|
{Item: &pb.Group{ScopeId: org1.PublicId}}: nil,
|
|
{Item: &pb.Group{ScopeId: org2.PublicId}}: nil,
|
|
{Item: &pb.Group{ScopeId: proj1.PublicId}}: nil,
|
|
{Item: &pb.Group{ScopeId: proj2.PublicId}}: nil,
|
|
{Item: &pb.Group{ScopeId: proj3.PublicId}}: nil,
|
|
},
|
|
},
|
|
{
|
|
name: "oidc grant all can create all",
|
|
userFunc: iam.TestUserManagedGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, oidc.TestAuthMethodWithAccountInManagedGroup, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=*;actions=*"},
|
|
GrantScopes: []string{globals.GrantScopeThis, globals.GrantScopeDescendants},
|
|
},
|
|
}),
|
|
canCreateInScopes: map[*pbs.CreateGroupRequest]error{
|
|
{Item: &pb.Group{ScopeId: globals.GlobalPrefix}}: nil,
|
|
{Item: &pb.Group{ScopeId: org1.PublicId}}: nil,
|
|
{Item: &pb.Group{ScopeId: org2.PublicId}}: nil,
|
|
{Item: &pb.Group{ScopeId: proj1.PublicId}}: nil,
|
|
{Item: &pb.Group{ScopeId: proj2.PublicId}}: nil,
|
|
{Item: &pb.Group{ScopeId: proj3.PublicId}}: nil,
|
|
},
|
|
},
|
|
{
|
|
name: "grant children can only create in orgs",
|
|
userFunc: iam.TestUserDirectGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=*;actions=*"},
|
|
GrantScopes: []string{globals.GrantScopeChildren},
|
|
},
|
|
}),
|
|
canCreateInScopes: map[*pbs.CreateGroupRequest]error{
|
|
{Item: &pb.Group{ScopeId: globals.GlobalPrefix}}: handlers.ForbiddenError(),
|
|
{Item: &pb.Group{ScopeId: org1.PublicId}}: nil,
|
|
{Item: &pb.Group{ScopeId: org2.PublicId}}: nil,
|
|
{Item: &pb.Group{ScopeId: proj1.PublicId}}: handlers.ForbiddenError(),
|
|
{Item: &pb.Group{ScopeId: proj2.PublicId}}: handlers.ForbiddenError(),
|
|
{Item: &pb.Group{ScopeId: proj3.PublicId}}: handlers.ForbiddenError(),
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testcases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
user, account := tc.userFunc()
|
|
tok, err := atRepo.CreateAuthToken(ctx, user, account.GetPublicId())
|
|
require.NoError(t, err)
|
|
fullGrantAuthCtx := cauth.TestAuthContextFromToken(t, conn, wrap, tok, iamRepo)
|
|
|
|
for req, wantErr := range tc.canCreateInScopes {
|
|
_, err := s.CreateGroup(fullGrantAuthCtx, req)
|
|
if wantErr != nil {
|
|
require.ErrorIs(t, err, wantErr)
|
|
continue
|
|
}
|
|
require.NoError(t, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGrants_DeleteGroup(t *testing.T) {
|
|
ctx := context.Background()
|
|
conn, _ := db.TestSetup(t, "postgres")
|
|
rw := db.New(conn)
|
|
wrap := db.TestWrapper(t)
|
|
iamRepo := iam.TestRepo(t, conn, wrap)
|
|
kmsCache := kms.TestKms(t, conn, wrap)
|
|
repoFn := func() (*iam.Repository, error) {
|
|
return iamRepo, nil
|
|
}
|
|
atRepo, err := authtoken.NewRepository(ctx, rw, rw, kmsCache)
|
|
require.NoError(t, err)
|
|
|
|
s, err := groups.NewService(ctx, repoFn, 1000)
|
|
require.NoError(t, err)
|
|
|
|
org1, proj1 := iam.TestScopes(t, iamRepo)
|
|
org2, proj2 := iam.TestScopes(t, iamRepo)
|
|
proj3 := iam.TestProject(t, iamRepo, org2.GetPublicId())
|
|
|
|
allScopeIds := []string{globals.GlobalPrefix, org1.PublicId, org2.PublicId, proj1.PublicId, proj2.PublicId, proj3.PublicId}
|
|
testcases := []struct {
|
|
name string
|
|
userFunc func() (*iam.User, auth.Account)
|
|
deleteAllowedAtScopeIds []string
|
|
}{
|
|
{
|
|
name: "grant all can delete all",
|
|
userFunc: iam.TestUserDirectGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=*;actions=*"},
|
|
GrantScopes: []string{globals.GrantScopeThis, globals.GrantScopeDescendants},
|
|
},
|
|
}),
|
|
deleteAllowedAtScopeIds: allScopeIds,
|
|
},
|
|
{
|
|
name: "grant children can only delete in orgs",
|
|
userFunc: iam.TestUserDirectGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=*;actions=*"},
|
|
GrantScopes: []string{globals.GrantScopeChildren},
|
|
},
|
|
}),
|
|
deleteAllowedAtScopeIds: []string{org1.PublicId, org2.PublicId},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testcases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
// setup a map to track which scope correlates to a group
|
|
scopeIdGroupMap := map[string]*iam.Group{}
|
|
for _, scp := range allScopeIds {
|
|
g := iam.TestGroup(t, conn, scp)
|
|
scopeIdGroupMap[scp] = g
|
|
}
|
|
user, account := tc.userFunc()
|
|
tok, err := atRepo.CreateAuthToken(ctx, user, account.GetPublicId())
|
|
require.NoError(t, err)
|
|
fullGrantAuthCtx := cauth.TestAuthContextFromToken(t, conn, wrap, tok, iamRepo)
|
|
for scope, group := range scopeIdGroupMap {
|
|
_, err = s.DeleteGroup(fullGrantAuthCtx, &pbs.DeleteGroupRequest{Id: group.PublicId})
|
|
if !slices.Contains(tc.deleteAllowedAtScopeIds, scope) {
|
|
require.ErrorIs(t, err, handlers.ForbiddenError())
|
|
continue
|
|
}
|
|
require.NoErrorf(t, err, "failed to delete group in scope %s", scope)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGrants_UpdateGroup(t *testing.T) {
|
|
testcases := []struct {
|
|
name string
|
|
setupScopesResourcesAndUser func(t *testing.T, conn *db.DB, iamRepo *iam.Repository, kmsCache *kms.Kms) (*iam.Group, func() (*iam.User, auth.Account))
|
|
wantErr error
|
|
}{
|
|
{
|
|
name: "global_scope_group_good_grant_success",
|
|
setupScopesResourcesAndUser: func(t *testing.T, conn *db.DB, iamRepo *iam.Repository, kmsCache *kms.Kms) (*iam.Group, func() (*iam.User, auth.Account)) {
|
|
g := iam.TestGroup(t, conn, globals.GlobalPrefix)
|
|
return g, iam.TestUserDirectGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=*;actions=*"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
})
|
|
},
|
|
wantErr: nil,
|
|
},
|
|
{
|
|
name: "grant specific scope success",
|
|
setupScopesResourcesAndUser: func(t *testing.T, conn *db.DB, iamRepo *iam.Repository, kmsCache *kms.Kms) (*iam.Group, func() (*iam.User, auth.Account)) {
|
|
_, proj := iam.TestScopes(t, iamRepo)
|
|
g := iam.TestGroup(t, conn, proj.PublicId)
|
|
return g, iam.TestUserDirectGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=*;actions=*"},
|
|
GrantScopes: []string{proj.PublicId},
|
|
},
|
|
})
|
|
},
|
|
wantErr: nil,
|
|
},
|
|
{
|
|
name: "grant specific resource and scope success",
|
|
setupScopesResourcesAndUser: func(t *testing.T, conn *db.DB, iamRepo *iam.Repository, kmsCache *kms.Kms) (*iam.Group, func() (*iam.User, auth.Account)) {
|
|
_, proj := iam.TestScopes(t, iamRepo)
|
|
g := iam.TestGroup(t, conn, proj.PublicId)
|
|
return g, iam.TestUserDirectGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{fmt.Sprintf("ids=%s;types=group;actions=*", g.PublicId)},
|
|
GrantScopes: []string{proj.PublicId},
|
|
},
|
|
})
|
|
},
|
|
wantErr: nil,
|
|
},
|
|
{
|
|
name: "no grant fails update",
|
|
setupScopesResourcesAndUser: func(t *testing.T, conn *db.DB, iamRepo *iam.Repository, kmsCache *kms.Kms) (*iam.Group, func() (*iam.User, auth.Account)) {
|
|
g := iam.TestGroup(t, conn, globals.GlobalPrefix)
|
|
return g, iam.TestUserDirectGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=*;actions=*"},
|
|
GrantScopes: []string{globals.GrantScopeChildren},
|
|
},
|
|
})
|
|
},
|
|
wantErr: handlers.ForbiddenError(),
|
|
},
|
|
}
|
|
for _, tc := range testcases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
ctx := context.Background()
|
|
conn, _ := db.TestSetup(t, "postgres")
|
|
rw := db.New(conn)
|
|
wrap := db.TestWrapper(t)
|
|
iamRepo := iam.TestRepo(t, conn, wrap)
|
|
kmsCache := kms.TestKms(t, conn, wrap)
|
|
atRepo, err := authtoken.NewRepository(ctx, rw, rw, kmsCache)
|
|
require.NoError(t, err)
|
|
repoFn := func() (*iam.Repository, error) {
|
|
return iamRepo, nil
|
|
}
|
|
s, err := groups.NewService(ctx, repoFn, 1000)
|
|
require.NoError(t, err)
|
|
original, userFunc := tc.setupScopesResourcesAndUser(t, conn, iamRepo, kmsCache)
|
|
user, account := userFunc()
|
|
tok, err := atRepo.CreateAuthToken(ctx, user, account.GetPublicId())
|
|
require.NoError(t, err)
|
|
fullGrantAuthCtx := cauth.TestAuthContextFromToken(t, conn, wrap, tok, iamRepo)
|
|
got, err := s.UpdateGroup(fullGrantAuthCtx, &pbs.UpdateGroupRequest{
|
|
Id: original.PublicId,
|
|
Item: &pb.Group{
|
|
Name: &wrapperspb.StringValue{Value: "new-name"},
|
|
Description: &wrapperspb.StringValue{Value: "new-description"},
|
|
Version: 1,
|
|
},
|
|
UpdateMask: &fieldmaskpb.FieldMask{
|
|
Paths: []string{"name", "description"},
|
|
},
|
|
})
|
|
if tc.wantErr != nil {
|
|
require.Error(t, err)
|
|
require.ErrorIs(t, err, tc.wantErr)
|
|
return
|
|
}
|
|
require.NoError(t, err)
|
|
require.Equal(t, uint32(2), got.Item.Version)
|
|
require.True(t, got.Item.UpdatedTime.AsTime().After(original.UpdateTime.AsTime()))
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGrants_GroupMembership(t *testing.T) {
|
|
ctx := context.Background()
|
|
conn, _ := db.TestSetup(t, "postgres")
|
|
rw := db.New(conn)
|
|
wrap := db.TestWrapper(t)
|
|
iamRepo := iam.TestRepo(t, conn, wrap)
|
|
kmsCache := kms.TestKms(t, conn, wrap)
|
|
repoFn := func() (*iam.Repository, error) {
|
|
return iamRepo, nil
|
|
}
|
|
atRepo, err := authtoken.NewRepository(ctx, rw, rw, kmsCache)
|
|
require.NoError(t, err)
|
|
s, err := groups.NewService(ctx, repoFn, 1000)
|
|
require.NoError(t, err)
|
|
|
|
org1, _ := iam.TestScopes(t, iamRepo)
|
|
org2, proj2 := iam.TestScopes(t, iamRepo)
|
|
proj3 := iam.TestProject(t, iamRepo, org2.GetPublicId())
|
|
|
|
globalUsers := []*iam.User{iam.TestUser(t, iamRepo, globals.GlobalPrefix), iam.TestUser(t, iamRepo, globals.GlobalPrefix)}
|
|
org1Users := []*iam.User{iam.TestUser(t, iamRepo, org1.PublicId), iam.TestUser(t, iamRepo, org1.PublicId)}
|
|
org2Users := []*iam.User{iam.TestUser(t, iamRepo, org2.PublicId), iam.TestUser(t, iamRepo, org2.PublicId)}
|
|
|
|
type groupGetter interface {
|
|
GetItem() *pb.Group
|
|
}
|
|
|
|
type testActionResult struct {
|
|
action func(context.Context, *iam.Group) (groupGetter, error)
|
|
wantErr error
|
|
}
|
|
|
|
testcases := []struct {
|
|
name string
|
|
userFunc func() *iam.User
|
|
setupGroupAndRole func(t *testing.T) (*iam.Group, func() (*iam.User, auth.Account))
|
|
// collection of actions to be executed in the tests in order, *iam.Group returned from each action which
|
|
// gets passed to the next action as parameter to preserve information such as `version` increments
|
|
actions []testActionResult
|
|
}{
|
|
{
|
|
name: "all actions valid grant success",
|
|
|
|
setupGroupAndRole: func(t *testing.T) (*iam.Group, func() (*iam.User, auth.Account)) {
|
|
group := iam.TestGroup(t, conn, globals.GlobalPrefix)
|
|
return group, iam.TestUserGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=*;actions=*"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
})
|
|
},
|
|
actions: []testActionResult{
|
|
{
|
|
action: func(authCtx context.Context, g *iam.Group) (groupGetter, error) {
|
|
out, err := s.AddGroupMembers(authCtx, &pbs.AddGroupMembersRequest{
|
|
Id: g.PublicId,
|
|
Version: g.Version,
|
|
MemberIds: userIDs(org1Users),
|
|
})
|
|
return out, err
|
|
},
|
|
wantErr: nil,
|
|
},
|
|
{
|
|
action: func(authCtx context.Context, g *iam.Group) (groupGetter, error) {
|
|
out, err := s.SetGroupMembers(authCtx, &pbs.SetGroupMembersRequest{
|
|
Id: g.PublicId,
|
|
Version: g.Version,
|
|
MemberIds: userIDs(globalUsers),
|
|
})
|
|
return out, err
|
|
},
|
|
wantErr: nil,
|
|
},
|
|
{
|
|
action: func(authCtx context.Context, g *iam.Group) (groupGetter, error) {
|
|
out, err := s.RemoveGroupMembers(authCtx, &pbs.RemoveGroupMembersRequest{
|
|
Id: g.PublicId,
|
|
Version: g.Version,
|
|
MemberIds: userIDs(globalUsers),
|
|
})
|
|
return out, err
|
|
},
|
|
wantErr: nil,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "only add and set allowed fail to remove",
|
|
setupGroupAndRole: func(t *testing.T) (*iam.Group, func() (*iam.User, auth.Account)) {
|
|
group := iam.TestGroup(t, conn, org1.PublicId)
|
|
return group, iam.TestUserGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: org1.PublicId,
|
|
Grants: []string{"ids=*;type=*;actions=add-members"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: org1.PublicId,
|
|
Grants: []string{"ids=*;type=*;actions=set-members"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
})
|
|
},
|
|
actions: []testActionResult{
|
|
{
|
|
action: func(authCtx context.Context, g *iam.Group) (groupGetter, error) {
|
|
out, err := s.AddGroupMembers(authCtx, &pbs.AddGroupMembersRequest{
|
|
Id: g.PublicId,
|
|
Version: g.Version,
|
|
MemberIds: userIDs(org1Users),
|
|
})
|
|
return out, err
|
|
},
|
|
wantErr: nil,
|
|
},
|
|
{
|
|
action: func(authCtx context.Context, g *iam.Group) (groupGetter, error) {
|
|
out, err := s.SetGroupMembers(authCtx, &pbs.SetGroupMembersRequest{
|
|
Id: g.PublicId,
|
|
Version: g.Version,
|
|
MemberIds: userIDs(org1Users),
|
|
})
|
|
return out, err
|
|
},
|
|
wantErr: nil,
|
|
},
|
|
{
|
|
action: func(authCtx context.Context, g *iam.Group) (groupGetter, error) {
|
|
out, err := s.RemoveGroupMembers(authCtx, &pbs.RemoveGroupMembersRequest{
|
|
Id: g.PublicId,
|
|
Version: g.Version,
|
|
MemberIds: userIDs(org1Users),
|
|
})
|
|
return out, err
|
|
},
|
|
wantErr: handlers.ForbiddenError(),
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "add_member_valid_specific_grant_success",
|
|
setupGroupAndRole: func(t *testing.T) (*iam.Group, func() (*iam.User, auth.Account)) {
|
|
group := iam.TestGroup(t, conn, org2.PublicId)
|
|
return group, iam.TestUserGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: org2.PublicId,
|
|
Grants: []string{fmt.Sprintf("ids=%s;types=group;actions=add-members", group.PublicId)},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
})
|
|
},
|
|
actions: []testActionResult{
|
|
{
|
|
action: func(authCtx context.Context, g *iam.Group) (groupGetter, error) {
|
|
out, err := s.AddGroupMembers(authCtx, &pbs.AddGroupMembersRequest{
|
|
Id: g.PublicId,
|
|
Version: g.Version,
|
|
MemberIds: userIDs(org2Users),
|
|
})
|
|
return out, err
|
|
},
|
|
wantErr: nil,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "remove_member_valid_specific_grant_success",
|
|
setupGroupAndRole: func(t *testing.T) (*iam.Group, func() (*iam.User, auth.Account)) {
|
|
group := iam.TestGroup(t, conn, proj2.PublicId)
|
|
iam.TestGroupMember(t, conn, group.PublicId, org2Users[0].PublicId)
|
|
iam.TestGroupMember(t, conn, group.PublicId, org2Users[1].PublicId)
|
|
return group, iam.TestUserGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{fmt.Sprintf("ids=%s;types=group;actions=remove-members", group.PublicId)},
|
|
GrantScopes: []string{proj2.PublicId},
|
|
},
|
|
})
|
|
},
|
|
actions: []testActionResult{
|
|
{
|
|
action: func(authCtx context.Context, g *iam.Group) (groupGetter, error) {
|
|
out, err := s.RemoveGroupMembers(authCtx, &pbs.RemoveGroupMembersRequest{
|
|
Id: g.PublicId,
|
|
Version: g.Version,
|
|
MemberIds: userIDs(org2Users),
|
|
})
|
|
return out, err
|
|
},
|
|
wantErr: nil,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "cross_scope_add_member_valid_specific_grant_success",
|
|
setupGroupAndRole: func(t *testing.T) (*iam.Group, func() (*iam.User, auth.Account)) {
|
|
group := iam.TestGroup(t, conn, proj3.PublicId)
|
|
return group, iam.TestUserGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{fmt.Sprintf("ids=%s;types=group;actions=add-members", group.PublicId)},
|
|
GrantScopes: []string{globals.GrantScopeDescendants},
|
|
},
|
|
})
|
|
},
|
|
actions: []testActionResult{
|
|
{
|
|
action: func(authCtx context.Context, g *iam.Group) (groupGetter, error) {
|
|
users := userIDs(org1Users)
|
|
users = append(users, userIDs(org2Users)...)
|
|
out, err := s.AddGroupMembers(authCtx, &pbs.AddGroupMembersRequest{
|
|
Id: g.PublicId,
|
|
Version: g.Version,
|
|
MemberIds: users,
|
|
})
|
|
return out, err
|
|
},
|
|
wantErr: nil,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "add_member_with_valid_grant_string_invalid_scope_forbidden_error",
|
|
setupGroupAndRole: func(t *testing.T) (*iam.Group, func() (*iam.User, auth.Account)) {
|
|
group := iam.TestGroup(t, conn, org2.PublicId)
|
|
return group, iam.TestUserGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=*;actions=*"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
})
|
|
},
|
|
actions: []testActionResult{
|
|
{
|
|
action: func(authCtx context.Context, g *iam.Group) (groupGetter, error) {
|
|
out, err := s.AddGroupMembers(authCtx, &pbs.AddGroupMembersRequest{
|
|
Id: g.PublicId,
|
|
Version: g.Version,
|
|
MemberIds: userIDs(org2Users),
|
|
})
|
|
return out, err
|
|
},
|
|
wantErr: handlers.ForbiddenError(),
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "multiple_grants_success",
|
|
setupGroupAndRole: func(t *testing.T) (*iam.Group, func() (*iam.User, auth.Account)) {
|
|
group := iam.TestGroup(t, conn, proj2.PublicId)
|
|
return group, iam.TestUserGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: proj2.PublicId,
|
|
Grants: []string{fmt.Sprintf("ids=%s;types=group;actions=add-members", group.PublicId)},
|
|
GrantScopes: []string{proj2.PublicId},
|
|
},
|
|
{
|
|
RoleScopeId: proj2.PublicId,
|
|
Grants: []string{fmt.Sprintf("ids=%s;types=group;actions=set-members", group.PublicId)},
|
|
GrantScopes: []string{proj2.PublicId},
|
|
},
|
|
{
|
|
RoleScopeId: proj2.PublicId,
|
|
Grants: []string{fmt.Sprintf("ids=%s;types=group;actions=remove-members", group.PublicId)},
|
|
GrantScopes: []string{proj2.PublicId},
|
|
},
|
|
})
|
|
},
|
|
actions: []testActionResult{
|
|
{
|
|
action: func(authCtx context.Context, g *iam.Group) (groupGetter, error) {
|
|
out, err := s.AddGroupMembers(authCtx, &pbs.AddGroupMembersRequest{
|
|
Id: g.PublicId,
|
|
Version: g.Version,
|
|
MemberIds: userIDs(org2Users),
|
|
})
|
|
return out, err
|
|
},
|
|
wantErr: nil,
|
|
},
|
|
{
|
|
action: func(authCtx context.Context, g *iam.Group) (groupGetter, error) {
|
|
out, err := s.SetGroupMembers(authCtx, &pbs.SetGroupMembersRequest{
|
|
Id: g.PublicId,
|
|
Version: g.Version,
|
|
MemberIds: userIDs(org2Users),
|
|
})
|
|
return out, err
|
|
},
|
|
wantErr: nil,
|
|
},
|
|
{
|
|
action: func(authCtx context.Context, g *iam.Group) (groupGetter, error) {
|
|
out, err := s.RemoveGroupMembers(authCtx, &pbs.RemoveGroupMembersRequest{
|
|
Id: g.PublicId,
|
|
Version: g.Version,
|
|
MemberIds: userIDs(org2Users),
|
|
})
|
|
return out, err
|
|
},
|
|
wantErr: nil,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testcases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
group, userFn := tc.setupGroupAndRole(t)
|
|
user, account := userFn()
|
|
tok, err := atRepo.CreateAuthToken(ctx, user, account.GetPublicId())
|
|
require.NoError(t, err)
|
|
fullGrantAuthCtx := cauth.TestAuthContextFromToken(t, conn, wrap, tok, iamRepo)
|
|
for _, act := range tc.actions {
|
|
out, err := act.action(fullGrantAuthCtx, group)
|
|
if act.wantErr != nil {
|
|
require.Error(t, err)
|
|
require.ErrorIs(t, err, act.wantErr)
|
|
continue
|
|
}
|
|
require.NoError(t, err)
|
|
// set version for future updates
|
|
group.Version = out.GetItem().Version
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestOutputFields_ListGroups(t *testing.T) {
|
|
ctx := context.Background()
|
|
conn, _ := db.TestSetup(t, "postgres")
|
|
rw := db.New(conn)
|
|
wrap := db.TestWrapper(t)
|
|
iamRepo := iam.TestRepo(t, conn, wrap)
|
|
kmsCache := kms.TestKms(t, conn, wrap)
|
|
atRepo, err := authtoken.NewRepository(ctx, rw, rw, kmsCache)
|
|
require.NoError(t, err)
|
|
repoFn := func() (*iam.Repository, error) {
|
|
return iamRepo, nil
|
|
}
|
|
|
|
globalGroup := iam.TestGroup(t, conn, globals.GlobalPrefix, iam.WithDescription("global"), iam.WithName("global"))
|
|
|
|
org, proj := iam.TestScopes(t, iamRepo)
|
|
orgGroup := iam.TestGroup(t, conn, org.PublicId, iam.WithDescription("org"), iam.WithName("org"))
|
|
projGroup := iam.TestGroup(t, conn, proj.PublicId, iam.WithDescription("proj"), iam.WithName("proj"))
|
|
|
|
globalUser := iam.TestUser(t, iamRepo, globals.GlobalPrefix)
|
|
orgUser := iam.TestUser(t, iamRepo, globals.GlobalPrefix)
|
|
projectUser := iam.TestUser(t, iamRepo, globals.GlobalPrefix)
|
|
|
|
_ = iam.TestGroupMember(t, conn, globalGroup.PublicId, globalUser.PublicId)
|
|
_ = iam.TestGroupMember(t, conn, orgGroup.PublicId, orgUser.PublicId)
|
|
_ = iam.TestGroupMember(t, conn, projGroup.PublicId, projectUser.PublicId)
|
|
s, err := groups.NewService(ctx, repoFn, 1000)
|
|
require.NoError(t, err)
|
|
testcases := []struct {
|
|
name string
|
|
userFunc func() (*iam.User, auth.Account)
|
|
// keys are the group IDs | this also means 'id' is required in the outputfields for assertions to work properly
|
|
expectOutfields map[string][]string
|
|
}{
|
|
{
|
|
name: "grants name, version, description",
|
|
userFunc: iam.TestUserDirectGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=id,name,description"},
|
|
GrantScopes: []string{globals.GrantScopeThis, globals.GrantScopeDescendants},
|
|
},
|
|
}),
|
|
expectOutfields: map[string][]string{
|
|
globalGroup.PublicId: {globals.IdField, globals.NameField, globals.DescriptionField},
|
|
orgGroup.PublicId: {globals.IdField, globals.NameField, globals.DescriptionField},
|
|
projGroup.PublicId: {globals.IdField, globals.NameField, globals.DescriptionField},
|
|
},
|
|
},
|
|
{
|
|
name: "grants scope, scopeId, authorized_actions",
|
|
userFunc: iam.TestUserManagedGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, ldap.TestAuthMethodWithAccountInManagedGroup, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=id,scope,scope_id,authorized_actions"},
|
|
GrantScopes: []string{globals.GrantScopeThis, globals.GrantScopeDescendants},
|
|
},
|
|
}),
|
|
expectOutfields: map[string][]string{
|
|
globalGroup.PublicId: {globals.IdField, globals.ScopeField, globals.ScopeIdField, globals.AuthorizedActionsField},
|
|
orgGroup.PublicId: {globals.IdField, globals.ScopeField, globals.ScopeIdField, globals.AuthorizedActionsField},
|
|
projGroup.PublicId: {globals.IdField, globals.ScopeField, globals.ScopeIdField, globals.AuthorizedActionsField},
|
|
},
|
|
},
|
|
{
|
|
name: "grants update_time, create_time",
|
|
userFunc: iam.TestUserManagedGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, oidc.TestAuthMethodWithAccountInManagedGroup, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=id,updated_time,created_time,members,member_ids"},
|
|
GrantScopes: []string{globals.GrantScopeThis, globals.GrantScopeDescendants},
|
|
},
|
|
}),
|
|
expectOutfields: map[string][]string{
|
|
globalGroup.PublicId: {globals.IdField, globals.CreatedTimeField, globals.UpdatedTimeField},
|
|
orgGroup.PublicId: {globals.IdField, globals.CreatedTimeField, globals.UpdatedTimeField},
|
|
projGroup.PublicId: {globals.IdField, globals.CreatedTimeField, globals.UpdatedTimeField},
|
|
},
|
|
},
|
|
{
|
|
name: "different output_fields for different scope",
|
|
userFunc: iam.TestUserDirectGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=id,name,description"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=id,scope,scope_id,created_time,updated_time"},
|
|
GrantScopes: []string{globals.GrantScopeChildren},
|
|
},
|
|
{
|
|
RoleScopeId: proj.PublicId,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=id,authorized_actions"},
|
|
GrantScopes: []string{proj.PublicId},
|
|
},
|
|
}),
|
|
expectOutfields: map[string][]string{
|
|
globalGroup.PublicId: {globals.IdField, globals.NameField, globals.DescriptionField},
|
|
orgGroup.PublicId: {globals.IdField, globals.ScopeField, globals.ScopeIdField, globals.CreatedTimeField, globals.UpdatedTimeField},
|
|
projGroup.PublicId: {globals.IdField, globals.AuthorizedActionsField},
|
|
},
|
|
},
|
|
}
|
|
for _, tc := range testcases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
user, account := tc.userFunc()
|
|
tok, err := atRepo.CreateAuthToken(ctx, user, account.GetPublicId())
|
|
require.NoError(t, err)
|
|
fullGrantAuthCtx := cauth.TestAuthContextFromToken(t, conn, wrap, tok, iamRepo)
|
|
out, err := s.ListGroups(fullGrantAuthCtx, &pbs.ListGroupsRequest{
|
|
ScopeId: globals.GlobalPrefix,
|
|
Recursive: true,
|
|
})
|
|
require.NoError(t, err)
|
|
for _, item := range out.Items {
|
|
handlers.TestAssertOutputFields(t, item, tc.expectOutfields[item.Id])
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestOutputFields_GetGroup(t *testing.T) {
|
|
ctx := context.Background()
|
|
conn, _ := db.TestSetup(t, "postgres")
|
|
rw := db.New(conn)
|
|
wrap := db.TestWrapper(t)
|
|
iamRepo := iam.TestRepo(t, conn, wrap)
|
|
kmsCache := kms.TestKms(t, conn, wrap)
|
|
atRepo, err := authtoken.NewRepository(ctx, rw, rw, kmsCache)
|
|
require.NoError(t, err)
|
|
repoFn := func() (*iam.Repository, error) {
|
|
return iamRepo, nil
|
|
}
|
|
globalGroupWithMember := iam.TestGroup(t, conn, globals.GlobalPrefix, iam.WithDescription("global"), iam.WithName("global"))
|
|
u := iam.TestUser(t, iamRepo, globals.GlobalPrefix)
|
|
_ = iam.TestGroupMember(t, conn, globalGroupWithMember.PublicId, u.PublicId)
|
|
s, err := groups.NewService(ctx, repoFn, 1000)
|
|
require.NoError(t, err)
|
|
|
|
testcases := []struct {
|
|
name string
|
|
userFunc func() (*iam.User, auth.Account)
|
|
expectOutfields []string
|
|
}{
|
|
{
|
|
name: "grants name and description",
|
|
userFunc: iam.TestUserGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=read;output_fields=name,description"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
expectOutfields: []string{globals.NameField, globals.DescriptionField},
|
|
},
|
|
{
|
|
name: "grants scope and scopeId",
|
|
userFunc: iam.TestUserManagedGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, ldap.TestAuthMethodWithAccountInManagedGroup, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=read;output_fields=scope,scope_id"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
expectOutfields: []string{globals.ScopeField, globals.ScopeIdField},
|
|
},
|
|
{
|
|
name: "grants update_time and create_time",
|
|
userFunc: iam.TestUserManagedGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, oidc.TestAuthMethodWithAccountInManagedGroup, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=read;output_fields=updated_time,created_time"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
expectOutfields: []string{globals.UpdatedTimeField, globals.CreatedTimeField},
|
|
},
|
|
{
|
|
name: "grants id, authorized_actions, version",
|
|
userFunc: iam.TestUserGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=read;output_fields=id,authorized_actions,version"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
expectOutfields: []string{globals.IdField, globals.AuthorizedActionsField, globals.VersionField},
|
|
},
|
|
{
|
|
name: "grants members, member_id",
|
|
userFunc: iam.TestUserGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=read;output_fields=members,member_ids"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
expectOutfields: []string{globals.MembersField, globals.MemberIdsField},
|
|
},
|
|
{
|
|
name: "composite grants id, authorized_actions, member_ids",
|
|
userFunc: iam.TestUserGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=read;output_fields=id"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=read;output_fields=member_ids"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=read;output_fields=authorized_actions"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
expectOutfields: []string{globals.IdField, globals.MemberIdsField, globals.AuthorizedActionsField},
|
|
},
|
|
}
|
|
for _, tc := range testcases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
user, account := tc.userFunc()
|
|
tok, err := atRepo.CreateAuthToken(ctx, user, account.GetPublicId())
|
|
require.NoError(t, err)
|
|
fullGrantAuthCtx := cauth.TestAuthContextFromToken(t, conn, wrap, tok, iamRepo)
|
|
out, err := s.GetGroup(fullGrantAuthCtx, &pbs.GetGroupRequest{Id: globalGroupWithMember.PublicId})
|
|
require.NoError(t, err)
|
|
handlers.TestAssertOutputFields(t, out.Item, tc.expectOutfields)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestOutputFields_CreateGroup(t *testing.T) {
|
|
ctx := context.Background()
|
|
conn, _ := db.TestSetup(t, "postgres")
|
|
rw := db.New(conn)
|
|
wrap := db.TestWrapper(t)
|
|
iamRepo := iam.TestRepo(t, conn, wrap)
|
|
kmsCache := kms.TestKms(t, conn, wrap)
|
|
atRepo, err := authtoken.NewRepository(ctx, rw, rw, kmsCache)
|
|
require.NoError(t, err)
|
|
repoFn := func() (*iam.Repository, error) {
|
|
return iamRepo, nil
|
|
}
|
|
genUuid := func() string {
|
|
u, _ := uuid.GenerateUUID()
|
|
return u
|
|
}
|
|
|
|
s, err := groups.NewService(ctx, repoFn, 1000)
|
|
require.NoError(t, err)
|
|
testcases := []struct {
|
|
name string
|
|
userFunc func() (*iam.User, auth.Account)
|
|
input *pbs.CreateGroupRequest
|
|
expectOutfields []string
|
|
}{
|
|
{
|
|
name: "grants name and description",
|
|
input: &pbs.CreateGroupRequest{
|
|
Item: &pb.Group{
|
|
Name: &wrapperspb.StringValue{Value: genUuid()},
|
|
Description: &wrapperspb.StringValue{Value: genUuid()},
|
|
ScopeId: globals.GlobalPrefix,
|
|
},
|
|
},
|
|
userFunc: iam.TestUserGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=name,description"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
expectOutfields: []string{globals.NameField, globals.DescriptionField},
|
|
},
|
|
{
|
|
name: "grants scope and scopeId",
|
|
input: &pbs.CreateGroupRequest{
|
|
Item: &pb.Group{
|
|
Name: &wrapperspb.StringValue{Value: genUuid()},
|
|
Description: &wrapperspb.StringValue{Value: genUuid()},
|
|
ScopeId: globals.GlobalPrefix,
|
|
},
|
|
},
|
|
userFunc: iam.TestUserManagedGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, ldap.TestAuthMethodWithAccountInManagedGroup, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=scope,scope_id"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
expectOutfields: []string{globals.ScopeField, globals.ScopeIdField},
|
|
},
|
|
{
|
|
name: "grants update_time and create_time",
|
|
input: &pbs.CreateGroupRequest{
|
|
Item: &pb.Group{
|
|
Name: &wrapperspb.StringValue{Value: genUuid()},
|
|
Description: &wrapperspb.StringValue{Value: genUuid()},
|
|
ScopeId: globals.GlobalPrefix,
|
|
},
|
|
},
|
|
userFunc: iam.TestUserManagedGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, oidc.TestAuthMethodWithAccountInManagedGroup, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=updated_time,created_time"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
expectOutfields: []string{globals.UpdatedTimeField, globals.CreatedTimeField},
|
|
},
|
|
{
|
|
name: "grants id, authorized_actions, version",
|
|
input: &pbs.CreateGroupRequest{
|
|
Item: &pb.Group{
|
|
Name: &wrapperspb.StringValue{Value: genUuid()},
|
|
Description: &wrapperspb.StringValue{Value: genUuid()},
|
|
ScopeId: globals.GlobalPrefix,
|
|
},
|
|
},
|
|
userFunc: iam.TestUserGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=id,authorized_actions,version"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
expectOutfields: []string{globals.IdField, globals.AuthorizedActionsField, globals.VersionField},
|
|
},
|
|
{
|
|
name: "composite grants all fields",
|
|
input: &pbs.CreateGroupRequest{
|
|
Item: &pb.Group{
|
|
Name: &wrapperspb.StringValue{Value: genUuid()},
|
|
Description: &wrapperspb.StringValue{Value: genUuid()},
|
|
ScopeId: globals.GlobalPrefix,
|
|
},
|
|
},
|
|
userFunc: iam.TestUserGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=id"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=scope"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=scope_id"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=name"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=description"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=created_time"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=authorized_actions"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=version"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
expectOutfields: []string{
|
|
globals.IdField,
|
|
globals.ScopeField,
|
|
globals.ScopeIdField,
|
|
globals.NameField,
|
|
globals.DescriptionField,
|
|
globals.CreatedTimeField,
|
|
globals.AuthorizedActionsField,
|
|
globals.VersionField,
|
|
},
|
|
},
|
|
}
|
|
for _, tc := range testcases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
user, account := tc.userFunc()
|
|
tok, err := atRepo.CreateAuthToken(ctx, user, account.GetPublicId())
|
|
require.NoError(t, err)
|
|
fullGrantAuthCtx := cauth.TestAuthContextFromToken(t, conn, wrap, tok, iamRepo)
|
|
out, err := s.CreateGroup(fullGrantAuthCtx, tc.input)
|
|
require.NoError(t, err)
|
|
handlers.TestAssertOutputFields(t, out.Item, tc.expectOutfields)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestOutputFields_UpdateGroup(t *testing.T) {
|
|
ctx := context.Background()
|
|
conn, _ := db.TestSetup(t, "postgres")
|
|
rw := db.New(conn)
|
|
wrap := db.TestWrapper(t)
|
|
iamRepo := iam.TestRepo(t, conn, wrap)
|
|
kmsCache := kms.TestKms(t, conn, wrap)
|
|
atRepo, err := authtoken.NewRepository(ctx, rw, rw, kmsCache)
|
|
require.NoError(t, err)
|
|
repoFn := func() (*iam.Repository, error) {
|
|
return iamRepo, nil
|
|
}
|
|
|
|
// this can be used across test cases because we're only testing for output fields, not the update behaviors
|
|
inputFunc := func(t *testing.T) *pbs.UpdateGroupRequest {
|
|
name, _ := uuid.GenerateUUID()
|
|
desc, _ := uuid.GenerateUUID()
|
|
globalGroupWithMember := iam.TestGroup(t, conn, globals.GlobalPrefix, iam.WithDescription("global"), iam.WithName("global"))
|
|
u := iam.TestUser(t, iamRepo, globals.GlobalPrefix)
|
|
_ = iam.TestGroupMember(t, conn, globalGroupWithMember.PublicId, u.PublicId)
|
|
return &pbs.UpdateGroupRequest{
|
|
Id: globalGroupWithMember.PublicId,
|
|
Item: &pb.Group{
|
|
Name: &wrapperspb.StringValue{Value: name},
|
|
Description: &wrapperspb.StringValue{Value: desc},
|
|
Version: globalGroupWithMember.Version,
|
|
},
|
|
UpdateMask: &fieldmaskpb.FieldMask{
|
|
Paths: []string{"name", "description"},
|
|
},
|
|
}
|
|
}
|
|
|
|
s, err := groups.NewService(ctx, repoFn, 1000)
|
|
require.NoError(t, err)
|
|
testcases := []struct {
|
|
name string
|
|
userFunc func() (*iam.User, auth.Account)
|
|
expectOutfields []string
|
|
}{
|
|
{
|
|
name: "grants name and description",
|
|
userFunc: iam.TestUserGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=name,description"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
expectOutfields: []string{globals.NameField, globals.DescriptionField},
|
|
},
|
|
{
|
|
name: "grants scope and scopeId",
|
|
userFunc: iam.TestUserManagedGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, ldap.TestAuthMethodWithAccountInManagedGroup, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=scope,scope_id"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
expectOutfields: []string{globals.ScopeField, globals.ScopeIdField},
|
|
},
|
|
{
|
|
name: "grants update_time and create_time",
|
|
|
|
userFunc: iam.TestUserManagedGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, oidc.TestAuthMethodWithAccountInManagedGroup, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=updated_time,created_time"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
expectOutfields: []string{globals.UpdatedTimeField, globals.CreatedTimeField},
|
|
},
|
|
{
|
|
name: "grants id, authorized_actions, version",
|
|
userFunc: iam.TestUserGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=id,authorized_actions,version"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
expectOutfields: []string{globals.IdField, globals.AuthorizedActionsField, globals.VersionField},
|
|
},
|
|
{
|
|
name: "composite grants all fields",
|
|
userFunc: iam.TestUserGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=id"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=scope"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=scope_id"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=name"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=description"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=created_time"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=authorized_actions"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=version"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
expectOutfields: []string{
|
|
globals.IdField,
|
|
globals.ScopeField,
|
|
globals.ScopeIdField,
|
|
globals.NameField,
|
|
globals.DescriptionField,
|
|
globals.CreatedTimeField,
|
|
globals.AuthorizedActionsField,
|
|
globals.VersionField,
|
|
},
|
|
},
|
|
}
|
|
for _, tc := range testcases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
user, account := tc.userFunc()
|
|
tok, err := atRepo.CreateAuthToken(ctx, user, account.GetPublicId())
|
|
require.NoError(t, err)
|
|
fullGrantAuthCtx := cauth.TestAuthContextFromToken(t, conn, wrap, tok, iamRepo)
|
|
out, err := s.UpdateGroup(fullGrantAuthCtx, inputFunc(t))
|
|
require.NoError(t, err)
|
|
handlers.TestAssertOutputFields(t, out.Item, tc.expectOutfields)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestOutputFields_AddGroupMembers(t *testing.T) {
|
|
ctx := context.Background()
|
|
conn, _ := db.TestSetup(t, "postgres")
|
|
rw := db.New(conn)
|
|
wrap := db.TestWrapper(t)
|
|
iamRepo := iam.TestRepo(t, conn, wrap)
|
|
kmsCache := kms.TestKms(t, conn, wrap)
|
|
atRepo, err := authtoken.NewRepository(ctx, rw, rw, kmsCache)
|
|
require.NoError(t, err)
|
|
repoFn := func() (*iam.Repository, error) {
|
|
return iamRepo, nil
|
|
}
|
|
|
|
// this can be used across test cases because we're only testing for output fields, not the update behaviors
|
|
inputFunc := func(t *testing.T) *pbs.AddGroupMembersRequest {
|
|
name, _ := uuid.GenerateUUID()
|
|
desc, _ := uuid.GenerateUUID()
|
|
globalGroupWithMember := iam.TestGroup(t, conn, globals.GlobalPrefix, iam.WithDescription(desc), iam.WithName(name))
|
|
u := iam.TestUser(t, iamRepo, globals.GlobalPrefix)
|
|
return &pbs.AddGroupMembersRequest{
|
|
Id: globalGroupWithMember.PublicId,
|
|
Version: globalGroupWithMember.Version,
|
|
MemberIds: []string{u.PublicId},
|
|
}
|
|
}
|
|
s, err := groups.NewService(ctx, repoFn, 1000)
|
|
require.NoError(t, err)
|
|
testcases := []struct {
|
|
name string
|
|
userFunc func() (*iam.User, auth.Account)
|
|
expectOutfields []string
|
|
}{
|
|
{
|
|
name: "grants name and description",
|
|
userFunc: iam.TestUserGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=name,description"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
expectOutfields: []string{globals.NameField, globals.DescriptionField},
|
|
},
|
|
{
|
|
name: "grants scope and scopeId",
|
|
userFunc: iam.TestUserManagedGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, ldap.TestAuthMethodWithAccountInManagedGroup, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=scope,scope_id"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
expectOutfields: []string{globals.ScopeField, globals.ScopeIdField},
|
|
},
|
|
{
|
|
name: "grants update_time and create_time",
|
|
|
|
userFunc: iam.TestUserManagedGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, oidc.TestAuthMethodWithAccountInManagedGroup, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=updated_time,created_time"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
expectOutfields: []string{globals.UpdatedTimeField, globals.CreatedTimeField},
|
|
},
|
|
{
|
|
name: "grants id, authorized_actions, version",
|
|
userFunc: iam.TestUserGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=id,authorized_actions,version"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
expectOutfields: []string{globals.IdField, globals.AuthorizedActionsField, globals.VersionField},
|
|
},
|
|
{
|
|
name: "composite grants all fields",
|
|
userFunc: iam.TestUserGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=id"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=scope"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=scope_id"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=name"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=description"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=created_time"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=authorized_actions"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=version"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
expectOutfields: []string{
|
|
globals.IdField,
|
|
globals.ScopeField,
|
|
globals.ScopeIdField,
|
|
globals.NameField,
|
|
globals.DescriptionField,
|
|
globals.CreatedTimeField,
|
|
globals.AuthorizedActionsField,
|
|
globals.VersionField,
|
|
},
|
|
},
|
|
}
|
|
for _, tc := range testcases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
user, account := tc.userFunc()
|
|
tok, err := atRepo.CreateAuthToken(ctx, user, account.GetPublicId())
|
|
require.NoError(t, err)
|
|
fullGrantAuthCtx := cauth.TestAuthContextFromToken(t, conn, wrap, tok, iamRepo)
|
|
out, err := s.AddGroupMembers(fullGrantAuthCtx, inputFunc(t))
|
|
require.NoError(t, err)
|
|
handlers.TestAssertOutputFields(t, out.Item, tc.expectOutfields)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestOutputFields_SetGroupMembers(t *testing.T) {
|
|
ctx := context.Background()
|
|
conn, _ := db.TestSetup(t, "postgres")
|
|
rw := db.New(conn)
|
|
wrap := db.TestWrapper(t)
|
|
iamRepo := iam.TestRepo(t, conn, wrap)
|
|
kmsCache := kms.TestKms(t, conn, wrap)
|
|
atRepo, err := authtoken.NewRepository(ctx, rw, rw, kmsCache)
|
|
require.NoError(t, err)
|
|
repoFn := func() (*iam.Repository, error) {
|
|
return iamRepo, nil
|
|
}
|
|
|
|
// this can be used across test cases because we're only testing for output fields, not the update behaviors
|
|
inputFunc := func(t *testing.T) *pbs.SetGroupMembersRequest {
|
|
name, _ := uuid.GenerateUUID()
|
|
desc, _ := uuid.GenerateUUID()
|
|
globalGroupWithMember := iam.TestGroup(t, conn, globals.GlobalPrefix, iam.WithDescription(desc), iam.WithName(name))
|
|
u := iam.TestUser(t, iamRepo, globals.GlobalPrefix)
|
|
return &pbs.SetGroupMembersRequest{
|
|
Id: globalGroupWithMember.PublicId,
|
|
Version: globalGroupWithMember.Version,
|
|
MemberIds: []string{u.PublicId},
|
|
}
|
|
}
|
|
s, err := groups.NewService(ctx, repoFn, 1000)
|
|
require.NoError(t, err)
|
|
testcases := []struct {
|
|
name string
|
|
userFunc func() (*iam.User, auth.Account)
|
|
expectOutfields []string
|
|
}{
|
|
{
|
|
name: "grants name and description",
|
|
userFunc: iam.TestUserGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=name,description"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
expectOutfields: []string{globals.NameField, globals.DescriptionField},
|
|
},
|
|
{
|
|
name: "grants scope and scopeId",
|
|
userFunc: iam.TestUserManagedGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, ldap.TestAuthMethodWithAccountInManagedGroup, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=scope,scope_id"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
expectOutfields: []string{globals.ScopeField, globals.ScopeIdField},
|
|
},
|
|
{
|
|
name: "grants update_time and create_time",
|
|
|
|
userFunc: iam.TestUserManagedGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, oidc.TestAuthMethodWithAccountInManagedGroup, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=updated_time,created_time"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
expectOutfields: []string{globals.UpdatedTimeField, globals.CreatedTimeField},
|
|
},
|
|
{
|
|
name: "grants id, authorized_actions, version",
|
|
userFunc: iam.TestUserGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=id,authorized_actions,version"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
expectOutfields: []string{globals.IdField, globals.AuthorizedActionsField, globals.VersionField},
|
|
},
|
|
{
|
|
name: "composite grants all fields",
|
|
userFunc: iam.TestUserGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=id"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=scope"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=scope_id"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=name"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=description"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=created_time"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=authorized_actions"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=version"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
expectOutfields: []string{
|
|
globals.IdField,
|
|
globals.ScopeField,
|
|
globals.ScopeIdField,
|
|
globals.NameField,
|
|
globals.DescriptionField,
|
|
globals.CreatedTimeField,
|
|
globals.AuthorizedActionsField,
|
|
globals.VersionField,
|
|
},
|
|
},
|
|
}
|
|
for _, tc := range testcases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
user, account := tc.userFunc()
|
|
tok, err := atRepo.CreateAuthToken(ctx, user, account.GetPublicId())
|
|
require.NoError(t, err)
|
|
fullGrantAuthCtx := cauth.TestAuthContextFromToken(t, conn, wrap, tok, iamRepo)
|
|
out, err := s.SetGroupMembers(fullGrantAuthCtx, inputFunc(t))
|
|
require.NoError(t, err)
|
|
handlers.TestAssertOutputFields(t, out.Item, tc.expectOutfields)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestOutputFields_RemoveGroupMembers(t *testing.T) {
|
|
ctx := context.Background()
|
|
conn, _ := db.TestSetup(t, "postgres")
|
|
rw := db.New(conn)
|
|
wrap := db.TestWrapper(t)
|
|
iamRepo := iam.TestRepo(t, conn, wrap)
|
|
kmsCache := kms.TestKms(t, conn, wrap)
|
|
atRepo, err := authtoken.NewRepository(ctx, rw, rw, kmsCache)
|
|
require.NoError(t, err)
|
|
repoFn := func() (*iam.Repository, error) {
|
|
return iamRepo, nil
|
|
}
|
|
|
|
// this can be used across test cases because we're only testing for output fields, not the update behaviors
|
|
inputFunc := func(t *testing.T) *pbs.RemoveGroupMembersRequest {
|
|
name, _ := uuid.GenerateUUID()
|
|
desc, _ := uuid.GenerateUUID()
|
|
globalGroupWithMember := iam.TestGroup(t, conn, globals.GlobalPrefix, iam.WithDescription(desc), iam.WithName(name))
|
|
// create 2 users and remove one so the tests can differentiate between the group without members vs. having no access to read members
|
|
u1 := iam.TestUser(t, iamRepo, globals.GlobalPrefix)
|
|
u2 := iam.TestUser(t, iamRepo, globals.GlobalPrefix)
|
|
_ = iam.TestGroupMember(t, conn, globalGroupWithMember.PublicId, u1.PublicId)
|
|
_ = iam.TestGroupMember(t, conn, globalGroupWithMember.PublicId, u2.PublicId)
|
|
return &pbs.RemoveGroupMembersRequest{
|
|
Id: globalGroupWithMember.PublicId,
|
|
Version: globalGroupWithMember.Version,
|
|
MemberIds: []string{u2.PublicId},
|
|
}
|
|
}
|
|
s, err := groups.NewService(ctx, repoFn, 1000)
|
|
require.NoError(t, err)
|
|
testcases := []struct {
|
|
name string
|
|
userFunc func() (*iam.User, auth.Account)
|
|
expectOutfields []string
|
|
}{
|
|
{
|
|
name: "grants name and description",
|
|
userFunc: iam.TestUserGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=name,description"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
expectOutfields: []string{globals.NameField, globals.DescriptionField},
|
|
},
|
|
{
|
|
name: "grants scope and scopeId",
|
|
userFunc: iam.TestUserManagedGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, ldap.TestAuthMethodWithAccountInManagedGroup, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=scope,scope_id"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
expectOutfields: []string{globals.ScopeField, globals.ScopeIdField},
|
|
},
|
|
{
|
|
name: "grants update_time and create_time",
|
|
|
|
userFunc: iam.TestUserManagedGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, oidc.TestAuthMethodWithAccountInManagedGroup, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=updated_time,created_time"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
expectOutfields: []string{globals.UpdatedTimeField, globals.CreatedTimeField},
|
|
},
|
|
{
|
|
name: "grants id, authorized_actions, version",
|
|
userFunc: iam.TestUserGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=id,authorized_actions,version"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
expectOutfields: []string{globals.IdField, globals.AuthorizedActionsField, globals.VersionField},
|
|
},
|
|
{
|
|
name: "composite grants all fields",
|
|
userFunc: iam.TestUserGroupGrantsFunc(t, conn, kmsCache, globals.GlobalPrefix, password.TestAuthMethodWithAccount, []iam.TestRoleGrantsRequest{
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=id"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=scope"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=scope_id"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=name"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=description"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=created_time"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=authorized_actions"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
{
|
|
RoleScopeId: globals.GlobalPrefix,
|
|
Grants: []string{"ids=*;type=group;actions=*;output_fields=version"},
|
|
GrantScopes: []string{globals.GrantScopeThis},
|
|
},
|
|
}),
|
|
expectOutfields: []string{
|
|
globals.IdField,
|
|
globals.ScopeField,
|
|
globals.ScopeIdField,
|
|
globals.NameField,
|
|
globals.DescriptionField,
|
|
globals.CreatedTimeField,
|
|
globals.AuthorizedActionsField,
|
|
globals.VersionField,
|
|
},
|
|
},
|
|
}
|
|
for _, tc := range testcases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
user, account := tc.userFunc()
|
|
tok, err := atRepo.CreateAuthToken(ctx, user, account.GetPublicId())
|
|
require.NoError(t, err)
|
|
fullGrantAuthCtx := cauth.TestAuthContextFromToken(t, conn, wrap, tok, iamRepo)
|
|
out, err := s.RemoveGroupMembers(fullGrantAuthCtx, inputFunc(t))
|
|
require.NoError(t, err)
|
|
handlers.TestAssertOutputFields(t, out.Item, tc.expectOutfields)
|
|
})
|
|
}
|
|
}
|
|
|
|
func userIDs(users []*iam.User) []string {
|
|
result := make([]string, len(users))
|
|
for i, u := range users {
|
|
result[i] = u.PublicId
|
|
}
|
|
return result
|
|
}
|