fa754c7fa5
* Replicate values of group member_entity_ids and policies across nodes identically * Adding CL * fixing tests
697 lines
19 KiB
Go
697 lines
19 KiB
Go
package identity
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/hashicorp/go-secure-stdlib/strutil"
|
|
"github.com/hashicorp/vault/api"
|
|
"github.com/hashicorp/vault/sdk/helper/ldaputil"
|
|
"github.com/hashicorp/vault/sdk/logical"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/hashicorp/vault/helper/testhelpers/teststorage"
|
|
|
|
"github.com/go-ldap/ldap/v3"
|
|
log "github.com/hashicorp/go-hclog"
|
|
ldapcred "github.com/hashicorp/vault/builtin/credential/ldap"
|
|
"github.com/hashicorp/vault/helper/namespace"
|
|
ldaphelper "github.com/hashicorp/vault/helper/testhelpers/ldap"
|
|
vaulthttp "github.com/hashicorp/vault/http"
|
|
"github.com/hashicorp/vault/vault"
|
|
)
|
|
|
|
func TestIdentityStore_ExternalGroupMemberships_DifferentMounts(t *testing.T) {
|
|
coreConfig := &vault.CoreConfig{
|
|
CredentialBackends: map[string]logical.Factory{
|
|
"ldap": ldapcred.Factory,
|
|
},
|
|
}
|
|
conf, opts := teststorage.ClusterSetup(coreConfig, nil, nil)
|
|
cluster := vault.NewTestCluster(t, conf, opts)
|
|
cluster.Start()
|
|
defer cluster.Cleanup()
|
|
|
|
core := cluster.Cores[0].Core
|
|
client := cluster.Cores[0].Client
|
|
vault.TestWaitActive(t, core)
|
|
|
|
// Create a entity
|
|
secret, err := client.Logical().Write("identity/entity", map[string]interface{}{
|
|
"name": "testentityname",
|
|
})
|
|
require.NoError(t, err)
|
|
entityID := secret.Data["id"].(string)
|
|
|
|
cleanup, config1 := ldaphelper.PrepareTestContainer(t, "latest")
|
|
defer cleanup()
|
|
|
|
cleanup2, config2 := ldaphelper.PrepareTestContainer(t, "latest")
|
|
defer cleanup2()
|
|
|
|
setupFunc := func(path string, cfg *ldaputil.ConfigEntry) string {
|
|
// Create an external group
|
|
resp, err := client.Logical().Write("identity/group", map[string]interface{}{
|
|
"type": "external",
|
|
"name": path + "ldap_admin_staff",
|
|
"policies": []string{"admin-policy"},
|
|
})
|
|
require.NoError(t, err)
|
|
require.NotNil(t, resp)
|
|
require.NotNil(t, resp.Data)
|
|
groupID := resp.Data["id"].(string)
|
|
|
|
// Enable LDAP mount in Vault
|
|
err = client.Sys().EnableAuthWithOptions(path, &api.EnableAuthOptions{
|
|
Type: "ldap",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// Take out its accessor
|
|
auth, err := client.Sys().ListAuth()
|
|
require.NoError(t, err)
|
|
accessor := auth[path+"/"].Accessor
|
|
require.NotEmpty(t, accessor)
|
|
|
|
// Create an external group alias
|
|
resp, err = client.Logical().Write("identity/group-alias", map[string]interface{}{
|
|
"name": "admin_staff",
|
|
"canonical_id": groupID,
|
|
"mount_accessor": accessor,
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// Create a user in Vault
|
|
_, err = client.Logical().Write("auth/"+path+"/users/hermes conrad", map[string]interface{}{
|
|
"password": "hermes",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// Create an entity alias
|
|
client.Logical().Write("identity/entity-alias", map[string]interface{}{
|
|
"name": "hermes conrad",
|
|
"canonical_id": entityID,
|
|
"mount_accessor": accessor,
|
|
})
|
|
|
|
// Configure LDAP auth
|
|
secret, err = client.Logical().Write("auth/"+path+"/config", map[string]interface{}{
|
|
"url": cfg.Url,
|
|
"userattr": cfg.UserAttr,
|
|
"userdn": cfg.UserDN,
|
|
"groupdn": cfg.GroupDN,
|
|
"groupattr": cfg.GroupAttr,
|
|
"binddn": cfg.BindDN,
|
|
"bindpass": cfg.BindPassword,
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
secret, err = client.Logical().Write("auth/"+path+"/login/hermes conrad", map[string]interface{}{
|
|
"password": "hermes",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
policies, err := secret.TokenPolicies()
|
|
require.NoError(t, err)
|
|
require.Contains(t, policies, "admin-policy")
|
|
|
|
secret, err = client.Logical().Read("identity/group/id/" + groupID)
|
|
require.NoError(t, err)
|
|
require.Contains(t, secret.Data["member_entity_ids"], entityID)
|
|
|
|
return groupID
|
|
}
|
|
groupID1 := setupFunc("ldap", config1)
|
|
groupID2 := setupFunc("ldap2", config2)
|
|
|
|
// Remove hermes conrad from admin_staff group
|
|
removeLdapGroupMember(t, config1, "admin_staff", "hermes conrad")
|
|
secret, err = client.Logical().Write("auth/ldap/login/hermes conrad", map[string]interface{}{
|
|
"password": "hermes",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
secret, err = client.Logical().Read("identity/group/id/" + groupID1)
|
|
require.NoError(t, err)
|
|
require.NotContains(t, secret.Data["member_entity_ids"], entityID)
|
|
|
|
secret, err = client.Logical().Read("identity/group/id/" + groupID2)
|
|
require.NoError(t, err)
|
|
require.Contains(t, secret.Data["member_entity_ids"], entityID)
|
|
}
|
|
|
|
func TestIdentityStore_Integ_GroupAliases(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
var err error
|
|
coreConfig := &vault.CoreConfig{
|
|
DisableMlock: true,
|
|
DisableCache: true,
|
|
Logger: log.NewNullLogger(),
|
|
CredentialBackends: map[string]logical.Factory{
|
|
"ldap": ldapcred.Factory,
|
|
},
|
|
}
|
|
|
|
cluster := vault.NewTestCluster(t, coreConfig, &vault.TestClusterOptions{
|
|
HandlerFunc: vaulthttp.Handler,
|
|
})
|
|
|
|
cluster.Start()
|
|
defer cluster.Cleanup()
|
|
|
|
cores := cluster.Cores
|
|
|
|
vault.TestWaitActive(t, cores[0].Core)
|
|
|
|
client := cores[0].Client
|
|
|
|
err = client.Sys().EnableAuthWithOptions("ldap", &api.EnableAuthOptions{
|
|
Type: "ldap",
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
auth, err := client.Sys().ListAuth()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
accessor := auth["ldap/"].Accessor
|
|
|
|
secret, err := client.Logical().Write("identity/group", map[string]interface{}{
|
|
"type": "external",
|
|
"name": "ldap_ship_crew",
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
shipCrewGroupID := secret.Data["id"].(string)
|
|
|
|
secret, err = client.Logical().Write("identity/group", map[string]interface{}{
|
|
"type": "external",
|
|
"name": "ldap_admin_staff",
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
adminStaffGroupID := secret.Data["id"].(string)
|
|
|
|
secret, err = client.Logical().Write("identity/group", map[string]interface{}{
|
|
"type": "external",
|
|
"name": "ldap_devops",
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
devopsGroupID := secret.Data["id"].(string)
|
|
|
|
secret, err = client.Logical().Write("identity/group-alias", map[string]interface{}{
|
|
"name": "ship_crew",
|
|
"canonical_id": shipCrewGroupID,
|
|
"mount_accessor": accessor,
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
secret, err = client.Logical().Write("identity/group-alias", map[string]interface{}{
|
|
"name": "admin_staff",
|
|
"canonical_id": adminStaffGroupID,
|
|
"mount_accessor": accessor,
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
secret, err = client.Logical().Write("identity/group-alias", map[string]interface{}{
|
|
"name": "devops",
|
|
"canonical_id": devopsGroupID,
|
|
"mount_accessor": accessor,
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
secret, err = client.Logical().Read("identity/group/id/" + shipCrewGroupID)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
aliasMap := secret.Data["alias"].(map[string]interface{})
|
|
if aliasMap["canonical_id"] != shipCrewGroupID ||
|
|
aliasMap["name"] != "ship_crew" ||
|
|
aliasMap["mount_accessor"] != accessor {
|
|
t.Fatalf("bad: group alias: %#v\n", aliasMap)
|
|
}
|
|
|
|
secret, err = client.Logical().Read("identity/group/id/" + adminStaffGroupID)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
aliasMap = secret.Data["alias"].(map[string]interface{})
|
|
if aliasMap["canonical_id"] != adminStaffGroupID ||
|
|
aliasMap["name"] != "admin_staff" ||
|
|
aliasMap["mount_accessor"] != accessor {
|
|
t.Fatalf("bad: group alias: %#v\n", aliasMap)
|
|
}
|
|
|
|
cleanup, cfg := ldaphelper.PrepareTestContainer(t, "latest")
|
|
defer cleanup()
|
|
|
|
// Configure LDAP auth
|
|
secret, err = client.Logical().Write("auth/ldap/config", map[string]interface{}{
|
|
"url": cfg.Url,
|
|
"userattr": cfg.UserAttr,
|
|
"userdn": cfg.UserDN,
|
|
"groupdn": cfg.GroupDN,
|
|
"groupattr": cfg.GroupAttr,
|
|
"binddn": cfg.BindDN,
|
|
"bindpass": cfg.BindPassword,
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Create a local group in LDAP backend
|
|
secret, err = client.Logical().Write("auth/ldap/groups/devops", map[string]interface{}{
|
|
"policies": "default",
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Create a local group in LDAP backend
|
|
secret, err = client.Logical().Write("auth/ldap/groups/engineers", map[string]interface{}{
|
|
"policies": "default",
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Create a local user in LDAP
|
|
secret, err = client.Logical().Write("auth/ldap/users/hermes conrad", map[string]interface{}{
|
|
"policies": "default",
|
|
"groups": "engineers,devops",
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Login with LDAP and create a token
|
|
secret, err = client.Logical().Write("auth/ldap/login/hermes conrad", map[string]interface{}{
|
|
"password": "hermes",
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
token := secret.Auth.ClientToken
|
|
|
|
// Lookup the token to get the entity ID
|
|
secret, err = client.Auth().Token().Lookup(token)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
entityID := secret.Data["entity_id"].(string)
|
|
|
|
// Re-read the admin_staff, ship_crew and devops group. This entity ID should have
|
|
// been added to admin_staff but not ship_crew.
|
|
assertMember(t, client, entityID, "ship_crew", shipCrewGroupID, false)
|
|
assertMember(t, client, entityID, "admin_staff", adminStaffGroupID, true)
|
|
assertMember(t, client, entityID, "devops", devopsGroupID, true)
|
|
assertMember(t, client, entityID, "engineer", devopsGroupID, true)
|
|
|
|
// Now add Hermes to ship_crew
|
|
addLdapGroupMember(t, cfg, "ship_crew", "hermes conrad")
|
|
|
|
// Re-login with LDAP
|
|
secret, err = client.Logical().Write("auth/ldap/login/hermes conrad", map[string]interface{}{
|
|
"password": "hermes",
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Hermes should now be in ship_crew external group
|
|
assertMember(t, client, entityID, "ship_crew", shipCrewGroupID, true)
|
|
assertMember(t, client, entityID, "admin_staff", adminStaffGroupID, true)
|
|
assertMember(t, client, entityID, "devops", devopsGroupID, true)
|
|
assertMember(t, client, entityID, "engineer", devopsGroupID, true)
|
|
|
|
identityStore := cores[0].IdentityStore()
|
|
|
|
group, err := identityStore.MemDBGroupByID(shipCrewGroupID, true)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Remove its member entities
|
|
group.MemberEntityIDs = nil
|
|
|
|
ctx := namespace.RootContext(nil)
|
|
|
|
err = identityStore.UpsertGroup(ctx, group, true)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
group, err = identityStore.MemDBGroupByID(shipCrewGroupID, true)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if group.MemberEntityIDs != nil {
|
|
t.Fatalf("failed to remove entity ID from the group")
|
|
}
|
|
|
|
group, err = identityStore.MemDBGroupByID(adminStaffGroupID, true)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Remove its member entities
|
|
group.MemberEntityIDs = nil
|
|
|
|
err = identityStore.UpsertGroup(ctx, group, true)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
group, err = identityStore.MemDBGroupByID(adminStaffGroupID, true)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if group.MemberEntityIDs != nil {
|
|
t.Fatalf("failed to remove entity ID from the group")
|
|
}
|
|
|
|
group, err = identityStore.MemDBGroupByID(devopsGroupID, true)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Remove its member entities
|
|
group.MemberEntityIDs = nil
|
|
|
|
err = identityStore.UpsertGroup(ctx, group, true)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
group, err = identityStore.MemDBGroupByID(devopsGroupID, true)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if group.MemberEntityIDs != nil {
|
|
t.Fatalf("failed to remove entity ID from the group")
|
|
}
|
|
|
|
_, err = client.Auth().Token().Renew(token, 0)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
assertMember(t, client, entityID, "ship_crew", shipCrewGroupID, true)
|
|
assertMember(t, client, entityID, "admin_staff", adminStaffGroupID, true)
|
|
assertMember(t, client, entityID, "devops", devopsGroupID, true)
|
|
assertMember(t, client, entityID, "engineer", devopsGroupID, true)
|
|
|
|
// Remove user hermes conrad from the devops group in LDAP backend
|
|
secret, err = client.Logical().Write("auth/ldap/users/hermes conrad", map[string]interface{}{
|
|
"policies": "default",
|
|
"groups": "engineers",
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Renewing the token now should remove its entity ID from the devops
|
|
// group
|
|
_, err = client.Auth().Token().Renew(token, 0)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
group, err = identityStore.MemDBGroupByID(devopsGroupID, true)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if group.MemberEntityIDs != nil {
|
|
t.Fatalf("failed to remove entity ID from the group")
|
|
}
|
|
}
|
|
|
|
func TestIdentityStore_Integ_RemoveFromExternalGroup(t *testing.T) {
|
|
t.Parallel()
|
|
var err error
|
|
coreConfig := &vault.CoreConfig{
|
|
DisableMlock: true,
|
|
DisableCache: true,
|
|
Logger: log.NewNullLogger(),
|
|
CredentialBackends: map[string]logical.Factory{
|
|
"ldap": ldapcred.Factory,
|
|
},
|
|
}
|
|
|
|
cluster := vault.NewTestCluster(t, coreConfig, &vault.TestClusterOptions{
|
|
HandlerFunc: vaulthttp.Handler,
|
|
})
|
|
|
|
cluster.Start()
|
|
defer cluster.Cleanup()
|
|
|
|
cores := cluster.Cores
|
|
client := cores[0].Client
|
|
|
|
err = client.Sys().EnableAuthWithOptions("ldap", &api.EnableAuthOptions{
|
|
Type: "ldap",
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
auth, err := client.Sys().ListAuth()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
accessor := auth["ldap/"].Accessor
|
|
|
|
adminPolicy := "admin_policy"
|
|
secret, err := client.Logical().Write("identity/group", map[string]interface{}{
|
|
"type": "external",
|
|
"name": "ldap_admin_staff",
|
|
"policies": []string{adminPolicy},
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
adminStaffGroupID := secret.Data["id"].(string)
|
|
adminGroupName := "admin_staff"
|
|
|
|
secret, err = client.Logical().Write("identity/group-alias", map[string]interface{}{
|
|
"name": adminGroupName,
|
|
"canonical_id": adminStaffGroupID,
|
|
"mount_accessor": accessor,
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
secret, err = client.Logical().Read("identity/group/id/" + adminStaffGroupID)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
aliasMap := secret.Data["alias"].(map[string]interface{})
|
|
if aliasMap["canonical_id"] != adminStaffGroupID ||
|
|
aliasMap["name"] != adminGroupName ||
|
|
aliasMap["mount_accessor"] != accessor {
|
|
t.Fatalf("bad: group alias: %#v\n", aliasMap)
|
|
}
|
|
|
|
cleanup, cfg := ldaphelper.PrepareTestContainer(t, "latest")
|
|
defer cleanup()
|
|
|
|
// Configure LDAP auth
|
|
secret, err = client.Logical().Write("auth/ldap/config", map[string]interface{}{
|
|
"url": cfg.Url,
|
|
"userattr": cfg.UserAttr,
|
|
"userdn": cfg.UserDN,
|
|
"groupdn": cfg.GroupDN,
|
|
"groupattr": cfg.GroupAttr,
|
|
"binddn": cfg.BindDN,
|
|
"bindpass": cfg.BindPassword,
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Create a local user in LDAP
|
|
secret, err = client.Logical().Write("auth/ldap/users/hermes conrad", map[string]interface{}{
|
|
"policies": "default",
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Login with LDAP and create a token
|
|
secret, err = client.Logical().Write("auth/ldap/login/hermes conrad", map[string]interface{}{
|
|
"password": "hermes",
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
token := secret.Auth.ClientToken
|
|
tokenPolicies, err := secret.TokenPolicies()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !strutil.StrListContains(tokenPolicies, adminPolicy) {
|
|
t.Fatalf("expected token policies to contain %s, got: %v", adminPolicy, tokenPolicies)
|
|
}
|
|
|
|
// Lookup the token to get the entity ID
|
|
secret, err = client.Auth().Token().Lookup(token)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
entityID := secret.Data["entity_id"].(string)
|
|
|
|
assertMember(t, client, entityID, adminGroupName, adminStaffGroupID, true)
|
|
|
|
// Now remove Hermes from admin_staff
|
|
removeLdapGroupMember(t, cfg, adminGroupName, "hermes conrad")
|
|
|
|
// Re-login with LDAP
|
|
secret, err = client.Logical().Write("auth/ldap/login/hermes conrad", map[string]interface{}{
|
|
"password": "hermes",
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Hermes should now be out of admin_staff group
|
|
assertMember(t, client, entityID, adminGroupName, adminStaffGroupID, false)
|
|
tokenPolicies, err = secret.TokenPolicies()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if strutil.StrListContains(tokenPolicies, adminPolicy) {
|
|
t.Fatalf("expected token policies to not contain %s, got: %v", adminPolicy, tokenPolicies)
|
|
}
|
|
|
|
// Add Hermes back to admin_staff
|
|
addLdapGroupMember(t, cfg, adminGroupName, "hermes conrad")
|
|
|
|
// Re-login with LDAP
|
|
secret, err = client.Logical().Write("auth/ldap/login/hermes conrad", map[string]interface{}{
|
|
"password": "hermes",
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Hermes should now be back in admin_staff group
|
|
assertMember(t, client, entityID, adminGroupName, adminStaffGroupID, true)
|
|
tokenPolicies, err = secret.TokenPolicies()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !strutil.StrListContains(tokenPolicies, adminPolicy) {
|
|
t.Fatalf("expected token policies to contain %s, got: %v", adminPolicy, tokenPolicies)
|
|
}
|
|
|
|
// Remove Hermes from admin_staff once again
|
|
removeLdapGroupMember(t, cfg, adminGroupName, "hermes conrad")
|
|
|
|
oldToken := client.Token()
|
|
client.SetToken(secret.Auth.ClientToken)
|
|
secret, err = client.Auth().Token().RenewSelf(1)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
client.SetToken(oldToken)
|
|
assertMember(t, client, entityID, adminGroupName, adminStaffGroupID, false)
|
|
tokenPolicies, err = secret.TokenPolicies()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if strutil.StrListContains(tokenPolicies, adminPolicy) {
|
|
t.Fatalf("expected token policies to not contain %s, got: %v", adminPolicy, tokenPolicies)
|
|
}
|
|
}
|
|
|
|
func assertMember(t *testing.T, client *api.Client, entityID, groupName, groupID string, expectFound bool) {
|
|
t.Helper()
|
|
secret, err := client.Logical().Read("identity/group/id/" + groupID)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
groupMap := secret.Data
|
|
|
|
groupEntityMembers, ok := groupMap["member_entity_ids"].([]interface{})
|
|
if !ok && expectFound {
|
|
t.Fatalf("expected member_entity_ids not to be nil")
|
|
}
|
|
|
|
// if type assertion fails and expectFound is false, groupEntityMembers
|
|
// is nil, then let's just return, nothing to be done!
|
|
if !ok && !expectFound {
|
|
return
|
|
}
|
|
|
|
found := false
|
|
for _, entityIDRaw := range groupEntityMembers {
|
|
if entityIDRaw.(string) == entityID {
|
|
found = true
|
|
}
|
|
}
|
|
if found != expectFound {
|
|
negation := ""
|
|
if !expectFound {
|
|
negation = "not "
|
|
}
|
|
t.Fatalf("expected entity ID %q to %sbe part of %q group", entityID, negation, groupName)
|
|
}
|
|
}
|
|
|
|
func removeLdapGroupMember(t *testing.T, cfg *ldaputil.ConfigEntry, groupCN, userCN string) {
|
|
userDN := fmt.Sprintf("cn=%s,ou=people,dc=planetexpress,dc=com", userCN)
|
|
groupDN := fmt.Sprintf("cn=%s,ou=people,dc=planetexpress,dc=com", groupCN)
|
|
ldapreq := ldap.ModifyRequest{DN: groupDN}
|
|
ldapreq.Delete("member", []string{userDN})
|
|
addRemoveLdapGroupMember(t, cfg, userCN, &ldapreq)
|
|
}
|
|
|
|
func addLdapGroupMember(t *testing.T, cfg *ldaputil.ConfigEntry, groupCN, userCN string) {
|
|
userDN := fmt.Sprintf("cn=%s,ou=people,dc=planetexpress,dc=com", userCN)
|
|
groupDN := fmt.Sprintf("cn=%s,ou=people,dc=planetexpress,dc=com", groupCN)
|
|
ldapreq := ldap.ModifyRequest{DN: groupDN}
|
|
ldapreq.Add("member", []string{userDN})
|
|
addRemoveLdapGroupMember(t, cfg, userCN, &ldapreq)
|
|
}
|
|
|
|
func addRemoveLdapGroupMember(t *testing.T, cfg *ldaputil.ConfigEntry, userCN string, req *ldap.ModifyRequest) {
|
|
logger := log.New(nil)
|
|
ldapClient := ldaputil.Client{LDAP: ldaputil.NewLDAP(), Logger: logger}
|
|
// LDAP server won't accept changes unless we connect with TLS. This
|
|
// isn't the default config returned by PrepareTestContainer because
|
|
// the Vault LDAP backend won't work with it, even with InsecureTLS,
|
|
// because the ServerName should be planetexpress.com and not localhost.
|
|
conn, err := ldapClient.DialLDAP(cfg)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer conn.Close()
|
|
|
|
err = conn.Bind(cfg.BindDN, cfg.BindPassword)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = conn.Modify(req)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|