Files
grafana/pkg/services/multildap/multildap.go
T
Oleg Gaidarenko de92c360a1 LDAP: reduce API and allow its extension (#17209)
* Removes Add/Remove methods

* Publicise necessary fields and methods so we could extend it

* Publicise mock API

* More comments and additional simplifications

* Sync with master

Still having low coverage :/ - should be addressed in #17208
2019-05-27 10:36:49 +03:00

153 lines
2.9 KiB
Go

package multildap
import (
"errors"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/ldap"
)
// GetConfig gets LDAP config
var GetConfig = ldap.GetConfig
// IsEnabled checks if LDAP is enabled
var IsEnabled = ldap.IsEnabled
// ErrInvalidCredentials is returned if username and password do not match
var ErrInvalidCredentials = ldap.ErrInvalidCredentials
// ErrNoLDAPServers is returned when there is no LDAP servers specified
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")
// IMultiLDAP is interface for MultiLDAP
type IMultiLDAP interface {
Login(query *models.LoginUserQuery) (
*models.ExternalUserInfo, error,
)
Users(logins []string) (
[]*models.ExternalUserInfo, error,
)
User(login string) (
*models.ExternalUserInfo, error,
)
}
// MultiLDAP is basic struct of LDAP authorization
type MultiLDAP struct {
configs []*ldap.ServerConfig
}
// New creates the new LDAP auth
func New(configs []*ldap.ServerConfig) IMultiLDAP {
return &MultiLDAP{
configs: configs,
}
}
// Login tries to log in the user in multiples LDAP
func (multiples *MultiLDAP) Login(query *models.LoginUserQuery) (
*models.ExternalUserInfo, error,
) {
if len(multiples.configs) == 0 {
return nil, ErrNoLDAPServers
}
for _, config := range multiples.configs {
server := ldap.New(config)
if err := server.Dial(); err != nil {
return nil, err
}
defer server.Close()
user, err := server.Login(query)
if user != nil {
return user, nil
}
// Continue if we couldn't find the user
if err == ErrInvalidCredentials {
continue
}
if err != nil {
return nil, err
}
return user, nil
}
// Return invalid credentials if we couldn't find the user anywhere
return nil, ErrInvalidCredentials
}
// User gets a user by login
func (multiples *MultiLDAP) User(login string) (
*models.ExternalUserInfo,
error,
) {
if len(multiples.configs) == 0 {
return nil, ErrNoLDAPServers
}
search := []string{login}
for _, config := range multiples.configs {
server := ldap.New(config)
if err := server.Dial(); err != nil {
return nil, err
}
defer server.Close()
users, err := server.Users(search)
if err != nil {
return nil, err
}
if len(users) != 0 {
return users[0], nil
}
}
return nil, ErrDidNotFindUser
}
// Users gets users from multiple LDAP servers
func (multiples *MultiLDAP) Users(logins []string) (
[]*models.ExternalUserInfo,
error,
) {
var result []*models.ExternalUserInfo
if len(multiples.configs) == 0 {
return nil, ErrNoLDAPServers
}
for _, config := range multiples.configs {
server := ldap.New(config)
if err := server.Dial(); err != nil {
return nil, err
}
defer server.Close()
users, err := server.Users(logins)
if err != nil {
return nil, err
}
result = append(result, users...)
}
return result, nil
}