multildap_test.go 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. package multildap
  2. import (
  3. "errors"
  4. "testing"
  5. "github.com/grafana/grafana/pkg/models"
  6. "github.com/grafana/grafana/pkg/services/ldap"
  7. . "github.com/smartystreets/goconvey/convey"
  8. )
  9. func TestMultiLDAP(t *testing.T) {
  10. Convey("Multildap", t, func() {
  11. Convey("Ping()", func() {
  12. Convey("Should return error for absent config list", func() {
  13. setup()
  14. multi := New([]*ldap.ServerConfig{})
  15. _, err := multi.Ping()
  16. So(err, ShouldBeError)
  17. So(err, ShouldEqual, ErrNoLDAPServers)
  18. teardown()
  19. })
  20. Convey("Should return an unavailable status on dial error", func() {
  21. mock := setup()
  22. expectedErr := errors.New("Dial error")
  23. mock.dialErrReturn = expectedErr
  24. multi := New([]*ldap.ServerConfig{
  25. {Host: "10.0.0.1", Port: 361},
  26. })
  27. statuses, err := multi.Ping()
  28. So(err, ShouldBeNil)
  29. So(statuses[0].Host, ShouldEqual, "10.0.0.1")
  30. So(statuses[0].Port, ShouldEqual, 361)
  31. So(statuses[0].Available, ShouldBeFalse)
  32. So(statuses[0].Error, ShouldEqual, expectedErr)
  33. So(mock.closeCalledTimes, ShouldEqual, 0)
  34. teardown()
  35. })
  36. Convey("Should get the LDAP server statuses", func() {
  37. mock := setup()
  38. multi := New([]*ldap.ServerConfig{
  39. {Host: "10.0.0.1", Port: 361},
  40. })
  41. statuses, err := multi.Ping()
  42. So(err, ShouldBeNil)
  43. So(statuses[0].Host, ShouldEqual, "10.0.0.1")
  44. So(statuses[0].Port, ShouldEqual, 361)
  45. So(statuses[0].Available, ShouldBeTrue)
  46. So(statuses[0].Error, ShouldBeNil)
  47. So(mock.closeCalledTimes, ShouldEqual, 1)
  48. teardown()
  49. })
  50. })
  51. Convey("Login()", func() {
  52. Convey("Should return error for absent config list", func() {
  53. setup()
  54. multi := New([]*ldap.ServerConfig{})
  55. _, err := multi.Login(&models.LoginUserQuery{})
  56. So(err, ShouldBeError)
  57. So(err, ShouldEqual, ErrNoLDAPServers)
  58. teardown()
  59. })
  60. Convey("Should return a dial error", func() {
  61. mock := setup()
  62. expected := errors.New("Dial error")
  63. mock.dialErrReturn = expected
  64. multi := New([]*ldap.ServerConfig{
  65. {}, {},
  66. })
  67. _, err := multi.Login(&models.LoginUserQuery{})
  68. So(err, ShouldBeError)
  69. So(err, ShouldEqual, expected)
  70. teardown()
  71. })
  72. Convey("Should call underlying LDAP methods", func() {
  73. mock := setup()
  74. multi := New([]*ldap.ServerConfig{
  75. {}, {},
  76. })
  77. _, err := multi.Login(&models.LoginUserQuery{})
  78. So(mock.dialCalledTimes, ShouldEqual, 2)
  79. So(mock.loginCalledTimes, ShouldEqual, 2)
  80. So(mock.closeCalledTimes, ShouldEqual, 2)
  81. So(err, ShouldEqual, ErrInvalidCredentials)
  82. teardown()
  83. })
  84. Convey("Should get login result", func() {
  85. mock := setup()
  86. mock.loginReturn = &models.ExternalUserInfo{
  87. Login: "killa",
  88. }
  89. multi := New([]*ldap.ServerConfig{
  90. {}, {},
  91. })
  92. result, err := multi.Login(&models.LoginUserQuery{})
  93. So(mock.dialCalledTimes, ShouldEqual, 1)
  94. So(mock.loginCalledTimes, ShouldEqual, 1)
  95. So(mock.closeCalledTimes, ShouldEqual, 1)
  96. So(result.Login, ShouldEqual, "killa")
  97. So(err, ShouldBeNil)
  98. teardown()
  99. })
  100. Convey("Should still call a second error for invalid not found error", func() {
  101. mock := setup()
  102. mock.loginErrReturn = ErrCouldNotFindUser
  103. multi := New([]*ldap.ServerConfig{
  104. {}, {},
  105. })
  106. _, err := multi.Login(&models.LoginUserQuery{})
  107. So(mock.dialCalledTimes, ShouldEqual, 2)
  108. So(mock.loginCalledTimes, ShouldEqual, 2)
  109. So(mock.closeCalledTimes, ShouldEqual, 2)
  110. So(err, ShouldEqual, ErrInvalidCredentials)
  111. teardown()
  112. })
  113. Convey("Should return unknown error", func() {
  114. mock := setup()
  115. expected := errors.New("Something unknown")
  116. mock.loginErrReturn = expected
  117. multi := New([]*ldap.ServerConfig{
  118. {}, {},
  119. })
  120. _, err := multi.Login(&models.LoginUserQuery{})
  121. So(mock.dialCalledTimes, ShouldEqual, 1)
  122. So(mock.loginCalledTimes, ShouldEqual, 1)
  123. So(mock.closeCalledTimes, ShouldEqual, 1)
  124. So(err, ShouldEqual, expected)
  125. teardown()
  126. })
  127. })
  128. Convey("User()", func() {
  129. Convey("Should return error for absent config list", func() {
  130. setup()
  131. multi := New([]*ldap.ServerConfig{})
  132. _, _, err := multi.User("test")
  133. So(err, ShouldBeError)
  134. So(err, ShouldEqual, ErrNoLDAPServers)
  135. teardown()
  136. })
  137. Convey("Should return a dial error", func() {
  138. mock := setup()
  139. expected := errors.New("Dial error")
  140. mock.dialErrReturn = expected
  141. multi := New([]*ldap.ServerConfig{
  142. {}, {},
  143. })
  144. _, _, err := multi.User("test")
  145. So(err, ShouldBeError)
  146. So(err, ShouldEqual, expected)
  147. teardown()
  148. })
  149. Convey("Should call underlying LDAP methods", func() {
  150. mock := setup()
  151. multi := New([]*ldap.ServerConfig{
  152. {}, {},
  153. })
  154. _, _, err := multi.User("test")
  155. So(mock.dialCalledTimes, ShouldEqual, 2)
  156. So(mock.usersCalledTimes, ShouldEqual, 2)
  157. So(mock.closeCalledTimes, ShouldEqual, 2)
  158. So(err, ShouldEqual, ErrDidNotFindUser)
  159. teardown()
  160. })
  161. Convey("Should return some error", func() {
  162. mock := setup()
  163. expected := errors.New("Killa Gorilla")
  164. mock.usersErrReturn = expected
  165. multi := New([]*ldap.ServerConfig{
  166. {}, {},
  167. })
  168. _, _, err := multi.User("test")
  169. So(mock.dialCalledTimes, ShouldEqual, 1)
  170. So(mock.usersCalledTimes, ShouldEqual, 1)
  171. So(mock.closeCalledTimes, ShouldEqual, 1)
  172. So(err, ShouldEqual, expected)
  173. teardown()
  174. })
  175. Convey("Should get only one user", func() {
  176. mock := setup()
  177. mock.usersFirstReturn = []*models.ExternalUserInfo{
  178. {
  179. Login: "one",
  180. },
  181. {
  182. Login: "two",
  183. },
  184. }
  185. multi := New([]*ldap.ServerConfig{
  186. {}, {},
  187. })
  188. user, _, err := multi.User("test")
  189. So(mock.dialCalledTimes, ShouldEqual, 1)
  190. So(mock.usersCalledTimes, ShouldEqual, 1)
  191. So(mock.closeCalledTimes, ShouldEqual, 1)
  192. So(err, ShouldBeNil)
  193. So(user.Login, ShouldEqual, "one")
  194. teardown()
  195. })
  196. })
  197. Convey("Users()", func() {
  198. Convey("Should return error for absent config list", func() {
  199. setup()
  200. multi := New([]*ldap.ServerConfig{})
  201. _, err := multi.Users([]string{"test"})
  202. So(err, ShouldBeError)
  203. So(err, ShouldEqual, ErrNoLDAPServers)
  204. teardown()
  205. })
  206. Convey("Should return a dial error", func() {
  207. mock := setup()
  208. expected := errors.New("Dial error")
  209. mock.dialErrReturn = expected
  210. multi := New([]*ldap.ServerConfig{
  211. {}, {},
  212. })
  213. _, err := multi.Users([]string{"test"})
  214. So(err, ShouldBeError)
  215. So(err, ShouldEqual, expected)
  216. teardown()
  217. })
  218. Convey("Should call underlying LDAP methods", func() {
  219. mock := setup()
  220. multi := New([]*ldap.ServerConfig{
  221. {}, {},
  222. })
  223. _, err := multi.Users([]string{"test"})
  224. So(mock.dialCalledTimes, ShouldEqual, 2)
  225. So(mock.usersCalledTimes, ShouldEqual, 2)
  226. So(mock.closeCalledTimes, ShouldEqual, 2)
  227. So(err, ShouldBeNil)
  228. teardown()
  229. })
  230. Convey("Should return some error", func() {
  231. mock := setup()
  232. expected := errors.New("Killa Gorilla")
  233. mock.usersErrReturn = expected
  234. multi := New([]*ldap.ServerConfig{
  235. {}, {},
  236. })
  237. _, err := multi.Users([]string{"test"})
  238. So(mock.dialCalledTimes, ShouldEqual, 1)
  239. So(mock.usersCalledTimes, ShouldEqual, 1)
  240. So(mock.closeCalledTimes, ShouldEqual, 1)
  241. So(err, ShouldEqual, expected)
  242. teardown()
  243. })
  244. Convey("Should get users", func() {
  245. mock := setup()
  246. mock.usersFirstReturn = []*models.ExternalUserInfo{
  247. {
  248. Login: "one",
  249. },
  250. {
  251. Login: "two",
  252. },
  253. }
  254. mock.usersRestReturn = []*models.ExternalUserInfo{
  255. {
  256. Login: "three",
  257. },
  258. }
  259. multi := New([]*ldap.ServerConfig{
  260. {}, {},
  261. })
  262. users, err := multi.Users([]string{"test"})
  263. So(mock.dialCalledTimes, ShouldEqual, 2)
  264. So(mock.usersCalledTimes, ShouldEqual, 2)
  265. So(mock.closeCalledTimes, ShouldEqual, 2)
  266. So(err, ShouldBeNil)
  267. So(users[0].Login, ShouldEqual, "one")
  268. So(users[1].Login, ShouldEqual, "two")
  269. So(users[2].Login, ShouldEqual, "three")
  270. teardown()
  271. })
  272. })
  273. })
  274. }