multildap.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. package multildap
  2. import (
  3. "errors"
  4. "github.com/grafana/grafana/pkg/models"
  5. "github.com/grafana/grafana/pkg/services/ldap"
  6. )
  7. // GetConfig gets LDAP config
  8. var GetConfig = ldap.GetConfig
  9. // IsEnabled checks if LDAP is enabled
  10. var IsEnabled = ldap.IsEnabled
  11. // newLDAP return instance of the single LDAP server
  12. var newLDAP = ldap.New
  13. // ErrInvalidCredentials is returned if username and password do not match
  14. var ErrInvalidCredentials = ldap.ErrInvalidCredentials
  15. // ErrCouldNotFindUser is returned when username hasn't been found (not username+password)
  16. var ErrCouldNotFindUser = ldap.ErrCouldNotFindUser
  17. // ErrNoLDAPServers is returned when there is no LDAP servers specified
  18. var ErrNoLDAPServers = errors.New("No LDAP servers are configured")
  19. // ErrDidNotFindUser if request for user is unsuccessful
  20. var ErrDidNotFindUser = errors.New("Did not find a user")
  21. // IMultiLDAP is interface for MultiLDAP
  22. type IMultiLDAP interface {
  23. Login(query *models.LoginUserQuery) (
  24. *models.ExternalUserInfo, error,
  25. )
  26. Users(logins []string) (
  27. []*models.ExternalUserInfo, error,
  28. )
  29. User(login string) (
  30. *models.ExternalUserInfo, ldap.ServerConfig, error,
  31. )
  32. }
  33. // MultiLDAP is basic struct of LDAP authorization
  34. type MultiLDAP struct {
  35. configs []*ldap.ServerConfig
  36. }
  37. // New creates the new LDAP auth
  38. func New(configs []*ldap.ServerConfig) IMultiLDAP {
  39. return &MultiLDAP{
  40. configs: configs,
  41. }
  42. }
  43. // Login tries to log in the user in multiples LDAP
  44. func (multiples *MultiLDAP) Login(query *models.LoginUserQuery) (
  45. *models.ExternalUserInfo, error,
  46. ) {
  47. if len(multiples.configs) == 0 {
  48. return nil, ErrNoLDAPServers
  49. }
  50. for _, config := range multiples.configs {
  51. server := newLDAP(config)
  52. if err := server.Dial(); err != nil {
  53. return nil, err
  54. }
  55. defer server.Close()
  56. user, err := server.Login(query)
  57. if user != nil {
  58. return user, nil
  59. }
  60. // Continue if we couldn't find the user
  61. if err == ErrCouldNotFindUser {
  62. continue
  63. }
  64. if err != nil {
  65. return nil, err
  66. }
  67. }
  68. // Return invalid credentials if we couldn't find the user anywhere
  69. return nil, ErrInvalidCredentials
  70. }
  71. // User attempts to find an user by login/username by searching into all of the configured LDAP servers. Then, if the user is found it returns the user alongisde the server it was found.
  72. func (multiples *MultiLDAP) User(login string) (
  73. *models.ExternalUserInfo,
  74. ldap.ServerConfig,
  75. error,
  76. ) {
  77. if len(multiples.configs) == 0 {
  78. return nil, ldap.ServerConfig{}, ErrNoLDAPServers
  79. }
  80. search := []string{login}
  81. for _, config := range multiples.configs {
  82. server := newLDAP(config)
  83. if err := server.Dial(); err != nil {
  84. return nil, *config, err
  85. }
  86. defer server.Close()
  87. if err := server.Bind(); err != nil {
  88. return nil, *config, err
  89. }
  90. users, err := server.Users(search)
  91. if err != nil {
  92. return nil, *config, err
  93. }
  94. if len(users) != 0 {
  95. return users[0], *config, nil
  96. }
  97. }
  98. return nil, ldap.ServerConfig{}, ErrDidNotFindUser
  99. }
  100. // Users gets users from multiple LDAP servers
  101. func (multiples *MultiLDAP) Users(logins []string) (
  102. []*models.ExternalUserInfo,
  103. error,
  104. ) {
  105. var result []*models.ExternalUserInfo
  106. if len(multiples.configs) == 0 {
  107. return nil, ErrNoLDAPServers
  108. }
  109. for _, config := range multiples.configs {
  110. server := newLDAP(config)
  111. if err := server.Dial(); err != nil {
  112. return nil, err
  113. }
  114. defer server.Close()
  115. if err := server.Bind(); err != nil {
  116. return nil, err
  117. }
  118. users, err := server.Users(logins)
  119. if err != nil {
  120. return nil, err
  121. }
  122. result = append(result, users...)
  123. }
  124. return result, nil
  125. }