Skip to content

Commit f3b6347

Browse files
committed
db: add a getAll method to kv and GetAllFiltered to DB
1 parent 0abf521 commit f3b6347

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

db/db.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,47 @@ func (db *DB) Get(caller Caller, name string) (*api.SecretValue, error) {
183183
return db.kv.get(name)
184184
}
185185

186+
// GetAllFiltered returns all versions of a secret and the active version number.
187+
func (db *DB) GetAllFiltered(caller Caller, name string, skip []api.SecretVersion) (*Filtered, error) {
188+
// We will not log an access unless we are returning at least one unfiltered
189+
// secret value. However, we still want a log if authorization fails.
190+
if !caller.Permissions.Allow(acl.ActionGet, name) {
191+
return nil, db.checkAndLog(caller, acl.ActionGet, name, 0)
192+
}
193+
db.mu.Lock()
194+
defer db.mu.Unlock()
195+
active, all, err := db.kv.getAll(name)
196+
if err != nil {
197+
return nil, err
198+
}
199+
out := &Filtered{
200+
Active: active,
201+
Versions: make([]api.SecretVersion, len(all)),
202+
}
203+
for i, sv := range all {
204+
out.Versions[i] = sv.Version
205+
if !slices.Contains(skip, sv.Version) {
206+
out.Values = append(out.Values, sv)
207+
}
208+
}
209+
210+
if len(out.Values) != 0 {
211+
// We got unfiltered secret values, log an access. We already know it's
212+
// authorized from the original check.
213+
if err := db.checkAndLog(caller, acl.ActionGet, name, 0); err != nil {
214+
return nil, err
215+
}
216+
}
217+
return out, nil
218+
}
219+
220+
// Filtered is the result of a successful GetAllFiltered call.
221+
type Filtered struct {
222+
Active api.SecretVersion // the active version of the secret
223+
Versions []api.SecretVersion // all known versions of the secret
224+
Values []*api.SecretValue // all non-filtered values of the secret
225+
}
226+
186227
// GetConditional returns a secret's active value if it is different from oldVersion.
187228
// If the active version is the same as oldVersion, it reports api.ErrValueNotChanged.
188229
func (db *DB) GetConditional(caller Caller, name string, oldVersion api.SecretVersion) (*api.SecretValue, error) {

db/kv.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,22 @@ func (kv *kv) get(name string) (*api.SecretValue, error) {
304304
}, nil
305305
}
306306

307+
// getAll returns all the versions of a secret, and the active version number.
308+
func (kv *kv) getAll(name string) (api.SecretVersion, []*api.SecretValue, error) {
309+
secret := kv.secrets[name]
310+
if secret == nil {
311+
return 0, nil, ErrNotFound
312+
}
313+
all := make([]*api.SecretValue, 0, len(secret.Versions))
314+
for v, bs := range secret.Versions {
315+
all = append(all, &api.SecretValue{
316+
Value: []byte(bs),
317+
Version: v,
318+
})
319+
}
320+
return secret.ActiveVersion, all, nil
321+
}
322+
307323
// getVersion returns a secret's value at a specific version.
308324
func (kv *kv) getVersion(name string, version api.SecretVersion) (*api.SecretValue, error) {
309325
secret := kv.secrets[name]

0 commit comments

Comments
 (0)