|
|
@@ -2,9 +2,11 @@ package ldap
|
|
|
|
|
|
import (
|
|
|
"fmt"
|
|
|
- "os"
|
|
|
+ "sync"
|
|
|
|
|
|
"github.com/BurntSushi/toml"
|
|
|
+ "github.com/grafana/grafana/pkg/util/errutil"
|
|
|
+ "golang.org/x/xerrors"
|
|
|
|
|
|
"github.com/grafana/grafana/pkg/log"
|
|
|
m "github.com/grafana/grafana/pkg/models"
|
|
|
@@ -56,47 +58,72 @@ type GroupToOrgRole struct {
|
|
|
var config *Config
|
|
|
var logger = log.New("ldap")
|
|
|
|
|
|
+// loadingMutex locks the reading of the config so multiple requests for reloading are sequential.
|
|
|
+var loadingMutex = &sync.Mutex{}
|
|
|
+
|
|
|
// IsEnabled checks if ldap is enabled
|
|
|
func IsEnabled() bool {
|
|
|
return setting.LdapEnabled
|
|
|
}
|
|
|
|
|
|
-// ReadConfig reads the config if
|
|
|
-// ldap is enabled otherwise it will return nil
|
|
|
-func ReadConfig() *Config {
|
|
|
+// ReloadConfig reads the config from the disc and caches it.
|
|
|
+func ReloadConfig() error {
|
|
|
if IsEnabled() == false {
|
|
|
return nil
|
|
|
}
|
|
|
+ loadingMutex.Lock()
|
|
|
+ defer loadingMutex.Unlock()
|
|
|
+
|
|
|
+ var err error
|
|
|
+ config, err = readConfig(setting.LdapConfigFile)
|
|
|
+ return err
|
|
|
+}
|
|
|
+
|
|
|
+// GetConfig returns the LDAP config if LDAP is enabled otherwise it returns nil. It returns either cached value of
|
|
|
+// the config or it reads it and caches it first.
|
|
|
+func GetConfig() (*Config, error) {
|
|
|
+ if IsEnabled() == false {
|
|
|
+ return nil, nil
|
|
|
+ }
|
|
|
|
|
|
// Make it a singleton
|
|
|
if config != nil {
|
|
|
- return config
|
|
|
+ return config, nil
|
|
|
}
|
|
|
|
|
|
- config = getConfig(setting.LdapConfigFile)
|
|
|
+ loadingMutex.Lock()
|
|
|
+ defer loadingMutex.Unlock()
|
|
|
+
|
|
|
+ var err error
|
|
|
+ config, err = readConfig(setting.LdapConfigFile)
|
|
|
|
|
|
- return config
|
|
|
+ return config, err
|
|
|
}
|
|
|
-func getConfig(configFile string) *Config {
|
|
|
+
|
|
|
+func readConfig(configFile string) (*Config, error) {
|
|
|
result := &Config{}
|
|
|
|
|
|
logger.Info("Ldap enabled, reading config file", "file", configFile)
|
|
|
|
|
|
_, err := toml.DecodeFile(configFile, result)
|
|
|
if err != nil {
|
|
|
- logger.Crit("Failed to load ldap config file", "error", err)
|
|
|
- os.Exit(1)
|
|
|
+ return nil, errutil.Wrap("Failed to load ldap config file", err)
|
|
|
}
|
|
|
|
|
|
if len(result.Servers) == 0 {
|
|
|
- logger.Crit("ldap enabled but no ldap servers defined in config file")
|
|
|
- os.Exit(1)
|
|
|
+ return nil, xerrors.New("ldap enabled but no ldap servers defined in config file")
|
|
|
}
|
|
|
|
|
|
// set default org id
|
|
|
for _, server := range result.Servers {
|
|
|
- assertNotEmptyCfg(server.SearchFilter, "search_filter")
|
|
|
- assertNotEmptyCfg(server.SearchBaseDNs, "search_base_dns")
|
|
|
+ err = assertNotEmptyCfg(server.SearchFilter, "search_filter")
|
|
|
+ if err != nil {
|
|
|
+ return nil, errutil.Wrap("Failed to validate SearchFilter section", err)
|
|
|
+ }
|
|
|
+ err = assertNotEmptyCfg(server.SearchBaseDNs, "search_base_dns")
|
|
|
+ if err != nil {
|
|
|
+ return nil, errutil.Wrap("Failed to validate SearchBaseDNs section", err)
|
|
|
+ }
|
|
|
|
|
|
for _, groupMap := range server.Groups {
|
|
|
if groupMap.OrgId == 0 {
|
|
|
@@ -105,22 +132,21 @@ func getConfig(configFile string) *Config {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- return result
|
|
|
+ return result, nil
|
|
|
}
|
|
|
|
|
|
-func assertNotEmptyCfg(val interface{}, propName string) {
|
|
|
+func assertNotEmptyCfg(val interface{}, propName string) error {
|
|
|
switch v := val.(type) {
|
|
|
case string:
|
|
|
if v == "" {
|
|
|
- logger.Crit("LDAP config file is missing option", "option", propName)
|
|
|
- os.Exit(1)
|
|
|
+ return xerrors.Errorf("LDAP config file is missing option: %v", propName)
|
|
|
}
|
|
|
case []string:
|
|
|
if len(v) == 0 {
|
|
|
- logger.Crit("LDAP config file is missing option", "option", propName)
|
|
|
- os.Exit(1)
|
|
|
+ return xerrors.Errorf("LDAP config file is missing option: %v", propName)
|
|
|
}
|
|
|
default:
|
|
|
fmt.Println("unknown")
|
|
|
}
|
|
|
+ return nil
|
|
|
}
|