multildap.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  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, 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 gets a user by login
  72. func (multiples *MultiLDAP) User(login string) (
  73. *models.ExternalUserInfo,
  74. error,
  75. ) {
  76. if len(multiples.configs) == 0 {
  77. return nil, ErrNoLDAPServers
  78. }
  79. search := []string{login}
  80. for _, config := range multiples.configs {
  81. server := newLDAP(config)
  82. if err := server.Dial(); err != nil {
  83. return nil, err
  84. }
  85. defer server.Close()
  86. if err := server.Bind(); err != nil {
  87. return nil, err
  88. }
  89. users, err := server.Users(search)
  90. if err != nil {
  91. return nil, err
  92. }
  93. if len(users) != 0 {
  94. return users[0], nil
  95. }
  96. }
  97. return nil, ErrDidNotFindUser
  98. }
  99. // Users gets users from multiple LDAP servers
  100. func (multiples *MultiLDAP) Users(logins []string) (
  101. []*models.ExternalUserInfo,
  102. error,
  103. ) {
  104. var result []*models.ExternalUserInfo
  105. if len(multiples.configs) == 0 {
  106. return nil, ErrNoLDAPServers
  107. }
  108. for _, config := range multiples.configs {
  109. server := newLDAP(config)
  110. if err := server.Dial(); err != nil {
  111. return nil, err
  112. }
  113. defer server.Close()
  114. if err := server.Bind(); err != nil {
  115. return nil, err
  116. }
  117. users, err := server.Users(logins)
  118. if err != nil {
  119. return nil, err
  120. }
  121. result = append(result, users...)
  122. }
  123. return result, nil
  124. }