Add managed groups test (#1289)
This commit is contained in:
1 parent
d6ef2732e7
commit
4d27b58d2d
3 files changed
+148
-24
No files matched your search
@@ -196,6 +196,20 @@ func TestManagedGroup(t *testing.T, conn *gorm.DB, am *AuthMethod, filter string
|
||||
return mg
|
||||
}
|
||||
|
||||
// TestManagedGroupMember adds given account IDs to a managed group
|
||||
func TestManagedGroupMember(t *testing.T, conn *gorm.DB, managedGroupId, memberId string, opt ...Option) *ManagedGroupMemberAccount {
|
||||
t.Helper()
|
||||
require := require.New(t)
|
||||
rw := db.New(conn)
|
||||
ctx := context.Background()
|
||||
|
||||
mg, err := NewManagedGroupMemberAccount(managedGroupId, memberId, opt...)
|
||||
require.NoError(err)
|
||||
|
||||
require.NoError(rw.Create(ctx, mg))
|
||||
return mg
|
||||
}
|
||||
|
||||
// TestConvertToUrls will convert URL string representations to a slice of
|
||||
// *url.URL
|
||||
func TestConvertToUrls(t *testing.T, urls ...string) []*url.URL {
|
||||
|
||||
@@ -407,6 +407,24 @@ user_groups (id) as (
|
||||
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,
|
||||
@@ -425,6 +443,9 @@ user_group_roles (role_id) as (
|
||||
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,
|
||||
|
||||
@@ -6,8 +6,10 @@ import (
|
||||
mathrand "math/rand"
|
||||
"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/hashicorp/boundary/internal/types/scope"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -21,10 +23,18 @@ func TestGrantsForUser(t *testing.T) {
|
||||
|
||||
userCount := 10
|
||||
groupCount := 30
|
||||
managedGroupCount := 30
|
||||
roleCount := 30
|
||||
// probFactor acts as a mod value; increasing means less probability. 2 =
|
||||
// 50%, 5 = 20%, etc.
|
||||
probFactor := 4
|
||||
probFactor := 5
|
||||
// Turning this off will let users be cross-scope instead of in the same
|
||||
// scope as the OIDC auth method
|
||||
testManagedGroups := true
|
||||
// Turning this off means users are not directly added to roles. Useful
|
||||
// since we can't set users to 0 (or we won't accounts) but if we want to
|
||||
// test only managed groups.
|
||||
addUsersDirectly := true
|
||||
|
||||
o, p := iam.TestScopes(
|
||||
t,
|
||||
@@ -33,16 +43,37 @@ func TestGrantsForUser(t *testing.T) {
|
||||
iam.WithSkipDefaultRoleCreation(true),
|
||||
)
|
||||
|
||||
// We're going to generate a bunch of users, groups, and managed groups.
|
||||
// These will be randomly assigned and we will record assignations.
|
||||
users := func() (ret []*iam.User) {
|
||||
ret = make([]*iam.User, 0, userCount)
|
||||
kmsCache := kms.TestKms(t, conn, wrap)
|
||||
databaseWrapper, err := kmsCache.GetWrapper(ctx, o.PublicId, kms.KeyPurposeDatabase)
|
||||
require.NoError(t, err)
|
||||
|
||||
authMethod := oidc.TestAuthMethod(
|
||||
t, conn, databaseWrapper, o.GetPublicId(), oidc.ActivePrivateState,
|
||||
"alice-rp", "fido",
|
||||
oidc.WithSigningAlgs(oidc.RS256),
|
||||
oidc.WithIssuer(oidc.TestConvertToUrls(t, "https://www.alice.com")[0]),
|
||||
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) {
|
||||
usrs = make([]*iam.User, 0, userCount)
|
||||
accts = make([]*oidc.Account, 0, userCount)
|
||||
scopeId := scope.Global.String()
|
||||
if mathrand.Int()%2 == 0 {
|
||||
if mathrand.Int()%2 == 0 || testManagedGroups {
|
||||
scopeId = o.GetPublicId()
|
||||
}
|
||||
for i := 0; i < userCount; i++ {
|
||||
ret = append(ret, iam.TestUser(t, iamRepo, scopeId, iam.WithName(fmt.Sprintf("testuser%d", i))))
|
||||
accts = append(accts, oidc.TestAccount(t, conn, authMethod, fmt.Sprintf("sub-%d", i)))
|
||||
usrs = append(usrs, iam.TestUser(
|
||||
t,
|
||||
iamRepo,
|
||||
scopeId,
|
||||
iam.WithAccountIds(accts[i].PublicId),
|
||||
iam.WithName(fmt.Sprintf("testuser%d", i)),
|
||||
))
|
||||
}
|
||||
return
|
||||
}()
|
||||
@@ -57,6 +88,13 @@ 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))))
|
||||
}
|
||||
return
|
||||
}()
|
||||
roles := func() (ret []*iam.Role) {
|
||||
ret = make([]*iam.Role, 0, roleCount)
|
||||
scopeId := o.GetPublicId()
|
||||
@@ -76,8 +114,7 @@ func TestGrantsForUser(t *testing.T) {
|
||||
userToGroupsMapping := map[string]map[string]bool{}
|
||||
for _, user := range users {
|
||||
for _, group := range groups {
|
||||
// Give each user about a chance of being in any specific
|
||||
// group
|
||||
// Give each user a chance of being in any specific group
|
||||
if mathrand.Int()%probFactor == 0 {
|
||||
userId := user.PublicId
|
||||
groupId := group.PublicId
|
||||
@@ -91,32 +128,55 @@ 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{}
|
||||
for i, user := range users {
|
||||
for _, managedGroup := range managedGroups {
|
||||
// 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
|
||||
managedGroupId := managedGroup.PublicId
|
||||
oidc.TestManagedGroupMember(t, conn, managedGroupId, accountId)
|
||||
currentMapping := userToManagedGroupsMapping[userId]
|
||||
if currentMapping == nil {
|
||||
currentMapping = make(map[string]bool)
|
||||
}
|
||||
currentMapping[managedGroupId] = true
|
||||
userToManagedGroupsMapping[userId] = currentMapping
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now, we're going to randomly assign users and groups to roles and also
|
||||
// store mappings
|
||||
userToRolesMapping := map[string]map[string]bool{}
|
||||
groupToRolesMapping := map[string]map[string]bool{}
|
||||
for _, role := range roles {
|
||||
for _, user := range users {
|
||||
// Give each user about a chance of being directly added to
|
||||
// any specific role
|
||||
if mathrand.Int()%probFactor == 0 {
|
||||
roleId := role.PublicId
|
||||
userId := user.PublicId
|
||||
iam.TestUserRole(t, conn, roleId, userId)
|
||||
currentMapping := userToRolesMapping[userId]
|
||||
if currentMapping == nil {
|
||||
currentMapping = make(map[string]bool)
|
||||
managedGroupToRolesMapping := map[string]map[string]bool{}
|
||||
if addUsersDirectly {
|
||||
for _, role := range roles {
|
||||
for _, user := range users {
|
||||
// Give each user a chance of being directly added to any specific
|
||||
// role
|
||||
if mathrand.Int()%probFactor == 0 {
|
||||
roleId := role.PublicId
|
||||
userId := user.PublicId
|
||||
iam.TestUserRole(t, conn, roleId, userId)
|
||||
currentMapping := userToRolesMapping[userId]
|
||||
if currentMapping == nil {
|
||||
currentMapping = make(map[string]bool)
|
||||
}
|
||||
currentMapping[roleId] = true
|
||||
userToRolesMapping[userId] = currentMapping
|
||||
}
|
||||
currentMapping[roleId] = true
|
||||
userToRolesMapping[userId] = currentMapping
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, role := range roles {
|
||||
for _, group := range groups {
|
||||
// Give each group about a chance of being directly added to
|
||||
// any specific role
|
||||
// Give each group a chance of being directly added to any specific
|
||||
// role
|
||||
if mathrand.Int()%probFactor == 0 {
|
||||
roleId := role.PublicId
|
||||
groupId := group.PublicId
|
||||
@@ -130,10 +190,29 @@ 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
|
||||
if mathrand.Int()%probFactor == 0 {
|
||||
roleId := role.PublicId
|
||||
managedGroupId := managedGroup.PublicId
|
||||
iam.TestManagedGroupRole(t, conn, roleId, managedGroupId)
|
||||
currentMapping := managedGroupToRolesMapping[managedGroupId]
|
||||
if currentMapping == nil {
|
||||
currentMapping = make(map[string]bool)
|
||||
}
|
||||
currentMapping[roleId] = true
|
||||
managedGroupToRolesMapping[managedGroupId] = currentMapping
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
tuples, err := iamRepo.GrantsForUser(ctx, user.PublicId)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -150,14 +229,24 @@ func TestGrantsForUser(t *testing.T) {
|
||||
expectedRoleIds := make(map[string]bool, len(tuples))
|
||||
for roleId := range userToRolesMapping[user.PublicId] {
|
||||
expectedRoleIds[roleId] = true
|
||||
rolesFromUsers++
|
||||
}
|
||||
for groupId := range userToGroupsMapping[user.PublicId] {
|
||||
for roleId := range groupToRolesMapping[groupId] {
|
||||
expectedRoleIds[roleId] = true
|
||||
rolesFromGroups++
|
||||
}
|
||||
}
|
||||
for managedGroupId := range userToManagedGroupsMapping[user.PublicId] {
|
||||
for roleId := range managedGroupToRolesMapping[managedGroupId] {
|
||||
expectedRoleIds[roleId] = true
|
||||
rolesFromManagedGroups++
|
||||
}
|
||||
}
|
||||
|
||||
// Now verify that the expected set and returned set match
|
||||
assert.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)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user