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.
1228 lines
37 KiB
1228 lines
37 KiB
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
package ldap
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sort"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/DATA-DOG/go-sqlmock"
|
|
"github.com/hashicorp/boundary/globals"
|
|
"github.com/hashicorp/boundary/internal/auth"
|
|
"github.com/hashicorp/boundary/internal/auth/ldap/store"
|
|
"github.com/hashicorp/boundary/internal/db"
|
|
dbassert "github.com/hashicorp/boundary/internal/db/assert"
|
|
"github.com/hashicorp/boundary/internal/errors"
|
|
"github.com/hashicorp/boundary/internal/iam"
|
|
"github.com/hashicorp/boundary/internal/kms"
|
|
"github.com/hashicorp/boundary/internal/oplog"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestRepository_CreateManagedGroup(t *testing.T) {
|
|
t.Parallel()
|
|
testConn, _ := db.TestSetup(t, "postgres")
|
|
testRw := db.New(testConn)
|
|
testRootWrapper := db.TestWrapper(t)
|
|
|
|
testKms := kms.TestKms(t, testConn, testRootWrapper)
|
|
iamRepo := iam.TestRepo(t, testConn, testRootWrapper)
|
|
org, _ := iam.TestScopes(t, iamRepo)
|
|
|
|
testCtx := context.Background()
|
|
orgDbWrapper, err := testKms.GetWrapper(testCtx, org.PublicId, kms.KeyPurposeDatabase)
|
|
require.NoError(t, err)
|
|
|
|
testAuthMethod := TestAuthMethod(t, testConn, orgDbWrapper, org.GetPublicId(), []string{"ldaps://ldap1"})
|
|
|
|
testRepo, err := NewRepository(testCtx, testRw, testRw, testKms)
|
|
assert.NoError(t, err)
|
|
require.NotNil(t, testRepo)
|
|
|
|
acct1 := TestAccount(t, testConn, testAuthMethod, "alice", WithMemberOfGroups(testCtx, testGrpNames...))
|
|
acct2 := TestAccount(t, testConn, testAuthMethod, "eve", WithMemberOfGroups(testCtx, testGrpNames...))
|
|
const notTestGroupName = "not-test-group-name"
|
|
acct3 := TestAccount(t, testConn, testAuthMethod, "bob", WithMemberOfGroups(testCtx, notTestGroupName))
|
|
|
|
tests := []struct {
|
|
name string
|
|
ctx context.Context
|
|
repo *Repository
|
|
scopeId string
|
|
in *ManagedGroup
|
|
opts []Option
|
|
want *ManagedGroup
|
|
wantMgmAcctIds []string
|
|
wantErrMatch *errors.Template
|
|
wantErrContains string
|
|
}{
|
|
{
|
|
name: "nil-ManagedGroup",
|
|
ctx: testCtx,
|
|
repo: testRepo,
|
|
scopeId: org.GetPublicId(),
|
|
wantErrMatch: errors.T(errors.InvalidParameter),
|
|
wantErrContains: "missing managed group: parameter violation: error #100",
|
|
},
|
|
{
|
|
name: "nil-embedded-ManagedGroup",
|
|
ctx: testCtx,
|
|
repo: testRepo,
|
|
scopeId: org.GetPublicId(),
|
|
in: &ManagedGroup{},
|
|
wantErrMatch: errors.T(errors.InvalidParameter),
|
|
wantErrContains: "missing embedded managed group: parameter violation: error #100",
|
|
},
|
|
{
|
|
name: "invalid-no-auth-method-id",
|
|
ctx: testCtx,
|
|
repo: testRepo,
|
|
scopeId: org.GetPublicId(),
|
|
in: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{},
|
|
},
|
|
wantErrMatch: errors.T(errors.InvalidParameter),
|
|
wantErrContains: "missing auth method id: parameter violation: error #100",
|
|
},
|
|
{
|
|
name: "invalid-no-group-names",
|
|
ctx: testCtx,
|
|
repo: testRepo,
|
|
scopeId: org.GetPublicId(),
|
|
in: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
AuthMethodId: testAuthMethod.PublicId,
|
|
},
|
|
},
|
|
wantErrMatch: errors.T(errors.InvalidParameter),
|
|
wantErrContains: "missing group names: parameter violation: error #100",
|
|
},
|
|
{
|
|
name: "invalid-public-id-set",
|
|
ctx: testCtx,
|
|
repo: testRepo,
|
|
scopeId: org.GetPublicId(),
|
|
in: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
AuthMethodId: testAuthMethod.PublicId,
|
|
GroupNames: string(TestEncodedGrpNames(t, testGrpNames...)),
|
|
PublicId: "mgldap_OOOOOOOOOO",
|
|
},
|
|
},
|
|
wantErrMatch: errors.T(errors.InvalidParameter),
|
|
wantErrContains: "public id must be empty: parameter violation: error #100",
|
|
},
|
|
{
|
|
name: "no-scope",
|
|
ctx: testCtx,
|
|
repo: testRepo,
|
|
in: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
AuthMethodId: testAuthMethod.PublicId,
|
|
GroupNames: string(TestEncodedGrpNames(t, testGrpNames...)),
|
|
},
|
|
},
|
|
wantErrMatch: errors.T(errors.InvalidParameter),
|
|
wantErrContains: "missing scope id: parameter violation: error #100",
|
|
},
|
|
{
|
|
name: "valid-no-options",
|
|
ctx: testCtx,
|
|
repo: testRepo,
|
|
scopeId: org.GetPublicId(),
|
|
in: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
AuthMethodId: testAuthMethod.PublicId,
|
|
GroupNames: string(TestEncodedGrpNames(t, testGrpNames...)),
|
|
},
|
|
},
|
|
want: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
AuthMethodId: testAuthMethod.PublicId,
|
|
GroupNames: string(TestEncodedGrpNames(t, testGrpNames...)),
|
|
},
|
|
},
|
|
wantMgmAcctIds: []string{acct1.PublicId, acct2.PublicId},
|
|
},
|
|
{
|
|
name: "valid-with-name",
|
|
ctx: testCtx,
|
|
repo: testRepo,
|
|
scopeId: org.GetPublicId(),
|
|
in: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
AuthMethodId: testAuthMethod.PublicId,
|
|
GroupNames: string(TestEncodedGrpNames(t, testGrpNames...)),
|
|
Name: "test-name-repo",
|
|
},
|
|
},
|
|
want: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
AuthMethodId: testAuthMethod.PublicId,
|
|
GroupNames: string(TestEncodedGrpNames(t, testGrpNames...)),
|
|
Name: "test-name-repo",
|
|
},
|
|
},
|
|
wantMgmAcctIds: []string{acct1.PublicId, acct2.PublicId},
|
|
},
|
|
{
|
|
name: "valid-with-description",
|
|
ctx: testCtx,
|
|
repo: testRepo,
|
|
scopeId: org.GetPublicId(),
|
|
in: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
AuthMethodId: testAuthMethod.PublicId,
|
|
GroupNames: string(TestEncodedGrpNames(t, testGrpNames...)),
|
|
Description: ("test-description-repo"),
|
|
Name: "myname",
|
|
},
|
|
},
|
|
want: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
AuthMethodId: testAuthMethod.PublicId,
|
|
GroupNames: string(TestEncodedGrpNames(t, testGrpNames...)),
|
|
Description: ("test-description-repo"),
|
|
Name: "myname",
|
|
},
|
|
},
|
|
wantMgmAcctIds: []string{acct1.PublicId, acct2.PublicId},
|
|
},
|
|
{
|
|
name: "not-test-grp-name",
|
|
ctx: testCtx,
|
|
repo: testRepo,
|
|
scopeId: org.GetPublicId(),
|
|
in: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
AuthMethodId: testAuthMethod.PublicId,
|
|
GroupNames: string(TestEncodedGrpNames(t, notTestGroupName)),
|
|
},
|
|
},
|
|
want: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
AuthMethodId: testAuthMethod.PublicId,
|
|
GroupNames: string(TestEncodedGrpNames(t, notTestGroupName)),
|
|
},
|
|
},
|
|
wantMgmAcctIds: []string{acct3.PublicId},
|
|
},
|
|
{
|
|
name: "duplicate-name", // must follow "valid-description" test
|
|
ctx: testCtx,
|
|
repo: testRepo,
|
|
scopeId: org.GetPublicId(),
|
|
in: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
AuthMethodId: testAuthMethod.PublicId,
|
|
GroupNames: string(TestEncodedGrpNames(t, testGrpNames...)),
|
|
Description: ("test-description-repo"),
|
|
Name: "myname",
|
|
},
|
|
},
|
|
wantErrMatch: errors.T(errors.NotUnique),
|
|
wantErrContains: `name "myname" already exists`,
|
|
},
|
|
{
|
|
name: "get-oplog-wrapper-err",
|
|
repo: func() *Repository {
|
|
testKms := &mockGetWrapperer{
|
|
getErr: errors.New(testCtx, errors.Encrypt, "test", "get-oplog-wrapper-err"),
|
|
}
|
|
|
|
testRepo, err := NewRepository(testCtx, testRw, testRw, testKms)
|
|
assert.NoError(t, err)
|
|
require.NotNil(t, testRepo)
|
|
return testRepo
|
|
}(),
|
|
scopeId: org.GetPublicId(),
|
|
in: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
AuthMethodId: testAuthMethod.PublicId,
|
|
GroupNames: string(TestEncodedGrpNames(t, testGrpNames...)),
|
|
},
|
|
},
|
|
wantErrMatch: errors.T(errors.Encrypt),
|
|
wantErrContains: "unable to get oplog wrapper",
|
|
},
|
|
{
|
|
name: "write-err",
|
|
repo: func() *Repository {
|
|
conn, mock := db.TestSetupWithMock(t)
|
|
mock.ExpectBegin()
|
|
mock.ExpectQuery(`SELECT`).WillReturnRows(sqlmock.NewRows([]string{"id", "version"}).AddRow("1", 1)) // oplog: get ticket
|
|
mock.ExpectQuery(`INSERT`).WillReturnError(fmt.Errorf("write-err"))
|
|
mock.ExpectRollback()
|
|
rw := db.New(conn)
|
|
r, err := NewRepository(testCtx, rw, rw, testKms)
|
|
require.NoError(t, err)
|
|
return r
|
|
}(),
|
|
scopeId: org.GetPublicId(),
|
|
in: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
AuthMethodId: testAuthMethod.PublicId,
|
|
GroupNames: string(TestEncodedGrpNames(t, testGrpNames...)),
|
|
},
|
|
},
|
|
wantErrMatch: errors.T(errors.Unknown),
|
|
wantErrContains: "write-err",
|
|
},
|
|
}
|
|
|
|
for _, tc := range tests {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
assert, require := assert.New(t), require.New(t)
|
|
got, err := tc.repo.CreateManagedGroup(tc.ctx, tc.scopeId, tc.in, tc.opts...)
|
|
if tc.wantErrMatch != nil {
|
|
require.Error(err)
|
|
assert.Truef(errors.Match(tc.wantErrMatch, err), "Unexpected error %s", err)
|
|
if tc.wantErrContains != "" {
|
|
assert.True(strings.Contains(err.Error(), tc.wantErrContains))
|
|
}
|
|
return
|
|
}
|
|
require.NoError(err)
|
|
assert.Empty(tc.in.PublicId)
|
|
require.NotNil(got)
|
|
assertPublicId(t, globals.LdapManagedGroupPrefix, got.PublicId)
|
|
assert.NotSame(tc.in, got)
|
|
assert.Equal(tc.want.Name, got.Name)
|
|
assert.Equal(tc.want.Description, got.Description)
|
|
assert.Equal(got.CreateTime, got.UpdateTime)
|
|
assert.Equal(tc.want.GroupNames, got.GroupNames)
|
|
assert.NoError(db.TestVerifyOplog(t, testRw, got.PublicId, db.WithOperation(oplog.OpType_OP_TYPE_CREATE), db.WithCreateNotBefore(10*time.Second)))
|
|
|
|
if tc.wantMgmAcctIds != nil {
|
|
mgmAccts := auth.TestManagedGroupMemberAccounts(t, testConn, got.PublicId)
|
|
for _, m := range mgmAccts {
|
|
t.Log("ManagedGroupId: ", m.ManagedGroupId)
|
|
t.Log(" MemberId: ", m.MemberId)
|
|
}
|
|
wantAccts := make([]*auth.ManagedGroupMemberAccount, 0, len(tc.wantMgmAcctIds))
|
|
for _, id := range tc.wantMgmAcctIds {
|
|
wantAccts = append(wantAccts, &auth.ManagedGroupMemberAccount{
|
|
ManagedGroupId: got.PublicId,
|
|
MemberId: id,
|
|
})
|
|
}
|
|
for _, m := range mgmAccts {
|
|
m.CreateTime = nil
|
|
}
|
|
auth.TestSortManagedGroupMemberAccounts(t, wantAccts)
|
|
assert.Equal(wantAccts, mgmAccts)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRepository_LookupManagedGroup(t *testing.T) {
|
|
t.Parallel()
|
|
testConn, _ := db.TestSetup(t, "postgres")
|
|
testRw := db.New(testConn)
|
|
rootWrapper := db.TestWrapper(t)
|
|
|
|
testKms := kms.TestKms(t, testConn, rootWrapper)
|
|
iamRepo := iam.TestRepo(t, testConn, rootWrapper)
|
|
org, _ := iam.TestScopes(t, iamRepo)
|
|
|
|
testCtx := context.Background()
|
|
orgDbWrapper, err := testKms.GetWrapper(testCtx, org.PublicId, kms.KeyPurposeDatabase)
|
|
require.NoError(t, err)
|
|
|
|
authMethod := TestAuthMethod(t, testConn, orgDbWrapper, org.PublicId, []string{"ldaps://ldap1"})
|
|
mg := TestManagedGroup(t, testConn, authMethod, testGrpNames)
|
|
acct1 := TestAccount(t, testConn, authMethod, "alice", WithMemberOfGroups(testCtx, testGrpNames...))
|
|
acct2 := TestAccount(t, testConn, authMethod, "eve", WithMemberOfGroups(testCtx, testGrpNames...))
|
|
|
|
newMgId, err := newManagedGroupId(testCtx)
|
|
require.NoError(t, err)
|
|
|
|
testRepo, err := NewRepository(testCtx, testRw, testRw, testKms)
|
|
assert.NoError(t, err)
|
|
require.NotNil(t, testRepo)
|
|
|
|
tests := []struct {
|
|
name string
|
|
ctx context.Context
|
|
repo *Repository
|
|
in string
|
|
want *ManagedGroup
|
|
wantMgmAcct []*auth.ManagedGroupMemberAccount
|
|
wantErrMatch *errors.Template
|
|
wantErrContains string
|
|
}{
|
|
{
|
|
name: "With no public id",
|
|
ctx: testCtx,
|
|
repo: testRepo,
|
|
wantErrMatch: errors.T(errors.InvalidParameter),
|
|
wantErrContains: "missing public id: parameter violation",
|
|
},
|
|
{
|
|
name: "With non existing mg id",
|
|
ctx: testCtx,
|
|
repo: testRepo,
|
|
in: newMgId,
|
|
},
|
|
{
|
|
name: "With existing mg id",
|
|
ctx: testCtx,
|
|
repo: testRepo,
|
|
in: mg.GetPublicId(),
|
|
want: mg,
|
|
wantMgmAcct: []*auth.ManagedGroupMemberAccount{
|
|
{
|
|
CreateTime: mg.CreateTime,
|
|
ManagedGroupId: mg.PublicId,
|
|
MemberId: acct1.PublicId,
|
|
},
|
|
{
|
|
CreateTime: mg.CreateTime,
|
|
ManagedGroupId: mg.PublicId,
|
|
MemberId: acct2.PublicId,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "read-err",
|
|
repo: func() *Repository {
|
|
conn, mock := db.TestSetupWithMock(t)
|
|
mock.ExpectQuery(`SELECT`).WillReturnError(fmt.Errorf("read-err"))
|
|
rw := db.New(conn)
|
|
r, err := NewRepository(testCtx, rw, rw, testKms)
|
|
require.NoError(t, err)
|
|
return r
|
|
}(),
|
|
in: mg.GetPublicId(),
|
|
wantErrMatch: errors.T(errors.Unknown),
|
|
wantErrContains: "read-err",
|
|
},
|
|
}
|
|
|
|
for _, tc := range tests {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
assert, require := assert.New(t), require.New(t)
|
|
got, err := tc.repo.LookupManagedGroup(tc.ctx, tc.in)
|
|
if tc.wantErrMatch != nil {
|
|
assert.Truef(errors.Match(tc.wantErrMatch, err), "Unexpected error %s", err)
|
|
if tc.wantErrContains != "" {
|
|
assert.Contains(err.Error(), tc.wantErrContains)
|
|
}
|
|
return
|
|
}
|
|
require.NoError(err)
|
|
assert.EqualValues(tc.want, got)
|
|
if tc.wantMgmAcct != nil {
|
|
mgmAccts := auth.TestManagedGroupMemberAccounts(t, testConn, tc.want.PublicId)
|
|
for _, m := range mgmAccts {
|
|
t.Log("ManagedGroupId: ", m.ManagedGroupId)
|
|
t.Log(" MemberId: ", m.MemberId)
|
|
}
|
|
auth.TestSortManagedGroupMemberAccounts(t, tc.wantMgmAcct)
|
|
assert.Equal(tc.wantMgmAcct, mgmAccts)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRepository_DeleteManagedGroup(t *testing.T) {
|
|
t.Parallel()
|
|
testConn, _ := db.TestSetup(t, "postgres")
|
|
testRw := db.New(testConn)
|
|
testWrapper := db.TestWrapper(t)
|
|
|
|
testCtx := context.Background()
|
|
testKms := kms.TestKms(t, testConn, testWrapper)
|
|
iamRepo := iam.TestRepo(t, testConn, testWrapper)
|
|
org, _ := iam.TestScopes(t, iamRepo)
|
|
|
|
orgDbWrapper, err := testKms.GetWrapper(testCtx, org.PublicId, kms.KeyPurposeDatabase)
|
|
require.NoError(t, err)
|
|
authMethod := TestAuthMethod(t, testConn, orgDbWrapper, org.PublicId, []string{"ldaps://ldap1"})
|
|
|
|
mg := TestManagedGroup(t, testConn, authMethod, testGrpNames)
|
|
newMgId, err := newManagedGroupId(testCtx)
|
|
require.NoError(t, err)
|
|
|
|
testRepo, err := NewRepository(testCtx, testRw, testRw, testKms)
|
|
assert.NoError(t, err)
|
|
require.NotNil(t, testRepo)
|
|
|
|
tests := []struct {
|
|
name string
|
|
ctx context.Context
|
|
repo *Repository
|
|
scopeId string
|
|
in string
|
|
want int
|
|
wantErrMatch *errors.Template
|
|
wantErrContains string
|
|
}{
|
|
{
|
|
name: "With no scope id",
|
|
ctx: testCtx,
|
|
repo: testRepo,
|
|
scopeId: "",
|
|
in: mg.GetPublicId(),
|
|
wantErrMatch: errors.T(errors.InvalidParameter),
|
|
wantErrContains: "missing scope id: parameter violation: error #100",
|
|
},
|
|
{
|
|
name: "With no public id",
|
|
ctx: testCtx,
|
|
repo: testRepo,
|
|
scopeId: org.GetPublicId(),
|
|
wantErrMatch: errors.T(errors.InvalidParameter),
|
|
wantErrContains: "missing public id: parameter violation: error #100",
|
|
},
|
|
{
|
|
name: "With non existing managed group id",
|
|
ctx: testCtx,
|
|
repo: testRepo,
|
|
scopeId: org.GetPublicId(),
|
|
in: newMgId,
|
|
wantErrMatch: errors.T(errors.RecordNotFound),
|
|
wantErrContains: "managed group not found",
|
|
},
|
|
{
|
|
name: "get-oplog-wrapper-err",
|
|
repo: func() *Repository {
|
|
testKms := &mockGetWrapperer{
|
|
getErr: errors.New(testCtx, errors.Encrypt, "test", "get-oplog-wrapper-err"),
|
|
}
|
|
|
|
testRepo, err := NewRepository(testCtx, testRw, testRw, testKms)
|
|
assert.NoError(t, err)
|
|
require.NotNil(t, testRepo)
|
|
return testRepo
|
|
}(),
|
|
scopeId: org.GetPublicId(),
|
|
in: mg.GetPublicId(),
|
|
wantErrMatch: errors.T(errors.Encrypt),
|
|
wantErrContains: "unable to get oplog wrapper",
|
|
},
|
|
{
|
|
name: "too-many-rows-affected",
|
|
repo: func() *Repository {
|
|
conn, mock := db.TestSetupWithMock(t)
|
|
mock.ExpectQuery(`SELECT`).WillReturnRows(sqlmock.NewRows([]string{"id", "scope_id", "auth_method_id"}).AddRow("1", "global", "1")) // get account
|
|
mock.ExpectBegin()
|
|
mock.ExpectQuery(`SELECT`).WillReturnRows(sqlmock.NewRows([]string{"id", "version"}).AddRow("1", 1)) // oplog: get ticket
|
|
mock.ExpectExec(`DELETE`).WillReturnResult(sqlmock.NewResult(1, 2))
|
|
mock.ExpectQuery(`INSERT`).WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow("1")) // oplog: entry
|
|
mock.ExpectQuery(`INSERT`).WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow("1")) // oplog: metadata
|
|
mock.ExpectExec(`UPDATE`).WillReturnResult(sqlmock.NewResult(0, 1)) // oplog: update ticket version
|
|
mock.ExpectQuery(`SELECT`).WillReturnRows(sqlmock.NewRows([]string{"id", "version"}).AddRow("1", 1)) // oplog: get ticket
|
|
|
|
mock.ExpectRollback()
|
|
rw := db.New(conn)
|
|
r, err := NewRepository(testCtx, rw, rw, testKms)
|
|
require.NoError(t, err)
|
|
return r
|
|
}(),
|
|
scopeId: org.GetPublicId(),
|
|
in: mg.GetPublicId(),
|
|
wantErrMatch: errors.T(errors.Unknown),
|
|
wantErrContains: "more than 1 resource would have been deleted",
|
|
},
|
|
{
|
|
name: "delete-err",
|
|
repo: func() *Repository {
|
|
conn, mock := db.TestSetupWithMock(t)
|
|
mock.ExpectQuery(`SELECT`).WillReturnRows(sqlmock.NewRows([]string{"id", "scope_id", "auth_method_id"}).AddRow("1", "global", "1")) // get account
|
|
mock.ExpectBegin()
|
|
mock.ExpectQuery(`SELECT`).WillReturnRows(sqlmock.NewRows([]string{"id", "version"}).AddRow("1", 1)) // oplog: get ticket
|
|
mock.ExpectExec(`DELETE`).WillReturnError(fmt.Errorf("delete-err"))
|
|
mock.ExpectRollback()
|
|
rw := db.New(conn)
|
|
r, err := NewRepository(testCtx, rw, rw, testKms)
|
|
require.NoError(t, err)
|
|
return r
|
|
}(),
|
|
scopeId: org.GetPublicId(),
|
|
in: mg.GetPublicId(),
|
|
wantErrMatch: errors.T(errors.Unknown),
|
|
wantErrContains: "delete-err",
|
|
},
|
|
{
|
|
name: "oplog-metadata-err",
|
|
repo: func() *Repository {
|
|
conn, mock := db.TestSetupWithMock(t)
|
|
mock.ExpectQuery(`SELECT`).WillReturnRows(sqlmock.NewRows([]string{"id", "scope_id"}).AddRow("1", "global")) // get account without auth method id
|
|
rw := db.New(conn)
|
|
r, err := NewRepository(testCtx, rw, rw, testKms)
|
|
require.NoError(t, err)
|
|
return r
|
|
}(),
|
|
scopeId: org.GetPublicId(),
|
|
in: mg.GetPublicId(),
|
|
wantErrMatch: errors.T(errors.Unknown),
|
|
wantErrContains: "unable to generate oplog metadata",
|
|
},
|
|
{
|
|
name: "With existing managed group id",
|
|
ctx: testCtx,
|
|
repo: testRepo,
|
|
scopeId: org.GetPublicId(),
|
|
in: mg.GetPublicId(),
|
|
want: 1,
|
|
},
|
|
}
|
|
for _, tc := range tests {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
assert, require := assert.New(t), require.New(t)
|
|
got, err := tc.repo.DeleteManagedGroup(context.Background(), tc.scopeId, tc.in)
|
|
if tc.wantErrMatch != nil {
|
|
assert.Truef(errors.Match(tc.wantErrMatch, err), "Unexpected error %s", err)
|
|
if tc.wantErrContains != "" {
|
|
assert.Contains(err.Error(), tc.wantErrContains)
|
|
}
|
|
return
|
|
}
|
|
require.NoError(err)
|
|
assert.EqualValues(tc.want, got)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRepository_ListManagedGroups(t *testing.T) {
|
|
t.Parallel()
|
|
testConn, _ := db.TestSetup(t, "postgres")
|
|
testRw := db.New(testConn)
|
|
testRootWrapper := db.TestWrapper(t)
|
|
|
|
testCtx := context.Background()
|
|
testKms := kms.TestKms(t, testConn, testRootWrapper)
|
|
iamRepo := iam.TestRepo(t, testConn, testRootWrapper)
|
|
org, _ := iam.TestScopes(t, iamRepo)
|
|
|
|
orgDbWrapper, err := testKms.GetWrapper(testCtx, org.PublicId, kms.KeyPurposeDatabase)
|
|
require.NoError(t, err)
|
|
authMethod1 := TestAuthMethod(t, testConn, orgDbWrapper, org.PublicId, []string{"ldaps://ldap1"})
|
|
authMethod2 := TestAuthMethod(t, testConn, orgDbWrapper, org.PublicId, []string{"ldaps://ldap2"})
|
|
authMethod3 := TestAuthMethod(t, testConn, orgDbWrapper, org.PublicId, []string{"ldaps://ldap3"})
|
|
|
|
mgs1 := []*ManagedGroup{
|
|
TestManagedGroup(t, testConn, authMethod1, testGrpNames),
|
|
TestManagedGroup(t, testConn, authMethod1, testGrpNames),
|
|
TestManagedGroup(t, testConn, authMethod1, testGrpNames),
|
|
}
|
|
sort.Slice(mgs1, func(i, j int) bool {
|
|
return strings.Compare(mgs1[i].PublicId, mgs1[j].PublicId) < 0
|
|
})
|
|
|
|
mgs2 := []*ManagedGroup{
|
|
TestManagedGroup(t, testConn, authMethod2, testGrpNames),
|
|
TestManagedGroup(t, testConn, authMethod2, testGrpNames),
|
|
TestManagedGroup(t, testConn, authMethod2, testGrpNames),
|
|
}
|
|
sort.Slice(mgs2, func(i, j int) bool {
|
|
return strings.Compare(mgs2[i].PublicId, mgs2[j].PublicId) < 0
|
|
})
|
|
|
|
testRepo, err := NewRepository(testCtx, testRw, testRw, testKms)
|
|
assert.NoError(t, err)
|
|
require.NotNil(t, testRepo)
|
|
|
|
tests := []struct {
|
|
name string
|
|
ctx context.Context
|
|
repo *Repository
|
|
in string
|
|
opts []Option
|
|
want []*ManagedGroup
|
|
wantErrMatch *errors.Template
|
|
wantErrContains string
|
|
}{
|
|
{
|
|
name: "With no auth method id",
|
|
ctx: testCtx,
|
|
repo: testRepo,
|
|
wantErrMatch: errors.T(errors.InvalidParameter),
|
|
wantErrContains: "missing auth method id: parameter violation: error #100",
|
|
},
|
|
{
|
|
name: "With no managed groups",
|
|
ctx: testCtx,
|
|
repo: testRepo,
|
|
in: authMethod3.GetPublicId(),
|
|
want: []*ManagedGroup{},
|
|
},
|
|
{
|
|
name: "With first auth method id",
|
|
ctx: testCtx,
|
|
repo: testRepo,
|
|
in: authMethod1.GetPublicId(),
|
|
want: mgs1,
|
|
},
|
|
{
|
|
name: "With first auth method id",
|
|
ctx: testCtx,
|
|
repo: testRepo,
|
|
in: authMethod2.GetPublicId(),
|
|
want: mgs2,
|
|
},
|
|
{
|
|
name: "read-err",
|
|
repo: func() *Repository {
|
|
conn, mock := db.TestSetupWithMock(t)
|
|
mock.ExpectQuery(`SELECT`).WillReturnError(fmt.Errorf("read-err"))
|
|
rw := db.New(conn)
|
|
r, err := NewRepository(testCtx, rw, rw, testKms)
|
|
require.NoError(t, err)
|
|
return r
|
|
}(),
|
|
in: authMethod1.GetPublicId(),
|
|
wantErrMatch: errors.T(errors.Unknown),
|
|
wantErrContains: "read-err",
|
|
},
|
|
}
|
|
|
|
for _, tc := range tests {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
assert, require := assert.New(t), require.New(t)
|
|
got, err := tc.repo.ListManagedGroups(tc.ctx, tc.in, tc.opts...)
|
|
if tc.wantErrMatch != nil {
|
|
require.Error(err)
|
|
assert.Truef(errors.Match(tc.wantErrMatch, err), "Unexpected error %s", err)
|
|
if tc.wantErrContains != "" {
|
|
assert.Contains(err.Error(), tc.wantErrContains)
|
|
}
|
|
return
|
|
}
|
|
require.NoError(err)
|
|
|
|
sort.Slice(got, func(i, j int) bool {
|
|
return strings.Compare(got[i].PublicId, got[j].PublicId) < 0
|
|
})
|
|
assert.EqualValues(tc.want, got)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRepository_ListManagedGroups_Limits(t *testing.T) {
|
|
t.Parallel()
|
|
testConn, _ := db.TestSetup(t, "postgres")
|
|
testRw := db.New(testConn)
|
|
testRootWrapper := db.TestWrapper(t)
|
|
|
|
testCtx := context.Background()
|
|
testKms := kms.TestKms(t, testConn, testRootWrapper)
|
|
iamRepo := iam.TestRepo(t, testConn, testRootWrapper)
|
|
org, _ := iam.TestScopes(t, iamRepo)
|
|
|
|
orgDbWrapper, err := testKms.GetWrapper(testCtx, org.PublicId, kms.KeyPurposeDatabase)
|
|
require.NoError(t, err)
|
|
|
|
am := TestAuthMethod(t, testConn, orgDbWrapper, org.PublicId, []string{"ldaps://ldap1"})
|
|
mgCount := 10
|
|
for i := 0; i < mgCount; i++ {
|
|
TestManagedGroup(t, testConn, am, testGrpNames)
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
repoOpts []Option
|
|
listOpts []Option
|
|
wantLen int
|
|
}{
|
|
{
|
|
name: "With no limits",
|
|
wantLen: mgCount,
|
|
},
|
|
{
|
|
name: "With repo limit",
|
|
repoOpts: []Option{WithLimit(testCtx, 3)},
|
|
wantLen: 3,
|
|
},
|
|
{
|
|
name: "With negative repo limit",
|
|
repoOpts: []Option{WithLimit(testCtx, -1)},
|
|
wantLen: mgCount,
|
|
},
|
|
{
|
|
name: "With List limit",
|
|
listOpts: []Option{WithLimit(testCtx, 3)},
|
|
wantLen: 3,
|
|
},
|
|
{
|
|
name: "With negative List limit",
|
|
listOpts: []Option{WithLimit(testCtx, -1)},
|
|
wantLen: mgCount,
|
|
},
|
|
{
|
|
name: "With repo smaller than list limit",
|
|
repoOpts: []Option{WithLimit(testCtx, 2)},
|
|
listOpts: []Option{WithLimit(testCtx, 6)},
|
|
wantLen: 6,
|
|
},
|
|
{
|
|
name: "With repo larger than list limit",
|
|
repoOpts: []Option{WithLimit(testCtx, 6)},
|
|
listOpts: []Option{WithLimit(testCtx, 2)},
|
|
wantLen: 2,
|
|
},
|
|
}
|
|
for _, tc := range tests {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
assert, require := assert.New(t), require.New(t)
|
|
repo, err := NewRepository(testCtx, testRw, testRw, testKms, tc.repoOpts...)
|
|
assert.NoError(err)
|
|
require.NotNil(repo)
|
|
got, err := repo.ListManagedGroups(context.Background(), am.GetPublicId(), tc.listOpts...)
|
|
require.NoError(err)
|
|
assert.Len(got, tc.wantLen)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRepository_UpdateManagedGroup(t *testing.T) {
|
|
t.Parallel()
|
|
testCtx := context.Background()
|
|
testConn, _ := db.TestSetup(t, "postgres")
|
|
testRw := db.New(testConn)
|
|
testRootWrapper := db.TestWrapper(t)
|
|
testKms := kms.TestKms(t, testConn, testRootWrapper)
|
|
iamRepo := iam.TestRepo(t, testConn, testRootWrapper)
|
|
org, _ := iam.TestScopes(t, iamRepo)
|
|
|
|
orgDbWrapper, err := testKms.GetWrapper(testCtx, org.PublicId, kms.KeyPurposeDatabase)
|
|
require.NoError(t, err)
|
|
am := TestAuthMethod(t, testConn, orgDbWrapper, org.PublicId, []string{"ldaps://ldap1"})
|
|
|
|
testRepo, err := NewRepository(testCtx, testRw, testRw, testKms)
|
|
assert.NoError(t, err)
|
|
require.NotNil(t, testRepo)
|
|
|
|
changeName := func(s string) func(*ManagedGroup) *ManagedGroup {
|
|
return func(mg *ManagedGroup) *ManagedGroup {
|
|
mg.Name = s
|
|
return mg
|
|
}
|
|
}
|
|
|
|
changeDescription := func(s string) func(*ManagedGroup) *ManagedGroup {
|
|
return func(mg *ManagedGroup) *ManagedGroup {
|
|
mg.Description = s
|
|
return mg
|
|
}
|
|
}
|
|
|
|
changeGrpNames := func(s string) func(*ManagedGroup) *ManagedGroup {
|
|
return func(mg *ManagedGroup) *ManagedGroup {
|
|
mg.GroupNames = s
|
|
return mg
|
|
}
|
|
}
|
|
|
|
makeNil := func() func(*ManagedGroup) *ManagedGroup {
|
|
return func(mg *ManagedGroup) *ManagedGroup {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
makeEmbeddedNil := func() func(*ManagedGroup) *ManagedGroup {
|
|
return func(mg *ManagedGroup) *ManagedGroup {
|
|
return &ManagedGroup{}
|
|
}
|
|
}
|
|
|
|
deletePublicId := func() func(*ManagedGroup) *ManagedGroup {
|
|
return func(mg *ManagedGroup) *ManagedGroup {
|
|
mg.PublicId = ""
|
|
return mg
|
|
}
|
|
}
|
|
|
|
nonExistentPublicId := func() func(*ManagedGroup) *ManagedGroup {
|
|
return func(mg *ManagedGroup) *ManagedGroup {
|
|
mg.PublicId = "abcd_OOOOOOOOOO"
|
|
return mg
|
|
}
|
|
}
|
|
|
|
combine := func(fns ...func(mg *ManagedGroup) *ManagedGroup) func(*ManagedGroup) *ManagedGroup {
|
|
return func(mg *ManagedGroup) *ManagedGroup {
|
|
for _, fn := range fns {
|
|
mg = fn(mg)
|
|
}
|
|
return mg
|
|
}
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
repo *Repository
|
|
scopeId string
|
|
version uint32
|
|
orig *ManagedGroup
|
|
chgFn func(*ManagedGroup) *ManagedGroup
|
|
masks []string
|
|
want *ManagedGroup
|
|
wantCount int
|
|
wantErrMatch *errors.Template
|
|
wantErrContains string
|
|
}{
|
|
{
|
|
name: "nil-ManagedGroup",
|
|
repo: testRepo,
|
|
scopeId: org.GetPublicId(),
|
|
version: 1,
|
|
orig: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{},
|
|
},
|
|
chgFn: makeNil(),
|
|
masks: []string{NameField, DescriptionField},
|
|
wantErrMatch: errors.T(errors.InvalidParameter),
|
|
wantErrContains: "missing ManagedGroup: parameter violation: error #100",
|
|
},
|
|
{
|
|
name: "nil-embedded-ManagedGroup",
|
|
repo: testRepo,
|
|
scopeId: org.GetPublicId(),
|
|
version: 1,
|
|
orig: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{},
|
|
},
|
|
chgFn: makeEmbeddedNil(),
|
|
masks: []string{NameField, DescriptionField},
|
|
wantErrMatch: errors.T(errors.InvalidParameter),
|
|
wantErrContains: "missing embedded ManagedGroup: parameter violation: error #100",
|
|
},
|
|
{
|
|
name: "no-scope-id",
|
|
repo: testRepo,
|
|
version: 1,
|
|
orig: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
Name: "no-scope-id-test-name-repo",
|
|
},
|
|
},
|
|
chgFn: changeName("no-scope-id-test-update-name-repo"),
|
|
masks: []string{NameField},
|
|
wantErrMatch: errors.T(errors.InvalidParameter),
|
|
wantErrContains: "missing scope id: parameter violation: error #100",
|
|
},
|
|
{
|
|
name: "missing-version",
|
|
repo: testRepo,
|
|
scopeId: org.GetPublicId(),
|
|
orig: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
Name: "missing-version-test-name-repo",
|
|
},
|
|
},
|
|
chgFn: changeName("test-update-name-repo"),
|
|
masks: []string{NameField},
|
|
wantErrMatch: errors.T(errors.InvalidParameter),
|
|
wantErrContains: "missing version: parameter violation: error #100",
|
|
},
|
|
{
|
|
name: "no-public-id",
|
|
repo: testRepo,
|
|
scopeId: org.GetPublicId(),
|
|
version: 1,
|
|
orig: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{},
|
|
},
|
|
chgFn: deletePublicId(),
|
|
masks: []string{NameField, DescriptionField},
|
|
wantErrMatch: errors.T(errors.InvalidParameter),
|
|
wantErrContains: "missing public id: parameter violation: error #100",
|
|
},
|
|
{
|
|
name: "updating-non-existent-ManagedGroup",
|
|
repo: testRepo,
|
|
scopeId: org.GetPublicId(),
|
|
version: 1,
|
|
orig: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
Name: "updating-non-existent-ManagedGroup-test-name-repo",
|
|
},
|
|
},
|
|
chgFn: combine(nonExistentPublicId(), changeName("updating-non-existent-ManagedGroup-test-update-name-repo")),
|
|
masks: []string{NameField},
|
|
wantErrMatch: errors.T(errors.RecordNotFound),
|
|
wantErrContains: "record not found, search issue: error #1100",
|
|
},
|
|
{
|
|
name: "empty-field-mask",
|
|
repo: testRepo,
|
|
scopeId: org.GetPublicId(),
|
|
version: 1,
|
|
orig: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
Name: "empty-field-mask-test-name-repo",
|
|
},
|
|
},
|
|
chgFn: changeName("empty-field-mask-test-update-name-repo"),
|
|
wantErrMatch: errors.T(errors.EmptyFieldMask),
|
|
wantErrContains: "missing field mask: parameter violation: error #104",
|
|
},
|
|
{
|
|
name: "read-only-fields-in-field-mask",
|
|
repo: testRepo,
|
|
scopeId: org.GetPublicId(),
|
|
version: 1,
|
|
orig: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
Name: "read-only-fields-in-field-mask-test-name-repo",
|
|
},
|
|
},
|
|
chgFn: changeName("read-only-fields-in-field-mask-test-update-name-repo"),
|
|
masks: []string{"PublicId", "CreateTime", "UpdateTime", "AuthMethodId"},
|
|
wantErrMatch: errors.T(errors.InvalidFieldMask),
|
|
wantErrContains: "PublicId: parameter violation: error #103",
|
|
},
|
|
{
|
|
name: "unknown-field-in-field-mask",
|
|
repo: testRepo,
|
|
scopeId: org.GetPublicId(),
|
|
version: 1,
|
|
orig: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
Name: "unknown-field-in-field-mask-test-name-repo",
|
|
},
|
|
},
|
|
chgFn: changeName("unknown-field-in-field-mask-test-update-name-repo"),
|
|
masks: []string{"Bilbo"},
|
|
wantErrMatch: errors.T(errors.InvalidFieldMask),
|
|
wantErrContains: "Bilbo: parameter violation: error #103",
|
|
},
|
|
{
|
|
name: "change-name",
|
|
repo: testRepo,
|
|
scopeId: org.GetPublicId(),
|
|
version: 1,
|
|
orig: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
Name: "change-name-test-name-repo",
|
|
},
|
|
},
|
|
chgFn: changeName("change-name-test-update-name-repo"),
|
|
masks: []string{NameField},
|
|
want: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
Name: "change-name-test-update-name-repo",
|
|
},
|
|
},
|
|
wantCount: 1,
|
|
},
|
|
{
|
|
name: "change-description",
|
|
repo: testRepo,
|
|
scopeId: org.GetPublicId(),
|
|
version: 1,
|
|
orig: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
Description: "test-description-repo",
|
|
},
|
|
},
|
|
chgFn: changeDescription("test-update-description-repo"),
|
|
masks: []string{DescriptionField},
|
|
want: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
Description: "test-update-description-repo",
|
|
},
|
|
},
|
|
wantCount: 1,
|
|
},
|
|
{
|
|
name: "change-grp-names",
|
|
repo: testRepo,
|
|
scopeId: org.GetPublicId(),
|
|
version: 1,
|
|
orig: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
GroupNames: TestEncodedGrpNames(t, "orig-admin", "orig-users"),
|
|
},
|
|
},
|
|
chgFn: changeGrpNames(TestEncodedGrpNames(t, testGrpNames...)),
|
|
masks: []string{GroupNamesField},
|
|
want: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
GroupNames: TestEncodedGrpNames(t, testGrpNames...),
|
|
},
|
|
},
|
|
wantCount: 1,
|
|
},
|
|
{
|
|
name: "change-name-and-description",
|
|
repo: testRepo,
|
|
scopeId: org.GetPublicId(),
|
|
version: 1,
|
|
orig: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
Name: "change-name-and-description-test-name-repo",
|
|
Description: "test-description-repo",
|
|
},
|
|
},
|
|
chgFn: combine(changeDescription("test-update-description-repo"), changeName("change-name-and-description-test-update-name-repo")),
|
|
masks: []string{NameField, DescriptionField},
|
|
want: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
Name: "change-name-and-description-test-update-name-repo",
|
|
Description: "test-update-description-repo",
|
|
},
|
|
},
|
|
wantCount: 1,
|
|
},
|
|
{
|
|
name: "delete-name",
|
|
repo: testRepo,
|
|
scopeId: org.GetPublicId(),
|
|
version: 1,
|
|
orig: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
Name: "delete-name-test-name-repo",
|
|
Description: "test-description-repo",
|
|
},
|
|
},
|
|
masks: []string{NameField},
|
|
chgFn: combine(changeDescription("test-update-description-repo"), changeName("")),
|
|
want: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
Description: "test-description-repo",
|
|
},
|
|
},
|
|
wantCount: 1,
|
|
},
|
|
{
|
|
name: "delete-description",
|
|
repo: testRepo,
|
|
scopeId: org.GetPublicId(),
|
|
version: 1,
|
|
orig: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
Name: "delete-description-test-name-repo",
|
|
Description: "test-description-repo",
|
|
},
|
|
},
|
|
masks: []string{DescriptionField},
|
|
chgFn: combine(changeDescription(""), changeName("test-update-name-repo")),
|
|
want: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
Name: "delete-description-test-name-repo",
|
|
},
|
|
},
|
|
wantCount: 1,
|
|
},
|
|
{
|
|
name: "delete-grp-names",
|
|
repo: testRepo,
|
|
scopeId: org.GetPublicId(),
|
|
version: 1,
|
|
orig: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
GroupNames: TestEncodedGrpNames(t, testGrpNames...),
|
|
},
|
|
},
|
|
masks: []string{GroupNamesField},
|
|
chgFn: combine(changeGrpNames("")),
|
|
wantErrMatch: errors.T(errors.NotNull),
|
|
wantErrContains: "group_names must not be empty: not null constraint violated: integrity violation: error #1001",
|
|
},
|
|
{
|
|
name: "do-not-delete-name",
|
|
repo: testRepo,
|
|
scopeId: org.GetPublicId(),
|
|
version: 1,
|
|
orig: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
Name: "do-not-delete-name-test-name-repo",
|
|
Description: "test-description-repo",
|
|
},
|
|
},
|
|
masks: []string{DescriptionField},
|
|
chgFn: combine(changeDescription("test-update-description-repo"), changeName("")),
|
|
want: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
Name: "do-not-delete-name-test-name-repo",
|
|
Description: "test-update-description-repo",
|
|
},
|
|
},
|
|
wantCount: 1,
|
|
},
|
|
{
|
|
name: "do-not-delete-description",
|
|
repo: testRepo,
|
|
scopeId: org.GetPublicId(),
|
|
version: 1,
|
|
orig: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
Name: "do-not-delete-description-test-name-repo",
|
|
Description: "test-description-repo",
|
|
},
|
|
},
|
|
masks: []string{NameField},
|
|
chgFn: combine(changeDescription(""), changeName("do-not-delete-description-test-update-name-repo")),
|
|
want: &ManagedGroup{
|
|
ManagedGroup: &store.ManagedGroup{
|
|
Name: "do-not-delete-description-test-update-name-repo",
|
|
Description: "test-description-repo",
|
|
},
|
|
},
|
|
wantCount: 1,
|
|
},
|
|
}
|
|
|
|
for _, tc := range tests {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
assert, require := assert.New(t), require.New(t)
|
|
require.NotEmpty(tc.repo)
|
|
|
|
orig := TestManagedGroup(t, testConn, am, testGrpNames, WithName(testCtx, tc.orig.GetName()), WithDescription(testCtx, tc.orig.GetDescription()))
|
|
|
|
tc.orig.AuthMethodId = am.PublicId
|
|
if tc.chgFn != nil {
|
|
orig = tc.chgFn(orig)
|
|
}
|
|
got, gotCount, err := tc.repo.UpdateManagedGroup(testCtx, tc.scopeId, orig, tc.version, tc.masks)
|
|
if tc.wantErrMatch != nil {
|
|
assert.True(errors.Match(tc.wantErrMatch, err), "want err: %q got: %q", tc.wantErrMatch.Code, err)
|
|
if tc.wantErrContains != "" {
|
|
assert.Contains(err.Error(), tc.wantErrContains)
|
|
}
|
|
assert.Equal(tc.wantCount, gotCount, "row count")
|
|
assert.Nil(got)
|
|
return
|
|
}
|
|
assert.NoError(err)
|
|
assert.Empty(tc.orig.PublicId)
|
|
if tc.wantCount == 0 {
|
|
assert.Equal(tc.wantCount, gotCount, "row count")
|
|
assert.Nil(got)
|
|
return
|
|
}
|
|
require.NotNil(got)
|
|
assertPublicId(t, globals.LdapManagedGroupPrefix, got.PublicId)
|
|
assert.Equal(tc.wantCount, gotCount, "row count")
|
|
assert.NotSame(tc.orig, got)
|
|
assert.Equal(tc.orig.AuthMethodId, got.AuthMethodId)
|
|
underlyingDB, err := testConn.SqlDB(testCtx)
|
|
require.NoError(err)
|
|
dbassert := dbassert.New(t, underlyingDB)
|
|
if tc.want.Name == "" {
|
|
dbassert.IsNull(got, "name")
|
|
return
|
|
}
|
|
assert.Equal(tc.want.Name, got.Name)
|
|
if tc.want.Description == "" {
|
|
dbassert.IsNull(got, "description")
|
|
return
|
|
}
|
|
assert.Equal(tc.want.Description, got.Description)
|
|
if tc.wantCount > 0 {
|
|
assert.NoError(db.TestVerifyOplog(t, testRw, got.PublicId, db.WithOperation(oplog.OpType_OP_TYPE_UPDATE), db.WithCreateNotBefore(10*time.Second)))
|
|
}
|
|
})
|
|
}
|
|
}
|