Skip to content
This repository was archived by the owner on Mar 15, 2024. It is now read-only.

Commit 458646a

Browse files
author
Amey Bhide
committed
Allow custom username prefix while creating ephemeral Splunk user
Tickets: TE-34
1 parent 3ca0d5e commit 458646a

File tree

5 files changed

+63
-8
lines changed

5 files changed

+63
-8
lines changed

README.md

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,17 @@ make dev
6666
vault secrets enable -path=splunk -plugin-name=vault-plugin-splunk plugin || true
6767
vault write splunk/config/local url="${SPLUNK_ADDR}" insecure_tls=true username=admin password="${SPLUNK_PASSWORD}" allowed_roles='*'
6868
vault write splunk/roles/local-admin roles=admin email='[email protected]' connection=local default_ttl=30s max_ttl=5m
69+
vault read splunk/roles/local-admin
70+
Key Value
71+
--- -----
72+
connection local
73+
default_app n/a
74+
default_ttl 30s
75+
76+
max_ttl 5m
77+
roles [admin]
78+
tz n/a
79+
user_prefix vault
6980
```
7081

7182
## Plugin Usage
@@ -82,9 +93,9 @@ Create temporary admin account:
8293
password 439e831b-e395-9999-2cd7-856381db3394
8394
roles [admin]
8495
url https://localhost:8089
85-
username vault_local-admin_okta-mweber_70c6c140-238d-e12b-3289-8e38f8c4d9f5_1553712516020311000
96+
username vault_70c6c140-238d-e12b-3289-8e38f8c4d9f5
8697

87-
This creates a new user account `vault_local-admin_okta-mweber_70c6...`
98+
This creates a new user account `vault_70c6c140-238d-e12b-3289-8e38f8c4d9f5`
8899
with a new random password. The account was configured to have the
89100
admin role. It will automatically be queued for deletion by vault
90101
after the configured lease ends, in 5 minutes. We can use `vault

backend_test.go

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ func TestBackend_basic(t *testing.T) {
2323
roleConfig := roleConfig{
2424
Connection: "testconn",
2525
Roles: []string{"admin"},
26+
UserPrefix: defaultUserPrefix,
2627
}
2728

2829
logicaltest.Test(t, logicaltest.TestCase{
@@ -85,22 +86,34 @@ func TestBackend_RoleCRUD(t *testing.T) {
8586
t.Fatal(err)
8687
}
8788

88-
roleConfig := roleConfig{
89+
testRoleConfig := roleConfig{
8990
Connection: "testconn",
9091
Roles: []string{"admin"},
92+
UserPrefix: "my-custom-prefix",
9193
}
9294

9395
logicaltest.Test(t, logicaltest.TestCase{
9496
LogicalBackend: b,
9597
Steps: []logicaltest.TestStep{
9698
testAccStepConfig(t),
97-
testAccStepRole(t, "test", roleConfig),
99+
testAccStepRole(t, "test", testRoleConfig),
98100
testAccStepRoleMissingRoleName(t),
99101
testAccStepRoleMissingRoles(t, "MISSING"),
100-
testAccStepRoleRead(t, "test", roleConfig),
102+
testAccStepRoleRead(t, "test", testRoleConfig),
101103
testAccStepRoleDelete(t, "test"),
102104
},
103105
})
106+
emptyUserPrefixConfig := roleConfig{
107+
Connection: "testconn",
108+
Roles: []string{"admin"},
109+
UserPrefix: "",
110+
}
111+
logicaltest.Test(t, logicaltest.TestCase{
112+
LogicalBackend: b,
113+
Steps: []logicaltest.TestStep{
114+
testEmptyUserPrefix(t, "test", emptyUserPrefixConfig),
115+
},
116+
})
104117
}
105118

106119
// Test steps
@@ -188,6 +201,22 @@ func testAccStepRoleMissingRoleName(t *testing.T) logicaltest.TestStep {
188201
}
189202
}
190203

204+
func testEmptyUserPrefix(t *testing.T, role string, config roleConfig) logicaltest.TestStep {
205+
return logicaltest.TestStep{
206+
Operation: logical.CreateOperation,
207+
Path: rolesPrefix + role,
208+
Data: config.toResponseData(),
209+
ErrorOk: true,
210+
Check: func(resp *logical.Response) error {
211+
if resp == nil {
212+
return fmt.Errorf("response is nil")
213+
}
214+
assert.Error(t, resp.Error(), "user_prefix can't be set to empty string")
215+
return nil
216+
},
217+
}
218+
}
219+
191220
func testAccStepCredsRead(t *testing.T, role string) logicaltest.TestStep {
192221
return logicaltest.TestStep{
193222
Operation: logical.ReadOperation,

path_creds_create.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ package splunk
33
import (
44
"context"
55
"fmt"
6-
"time"
7-
86
"github.com/hashicorp/errwrap"
97
"github.com/hashicorp/go-uuid"
108
"github.com/hashicorp/vault/helper/strutil"
@@ -62,7 +60,11 @@ func (b *backend) credsReadHandler(ctx context.Context, req *logical.Request, d
6260
if err != nil {
6361
return nil, err
6462
}
65-
username := fmt.Sprintf("vault_%s_%s_%s_%d", name, req.DisplayName, userUUID, time.Now().UnixNano())
63+
userPrefix := role.UserPrefix
64+
if role.UserPrefix == defaultUserPrefix {
65+
userPrefix = fmt.Sprintf("%s_%s", role.UserPrefix, req.DisplayName)
66+
}
67+
username := fmt.Sprintf("%s_%s", userPrefix, userUUID)
6668
passwd, err := uuid.GenerateUUID()
6769
if err != nil {
6870
return nil, errwrap.Wrapf("error generating new password {{err}}", err)

path_roles.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
)
1010

1111
const rolesPrefix = "roles/"
12+
const defaultUserPrefix = "vault"
1213

1314
func (b *backend) pathRoles() *framework.Path {
1415
return &framework.Path{
@@ -47,6 +48,11 @@ func (b *backend) pathRoles() *framework.Path {
4748
Type: framework.TypeString,
4849
Description: "User time zone.",
4950
},
51+
"user_prefix": &framework.FieldSchema{
52+
Type: framework.TypeString,
53+
Description: "Prefix for creating new users",
54+
Default: defaultUserPrefix,
55+
},
5056
},
5157
Callbacks: map[logical.Operation]framework.OperationFunc{
5258
logical.ReadOperation: b.rolesReadHandler,
@@ -124,6 +130,12 @@ func (b *backend) rolesWriteHandler(ctx context.Context, req *logical.Request, d
124130
if tzRaw, ok := getValue(data, req.Operation, "tz"); ok {
125131
role.TZ = tzRaw.(string)
126132
}
133+
if userPrefixRaw, ok := getValue(data, req.Operation, "user_prefix"); ok {
134+
role.UserPrefix = userPrefixRaw.(string)
135+
}
136+
if role.UserPrefix == "" {
137+
return logical.ErrorResponse("user_prefix can't be set to empty string"), nil
138+
}
127139

128140
if err := role.store(ctx, req.Storage, name); err != nil {
129141
return nil, err

role.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ type roleConfig struct {
2020
DefaultApp string `json:"default_app,omitempty" structs:"default_app"`
2121
Email string `json:"email,omitempty" structs:"email"`
2222
TZ string `json:"tz,omitempty" structs:"tz"`
23+
UserPrefix string `json:"user_prefix,omitempty" structs:"user_prefix"`
2324
}
2425

2526
// Role returns nil if role named `name` does not exist in `storage`, otherwise

0 commit comments

Comments
 (0)