open-vault/vault/external_tests/identity/identity_test.go

362 lines
9.1 KiB
Go
Raw Normal View History

2018-08-23 00:50:52 +00:00
package identity
import (
"github.com/go-ldap/ldap"
"github.com/hashicorp/vault/sdk/helper/ldaputil"
"testing"
log "github.com/hashicorp/go-hclog"
"github.com/hashicorp/vault/api"
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/sdk/logical"
"github.com/hashicorp/vault/vault"
)
func TestIdentityStore_Integ_GroupAliases(t *testing.T) {
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 := func(groupName, groupID string, expectFound bool) {
secret, err = client.Logical().Read("identity/group/id/" + groupID)
if err != nil {
t.Fatal(err)
}
groupMap := secret.Data
found := false
for _, entityIDRaw := range groupMap["member_entity_ids"].([]interface{}) {
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)
}
}
assertMember("ship_crew", shipCrewGroupID, false)
assertMember("admin_staff", adminStaffGroupID, true)
assertMember("devops", devopsGroupID, true)
assertMember("engineer", devopsGroupID, true)
// Now add Hermes to ship_crew
{
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)
}
hermesDn := "cn=Hermes Conrad,ou=people,dc=planetexpress,dc=com"
shipCrewDn := "cn=ship_crew,ou=people,dc=planetexpress,dc=com"
ldapreq := ldap.ModifyRequest{DN: shipCrewDn}
ldapreq.Add("member", []string{hermesDn})
err = conn.Modify(&ldapreq)
if err != nil {
t.Fatal(err)
}
}
// 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("ship_crew", shipCrewGroupID, true)
assertMember("admin_staff", adminStaffGroupID, true)
assertMember("devops", devopsGroupID, true)
assertMember("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("ship_crew", shipCrewGroupID, true)
assertMember("admin_staff", adminStaffGroupID, true)
assertMember("devops", devopsGroupID, true)
assertMember("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")
}
}