diff --git a/conf/ldap_multiple.toml b/conf/ldap_multiple.toml new file mode 100644 index 00000000000..911d57e57be --- /dev/null +++ b/conf/ldap_multiple.toml @@ -0,0 +1,53 @@ +# --- First LDAP Server --- + +[[servers]] +host = "10.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 = 'grafana' +search_filter = "(cn=%s)" +search_base_dns = ["ou=users,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 + +# --- Second LDAP Server --- + +[[servers]] +host = "10.0.0.2" +port = 389 +use_ssl = false +start_tls = false +ssl_skip_verify = false + +bind_dn = "cn=admin,dc=grafana,dc=org" +bind_password = 'grafana' +search_filter = "(cn=%s)" +search_base_dns = ["ou=users,dc=grafana,dc=org"] + +[servers.attributes] +name = "givenName" +surname = "sn" +username = "cn" +member_of = "memberOf" +email = "email" + +[[servers.group_mappings]] +group_dn = "cn=editors,ou=groups,dc=grafana,dc=org" +org_role = "Editor" + +[[servers.group_mappings]] +group_dn = "*" +org_role = "Viewer" diff --git a/pkg/services/multildap/multildap.go b/pkg/services/multildap/multildap.go index 3747a1aebd6..742cf3c3942 100644 --- a/pkg/services/multildap/multildap.go +++ b/pkg/services/multildap/multildap.go @@ -13,6 +13,9 @@ var GetConfig = ldap.GetConfig // IsEnabled checks if LDAP is enabled var IsEnabled = ldap.IsEnabled +// newLDAP return instance of the single LDAP server +var newLDAP = ldap.New + // ErrInvalidCredentials is returned if username and password do not match var ErrInvalidCredentials = ldap.ErrInvalidCredentials @@ -22,9 +25,6 @@ var ErrNoLDAPServers = errors.New("No LDAP servers are configured") // ErrDidNotFindUser if request for user is unsuccessful var ErrDidNotFindUser = errors.New("Did not find a user") -// newLDAP return instance of the single LDAP server -var newLDAP = ldap.New - // IMultiLDAP is interface for MultiLDAP type IMultiLDAP interface { Login(query *models.LoginUserQuery) ( diff --git a/pkg/services/multildap/test_test.go b/pkg/services/multildap/test_test.go deleted file mode 100644 index 3802f5971b4..00000000000 --- a/pkg/services/multildap/test_test.go +++ /dev/null @@ -1,61 +0,0 @@ -package multildap - -import ( - "github.com/grafana/grafana/pkg/models" - "github.com/grafana/grafana/pkg/services/ldap" -) - -type mockLDAP struct { - dialCalledTimes int - loginCalledTimes int - closeCalledTimes int - usersCalledTimes int - - dialErrReturn error - - loginErrReturn error - loginReturn *models.ExternalUserInfo - - usersErrReturn error - usersFirstReturn []*models.ExternalUserInfo - usersRestReturn []*models.ExternalUserInfo -} - -func (mock *mockLDAP) Login(*models.LoginUserQuery) (*models.ExternalUserInfo, error) { - - mock.loginCalledTimes = mock.loginCalledTimes + 1 - return mock.loginReturn, mock.loginErrReturn -} -func (mock *mockLDAP) Users([]string) ([]*models.ExternalUserInfo, error) { - mock.usersCalledTimes = mock.usersCalledTimes + 1 - - if mock.usersCalledTimes == 1 { - return mock.usersFirstReturn, mock.usersErrReturn - } - - return mock.usersRestReturn, mock.usersErrReturn -} -func (mock *mockLDAP) Auth(string, string) error { - return nil -} -func (mock *mockLDAP) Dial() error { - mock.dialCalledTimes = mock.dialCalledTimes + 1 - return mock.dialErrReturn -} -func (mock *mockLDAP) Close() { - mock.closeCalledTimes = mock.closeCalledTimes + 1 -} - -func setup() *mockLDAP { - mock := &mockLDAP{} - - newLDAP = func(config *ldap.ServerConfig) ldap.IServer { - return mock - } - - return mock -} - -func teardown() { - newLDAP = ldap.New -} diff --git a/pkg/services/multildap/testing.go b/pkg/services/multildap/testing.go new file mode 100644 index 00000000000..a5d5caefadd --- /dev/null +++ b/pkg/services/multildap/testing.go @@ -0,0 +1,104 @@ +package multildap + +import ( + "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/ldap" +) + +// MockLDAP represents testing struct for ldap testing +type MockLDAP struct { + dialCalledTimes int + loginCalledTimes int + closeCalledTimes int + usersCalledTimes int + + dialErrReturn error + + loginErrReturn error + loginReturn *models.ExternalUserInfo + + usersErrReturn error + usersFirstReturn []*models.ExternalUserInfo + usersRestReturn []*models.ExternalUserInfo +} + +// Login test fn +func (mock *MockLDAP) Login(*models.LoginUserQuery) (*models.ExternalUserInfo, error) { + + mock.loginCalledTimes = mock.loginCalledTimes + 1 + return mock.loginReturn, mock.loginErrReturn +} + +// Users test fn +func (mock *MockLDAP) Users([]string) ([]*models.ExternalUserInfo, error) { + mock.usersCalledTimes = mock.usersCalledTimes + 1 + + if mock.usersCalledTimes == 1 { + return mock.usersFirstReturn, mock.usersErrReturn + } + + return mock.usersRestReturn, mock.usersErrReturn +} + +// Auth test fn +func (mock *MockLDAP) Auth(string, string) error { + return nil +} + +// Dial test fn +func (mock *MockLDAP) Dial() error { + mock.dialCalledTimes = mock.dialCalledTimes + 1 + return mock.dialErrReturn +} + +// Close test fn +func (mock *MockLDAP) Close() { + mock.closeCalledTimes = mock.closeCalledTimes + 1 +} + +// MockMultiLDAP represents testing struct for multildap testing +type MockMultiLDAP struct { + LoginCalledTimes int + UsersCalledTimes int + UserCalledTimes int + + UsersResult []*models.ExternalUserInfo +} + +// Login test fn +func (mock *MockMultiLDAP) Login(query *models.LoginUserQuery) ( + *models.ExternalUserInfo, error, +) { + mock.LoginCalledTimes = mock.LoginCalledTimes + 1 + return nil, nil +} + +// Users test fn +func (mock *MockMultiLDAP) Users(logins []string) ( + []*models.ExternalUserInfo, error, +) { + mock.UsersCalledTimes = mock.UsersCalledTimes + 1 + return mock.UsersResult, nil +} + +// User test fn +func (mock *MockMultiLDAP) User(login string) ( + *models.ExternalUserInfo, error, +) { + mock.UserCalledTimes = mock.UserCalledTimes + 1 + return nil, nil +} + +func setup() *MockLDAP { + mock := &MockLDAP{} + + newLDAP = func(config *ldap.ServerConfig) ldap.IServer { + return mock + } + + return mock +} + +func teardown() { + newLDAP = ldap.New +}