ldap_login_test.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. package ldap
  2. import (
  3. "errors"
  4. "testing"
  5. . "github.com/smartystreets/goconvey/convey"
  6. "gopkg.in/ldap.v3"
  7. "github.com/grafana/grafana/pkg/infra/log"
  8. "github.com/grafana/grafana/pkg/models"
  9. )
  10. func TestLDAPLogin(t *testing.T) {
  11. defaultLogin := &models.LoginUserQuery{
  12. Username: "user",
  13. Password: "pwd",
  14. IpAddress: "192.168.1.1:56433",
  15. }
  16. Convey("Login()", t, func() {
  17. Convey("Should get invalid credentials when userBind fails", func() {
  18. connection := &MockConnection{}
  19. entry := ldap.Entry{}
  20. result := ldap.SearchResult{Entries: []*ldap.Entry{&entry}}
  21. connection.setSearchResult(&result)
  22. connection.BindProvider = func(username, password string) error {
  23. return &ldap.Error{
  24. ResultCode: 49,
  25. }
  26. }
  27. server := &Server{
  28. Config: &ServerConfig{
  29. SearchBaseDNs: []string{"BaseDNHere"},
  30. },
  31. Connection: connection,
  32. log: log.New("test-logger"),
  33. }
  34. _, err := server.Login(defaultLogin)
  35. So(err, ShouldEqual, ErrInvalidCredentials)
  36. })
  37. Convey("Returns an error when search didn't find anything", func() {
  38. connection := &MockConnection{}
  39. result := ldap.SearchResult{Entries: []*ldap.Entry{}}
  40. connection.setSearchResult(&result)
  41. connection.BindProvider = func(username, password string) error {
  42. return nil
  43. }
  44. server := &Server{
  45. Config: &ServerConfig{
  46. SearchBaseDNs: []string{"BaseDNHere"},
  47. },
  48. Connection: connection,
  49. log: log.New("test-logger"),
  50. }
  51. _, err := server.Login(defaultLogin)
  52. So(err, ShouldEqual, ErrCouldNotFindUser)
  53. })
  54. Convey("When search returns an error", func() {
  55. connection := &MockConnection{}
  56. expected := errors.New("Killa-gorilla")
  57. connection.setSearchError(expected)
  58. connection.BindProvider = func(username, password string) error {
  59. return nil
  60. }
  61. server := &Server{
  62. Config: &ServerConfig{
  63. SearchBaseDNs: []string{"BaseDNHere"},
  64. },
  65. Connection: connection,
  66. log: log.New("test-logger"),
  67. }
  68. _, err := server.Login(defaultLogin)
  69. So(err, ShouldEqual, expected)
  70. })
  71. Convey("When login with valid credentials", func() {
  72. connection := &MockConnection{}
  73. entry := ldap.Entry{
  74. DN: "dn", Attributes: []*ldap.EntryAttribute{
  75. {Name: "username", Values: []string{"markelog"}},
  76. {Name: "surname", Values: []string{"Gaidarenko"}},
  77. {Name: "email", Values: []string{"markelog@gmail.com"}},
  78. {Name: "name", Values: []string{"Oleg"}},
  79. {Name: "memberof", Values: []string{"admins"}},
  80. },
  81. }
  82. result := ldap.SearchResult{Entries: []*ldap.Entry{&entry}}
  83. connection.setSearchResult(&result)
  84. connection.BindProvider = func(username, password string) error {
  85. return nil
  86. }
  87. server := &Server{
  88. Config: &ServerConfig{
  89. Attr: AttributeMap{
  90. Username: "username",
  91. Name: "name",
  92. MemberOf: "memberof",
  93. },
  94. SearchBaseDNs: []string{"BaseDNHere"},
  95. },
  96. Connection: connection,
  97. log: log.New("test-logger"),
  98. }
  99. resp, err := server.Login(defaultLogin)
  100. So(err, ShouldBeNil)
  101. So(resp.Login, ShouldEqual, "markelog")
  102. })
  103. Convey("Should perform unauthentificate bind without admin", func() {
  104. connection := &MockConnection{}
  105. entry := ldap.Entry{
  106. DN: "test",
  107. }
  108. result := ldap.SearchResult{Entries: []*ldap.Entry{&entry}}
  109. connection.setSearchResult(&result)
  110. connection.UnauthenticatedBindProvider = func() error {
  111. return nil
  112. }
  113. server := &Server{
  114. Config: &ServerConfig{
  115. SearchBaseDNs: []string{"BaseDNHere"},
  116. },
  117. Connection: connection,
  118. log: log.New("test-logger"),
  119. }
  120. user, err := server.Login(defaultLogin)
  121. So(err, ShouldBeNil)
  122. So(user.AuthId, ShouldEqual, "test")
  123. So(connection.UnauthenticatedBindCalled, ShouldBeTrue)
  124. })
  125. Convey("Should perform authentificate binds", func() {
  126. connection := &MockConnection{}
  127. entry := ldap.Entry{
  128. DN: "test",
  129. }
  130. result := ldap.SearchResult{Entries: []*ldap.Entry{&entry}}
  131. connection.setSearchResult(&result)
  132. adminUsername := ""
  133. adminPassword := ""
  134. username := ""
  135. password := ""
  136. i := 0
  137. connection.BindProvider = func(name, pass string) error {
  138. i++
  139. if i == 1 {
  140. adminUsername = name
  141. adminPassword = pass
  142. }
  143. if i == 2 {
  144. username = name
  145. password = pass
  146. }
  147. return nil
  148. }
  149. server := &Server{
  150. Config: &ServerConfig{
  151. BindDN: "killa",
  152. BindPassword: "gorilla",
  153. SearchBaseDNs: []string{"BaseDNHere"},
  154. },
  155. Connection: connection,
  156. log: log.New("test-logger"),
  157. }
  158. user, err := server.Login(defaultLogin)
  159. So(err, ShouldBeNil)
  160. So(user.AuthId, ShouldEqual, "test")
  161. So(connection.BindCalled, ShouldBeTrue)
  162. So(adminUsername, ShouldEqual, "killa")
  163. So(adminPassword, ShouldEqual, "gorilla")
  164. So(username, ShouldEqual, "test")
  165. So(password, ShouldEqual, "pwd")
  166. })
  167. Convey("Should bind with user if %s exists in the bind_dn", func() {
  168. connection := &MockConnection{}
  169. entry := ldap.Entry{
  170. DN: "test",
  171. }
  172. connection.setSearchResult(&ldap.SearchResult{Entries: []*ldap.Entry{&entry}})
  173. authBindUser := ""
  174. authBindPassword := ""
  175. connection.BindProvider = func(name, pass string) error {
  176. authBindUser = name
  177. authBindPassword = pass
  178. return nil
  179. }
  180. server := &Server{
  181. Config: &ServerConfig{
  182. BindDN: "cn=%s,ou=users,dc=grafana,dc=org",
  183. SearchBaseDNs: []string{"BaseDNHere"},
  184. },
  185. Connection: connection,
  186. log: log.New("test-logger"),
  187. }
  188. _, err := server.Login(defaultLogin)
  189. So(err, ShouldBeNil)
  190. So(authBindUser, ShouldEqual, "cn=user,ou=users,dc=grafana,dc=org")
  191. So(authBindPassword, ShouldEqual, "pwd")
  192. So(connection.BindCalled, ShouldBeTrue)
  193. })
  194. })
  195. }