Add managed groups test (#1289)

pull/1278/head
Jeff Mitchell 5 years ago committed by GitHub
parent d6ef2732e7
commit 4d27b58d2d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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,42 +128,82 @@ 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{}
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
}
}
}
}
for _, role := range roles {
for _, user := range users {
// Give each user about a chance of being directly added to
// any specific role
for _, group := range groups {
// Give each group 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]
groupId := group.PublicId
iam.TestGroupRole(t, conn, roleId, groupId)
currentMapping := groupToRolesMapping[groupId]
if currentMapping == nil {
currentMapping = make(map[string]bool)
}
currentMapping[roleId] = true
userToRolesMapping[userId] = currentMapping
groupToRolesMapping[groupId] = currentMapping
}
}
}
for _, role := range roles {
for _, group := range groups {
// Give each group about a chance of being directly added to
// any specific role
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
groupId := group.PublicId
iam.TestGroupRole(t, conn, roleId, groupId)
currentMapping := groupToRolesMapping[groupId]
managedGroupId := managedGroup.PublicId
iam.TestManagedGroupRole(t, conn, roleId, managedGroupId)
currentMapping := managedGroupToRolesMapping[managedGroupId]
if currentMapping == nil {
currentMapping = make(map[string]bool)
}
currentMapping[roleId] = true
groupToRolesMapping[groupId] = currentMapping
managedGroupToRolesMapping[managedGroupId] = currentMapping
}
}
}
@ -134,6 +211,8 @@ 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
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)
}
}

Loading…
Cancel
Save