Skip to content

Commit

Permalink
enable hierarchical path for rotate-role endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
fairclothjm committed May 3, 2024
1 parent 83da570 commit cab0c82
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 73 deletions.
3 changes: 2 additions & 1 deletion path_rotate.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"context"
"errors"
"fmt"
"strings"
"time"

"github.com/hashicorp/vault/sdk/framework"
Expand Down Expand Up @@ -48,7 +49,7 @@ func (b *backend) pathRotateCredentials() []*framework.Path {
"(binddn) used by Vault to manage LDAP.",
},
{
Pattern: rotateRolePath + framework.GenericNameRegex("name"),
Pattern: strings.TrimSuffix(rotateRolePath, "/") + GenericNameWithForwardSlashRegex("name"),
DisplayAttrs: &framework.DisplayAttributes{
OperationPrefix: operationPrefixLDAP,
OperationVerb: "rotate",
Expand Down
136 changes: 64 additions & 72 deletions path_rotate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@ import (
"time"

"github.com/go-ldap/ldif"
"github.com/hashicorp/go-secure-stdlib/strutil"
"github.com/hashicorp/vault-plugin-secrets-openldap/client"
"github.com/hashicorp/vault/sdk/helper/ldaputil"
"github.com/hashicorp/vault/sdk/logical"
"github.com/stretchr/testify/assert"
)

func TestManualRotate(t *testing.T) {
t.Run("rotate root", func(t *testing.T) {
func TestManualRotateRoot(t *testing.T) {
t.Run("happy path rotate root", func(t *testing.T) {
b, storage := getBackend(false)
defer b.Cleanup(context.Background())

Expand Down Expand Up @@ -83,107 +84,99 @@ func TestManualRotate(t *testing.T) {
t.Fatal("should have got error, didn't")
}
})
}

t.Run("rotate role", func(t *testing.T) {
func TestManualRotateRole(t *testing.T) {
t.Run("happy path rotate role", func(t *testing.T) {
b, storage := getBackend(false)
defer b.Cleanup(context.Background())

data := map[string]interface{}{
"binddn": "tester",
"bindpass": "pa$$w0rd",
"url": "ldap://138.91.247.105",
"certificate": validCertificate,
}
roleName := "hashicorp"
configureOpenLDAPMount(t, b, storage)
createRole(t, b, storage, roleName)

req := &logical.Request{
Operation: logical.CreateOperation,
Path: configPath,
Storage: storage,
Data: data,
}
resp, _ := readStaticCred(t, b, storage, roleName)

resp, err := b.HandleRequest(context.Background(), req)
if err != nil || (resp != nil && resp.IsError()) {
t.Fatalf("err:%s resp:%#v\n", err, resp)
if resp.Data["password"] == "" {
t.Fatal("expected password to be set, it wasn't")
}
oldPassword := resp.Data["password"]

req = &logical.Request{
req := &logical.Request{
Operation: logical.UpdateOperation,
Path: rotateRootPath,
Path: rotateRolePath + roleName,
Storage: storage,
Data: nil,
}

resp, err = b.HandleRequest(context.Background(), req)
resp, err := b.HandleRequest(context.Background(), req)
if err != nil || (resp != nil && resp.IsError()) {
t.Fatalf("err:%s resp:%#v\n", err, resp)
}

data = map[string]interface{}{
"username": "hashicorp",
"dn": "uid=hashicorp,ou=users,dc=hashicorp,dc=com",
"rotation_period": "60s",
}
resp, _ = readStaticCred(t, b, storage, roleName)

req = &logical.Request{
Operation: logical.CreateOperation,
Path: staticRolePath + "hashicorp",
Storage: storage,
Data: data,
if resp.Data["password"] == "" {
t.Fatal("expected password to be set after rotate, it wasn't")
}

resp, err = b.HandleRequest(context.Background(), req)
if err != nil || (resp != nil && resp.IsError()) {
t.Fatalf("err:%s resp:%#v\n", err, resp)
if oldPassword == resp.Data["password"] {
t.Fatal("expected passwords to be different after rotation, they weren't")
}
})

req = &logical.Request{
Operation: logical.ReadOperation,
Path: staticCredPath + "hashicorp",
Storage: storage,
Data: nil,
}
t.Run("happy path rotate role with hierarchical path", func(t *testing.T) {
b, storage := getBackend(false)
defer b.Cleanup(context.Background())

resp, err = b.HandleRequest(context.Background(), req)
if err != nil || (resp != nil && resp.IsError()) {
t.Fatalf("err:%s resp:%#v\n", err, resp)
}
configureOpenLDAPMount(t, b, storage)

if resp.Data["password"] == "" {
t.Fatal("expected password to be set, it wasn't")
}
oldPassword := resp.Data["password"]
roles := []string{"org/secure", "org/platform/dev", "org/platform/support"}

req = &logical.Request{
Operation: logical.UpdateOperation,
Path: rotateRolePath + "hashicorp",
Storage: storage,
Data: nil,
// create all the roles
for _, role := range roles {
data := getTestStaticRoleConfig(role)
createStaticRoleWithData(t, b, storage, role, data)
}

resp, err = b.HandleRequest(context.Background(), req)
if err != nil || (resp != nil && resp.IsError()) {
t.Fatalf("err:%s resp:%#v\n", err, resp)
}
passwords := make([]string, 0)
// rotate all the creds
for _, role := range roles {
resp, _ := readStaticCred(t, b, storage, role)

req = &logical.Request{
Operation: logical.ReadOperation,
Path: staticCredPath + "hashicorp",
Storage: storage,
Data: nil,
}
if resp.Data["password"] == "" {
t.Fatal("expected password to be set, it wasn't")
}
oldPassword := resp.Data["password"]

resp, err = b.HandleRequest(context.Background(), req)
if err != nil || (resp != nil && resp.IsError()) {
t.Fatalf("err:%s resp:%#v\n", err, resp)
}
req := &logical.Request{
Operation: logical.UpdateOperation,
Path: rotateRolePath + role,
Storage: storage,
Data: nil,
}

if resp.Data["password"] == "" {
t.Fatal("expected password to be set after rotate, it wasn't")
resp, err := b.HandleRequest(context.Background(), req)
if err != nil || (resp != nil && resp.IsError()) {
t.Fatalf("err:%s resp:%#v\n", err, resp)
}

resp, _ = readStaticCred(t, b, storage, role)

newPassword := resp.Data["password"]
if newPassword == "" {
t.Fatal("expected password to be set after rotate, it wasn't")
}

if oldPassword == newPassword {
t.Fatal("expected passwords to be different after rotation, they weren't")
}
passwords = append(passwords, newPassword.(string))
}

if oldPassword == resp.Data["password"] {
t.Fatal("expected passwords to be different after rotation, they weren't")
// extra pendantic check that the hierarchical paths don't return the same data
if len(passwords) != len(strutil.RemoveDuplicates(passwords, false)) {
t.Fatal("expected unique static-role paths to return unique passwords")
}
})

Expand Down Expand Up @@ -284,7 +277,6 @@ func TestRollbackPassword(t *testing.T) {
}
assert.Equal(t, testCase.expectedPassword, fclient.password)
assert.Equal(t, testCase.expectedRollbackCalls, fclient.count)

})
}
}

0 comments on commit cab0c82

Please sign in to comment.