forked from splunk/vault-plugin-splunk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpath_creds_create.go
110 lines (96 loc) · 3.03 KB
/
path_creds_create.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package splunk
import (
"context"
"fmt"
"time"
"github.com/hashicorp/errwrap"
"github.com/hashicorp/go-uuid"
"github.com/hashicorp/vault/helper/strutil"
"github.com/hashicorp/vault/logical"
"github.com/hashicorp/vault/logical/framework"
"github.com/splunk/vault-plugin-splunk/clients/splunk"
)
func (b *backend) pathCredsCreate() *framework.Path {
return &framework.Path{
Pattern: "creds/" + framework.GenericNameRegex("name"),
Fields: map[string]*framework.FieldSchema{
"name": &framework.FieldSchema{
Type: framework.TypeString,
Description: "Name of the role",
},
},
Callbacks: map[logical.Operation]framework.OperationFunc{
logical.ReadOperation: b.credsReadHandler,
},
HelpSynopsis: pathCredsCreateHelpSyn,
HelpDescription: pathCredsCreateHelpDesc,
}
}
func (b *backend) credsReadHandler(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
name := d.Get("name").(string)
role, err := roleConfigLoad(ctx, req.Storage, name)
if err != nil {
return nil, err
}
if role == nil {
return logical.ErrorResponse(fmt.Sprintf("role not found: %q", name)), nil
}
config, err := connectionConfigLoad(ctx, req.Storage, role.Connection)
if err != nil {
return nil, err
}
// If role name isn't in allowed roles, send back a permission denied.
if !strutil.StrListContains(config.AllowedRoles, "*") && !strutil.StrListContainsGlob(config.AllowedRoles, name) {
return nil, fmt.Errorf("%q is not an allowed role for connection %q", name, role.Connection)
}
conn, err := b.ensureConnection(ctx, role.Connection, config)
if err != nil {
return nil, err
}
// Generate credentials
userUUID, err := uuid.GenerateUUID()
if err != nil {
return nil, err
}
username := fmt.Sprintf("vault_%s_%s_%s_%d", name, req.DisplayName, userUUID, time.Now().UnixNano())
passwd, err := uuid.GenerateUUID()
if err != nil {
return nil, errwrap.Wrapf("error generating new password {{err}}", err)
}
opts := splunk.CreateUserOptions{
Name: username,
Password: passwd,
Roles: role.Roles,
DefaultApp: role.DefaultApp,
Email: role.Email,
TZ: role.TZ,
}
if _, _, err := conn.AccessControl.Authentication.Users.Create(&opts); err != nil {
return nil, err
}
resp := b.Secret(secretCredsType).Response(map[string]interface{}{
// return to user
"username": username,
"password": passwd,
"roles": role.Roles,
"connection": role.Connection,
"url": conn.Params().BaseURL,
}, map[string]interface{}{
// store (with lease)
"username": username,
"role": name,
"connection": role.Connection,
})
resp.Secret.TTL = role.DefaultTTL
resp.Secret.MaxTTL = role.MaxTTL
return resp, nil
}
const pathCredsCreateHelpSyn = `
Request Splunk credentials for a certain role.
`
const pathCredsCreateHelpDesc = `
This path reads Splunk credentials for a certain role. The credentials
will be generated on demand and will be automatically revoked when
their lease expires. Leases can be extended until a configured
maximum life-time.
`