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
|
package certificate
import (
"crypto/x509"
"maps"
"sync"
)
// Cache represents an thread-safe in-memory cache of the certificates in the database.
type Cache struct {
// certificates is a map of certificate Type to map of certificate fingerprint to x509.Certificate.
certificates map[Type]map[string]x509.Certificate
// projects is a map of certificate fingerprint to slice of projects the certificate is restricted to.
// If a certificate fingerprint is present in certificates, but not present in projects, it means the certificate is
// not restricted.
projects map[string][]string
mu sync.RWMutex
}
// SetCertificatesAndProjects sets both certificates and projects on the Cache.
func (c *Cache) SetCertificatesAndProjects(certificates map[Type]map[string]x509.Certificate, projects map[string][]string) {
c.mu.Lock()
defer c.mu.Unlock()
c.certificates = certificates
c.projects = projects
}
// SetCertificates sets the certificates on the Cache.
func (c *Cache) SetCertificates(certificates map[Type]map[string]x509.Certificate) {
c.mu.Lock()
defer c.mu.Unlock()
c.certificates = certificates
}
// SetProjects sets the projects on the Cache.
func (c *Cache) SetProjects(projects map[string][]string) {
c.mu.Lock()
defer c.mu.Unlock()
c.projects = projects
}
// GetCertificatesAndProjects returns a read-only copy of the certificate and project maps.
func (c *Cache) GetCertificatesAndProjects() (map[Type]map[string]x509.Certificate, map[string][]string) {
c.mu.RLock()
defer c.mu.RUnlock()
certificates := make(map[Type]map[string]x509.Certificate, len(c.certificates))
for t, m := range c.certificates {
certificates[t] = make(map[string]x509.Certificate, len(m))
maps.Copy(certificates[t], m)
}
projects := make(map[string][]string, len(c.projects))
for f, projectNames := range c.projects {
projectNamesCopy := make([]string, 0, len(projectNames))
projectNamesCopy = append(projectNamesCopy, projectNames...)
projects[f] = projectNamesCopy
}
return certificates, projects
}
// GetCertificates returns a read-only copy of the certificate map.
func (c *Cache) GetCertificates() map[Type]map[string]x509.Certificate {
c.mu.RLock()
defer c.mu.RUnlock()
certificates := make(map[Type]map[string]x509.Certificate, len(c.certificates))
for t, m := range c.certificates {
certificates[t] = make(map[string]x509.Certificate, len(m))
maps.Copy(certificates[t], m)
}
return certificates
}
// GetProjects returns a read-only copy of the project map.
func (c *Cache) GetProjects() map[string][]string {
c.mu.RLock()
defer c.mu.RUnlock()
projects := make(map[string][]string, len(c.projects))
for f, projectNames := range c.projects {
projectNamesCopy := make([]string, 0, len(projectNames))
projectNamesCopy = append(projectNamesCopy, projectNames...)
projects[f] = projectNamesCopy
}
return projects
}
|