mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
feat(ldap): work on reading ldap config from toml file, #1450
This commit is contained in:
parent
262a09bb2d
commit
0b5ba55131
@ -9,7 +9,7 @@ watch_dirs = [
|
|||||||
"$WORKDIR/public/views",
|
"$WORKDIR/public/views",
|
||||||
"$WORKDIR/conf",
|
"$WORKDIR/conf",
|
||||||
]
|
]
|
||||||
watch_exts = [".go", ".ini"]
|
watch_exts = [".go", "conf/*"]
|
||||||
build_delay = 1500
|
build_delay = 1500
|
||||||
cmds = [
|
cmds = [
|
||||||
["go", "build", "-o", "./bin/grafana-server"],
|
["go", "build", "-o", "./bin/grafana-server"],
|
||||||
|
7
build.go
7
build.go
@ -128,6 +128,7 @@ type linuxPackageOptions struct {
|
|||||||
binPath string
|
binPath string
|
||||||
configDir string
|
configDir string
|
||||||
configFilePath string
|
configFilePath string
|
||||||
|
ldapFilePath string
|
||||||
etcDefaultPath string
|
etcDefaultPath string
|
||||||
etcDefaultFilePath string
|
etcDefaultFilePath string
|
||||||
initdScriptFilePath string
|
initdScriptFilePath string
|
||||||
@ -148,6 +149,7 @@ func createLinuxPackages() {
|
|||||||
binPath: "/usr/sbin/grafana-server",
|
binPath: "/usr/sbin/grafana-server",
|
||||||
configDir: "/etc/grafana",
|
configDir: "/etc/grafana",
|
||||||
configFilePath: "/etc/grafana/grafana.ini",
|
configFilePath: "/etc/grafana/grafana.ini",
|
||||||
|
ldapFilePath: "/etc/grafana/ldap.toml",
|
||||||
etcDefaultPath: "/etc/default",
|
etcDefaultPath: "/etc/default",
|
||||||
etcDefaultFilePath: "/etc/default/grafana-server",
|
etcDefaultFilePath: "/etc/default/grafana-server",
|
||||||
initdScriptFilePath: "/etc/init.d/grafana-server",
|
initdScriptFilePath: "/etc/init.d/grafana-server",
|
||||||
@ -167,6 +169,7 @@ func createLinuxPackages() {
|
|||||||
binPath: "/usr/sbin/grafana-server",
|
binPath: "/usr/sbin/grafana-server",
|
||||||
configDir: "/etc/grafana",
|
configDir: "/etc/grafana",
|
||||||
configFilePath: "/etc/grafana/grafana.ini",
|
configFilePath: "/etc/grafana/grafana.ini",
|
||||||
|
ldapFilePath: "/etc/grafana/ldap.toml",
|
||||||
etcDefaultPath: "/etc/sysconfig",
|
etcDefaultPath: "/etc/sysconfig",
|
||||||
etcDefaultFilePath: "/etc/sysconfig/grafana-server",
|
etcDefaultFilePath: "/etc/sysconfig/grafana-server",
|
||||||
initdScriptFilePath: "/etc/init.d/grafana-server",
|
initdScriptFilePath: "/etc/init.d/grafana-server",
|
||||||
@ -204,8 +207,10 @@ func createPackage(options linuxPackageOptions) {
|
|||||||
runPrint("cp", "-a", filepath.Join(workingDir, "tmp")+"/.", filepath.Join(packageRoot, options.homeDir))
|
runPrint("cp", "-a", filepath.Join(workingDir, "tmp")+"/.", filepath.Join(packageRoot, options.homeDir))
|
||||||
// remove bin path
|
// remove bin path
|
||||||
runPrint("rm", "-rf", filepath.Join(packageRoot, options.homeDir, "bin"))
|
runPrint("rm", "-rf", filepath.Join(packageRoot, options.homeDir, "bin"))
|
||||||
// copy sample ini file to /etc/opt/grafana
|
// copy sample ini file to /etc/grafana
|
||||||
runPrint("cp", "conf/sample.ini", filepath.Join(packageRoot, options.configFilePath))
|
runPrint("cp", "conf/sample.ini", filepath.Join(packageRoot, options.configFilePath))
|
||||||
|
// copy sample ldap toml config file to /etc/grafana/ldap.toml
|
||||||
|
runPrint("cp", "conf/sample.ini", filepath.Join(packageRoot, ldapFilePath))
|
||||||
|
|
||||||
args := []string{
|
args := []string{
|
||||||
"-s", "dir",
|
"-s", "dir",
|
||||||
|
@ -181,22 +181,8 @@ auto_sign_up = true
|
|||||||
|
|
||||||
#################################### Auth LDAP ##########################
|
#################################### Auth LDAP ##########################
|
||||||
[auth.ldap]
|
[auth.ldap]
|
||||||
enabled = true
|
enabled = false
|
||||||
hosts = ldap://127.0.0.1:389
|
config_file = /etc/grafana/ldap.toml
|
||||||
use_ssl = false
|
|
||||||
bind_path = cn=%s,dc=grafana,dc=org
|
|
||||||
bind_password =
|
|
||||||
search_bases = dc=grafana,dc=org
|
|
||||||
search_filter = (cn=%s)
|
|
||||||
attr_username = cn
|
|
||||||
attr_name = givenName
|
|
||||||
attr_surname = sn
|
|
||||||
attr_email = email
|
|
||||||
attr_member_of = memberOf
|
|
||||||
|
|
||||||
[auth.ldap.member.to.role.map]
|
|
||||||
-: cn=admins,dc=grafana,dc=org -> "Admin" in "Main Org."
|
|
||||||
-: cn=users,dc=grafana,dc=org -> "Viewer" in "Main Org."
|
|
||||||
|
|
||||||
#################################### SMTP / Emailing ##########################
|
#################################### SMTP / Emailing ##########################
|
||||||
[smtp]
|
[smtp]
|
||||||
|
31
conf/ldap.toml
Normal file
31
conf/ldap.toml
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
verbose_logging = true
|
||||||
|
|
||||||
|
[[servers]]
|
||||||
|
host = "127.0.0.1"
|
||||||
|
port = 389
|
||||||
|
use_ssl = false
|
||||||
|
|
||||||
|
bind_dn = "cn=admin,dc=grafana,dc=org"
|
||||||
|
bind_password = "grafana"
|
||||||
|
|
||||||
|
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,dc=grafana,dc=org"
|
||||||
|
org_role = "Admin"
|
||||||
|
|
||||||
|
[[server.ldap_group_to_org_role_mappings]]
|
||||||
|
group_dn = "cn=users,dc=grafana,dc=org"
|
||||||
|
org_role = "Editor"
|
||||||
|
|
||||||
|
[[servers.group_mappings]]
|
||||||
|
group_dn = "*"
|
||||||
|
org_role = "Viewer"
|
@ -178,6 +178,11 @@
|
|||||||
[auth.basic]
|
[auth.basic]
|
||||||
;enabled = true
|
;enabled = true
|
||||||
|
|
||||||
|
#################################### Auth LDAP ##########################
|
||||||
|
[auth.ldap]
|
||||||
|
enabled = false
|
||||||
|
config_file = /etc/grafana/ldap.toml
|
||||||
|
|
||||||
#################################### SMTP / Emailing ##########################
|
#################################### SMTP / Emailing ##########################
|
||||||
[smtp]
|
[smtp]
|
||||||
;enabled = false
|
;enabled = false
|
||||||
|
2
main.go
2
main.go
@ -12,6 +12,7 @@ import (
|
|||||||
|
|
||||||
"github.com/grafana/grafana/pkg/cmd"
|
"github.com/grafana/grafana/pkg/cmd"
|
||||||
"github.com/grafana/grafana/pkg/log"
|
"github.com/grafana/grafana/pkg/log"
|
||||||
|
"github.com/grafana/grafana/pkg/login"
|
||||||
"github.com/grafana/grafana/pkg/metrics"
|
"github.com/grafana/grafana/pkg/metrics"
|
||||||
"github.com/grafana/grafana/pkg/plugins"
|
"github.com/grafana/grafana/pkg/plugins"
|
||||||
"github.com/grafana/grafana/pkg/services/eventpublisher"
|
"github.com/grafana/grafana/pkg/services/eventpublisher"
|
||||||
@ -54,6 +55,7 @@ func main() {
|
|||||||
initRuntime()
|
initRuntime()
|
||||||
|
|
||||||
search.Init()
|
search.Init()
|
||||||
|
login.Init()
|
||||||
social.NewOAuthService()
|
social.NewOAuthService()
|
||||||
eventpublisher.Init()
|
eventpublisher.Init()
|
||||||
plugins.Init()
|
plugins.Init()
|
||||||
|
@ -4,9 +4,9 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/api/dtos"
|
"github.com/grafana/grafana/pkg/api/dtos"
|
||||||
"github.com/grafana/grafana/pkg/auth"
|
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
"github.com/grafana/grafana/pkg/log"
|
"github.com/grafana/grafana/pkg/log"
|
||||||
|
"github.com/grafana/grafana/pkg/login"
|
||||||
"github.com/grafana/grafana/pkg/metrics"
|
"github.com/grafana/grafana/pkg/metrics"
|
||||||
"github.com/grafana/grafana/pkg/middleware"
|
"github.com/grafana/grafana/pkg/middleware"
|
||||||
m "github.com/grafana/grafana/pkg/models"
|
m "github.com/grafana/grafana/pkg/models"
|
||||||
@ -88,13 +88,13 @@ func LoginApiPing(c *middleware.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func LoginPost(c *middleware.Context, cmd dtos.LoginCommand) Response {
|
func LoginPost(c *middleware.Context, cmd dtos.LoginCommand) Response {
|
||||||
authQuery := auth.AuthenticateUserQuery{
|
authQuery := login.LoginUserQuery{
|
||||||
Username: cmd.User,
|
Username: cmd.User,
|
||||||
Password: cmd.Password,
|
Password: cmd.Password,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := bus.Dispatch(&authQuery); err != nil {
|
if err := bus.Dispatch(&authQuery); err != nil {
|
||||||
if err == auth.ErrInvalidCredentials {
|
if err == login.ErrInvalidCredentials {
|
||||||
return ApiError(401, "Invalid username or password", err)
|
return ApiError(401, "Invalid username or password", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
package auth
|
|
||||||
|
|
||||||
import m "github.com/grafana/grafana/pkg/models"
|
|
||||||
|
|
||||||
type LdapGroupToOrgRole struct {
|
|
||||||
GroupDN string
|
|
||||||
OrgId int64
|
|
||||||
OrgRole m.RoleType
|
|
||||||
}
|
|
||||||
|
|
||||||
type LdapServerConf struct {
|
|
||||||
Host string
|
|
||||||
Port string
|
|
||||||
UseSSL bool
|
|
||||||
BindDN string
|
|
||||||
BindPassword string
|
|
||||||
AttrUsername string
|
|
||||||
AttrName string
|
|
||||||
AttrSurname string
|
|
||||||
AttrEmail string
|
|
||||||
AttrMemberOf string
|
|
||||||
|
|
||||||
SearchFilter string
|
|
||||||
SearchBaseDNs []string
|
|
||||||
|
|
||||||
LdapGroups []*LdapGroupToOrgRole
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
package auth
|
package login
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
@ -13,24 +13,25 @@ var (
|
|||||||
ErrInvalidCredentials = errors.New("Invalid Username or Password")
|
ErrInvalidCredentials = errors.New("Invalid Username or Password")
|
||||||
)
|
)
|
||||||
|
|
||||||
type AuthenticateUserQuery struct {
|
type LoginUserQuery struct {
|
||||||
Username string
|
Username string
|
||||||
Password string
|
Password string
|
||||||
User *m.User
|
User *m.User
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func Init() {
|
||||||
bus.AddHandler("auth", AuthenticateUser)
|
bus.AddHandler("auth", AuthenticateUser)
|
||||||
|
loadLdapConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
func AuthenticateUser(query *AuthenticateUserQuery) error {
|
func AuthenticateUser(query *LoginUserQuery) error {
|
||||||
err := loginUsingGrafanaDB(query)
|
err := loginUsingGrafanaDB(query)
|
||||||
if err == nil || err != ErrInvalidCredentials {
|
if err == nil || err != ErrInvalidCredentials {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if setting.LdapEnabled {
|
if setting.LdapEnabled {
|
||||||
for _, server := range ldapServers {
|
for _, server := range ldapCfg.Servers {
|
||||||
auther := NewLdapAuthenticator(server)
|
auther := NewLdapAuthenticator(server)
|
||||||
err = auther.login(query)
|
err = auther.login(query)
|
||||||
if err == nil || err != ErrInvalidCredentials {
|
if err == nil || err != ErrInvalidCredentials {
|
||||||
@ -42,7 +43,7 @@ func AuthenticateUser(query *AuthenticateUserQuery) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func loginUsingGrafanaDB(query *AuthenticateUserQuery) error {
|
func loginUsingGrafanaDB(query *LoginUserQuery) error {
|
||||||
userQuery := m.GetUserByLoginQuery{LoginOrEmail: query.Username}
|
userQuery := m.GetUserByLoginQuery{LoginOrEmail: query.Username}
|
||||||
|
|
||||||
if err := bus.Dispatch(&userQuery); err != nil {
|
if err := bus.Dispatch(&userQuery); err != nil {
|
@ -1,40 +1,17 @@
|
|||||||
package auth
|
package login
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/davecgh/go-spew/spew"
|
||||||
"github.com/go-ldap/ldap"
|
"github.com/go-ldap/ldap"
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
"github.com/grafana/grafana/pkg/log"
|
"github.com/grafana/grafana/pkg/log"
|
||||||
m "github.com/grafana/grafana/pkg/models"
|
m "github.com/grafana/grafana/pkg/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ldapServers []*LdapServerConf
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
ldapServers = []*LdapServerConf{
|
|
||||||
{
|
|
||||||
UseSSL: false,
|
|
||||||
Host: "127.0.0.1",
|
|
||||||
Port: "389",
|
|
||||||
BindDN: "cn=admin,dc=grafana,dc=org",
|
|
||||||
BindPassword: "grafana",
|
|
||||||
AttrName: "givenName",
|
|
||||||
AttrSurname: "sn",
|
|
||||||
AttrUsername: "cn",
|
|
||||||
AttrMemberOf: "memberOf",
|
|
||||||
AttrEmail: "email",
|
|
||||||
SearchFilter: "(cn=%s)",
|
|
||||||
SearchBaseDNs: []string{"dc=grafana,dc=org"},
|
|
||||||
LdapGroups: []*LdapGroupToOrgRole{
|
|
||||||
{GroupDN: "cn=users,dc=grafana,dc=org", OrgId: 1, OrgRole: m.ROLE_VIEWER},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type ldapAuther struct {
|
type ldapAuther struct {
|
||||||
server *LdapServerConf
|
server *LdapServerConf
|
||||||
conn *ldap.Conn
|
conn *ldap.Conn
|
||||||
@ -45,7 +22,7 @@ func NewLdapAuthenticator(server *LdapServerConf) *ldapAuther {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *ldapAuther) Dial() error {
|
func (a *ldapAuther) Dial() error {
|
||||||
address := fmt.Sprintf("%s:%s", a.server.Host, a.server.Port)
|
address := fmt.Sprintf("%s:%d", a.server.Host, a.server.Port)
|
||||||
var err error
|
var err error
|
||||||
if a.server.UseSSL {
|
if a.server.UseSSL {
|
||||||
a.conn, err = ldap.DialTLS("tcp", address, nil)
|
a.conn, err = ldap.DialTLS("tcp", address, nil)
|
||||||
@ -56,7 +33,7 @@ func (a *ldapAuther) Dial() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *ldapAuther) login(query *AuthenticateUserQuery) error {
|
func (a *ldapAuther) login(query *LoginUserQuery) error {
|
||||||
if err := a.Dial(); err != nil {
|
if err := a.Dial(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -71,10 +48,9 @@ func (a *ldapAuther) login(query *AuthenticateUserQuery) error {
|
|||||||
if ldapUser, err := a.searchForUser(query.Username); err != nil {
|
if ldapUser, err := a.searchForUser(query.Username); err != nil {
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
log.Info("Surname: %s", ldapUser.LastName)
|
if ldapCfg.VerboseLogging {
|
||||||
log.Info("givenName: %s", ldapUser.FirstName)
|
log.Info("Ldap User Info: %s", spew.Sdump(ldapUser))
|
||||||
log.Info("email: %s", ldapUser.Email)
|
}
|
||||||
log.Info("memberOf: %s", ldapUser.MemberOf)
|
|
||||||
|
|
||||||
// check if a second user bind is needed
|
// check if a second user bind is needed
|
||||||
if a.server.BindPassword != "" {
|
if a.server.BindPassword != "" {
|
||||||
@ -164,6 +140,8 @@ func (a *ldapAuther) syncOrgRoles(user *m.User, ldapUser *ldapUserInfo) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// ignore subsequent ldap group mapping matches
|
||||||
|
break
|
||||||
} else {
|
} else {
|
||||||
// remove role
|
// remove role
|
||||||
cmd := m.RemoveOrgUserCommand{OrgId: org.OrgId, UserId: user.Id}
|
cmd := m.RemoveOrgUserCommand{OrgId: org.OrgId, UserId: user.Id}
|
||||||
@ -244,11 +222,11 @@ func (a *ldapAuther) searchForUser(username string) (*ldapUserInfo, error) {
|
|||||||
Scope: ldap.ScopeWholeSubtree,
|
Scope: ldap.ScopeWholeSubtree,
|
||||||
DerefAliases: ldap.NeverDerefAliases,
|
DerefAliases: ldap.NeverDerefAliases,
|
||||||
Attributes: []string{
|
Attributes: []string{
|
||||||
a.server.AttrUsername,
|
a.server.Attr.Username,
|
||||||
a.server.AttrSurname,
|
a.server.Attr.Surname,
|
||||||
a.server.AttrEmail,
|
a.server.Attr.Email,
|
||||||
a.server.AttrName,
|
a.server.Attr.Name,
|
||||||
a.server.AttrMemberOf,
|
a.server.Attr.MemberOf,
|
||||||
},
|
},
|
||||||
Filter: fmt.Sprintf(a.server.SearchFilter, username),
|
Filter: fmt.Sprintf(a.server.SearchFilter, username),
|
||||||
}
|
}
|
||||||
@ -264,20 +242,20 @@ func (a *ldapAuther) searchForUser(username string) (*ldapUserInfo, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(searchResult.Entries) == 0 {
|
if len(searchResult.Entries) == 0 {
|
||||||
return nil, errors.New("Ldap search matched no entry, please review your filter setting.")
|
return nil, ErrInvalidCredentials
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(searchResult.Entries) > 1 {
|
if len(searchResult.Entries) > 1 {
|
||||||
return nil, errors.New("Ldap search matched mopre than one entry, please review your filter setting")
|
return nil, errors.New("Ldap search matched more than one entry, please review your filter setting")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &ldapUserInfo{
|
return &ldapUserInfo{
|
||||||
DN: searchResult.Entries[0].DN,
|
DN: searchResult.Entries[0].DN,
|
||||||
LastName: getLdapAttr(a.server.AttrSurname, searchResult),
|
LastName: getLdapAttr(a.server.Attr.Surname, searchResult),
|
||||||
FirstName: getLdapAttr(a.server.AttrName, searchResult),
|
FirstName: getLdapAttr(a.server.Attr.Name, searchResult),
|
||||||
Username: getLdapAttr(a.server.AttrUsername, searchResult),
|
Username: getLdapAttr(a.server.Attr.Username, searchResult),
|
||||||
Email: getLdapAttr(a.server.AttrEmail, searchResult),
|
Email: getLdapAttr(a.server.Attr.Email, searchResult),
|
||||||
MemberOf: getLdapAttrArray(a.server.AttrMemberOf, searchResult),
|
MemberOf: getLdapAttrArray(a.server.Attr.MemberOf, searchResult),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package auth
|
package login
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
@ -139,6 +139,25 @@ func TestLdapAuther(t *testing.T) {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
ldapAutherScenario("given multiple matching ldap groups", func(sc *scenarioContext) {
|
||||||
|
ldapAuther := NewLdapAuthenticator(&LdapServerConf{
|
||||||
|
LdapGroups: []*LdapGroupToOrgRole{
|
||||||
|
{GroupDN: "cn=admins", OrgId: 1, OrgRole: "Admin"},
|
||||||
|
{GroupDN: "*", OrgId: 1, OrgRole: "Viewer"},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
sc.userOrgsQueryReturns([]*m.UserOrgDTO{{OrgId: 1, Role: m.ROLE_ADMIN}})
|
||||||
|
err := ldapAuther.syncOrgRoles(&m.User{}, &ldapUserInfo{
|
||||||
|
MemberOf: []string{"cn=admins"},
|
||||||
|
})
|
||||||
|
|
||||||
|
Convey("Should take first match, and ignore subsequent matches", func() {
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
So(sc.updateOrgUserCmd, ShouldBeNil)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package auth
|
package login
|
||||||
|
|
||||||
type ldapUserInfo struct {
|
type ldapUserInfo struct {
|
||||||
DN string
|
DN string
|
65
pkg/login/settings.go
Normal file
65
pkg/login/settings.go
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
package login
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/BurntSushi/toml"
|
||||||
|
"github.com/grafana/grafana/pkg/log"
|
||||||
|
m "github.com/grafana/grafana/pkg/models"
|
||||||
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
|
)
|
||||||
|
|
||||||
|
type LdapConfig struct {
|
||||||
|
Servers []*LdapServerConf `toml:"servers"`
|
||||||
|
VerboseLogging bool `toml:"verbose_logging"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type LdapServerConf struct {
|
||||||
|
Host string `toml:"host"`
|
||||||
|
Port int `toml:"port"`
|
||||||
|
UseSSL bool `toml:"use_ssl"`
|
||||||
|
BindDN string `toml:"bind_dn"`
|
||||||
|
BindPassword string `toml:"bind_password"`
|
||||||
|
Attr LdapAttributeMap `toml:"attributes"`
|
||||||
|
|
||||||
|
SearchFilter string `toml:"search_filter"`
|
||||||
|
SearchBaseDNs []string `toml:"search_base_dns"`
|
||||||
|
|
||||||
|
LdapGroups []*LdapGroupToOrgRole `toml:"group_mappings"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type LdapAttributeMap struct {
|
||||||
|
Username string `toml:"username"`
|
||||||
|
Name string `toml:"name"`
|
||||||
|
Surname string `toml:"surname"`
|
||||||
|
Email string `toml:"email"`
|
||||||
|
MemberOf string `toml:"member_of"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type LdapGroupToOrgRole struct {
|
||||||
|
GroupDN string `toml:"group_dn"`
|
||||||
|
OrgId int64 `toml:"org_id"`
|
||||||
|
OrgRole m.RoleType `toml:"org_role"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var ldapCfg LdapConfig
|
||||||
|
|
||||||
|
func loadLdapConfig() {
|
||||||
|
if !setting.LdapEnabled {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info("Login: Ldap enabled, reading config file: %s", setting.LdapConfigFile)
|
||||||
|
|
||||||
|
_, err := toml.DecodeFile(setting.LdapConfigFile, &ldapCfg)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(3, "Failed to load ldap config file: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// set default org id
|
||||||
|
for _, server := range ldapCfg.Servers {
|
||||||
|
for _, groupMap := range server.LdapGroups {
|
||||||
|
if groupMap.OrgId == 0 {
|
||||||
|
groupMap.OrgId = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -118,7 +118,8 @@ var (
|
|||||||
GoogleAnalyticsId string
|
GoogleAnalyticsId string
|
||||||
|
|
||||||
// LDAP
|
// LDAP
|
||||||
LdapEnabled bool
|
LdapEnabled bool
|
||||||
|
LdapConfigFile string
|
||||||
|
|
||||||
// SMTP email settings
|
// SMTP email settings
|
||||||
Smtp SmtpSettings
|
Smtp SmtpSettings
|
||||||
@ -417,6 +418,7 @@ func NewConfigContext(args *CommandLineArgs) {
|
|||||||
|
|
||||||
ldapSec := Cfg.Section("auth.ldap")
|
ldapSec := Cfg.Section("auth.ldap")
|
||||||
LdapEnabled = ldapSec.Key("enabled").MustBool(false)
|
LdapEnabled = ldapSec.Key("enabled").MustBool(false)
|
||||||
|
LdapConfigFile = ldapSec.Key("config_file").String()
|
||||||
|
|
||||||
readSessionConfig()
|
readSessionConfig()
|
||||||
readSmtpSettings()
|
readSmtpSettings()
|
||||||
|
Loading…
Reference in New Issue
Block a user