diff --git a/internal/auth/ldap/managed_group_role_grants_test.go b/internal/auth/ldap/managed_group_role_grants_test.go new file mode 100644 index 0000000000..6d24af9307 --- /dev/null +++ b/internal/auth/ldap/managed_group_role_grants_test.go @@ -0,0 +1,123 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package ldap + +import ( + "context" + "testing" + + "github.com/hashicorp/boundary/internal/auth/oidc" + "github.com/hashicorp/boundary/internal/db" + "github.com/hashicorp/boundary/internal/iam" + "github.com/hashicorp/boundary/internal/kms" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +// TestLdapManagedGroupRoleGrants ensures that user roles that +// include a ldap managed groups principal are properly returned from queries to +// auth_managed_group_member_account and iam repository.GrantsForUser(...) +// +// this test depends on changes made in 65/01_ldap.up.sql to the +// auth_managed_group_member_account view +func TestLdapManagedGroupRoleGrants(t *testing.T) { + t.Parallel() + const ( + testGrpName = "testAdminGrp" + testGrpName2 = "testUserGrp" + testLdapUrl = "ldap://test.ldap" + testLoginName = "test-user" + testGrant = "id=*;type=*;actions=*" + testClientId = "alice-rp" + testClientSecret = "fido" + testIssuer = "https://www.alice.com" + testCallbackUrl = "https://www.alice.com/callback" + ) + testCtx := context.Background() + testConn, _ := db.TestSetup(t, "postgres") + testRootWrapper := db.TestWrapper(t) + testRw := db.New(testConn) + testKms := kms.TestKms(t, testConn, testRootWrapper) + iamRepo := iam.TestRepo(t, testConn, testRootWrapper) + testOrg, _ := iam.TestScopes( + t, + iamRepo, + iam.WithSkipAdminRoleCreation(true), + iam.WithSkipDefaultRoleCreation(true), + ) + testScopeId := testOrg.GetPublicId() + testGlobalDbWrapper, err := testKms.GetWrapper(testCtx, testScopeId, kms.KeyPurposeDatabase) + require.NoError(t, err) + ldapRepo, err := NewRepository(testCtx, testRw, testRw, testKms) + require.NoError(t, err) + + testAm := TestAuthMethod(t, testConn, testGlobalDbWrapper, testScopeId, []string{testLdapUrl}) + testAcct := TestAccount(t, testConn, testAm, testLoginName, WithMemberOfGroups(testCtx, testGrpName)) + testManagedGrp := TestManagedGroup(t, testConn, testAm, []string{testGrpName}) + TestManagedGroup(t, testConn, testAm, []string{testGrpName2}) + + testUser := iam.TestUser(t, iamRepo, testScopeId, iam.WithAccountIds(testAcct.PublicId)) + testRole := iam.TestRole(t, testConn, testScopeId) + _ = iam.TestRoleGrant(t, testConn, testRole.GetPublicId(), testGrant) + iam.TestManagedGroupRole(t, testConn, testRole.GetPublicId(), testManagedGrp.GetPublicId()) + + // check the view to make sure it's correct, before trying the CTE used by + // GrantsForUser(...) which depends on this view + memberAccts, err := ldapRepo.ListManagedGroupMembershipsByMember(testCtx, testAcct.GetPublicId()) + require.NoError(t, err) + require.Len(t, memberAccts, 1) + require.Equal(t, testManagedGrp.GetPublicId(), memberAccts[0].GetManagedGroupId()) + require.Equal(t, testAcct.GetPublicId(), memberAccts[0].GetMemberId()) + t.Log("found managed group member acct: ", memberAccts[0].GetManagedGroupId(), memberAccts[0].GetMemberId()) + + // okay, let's try the CTE and make sure the user has the grants given via + // the ldap managed group + tuples, err := iamRepo.GrantsForUser(testCtx, testUser.PublicId) + require.NoError(t, err) + // De-dupe role IDs + roleIds := make(map[string]bool, len(tuples)) + for _, tuple := range tuples { + roleIds[tuple.RoleId] = true + } + t.Log("looking for role: ", testRole.GetPublicId()) + t.Log("found role/grant: ", tuples) + assert.EqualValues(t, map[string]bool{testRole.GetPublicId(): true}, roleIds) + + // make sure a user without the appropriate managed group doesn't have grants + testUserWithoutManagedGroupRole := iam.TestUser(t, iamRepo, testScopeId) + tuples, err = iamRepo.GrantsForUser(testCtx, testUserWithoutManagedGroupRole.PublicId) + require.NoError(t, err) + assert.Equal(t, 0, len(tuples)) + + // okay, let's test a user that has both an oidc managed group and an ldap + // managed group + testOidcAm := oidc.TestAuthMethod( + t, testConn, testGlobalDbWrapper, testScopeId, oidc.ActivePrivateState, + testClientId, testClientSecret, + oidc.WithSigningAlgs(oidc.RS256), + oidc.WithIssuer(oidc.TestConvertToUrls(t, testIssuer)[0]), + oidc.WithApiUrl(oidc.TestConvertToUrls(t, testCallbackUrl)[0]), + ) + testOidcAcct := oidc.TestAccount(t, testConn, testOidcAm, "sub") + testOidcManagedGrp := oidc.TestManagedGroup(t, testConn, testOidcAm, oidc.TestFakeManagedGroupFilter) + oidc.TestManagedGroupMember(t, testConn, testOidcManagedGrp.GetPublicId(), testOidcAcct.GetPublicId()) + + // add the oidc account to our test user.... + _, err = iamRepo.AddUserAccounts(testCtx, testUser.GetPublicId(), 2, []string{testOidcAcct.GetPublicId()}) + require.NoError(t, err) + + testRole2 := iam.TestRole(t, testConn, testScopeId) + _ = iam.TestRoleGrant(t, testConn, testRole2.GetPublicId(), testGrant) + iam.TestManagedGroupRole(t, testConn, testRole2.GetPublicId(), testOidcManagedGrp.GetPublicId()) + + tuples, err = iamRepo.GrantsForUser(testCtx, testUser.GetPublicId()) + require.NoError(t, err) + assert.Equal(t, 2, len(tuples)) + t.Log("tuples:", tuples) + + assert.Equal(t, + map[string]bool{testRole.GetPublicId(): true, testRole2.GetPublicId(): true}, + map[string]bool{tuples[0].RoleId: true, tuples[1].RoleId: true}, + ) +} diff --git a/internal/daemon/controller/handlers/managed_groups/managed_group_service.go b/internal/daemon/controller/handlers/managed_groups/managed_group_service.go index bae8dbf44c..b4bd7b2be6 100644 --- a/internal/daemon/controller/handlers/managed_groups/managed_group_service.go +++ b/internal/daemon/controller/handlers/managed_groups/managed_group_service.go @@ -606,11 +606,11 @@ func (s Service) listFromRepo(ctx context.Context, authMethodId string) ([]auth. if err != nil { return nil, errors.Wrap(ctx, err, op) } - oidcl, err := ldapRepo.ListManagedGroups(ctx, authMethodId, ldap.WithLimit(ctx, -1)) + ldapUl, err := ldapRepo.ListManagedGroups(ctx, authMethodId, ldap.WithLimit(ctx, -1)) if err != nil { return nil, errors.Wrap(ctx, err, op) } - for _, a := range oidcl { + for _, a := range ldapUl { outUl = append(outUl, a) } } diff --git a/internal/iam/query.go b/internal/iam/query.go index 1cb16a1ad0..e675b9d93e 100644 --- a/internal/iam/query.go +++ b/internal/iam/query.go @@ -111,4 +111,69 @@ const ( select * from final order by action, member_id; ` + + grantsQuery = ` + with + users (id) as ( + select public_id + from iam_user + %s -- anonUser || authUser + ), + user_groups (id) as ( + select group_id + from iam_group_member_user + where member_id in (select id from users) + ), + user_accounts (id) as ( + select public_id + from auth_account + where iam_user_id in (select id from users) + ), + user_managed_groups (id) as ( + select managed_group_id + from auth_managed_group_member_account + where member_id in (select id from user_accounts) + ), + managed_group_roles (role_id) as ( + select role_id + from iam_managed_group_role + where principal_id in (select id from user_managed_groups) + ), + group_roles (role_id) as ( + select role_id + from iam_group_role + where principal_id in (select id from user_groups) + ), + user_roles (role_id) as ( + select role_id + from iam_user_role + where principal_id in (select id from users) + ), + user_group_roles (role_id) as ( + select role_id + from group_roles + union + select role_id + from user_roles + union + select role_id + from managed_group_roles + ), + roles (role_id, grant_scope_id) as ( + select iam_role.public_id, + iam_role.grant_scope_id + from iam_role + where public_id in (select role_id from user_group_roles) + ), + final (role_id, role_scope, role_grant) as ( + select roles.role_id, + roles.grant_scope_id, + iam_role_grant.canonical_grant + from roles + inner join iam_role_grant + on roles.role_id = iam_role_grant.role_id + -- only retrieves roles with a grant! there can be roles that don't have grants (it's a valid state in boundary) + ) + select role_id as role_id, role_scope as scope_id, role_grant as grant from final; + ` ) diff --git a/internal/iam/repository_role_grant.go b/internal/iam/repository_role_grant.go index 175b802f02..d19c394a07 100644 --- a/internal/iam/repository_role_grant.go +++ b/internal/iam/repository_role_grant.go @@ -396,79 +396,8 @@ func (r *Repository) GrantsForUser(ctx context.Context, userId string, _ ...Opti } const ( - anonUser = `where public_id in (?)` - authUser = `where public_id in ('u_anon', 'u_auth', ?)` - grantsQuery = ` -with -users (id) as ( - select public_id - from iam_user - %s -- anonUser || authUser -), -user_groups (id) as ( - select group_id - from iam_group_member_user, - users - where member_id in (users.id) -), -user_accounts (id) as ( - select public_id - from auth_account, - users - where iam_user_id in (users.id) -), -user_managed_groups (id) as ( - select managed_group_id - from auth_managed_group_member_account, - user_accounts - where member_id in (user_accounts.id) -), -managed_group_roles (role_id) as ( - select role_id - from iam_managed_group_role, - user_managed_groups - where principal_id in (user_managed_groups.id) -), -group_roles (role_id) as ( - select role_id - from iam_group_role, - user_groups - where principal_id in (user_groups.id) -), -user_roles (role_id) as ( - select role_id - from iam_user_role, - users - where principal_id in (users.id) -), -user_group_roles (role_id) as ( - select role_id - from group_roles - union - select role_id - from user_roles - union - select role_id - from managed_group_roles -), -roles (role_id, grant_scope_id) as ( - select iam_role.public_id, - iam_role.grant_scope_id - from iam_role, - user_group_roles - where public_id in (user_group_roles.role_id) -), -final (role_id, role_scope, role_grant) as ( - select roles.role_id, - roles.grant_scope_id, - iam_role_grant.canonical_grant - from roles - inner - join iam_role_grant - on roles.role_id = iam_role_grant.role_id -) -select role_id as role_id, role_scope as scope_id, role_grant as grant from final; - ` + anonUser = `where public_id in (?)` + authUser = `where public_id in ('u_anon', 'u_auth', ?)` ) var query string diff --git a/internal/iam/repository_role_grant_ext_test.go b/internal/iam/repository_role_grant_ext_test.go index 99a6793c65..b597a88ed1 100644 --- a/internal/iam/repository_role_grant_ext_test.go +++ b/internal/iam/repository_role_grant_ext_test.go @@ -5,10 +5,13 @@ package iam_test import ( "context" + "encoding/json" "fmt" mathrand "math/rand" "testing" + "github.com/hashicorp/boundary/internal/auth/ldap" + "github.com/hashicorp/boundary/internal/auth/ldap/store" "github.com/hashicorp/boundary/internal/auth/oidc" "github.com/hashicorp/boundary/internal/db" "github.com/hashicorp/boundary/internal/iam" @@ -16,6 +19,7 @@ import ( "github.com/hashicorp/boundary/internal/types/scope" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "google.golang.org/protobuf/proto" ) func TestGrantsForUser(t *testing.T) { @@ -23,11 +27,16 @@ func TestGrantsForUser(t *testing.T) { conn, _ := db.TestSetup(t, "postgres") wrap := db.TestWrapper(t) iamRepo := iam.TestRepo(t, conn, wrap) + rw := db.New(conn) + kmsCache := kms.TestKms(t, conn, wrap) + ldapRepo, err := ldap.NewRepository(ctx, rw, rw, kmsCache) + require.NoError(t, err) userCount := 10 groupCount := 30 - managedGroupCount := 30 - roleCount := 30 + oidcManagedGroupCount := 30 + ldapManagedGroupCount := 30 + roleCount := 1 // probFactor acts as a mod value; increasing means less probability. 2 = // 50%, 5 = 20%, etc. probFactor := 5 @@ -45,12 +54,10 @@ func TestGrantsForUser(t *testing.T) { iam.WithSkipAdminRoleCreation(true), iam.WithSkipDefaultRoleCreation(true), ) - - kmsCache := kms.TestKms(t, conn, wrap) databaseWrapper, err := kmsCache.GetWrapper(ctx, o.PublicId, kms.KeyPurposeDatabase) require.NoError(t, err) - authMethod := oidc.TestAuthMethod( + oidcAuthMethod := oidc.TestAuthMethod( t, conn, databaseWrapper, o.GetPublicId(), oidc.ActivePrivateState, "alice-rp", "fido", oidc.WithSigningAlgs(oidc.RS256), @@ -58,23 +65,26 @@ func TestGrantsForUser(t *testing.T) { oidc.WithApiUrl(oidc.TestConvertToUrls(t, "https://www.alice.com/callback")[0]), ) - // We're going to generate a bunch of users (each tied to an account), - // groups, and managed groups. These will be randomly assigned and we will - // record assignations. - users, accounts := func() (usrs []*iam.User, accts []*oidc.Account) { + ldapAuthMethod := ldap.TestAuthMethod(t, conn, databaseWrapper, o.GetPublicId(), []string{"ldap://test"}) + + // We're going to generate a bunch of users (each tied to 2 accounts; oidc + // and ldap), groups, and managed groups (oidc and ldap). These will be + // randomly assigned and we will record assignations. + users, oidcAccounts, ldapAccounts := func() (usrs []*iam.User, oidcAccts []*oidc.Account, ldapAccts []*ldap.Account) { usrs = make([]*iam.User, 0, userCount) - accts = make([]*oidc.Account, 0, userCount) + oidcAccts = make([]*oidc.Account, 0, userCount) scopeId := scope.Global.String() if mathrand.Int()%2 == 0 || testManagedGroups { scopeId = o.GetPublicId() } for i := 0; i < userCount; i++ { - accts = append(accts, oidc.TestAccount(t, conn, authMethod, fmt.Sprintf("sub-%d", i))) + oidcAccts = append(oidcAccts, oidc.TestAccount(t, conn, oidcAuthMethod, fmt.Sprintf("sub-%d", i))) + ldapAccts = append(ldapAccts, ldap.TestAccount(t, conn, ldapAuthMethod, fmt.Sprintf("login-name-%d", i))) usrs = append(usrs, iam.TestUser( t, iamRepo, scopeId, - iam.WithAccountIds(accts[i].PublicId), + iam.WithAccountIds(oidcAccts[i].PublicId, ldapAccts[i].PublicId), iam.WithName(fmt.Sprintf("testuser%d", i)), )) } @@ -91,10 +101,18 @@ func TestGrantsForUser(t *testing.T) { } return }() - managedGroups := func() (ret []*oidc.ManagedGroup) { - ret = make([]*oidc.ManagedGroup, 0, managedGroupCount) - for i := 0; i < managedGroupCount; i++ { - ret = append(ret, oidc.TestManagedGroup(t, conn, authMethod, oidc.TestFakeManagedGroupFilter, oidc.WithName(fmt.Sprintf("testmanagedgroup%d", i)))) + oidcManagedGroups := func() (ret []*oidc.ManagedGroup) { + ret = make([]*oidc.ManagedGroup, 0, oidcManagedGroupCount) + for i := 0; i < oidcManagedGroupCount; i++ { + ret = append(ret, oidc.TestManagedGroup(t, conn, oidcAuthMethod, oidc.TestFakeManagedGroupFilter, oidc.WithName(fmt.Sprintf("oidc-testmanagedgroup%d", i)))) + } + return + }() + ldapManagedGroups := func() (ret []*ldap.ManagedGroup) { + ret = make([]*ldap.ManagedGroup, 0, ldapManagedGroupCount) + for i := 0; i < ldapManagedGroupCount; i++ { + name := fmt.Sprintf("ldap-testmanagedgroup%d", i) + ret = append(ret, ldap.TestManagedGroup(t, conn, ldapAuthMethod, []string{name}, ldap.WithName(ctx, name))) } return }() @@ -131,23 +149,92 @@ func TestGrantsForUser(t *testing.T) { } } } - // This variable stores an easy way to lookup, given a managed group ID, whether a - // user is in that group. - userToManagedGroupsMapping := map[string]map[string]bool{} + // This variable stores an easy way to lookup, given a user id, whether or + // not it's in an oidc managed group. + userToOidcManagedGroupsMapping := map[string]map[string]bool{} for i, user := range users { - for _, managedGroup := range managedGroups { + for _, managedGroup := range oidcManagedGroups { // Give each user (account) a chance of being in any specific managed group if mathrand.Int()%probFactor == 0 { userId := user.PublicId - accountId := accounts[i].PublicId + accountId := oidcAccounts[i].PublicId managedGroupId := managedGroup.PublicId oidc.TestManagedGroupMember(t, conn, managedGroupId, accountId) - currentMapping := userToManagedGroupsMapping[userId] + currentMapping := userToOidcManagedGroupsMapping[userId] if currentMapping == nil { currentMapping = make(map[string]bool) } currentMapping[managedGroupId] = true - userToManagedGroupsMapping[userId] = currentMapping + userToOidcManagedGroupsMapping[userId] = currentMapping + } + } + } + + ldapAcctCloneFunc := func(a *ldap.Account) *ldap.Account { + cp := proto.Clone(a.Account) + return &ldap.Account{ + Account: cp.(*store.Account), + } + } + // This variable stores an easy way to lookup, given a user id, whether or + // not it's in an ldap managed group. + userToLdapManagedGroupsMapping := map[string]map[string]bool{} + + // This variable stores an easy way to lookup, giving an ldap managed group + // id, whether or not it has a user id + ldapManagedGroupToUser := map[string]map[string]bool{} + + for i, user := range users { + userLdapAcct := ldapAccounts[i] // the first acct goes with the first user + acctClone := ldapAcctCloneFunc(userLdapAcct) // clone it just in case it's changed during a db update + for _, managedGroup := range ldapManagedGroups { + // Give each user (account) a chance of being in any specific managed group + if mathrand.Int()%probFactor == 0 { + var existingAcctGroups []string + if acctClone.GetMemberOfGroups() != "" { + require.NoError(t, json.Unmarshal([]byte(acctClone.GetMemberOfGroups()), &existingAcctGroups)) + } + var existingManagedGroups []string + require.NoError(t, json.Unmarshal([]byte(managedGroup.GetGroupNames()), &existingManagedGroups)) + newGrps, err := json.Marshal(append(existingAcctGroups, existingManagedGroups...)) + require.NoError(t, err) + acctClone.MemberOfGroups = string(newGrps) + updated, err := rw.Update(ctx, acctClone, []string{"MemberOfGroups"}, nil) + require.NoError(t, err) + require.Equal(t, 1, updated) + userId := user.GetPublicId() + currentMapping := userToLdapManagedGroupsMapping[userId] + if currentMapping == nil { + currentMapping = make(map[string]bool) + } + currentMapping[managedGroup.GetPublicId()] = true + userToLdapManagedGroupsMapping[userId] = currentMapping + + currentMapGrpsToUser := ldapManagedGroupToUser[managedGroup.GetPublicId()] + if currentMapGrpsToUser == nil { + currentMapGrpsToUser = make(map[string]bool) + } + currentMapGrpsToUser[userId] = true + ldapManagedGroupToUser[managedGroup.GetPublicId()] = currentMapGrpsToUser + + // check that the acct is part of the managed grp + // 1) check acct is returned from + // auth_managed_group_member_account search + // 2) check that acct belongs to the user + memberAccts, err := ldapRepo.ListManagedGroupMembershipsByMember(ctx, userLdapAcct.GetPublicId()) + require.NoError(t, err) + require.GreaterOrEqual(t, len(memberAccts), 1) + found := false + for _, m := range memberAccts { + if m.GetManagedGroupId() == managedGroup.GetPublicId() && m.GetMemberId() == userLdapAcct.GetPublicId() { + found = true + } + } + require.Truef(t, found, "did not find acct in managed grp search") + + accts, err := iamRepo.ListUserAccounts(ctx, userId) + require.NoError(t, err) + require.Contains(t, accts, userLdapAcct.GetPublicId()) } } } @@ -156,7 +243,8 @@ func TestGrantsForUser(t *testing.T) { // store mappings userToRolesMapping := map[string]map[string]bool{} groupToRolesMapping := map[string]map[string]bool{} - managedGroupToRolesMapping := map[string]map[string]bool{} + oidcManagedGroupToRolesMapping := map[string]map[string]bool{} + ldapManagedGroupToRolesMapping := map[string]map[string]bool{} if addUsersDirectly { for _, role := range roles { for _, user := range users { @@ -194,19 +282,53 @@ func TestGrantsForUser(t *testing.T) { } } for _, role := range roles { - for _, managedGroup := range managedGroups { - // Give each managed group a chance of being directly added to any - // specific role + roleId := role.PublicId + for _, oidcManagedGroup := range oidcManagedGroups { + // Give each oidc managed group a chance of being directly added to + // any specific role if mathrand.Int()%probFactor == 0 { - roleId := role.PublicId - managedGroupId := managedGroup.PublicId + managedGroupId := oidcManagedGroup.PublicId iam.TestManagedGroupRole(t, conn, roleId, managedGroupId) - currentMapping := managedGroupToRolesMapping[managedGroupId] + currentMapping := oidcManagedGroupToRolesMapping[managedGroupId] if currentMapping == nil { currentMapping = make(map[string]bool) } currentMapping[roleId] = true - managedGroupToRolesMapping[managedGroupId] = currentMapping + oidcManagedGroupToRolesMapping[managedGroupId] = currentMapping + } + } + for _, ldapManagedGroup := range ldapManagedGroups { + // Give each ldap managed group a chance of being directly added to + // any specific role + if mathrand.Int()%probFactor == 0 { + ldapManagedGroupId := ldapManagedGroup.GetPublicId() + iam.TestManagedGroupRole(t, conn, roleId, ldapManagedGroupId) + currentMapping := ldapManagedGroupToRolesMapping[ldapManagedGroupId] + if currentMapping == nil { + currentMapping = make(map[string]bool) + } + currentMapping[roleId] = true + ldapManagedGroupToRolesMapping[ldapManagedGroupId] = currentMapping + + // just check if role shows up for the user now. + for userId := range ldapManagedGroupToUser[ldapManagedGroupId] { + tuples, err := iamRepo.GrantsForUser(ctx, userId) + t.Log("userId/tuples:", userId, tuples) + require.NoError(t, err) + found := false + foundRoles := []string{} + for _, gt := range tuples { + foundRoles = append(foundRoles, gt.RoleId) + if gt.RoleId == roleId { + found = true + break + } + } + if found { + t.Log("FOUND:", userId, ldapManagedGroupId, foundRoles) + } + assert.Truef(t, found, "did not find role id %s in grants for user %s, grp %s, found user roles %s", roleId, userId, ldapManagedGroupId, foundRoles) + } } } } @@ -214,7 +336,7 @@ func TestGrantsForUser(t *testing.T) { // Now, fetch the set of grants. We're going to be testing this by looking // at the role IDs of the matching grant tuples. for _, user := range users { - var rolesFromUsers, rolesFromGroups, rolesFromManagedGroups int + var rolesFromUsers, rolesFromGroups, rolesFromOidcManagedGroups, rolesFromLdapManagedGroups int tuples, err := iamRepo.GrantsForUser(ctx, user.PublicId) require.NoError(t, err) @@ -240,16 +362,30 @@ func TestGrantsForUser(t *testing.T) { rolesFromGroups++ } } - for managedGroupId := range userToManagedGroupsMapping[user.PublicId] { - for roleId := range managedGroupToRolesMapping[managedGroupId] { + for managedGroupId := range userToOidcManagedGroupsMapping[user.PublicId] { + for roleId := range oidcManagedGroupToRolesMapping[managedGroupId] { + expectedRoleIds[roleId] = true + rolesFromOidcManagedGroups++ + } + } + for managedGroupId := range userToLdapManagedGroupsMapping[user.PublicId] { + for roleId := range ldapManagedGroupToRolesMapping[managedGroupId] { + if !expectedRoleIds[roleId] { + t.Log("Adding ldap role: ", roleId) + } expectedRoleIds[roleId] = true - rolesFromManagedGroups++ + rolesFromLdapManagedGroups++ } } // Now verify that the expected set and returned set match - assert.EqualValues(t, expectedRoleIds, roleIds) + require.EqualValues(t, expectedRoleIds, roleIds) - t.Log("finished user", user.PublicId, "total roles", len(expectedRoleIds), "roles from users", rolesFromUsers, "roles from groups", rolesFromGroups, "roles from managed groups", rolesFromManagedGroups) + t.Log("finished user", user.PublicId, + "total roles", len(expectedRoleIds), + ", roles from users", rolesFromUsers, + ", roles from groups", rolesFromGroups, + ", roles from oidc managed groups", rolesFromOidcManagedGroups, + ", roles from ldap managed groups", rolesFromLdapManagedGroups) } }