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
|
package jwtbundle
import (
"sort"
"sync"
"github.com/spiffe/go-spiffe/v2/spiffeid"
)
// Set is a set of bundles, keyed by trust domain.
type Set struct {
mtx sync.RWMutex
bundles map[spiffeid.TrustDomain]*Bundle
}
// NewSet creates a new set initialized with the given bundles.
func NewSet(bundles ...*Bundle) *Set {
bundlesMap := make(map[spiffeid.TrustDomain]*Bundle)
for _, b := range bundles {
if b != nil {
bundlesMap[b.trustDomain] = b
}
}
return &Set{
bundles: bundlesMap,
}
}
// Add adds a new bundle into the set. If a bundle already exists for the
// trust domain, the existing bundle is replaced.
func (s *Set) Add(bundle *Bundle) {
s.mtx.Lock()
defer s.mtx.Unlock()
if bundle != nil {
s.bundles[bundle.trustDomain] = bundle
}
}
// Remove removes the bundle for the given trust domain.
func (s *Set) Remove(trustDomain spiffeid.TrustDomain) {
s.mtx.Lock()
defer s.mtx.Unlock()
delete(s.bundles, trustDomain)
}
// Has returns true if there is a bundle for the given trust domain.
func (s *Set) Has(trustDomain spiffeid.TrustDomain) bool {
s.mtx.RLock()
defer s.mtx.RUnlock()
_, ok := s.bundles[trustDomain]
return ok
}
// Get returns a bundle for the given trust domain. If the bundle is in the set
// it is returned and the boolean is true. Otherwise, the returned value is
// nil and the boolean is false.
func (s *Set) Get(trustDomain spiffeid.TrustDomain) (*Bundle, bool) {
s.mtx.RLock()
defer s.mtx.RUnlock()
bundle, ok := s.bundles[trustDomain]
return bundle, ok
}
// Bundles returns the bundles in the set sorted by trust domain.
func (s *Set) Bundles() []*Bundle {
s.mtx.RLock()
defer s.mtx.RUnlock()
out := make([]*Bundle, 0, len(s.bundles))
for _, bundle := range s.bundles {
out = append(out, bundle)
}
sort.Slice(out, func(a, b int) bool {
return out[a].TrustDomain().Compare(out[b].TrustDomain()) < 0
})
return out
}
// Len returns the number of bundles in the set.
func (s *Set) Len() int {
s.mtx.RLock()
defer s.mtx.RUnlock()
return len(s.bundles)
}
// GetJWTBundleForTrustDomain returns the JWT bundle for the given trust
// domain. It implements the Source interface.
func (s *Set) GetJWTBundleForTrustDomain(trustDomain spiffeid.TrustDomain) (*Bundle, error) {
s.mtx.RLock()
defer s.mtx.RUnlock()
bundle, ok := s.bundles[trustDomain]
if !ok {
return nil, jwtbundleErr.New("no JWT bundle for trust domain %q", trustDomain)
}
return bundle, nil
}
|