// Copyright (c) The OpenTofu Authors // SPDX-License-Identifier: MPL-2.0 // Copyright (c) 2023 HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 package lockingencryptionregistry import ( "sync" "github.com/opentofu/opentofu/internal/encryption/keyprovider" "github.com/opentofu/opentofu/internal/encryption/method" "github.com/opentofu/opentofu/internal/encryption/registry" ) // New returns a new encryption registry that locks for parallel access. func New() registry.Registry { return &lockingRegistry{ lock: &sync.RWMutex{}, providers: map[keyprovider.ID]keyprovider.Descriptor{}, methods: map[method.ID]method.Descriptor{}, } } type lockingRegistry struct { lock *sync.RWMutex providers map[keyprovider.ID]keyprovider.Descriptor methods map[method.ID]method.Descriptor } func (l *lockingRegistry) RegisterKeyProvider(keyProvider keyprovider.Descriptor) error { l.lock.Lock() defer l.lock.Unlock() id := keyProvider.ID() if err := id.Validate(); err != nil { return ®istry.InvalidKeyProviderError{KeyProvider: keyProvider, Cause: err} } if _, ok := l.providers[id]; ok { return ®istry.KeyProviderAlreadyRegisteredError{ID: id} } l.providers[id] = keyProvider return nil } func (l *lockingRegistry) RegisterMethod(method method.Descriptor) error { l.lock.Lock() defer l.lock.Unlock() id := method.ID() if err := id.Validate(); err != nil { return ®istry.InvalidMethodError{Method: method, Cause: err} } if previousMethod, ok := l.methods[id]; ok { return ®istry.MethodAlreadyRegisteredError{ID: id, CurrentMethod: method, PreviousMethod: previousMethod} } l.methods[id] = method return nil } func (l *lockingRegistry) GetKeyProviderDescriptor(id keyprovider.ID) (keyprovider.Descriptor, error) { l.lock.RLock() defer l.lock.RUnlock() provider, ok := l.providers[id] if !ok { return nil, ®istry.KeyProviderNotFoundError{ID: id} } return provider, nil } func (l *lockingRegistry) GetMethodDescriptor(id method.ID) (method.Descriptor, error) { l.lock.RLock() defer l.lock.RUnlock() foundMethod, ok := l.methods[id] if !ok { return nil, ®istry.MethodNotFoundError{ID: id} } return foundMethod, nil }