| 
 | 1 | +// Copyright (c) Tailscale Inc & AUTHORS  | 
 | 2 | +// SPDX-License-Identifier: BSD-3-Clause  | 
 | 3 | + | 
 | 4 | +package setec  | 
 | 5 | + | 
 | 6 | +import (  | 
 | 7 | +	"sync"  | 
 | 8 | + | 
 | 9 | +	"github.com/tailscale/setec/types/api"  | 
 | 10 | +)  | 
 | 11 | + | 
 | 12 | +/*  | 
 | 13 | +   TODO:  | 
 | 14 | +   - Cache needs to be able to hold multiple values.  | 
 | 15 | +   - Keep track of single- vs keyring-valued secrets.  | 
 | 16 | +   - Update polling logic to use GetAll for keyrings.  | 
 | 17 | +   - Add settings.  | 
 | 18 | +*/  | 
 | 19 | + | 
 | 20 | +// A Keyring represents a a collection of one or more available versions of a  | 
 | 21 | +// named secret.  | 
 | 22 | +type Keyring struct {  | 
 | 23 | +	name string  | 
 | 24 | + | 
 | 25 | +	mu     sync.Mutex  | 
 | 26 | +	active int                // index into values  | 
 | 27 | +	values []*api.SecretValue // in increasing order by version  | 
 | 28 | +}  | 
 | 29 | + | 
 | 30 | +// Get returns the key at index i of the keyring. Index 0 always refers to the  | 
 | 31 | +// current active version, and further indexes refer to other versions in order  | 
 | 32 | +// from newest to oldest.  | 
 | 33 | +//  | 
 | 34 | +// If i >= r.Len(), Get returns nil. If i < 0, Get panics.  | 
 | 35 | +//  | 
 | 36 | +// The Keyring retains ownership of the bytes returned, but the store will  | 
 | 37 | +// never modify the contents of the secret, so it is safe to share the slice  | 
 | 38 | +// without copying as long as the caller does not modify them.  | 
 | 39 | +func (r *Keyring) Get(i int) []byte {  | 
 | 40 | +	r.mu.Lock()  | 
 | 41 | +	defer r.mu.Unlock()  | 
 | 42 | +	switch {  | 
 | 43 | +	case i < 0:  | 
 | 44 | +		panic("index is negative")  | 
 | 45 | +	case i < len(r.values):  | 
 | 46 | +		return r.values[i].Value  | 
 | 47 | +	default:  | 
 | 48 | +		return nil  | 
 | 49 | +	}  | 
 | 50 | +}  | 
 | 51 | + | 
 | 52 | +// GetString returns a copy of the key at index i of the keyring as a string.  | 
 | 53 | +// If i >= r.Len(), GetString returns "". Otherwise, GetString behaves as Get.  | 
 | 54 | +func (r *Keyring) GetString(i int) string { return string(r.Get(i)) }  | 
 | 55 | + | 
 | 56 | +// Len reports the number of keys stored in r. The length is always positive,  | 
 | 57 | +// counting the active version.  | 
 | 58 | +func (r *Keyring) Len() int {  | 
 | 59 | +	r.mu.Lock()  | 
 | 60 | +	defer r.mu.Unlock()  | 
 | 61 | +	return len(r.values)  | 
 | 62 | +}  | 
0 commit comments