From 0fbf72b5fca1cbf5ee3f0182abe45d5771dcf1f1 Mon Sep 17 00:00:00 2001 From: Robert Lin Date: Fri, 9 Aug 2024 11:11:33 -0700 Subject: [PATCH] fix/sg: add lock to secrets.Store CRUD --- dev/sg/internal/secrets/store.go | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/dev/sg/internal/secrets/store.go b/dev/sg/internal/secrets/store.go index 81615d79e635f..97705303c1d92 100644 --- a/dev/sg/internal/secrets/store.go +++ b/dev/sg/internal/secrets/store.go @@ -38,6 +38,9 @@ type secretManagerClient interface { // Store holds secrets regardless on their form, as long as they are marshallable in JSON. type Store struct { + // All methods reading/writing from Store must claim this lock. + mux sync.Mutex + filepath string // persistedData holds secrets that should be persisted to filepath. persistedData map[string]json.RawMessage @@ -154,6 +157,9 @@ func LoadFromFile(filepath string) (*Store, error) { // Write serializes the store content in the given writer. func (s *Store) Write(w io.Writer) error { + s.mux.Lock() + defer s.mux.Unlock() + enc := json.NewEncoder(w) return enc.Encode(s.persistedData) } @@ -170,6 +176,9 @@ func (s *Store) SaveFile() error { // Put stores serialized data in memory. func (s *Store) Put(key string, data any) error { + s.mux.Lock() + defer s.mux.Unlock() + b, err := json.Marshal(data) if err != nil { return err @@ -180,7 +189,9 @@ func (s *Store) Put(key string, data any) error { // PutAndSave saves automatically after calling Put. func (s *Store) PutAndSave(key string, data any) error { + s.mux.Lock() err := s.Put(key, data) + s.mux.Unlock() // call explicitly here since s.SaveFile might lock as well if err != nil { return err } @@ -189,6 +200,9 @@ func (s *Store) PutAndSave(key string, data any) error { // Get fetches a value from memory and uses the given target to deserialize it. func (s *Store) Get(key string, target any) error { + s.mux.Lock() + defer s.mux.Unlock() + if v, ok := s.persistedData[key]; ok { return json.Unmarshal(v, target) } @@ -204,6 +218,9 @@ func (s *Store) Get(key string, target any) error { } func (s *Store) GetExternal(ctx context.Context, secret ExternalSecret, fallbacks ...FallbackFunc) (string, error) { + s.mux.Lock() + defer s.mux.Unlock() + var value externalSecretValue // Check if we already have this secret @@ -268,6 +285,9 @@ func (s *Store) GetExternal(ctx context.Context, secret ExternalSecret, fallback // Remove deletes a value from memory. func (s *Store) Remove(key string) error { + s.mux.Lock() + defer s.mux.Unlock() + if _, exists := s.persistedData[key]; exists { delete(s.persistedData, key) return nil @@ -277,6 +297,9 @@ func (s *Store) Remove(key string) error { // Keys returns out all keys func (s *Store) Keys() []string { + s.mux.Lock() + defer s.mux.Unlock() + keys := make([]string, 0, len(s.persistedData)) for key := range s.persistedData { keys = append(keys, key)