LDAP: Fix LDAP config cache (#89998)

* initialize LDAP config cache

* check err is nil

* return the config from cache only if the config file has not been modified

* rename var from test
This commit is contained in:
Mihai Doarna 2024-07-05 11:10:52 +03:00 committed by GitHub
parent e7780c9c9c
commit e299621766
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 47 additions and 5 deletions

View File

@ -4,6 +4,7 @@ import (
"fmt"
"os"
"sync"
"time"
"github.com/BurntSushi/toml"
@ -93,7 +94,11 @@ var loadingMutex = &sync.Mutex{}
// We need to define in this space so `GetConfig` fn
// could be defined as singleton
var config *ServersConfig
var cachedConfig struct {
config *ServersConfig
filePath string
fileModified time.Time
}
func GetLDAPConfig(cfg *setting.Cfg) *Config {
return &Config{
@ -117,15 +122,27 @@ func GetConfig(cfg *Config) (*ServersConfig, error) {
return nil, nil
}
// Make it a singleton
if config != nil {
return config, nil
configFileStats, err := os.Stat(cfg.ConfigFilePath)
if err != nil {
return nil, err
}
configFileModified := configFileStats.ModTime()
// return the config from cache if the config file hasn't been modified
if cachedConfig.config != nil && cachedConfig.filePath == cfg.ConfigFilePath && cachedConfig.fileModified.Equal(configFileModified) {
return cachedConfig.config, nil
}
loadingMutex.Lock()
defer loadingMutex.Unlock()
return readConfig(cfg.ConfigFilePath)
cachedConfig.config, err = readConfig(cfg.ConfigFilePath)
if err == nil {
cachedConfig.filePath = cfg.ConfigFilePath
cachedConfig.fileModified = configFileModified
}
return cachedConfig.config, err
}
func readConfig(configFile string) (*ServersConfig, error) {

View File

@ -25,3 +25,28 @@ func TestReadingLDAPSettingsWithEnvVariable(t *testing.T) {
require.NoError(t, err)
assert.EqualValues(t, "MySecret", config.Servers[0].BindPassword)
}
func TestReadingLDAPSettingsUsingCache(t *testing.T) {
cfg := &Config{
Enabled: true,
ConfigFilePath: "testdata/ldap.toml",
}
// cache is empty initially
assert.Nil(t, cachedConfig.config)
firstConfig, err := GetConfig(cfg)
// cache has been initialized
assert.NotNil(t, cachedConfig.config)
assert.EqualValues(t, *firstConfig, *cachedConfig.config)
assert.Nil(t, err)
assert.EqualValues(t, "127.0.0.1", cachedConfig.config.Servers[0].Host)
// make sure the cached config is returned on subsequent calls
config := cachedConfig.config
secondConfig, err := GetConfig(cfg)
assert.Equal(t, config, secondConfig)
assert.Nil(t, err)
}