fix(GODT-2606): Improve Vault concurrency scopes

Rewrite the vault to have one RWlock rather then two separate locks for
data and reference counts.

In certain circumstance, it could be possible that that different
requests could end up in undefined states if a user got deleted
successfully while at he same time another goroutine/thread is loading
the given user.

While I have not been able to reproduce this in a test, restricting the
access scope to one lock rather than two, should avoid corner cases
where logic code is executing outside of the lock scope.
This commit is contained in:
Leander Beernaert
2023-05-12 16:01:31 +02:00
parent faf3780eee
commit 0ef9c9c9c9
7 changed files with 214 additions and 110 deletions

View File

@ -30,7 +30,12 @@ import (
// If CertPEMPath is set, it will attempt to read the certificate from the file.
// Otherwise, or on read/validation failure, it will return the certificate from the vault.
func (vault *Vault) GetBridgeTLSCert() ([]byte, []byte) {
if certPath, keyPath := vault.get().Certs.CustomCertPath, vault.get().Certs.CustomKeyPath; certPath != "" && keyPath != "" {
vault.lock.RLock()
defer vault.lock.RUnlock()
certs := vault.getUnsafe().Certs
if certPath, keyPath := certs.CustomCertPath, certs.CustomKeyPath; certPath != "" && keyPath != "" {
if certPEM, keyPEM, err := readPEMCert(certPath, keyPath); err == nil {
return certPEM, keyPEM
}
@ -38,7 +43,7 @@ func (vault *Vault) GetBridgeTLSCert() ([]byte, []byte) {
logrus.Error("Failed to read certificate from file, using default")
}
return vault.get().Certs.Bridge.Cert, vault.get().Certs.Bridge.Key
return certs.Bridge.Cert, certs.Bridge.Key
}
// SetBridgeTLSCertPath sets the path to PEM-encoded certificates for the bridge.
@ -47,7 +52,7 @@ func (vault *Vault) SetBridgeTLSCertPath(certPath, keyPath string) error {
return fmt.Errorf("invalid certificate: %w", err)
}
return vault.mod(func(data *Data) {
return vault.modSafe(func(data *Data) {
data.Certs.CustomCertPath = certPath
data.Certs.CustomKeyPath = keyPath
})
@ -55,18 +60,18 @@ func (vault *Vault) SetBridgeTLSCertPath(certPath, keyPath string) error {
// SetBridgeTLSCertKey sets the path to PEM-encoded certificates for the bridge.
func (vault *Vault) SetBridgeTLSCertKey(cert, key []byte) error {
return vault.mod(func(data *Data) {
return vault.modSafe(func(data *Data) {
data.Certs.Bridge.Cert = cert
data.Certs.Bridge.Key = key
})
}
func (vault *Vault) GetCertsInstalled() bool {
return vault.get().Certs.Installed
return vault.getSafe().Certs.Installed
}
func (vault *Vault) SetCertsInstalled(installed bool) error {
return vault.mod(func(data *Data) {
return vault.modSafe(func(data *Data) {
data.Certs.Installed = installed
})
}