diff --git a/pkg/services/ldap/settings.go b/pkg/services/ldap/settings.go index 720180716f6..7165cb892f4 100644 --- a/pkg/services/ldap/settings.go +++ b/pkg/services/ldap/settings.go @@ -2,6 +2,7 @@ package ldap import ( "fmt" + "io/ioutil" "sync" "github.com/BurntSushi/toml" @@ -118,7 +119,15 @@ func readConfig(configFile string) (*Config, error) { logger.Info("LDAP enabled, reading config file", "file", configFile) - _, err := toml.DecodeFile(configFile, result) + fileBytes, err := ioutil.ReadFile(configFile) + if err != nil { + return nil, errutil.Wrap("Failed to load LDAP config file", err) + } + + // interpolate full toml string (it can contain ENV variables) + stringContent := setting.EvalEnvVarExpression(string(fileBytes)) + + _, err = toml.Decode(stringContent, result) if err != nil { return nil, errutil.Wrap("Failed to load LDAP config file", err) } diff --git a/pkg/services/ldap/settings_test.go b/pkg/services/ldap/settings_test.go new file mode 100644 index 00000000000..6cb27b48c6f --- /dev/null +++ b/pkg/services/ldap/settings_test.go @@ -0,0 +1,22 @@ +package ldap + +import ( + "os" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestReadingLDAPSettings(t *testing.T) { + config, err := readConfig("testdata/ldap.toml") + assert.Nil(t, err, "No error when reading ldap config") + assert.EqualValues(t, "127.0.0.1", config.Servers[0].Host) +} + +func TestReadingLDAPSettingsWithEnvVariable(t *testing.T) { + os.Setenv("ENV_PASSWORD", "MySecret") + + config, err := readConfig("testdata/ldap.toml") + assert.Nil(t, err, "No error when reading ldap config") + assert.EqualValues(t, "MySecret", config.Servers[0].BindPassword) +} diff --git a/pkg/services/ldap/testdata/ldap.toml b/pkg/services/ldap/testdata/ldap.toml new file mode 100644 index 00000000000..e60ef4e6b73 --- /dev/null +++ b/pkg/services/ldap/testdata/ldap.toml @@ -0,0 +1,27 @@ +[[servers]] +host = "127.0.0.1" +port = 389 +use_ssl = false +start_tls = false +ssl_skip_verify = false +bind_dn = "cn=admin,dc=grafana,dc=org" +bind_password = '${ENV_PASSWORD}' +search_filter = "(cn=%s)" +search_base_dns = ["dc=grafana,dc=org"] + +[servers.attributes] +name = "givenName" +surname = "sn" +username = "cn" +member_of = "memberOf" +email = "email" + +[[servers.group_mappings]] +group_dn = "cn=admins,ou=groups,dc=grafana,dc=org" +org_role = "Admin" +grafana_admin = true + +[[servers.group_mappings]] +group_dn = "cn=users,ou=groups,dc=grafana,dc=org" +org_role = "Editor" + diff --git a/pkg/setting/setting.go b/pkg/setting/setting.go index a83301dab8c..eb333465556 100644 --- a/pkg/setting/setting.go +++ b/pkg/setting/setting.go @@ -412,7 +412,7 @@ func makeAbsolute(path string, root string) string { return filepath.Join(root, path) } -func evalEnvVarExpression(value string) string { +func EvalEnvVarExpression(value string) string { regex := regexp.MustCompile(`\${(\w+)}`) return regex.ReplaceAllStringFunc(value, func(envVar string) string { envVar = strings.TrimPrefix(envVar, "${") @@ -431,7 +431,7 @@ func evalEnvVarExpression(value string) string { func evalConfigValues(file *ini.File) { for _, section := range file.Sections() { for _, key := range section.Keys() { - key.SetValue(evalEnvVarExpression(key.Value())) + key.SetValue(EvalEnvVarExpression(key.Value())) } } }