forked from kula/vault-plugin-secrets-backblazeb2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
b2_application_key.go
147 lines (119 loc) · 3.46 KB
/
b2_application_key.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package vault_plugin_secrets_backblazeb2
import (
"context"
"errors"
"fmt"
b2client "github.com/Backblaze/blazer/b2"
"github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/logical"
)
const b2KeyType = "b2_application_key"
func (b *backblazeB2Backend) b2ApplicationsKey() *framework.Secret {
return &framework.Secret{
Type: b2KeyType,
Fields: map[string]*framework.FieldSchema{
"application_key_id": {
Type: framework.TypeString,
Description: "Application Key ID",
},
"application_key": {
Type: framework.TypeString,
Description: "Application Key",
},
},
Revoke: b.b2ApplicationKeyRevoke,
Renew: b.b2ApplicationKeyRenew,
}
}
func (b *backblazeB2Backend) b2ApplicationKeyCreate(ctx context.Context, s logical.Storage,
keyName string, role backblazeB2RoleEntry) (*b2client.Key, error) {
client, err := b.getB2Client(ctx, s)
if err != nil {
return nil, err
}
// Set key options
var keyOpts []b2client.KeyOption
// Set capabilities
keyOpts = append(keyOpts, b2client.Capabilities(role.Capabilities...))
// If bucketName is set, look up the bucket and create that way.
// Else, create the key directly. This is how Blazer does it.
if role.BucketName != "" {
bucket, err := client.Bucket(ctx, role.BucketName)
if err != nil {
return nil, err
}
// Set prefix if asked for
if role.NamePrefix != "" {
keyOpts = append(keyOpts, b2client.Prefix(role.NamePrefix))
}
newKey, err := bucket.CreateKey(ctx, keyName, keyOpts...)
if err != nil {
return nil, err
}
return newKey, nil
} else {
newKey, err := client.CreateKey(ctx, keyName, keyOpts...)
if err != nil {
return nil, err
}
return newKey, nil
}
}
func (b *backblazeB2Backend) b2ApplicationKeyRevoke(ctx context.Context, req *logical.Request, _ *framework.FieldData) (*logical.Response, error) {
client, err := b.getB2Client(ctx, req.Storage)
if err != nil {
return nil, err
}
// Get applicationKeyId from secret internal data
applicationKeyIdRaw, ok := req.Secret.InternalData["application_key_id"]
if !ok {
return nil, fmt.Errorf("secret is missing internal application_key_id")
}
applicationKeyId, ok := applicationKeyIdRaw.(string)
if !ok {
return nil, fmt.Errorf("internal application_key_id is not a string")
}
// Find key
var applicationKey *b2client.Key
keys, _, err := client.ListKeys(ctx, 1, applicationKeyId)
if err != nil {
return nil, err
}
// We should only get one, but verify
for _, key := range keys {
if key.ID() == applicationKeyId {
applicationKey = key
break
}
}
if applicationKey == nil {
return nil, fmt.Errorf("cannot find key in b2")
}
if err := applicationKey.Delete(ctx); err != nil {
return nil, err
}
return nil, nil
}
func (b *backblazeB2Backend) b2ApplicationKeyRenew(ctx context.Context, req *logical.Request, _ *framework.FieldData) (*logical.Response, error) {
roleRaw, ok := req.Secret.InternalData["role"]
if !ok {
return nil, fmt.Errorf("secret is missing role internal data")
}
// get the role entry
role := roleRaw.(string)
roleEntry, err := b.getRole(ctx, req.Storage, role)
if err != nil {
return nil, fmt.Errorf("error retrieving role: %w", err)
}
if roleEntry == nil {
return nil, errors.New("error retrieving role: role is nil")
}
resp := &logical.Response{Secret: req.Secret}
if roleEntry.TTL > 0 {
resp.Secret.TTL = roleEntry.TTL
}
if roleEntry.MaxTTL > 0 {
resp.Secret.MaxTTL = roleEntry.MaxTTL
}
return resp, nil
}