You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

admin_auth_ldap_test.go 33KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325
  1. // Copyright 2019 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package cmd
  4. import (
  5. "context"
  6. "testing"
  7. "code.gitea.io/gitea/models/auth"
  8. "code.gitea.io/gitea/services/auth/source/ldap"
  9. "github.com/stretchr/testify/assert"
  10. "github.com/urfave/cli/v2"
  11. )
  12. func TestAddLdapBindDn(t *testing.T) {
  13. // Mock cli functions to do not exit on error
  14. osExiter := cli.OsExiter
  15. defer func() { cli.OsExiter = osExiter }()
  16. cli.OsExiter = func(code int) {}
  17. // Test cases
  18. cases := []struct {
  19. args []string
  20. source *auth.Source
  21. errMsg string
  22. }{
  23. // case 0
  24. {
  25. args: []string{
  26. "ldap-test",
  27. "--name", "ldap (via Bind DN) source full",
  28. "--not-active",
  29. "--security-protocol", "ldaps",
  30. "--skip-tls-verify",
  31. "--host", "ldap-bind-server full",
  32. "--port", "9876",
  33. "--user-search-base", "ou=Users,dc=full-domain-bind,dc=org",
  34. "--user-filter", "(memberOf=cn=user-group,ou=example,dc=full-domain-bind,dc=org)",
  35. "--admin-filter", "(memberOf=cn=admin-group,ou=example,dc=full-domain-bind,dc=org)",
  36. "--restricted-filter", "(memberOf=cn=restricted-group,ou=example,dc=full-domain-bind,dc=org)",
  37. "--username-attribute", "uid-bind full",
  38. "--firstname-attribute", "givenName-bind full",
  39. "--surname-attribute", "sn-bind full",
  40. "--email-attribute", "mail-bind full",
  41. "--public-ssh-key-attribute", "publickey-bind full",
  42. "--avatar-attribute", "avatar-bind full",
  43. "--bind-dn", "cn=readonly,dc=full-domain-bind,dc=org",
  44. "--bind-password", "secret-bind-full",
  45. "--attributes-in-bind",
  46. "--synchronize-users",
  47. "--page-size", "99",
  48. },
  49. source: &auth.Source{
  50. Type: auth.LDAP,
  51. Name: "ldap (via Bind DN) source full",
  52. IsActive: false,
  53. IsSyncEnabled: true,
  54. Cfg: &ldap.Source{
  55. Name: "ldap (via Bind DN) source full",
  56. Host: "ldap-bind-server full",
  57. Port: 9876,
  58. SecurityProtocol: ldap.SecurityProtocol(1),
  59. SkipVerify: true,
  60. BindDN: "cn=readonly,dc=full-domain-bind,dc=org",
  61. BindPassword: "secret-bind-full",
  62. UserBase: "ou=Users,dc=full-domain-bind,dc=org",
  63. AttributeUsername: "uid-bind full",
  64. AttributeName: "givenName-bind full",
  65. AttributeSurname: "sn-bind full",
  66. AttributeMail: "mail-bind full",
  67. AttributesInBind: true,
  68. AttributeSSHPublicKey: "publickey-bind full",
  69. AttributeAvatar: "avatar-bind full",
  70. SearchPageSize: 99,
  71. Filter: "(memberOf=cn=user-group,ou=example,dc=full-domain-bind,dc=org)",
  72. AdminFilter: "(memberOf=cn=admin-group,ou=example,dc=full-domain-bind,dc=org)",
  73. RestrictedFilter: "(memberOf=cn=restricted-group,ou=example,dc=full-domain-bind,dc=org)",
  74. Enabled: true,
  75. },
  76. },
  77. },
  78. // case 1
  79. {
  80. args: []string{
  81. "ldap-test",
  82. "--name", "ldap (via Bind DN) source min",
  83. "--security-protocol", "unencrypted",
  84. "--host", "ldap-bind-server min",
  85. "--port", "1234",
  86. "--user-search-base", "ou=Users,dc=min-domain-bind,dc=org",
  87. "--user-filter", "(memberOf=cn=user-group,ou=example,dc=min-domain-bind,dc=org)",
  88. "--email-attribute", "mail-bind min",
  89. },
  90. source: &auth.Source{
  91. Type: auth.LDAP,
  92. Name: "ldap (via Bind DN) source min",
  93. IsActive: true,
  94. Cfg: &ldap.Source{
  95. Name: "ldap (via Bind DN) source min",
  96. Host: "ldap-bind-server min",
  97. Port: 1234,
  98. SecurityProtocol: ldap.SecurityProtocol(0),
  99. UserBase: "ou=Users,dc=min-domain-bind,dc=org",
  100. AttributeMail: "mail-bind min",
  101. Filter: "(memberOf=cn=user-group,ou=example,dc=min-domain-bind,dc=org)",
  102. Enabled: true,
  103. },
  104. },
  105. },
  106. // case 2
  107. {
  108. args: []string{
  109. "ldap-test",
  110. "--name", "ldap (via Bind DN) source",
  111. "--security-protocol", "zzzzz",
  112. "--host", "ldap-server",
  113. "--port", "1234",
  114. "--user-search-base", "ou=Users,dc=domain,dc=org",
  115. "--user-filter", "(memberOf=cn=user-group,ou=example,dc=domain,dc=org)",
  116. "--email-attribute", "mail",
  117. },
  118. errMsg: "Unknown security protocol name: zzzzz",
  119. },
  120. // case 3
  121. {
  122. args: []string{
  123. "ldap-test",
  124. "--security-protocol", "unencrypted",
  125. "--host", "ldap-server",
  126. "--port", "1234",
  127. "--user-search-base", "ou=Users,dc=domain,dc=org",
  128. "--user-filter", "(memberOf=cn=user-group,ou=example,dc=domain,dc=org)",
  129. "--email-attribute", "mail",
  130. },
  131. errMsg: "name is not set",
  132. },
  133. // case 4
  134. {
  135. args: []string{
  136. "ldap-test",
  137. "--name", "ldap (via Bind DN) source",
  138. "--host", "ldap-server",
  139. "--port", "1234",
  140. "--user-search-base", "ou=Users,dc=domain,dc=org",
  141. "--user-filter", "(memberOf=cn=user-group,ou=example,dc=domain,dc=org)",
  142. "--email-attribute", "mail",
  143. },
  144. errMsg: "security-protocol is not set",
  145. },
  146. // case 5
  147. {
  148. args: []string{
  149. "ldap-test",
  150. "--name", "ldap (via Bind DN) source",
  151. "--security-protocol", "unencrypted",
  152. "--port", "1234",
  153. "--user-search-base", "ou=Users,dc=domain,dc=org",
  154. "--user-filter", "(memberOf=cn=user-group,ou=example,dc=domain,dc=org)",
  155. "--email-attribute", "mail",
  156. },
  157. errMsg: "host is not set",
  158. },
  159. // case 6
  160. {
  161. args: []string{
  162. "ldap-test",
  163. "--name", "ldap (via Bind DN) source",
  164. "--security-protocol", "unencrypted",
  165. "--host", "ldap-server",
  166. "--user-search-base", "ou=Users,dc=domain,dc=org",
  167. "--user-filter", "(memberOf=cn=user-group,ou=example,dc=domain,dc=org)",
  168. "--email-attribute", "mail",
  169. },
  170. errMsg: "port is not set",
  171. },
  172. // case 7
  173. {
  174. args: []string{
  175. "ldap-test",
  176. "--name", "ldap (via Bind DN) source",
  177. "--security-protocol", "unencrypted",
  178. "--host", "ldap-server",
  179. "--port", "1234",
  180. "--user-search-base", "ou=Users,dc=domain,dc=org",
  181. "--email-attribute", "mail",
  182. },
  183. errMsg: "user-filter is not set",
  184. },
  185. // case 8
  186. {
  187. args: []string{
  188. "ldap-test",
  189. "--name", "ldap (via Bind DN) source",
  190. "--security-protocol", "unencrypted",
  191. "--host", "ldap-server",
  192. "--port", "1234",
  193. "--user-search-base", "ou=Users,dc=domain,dc=org",
  194. "--user-filter", "(memberOf=cn=user-group,ou=example,dc=domain,dc=org)",
  195. },
  196. errMsg: "email-attribute is not set",
  197. },
  198. }
  199. for n, c := range cases {
  200. // Mock functions.
  201. var createdAuthSource *auth.Source
  202. service := &authService{
  203. initDB: func(context.Context) error {
  204. return nil
  205. },
  206. createAuthSource: func(authSource *auth.Source) error {
  207. createdAuthSource = authSource
  208. return nil
  209. },
  210. updateAuthSource: func(authSource *auth.Source) error {
  211. assert.FailNow(t, "case %d: should not call updateAuthSource", n)
  212. return nil
  213. },
  214. getAuthSourceByID: func(id int64) (*auth.Source, error) {
  215. assert.FailNow(t, "case %d: should not call getAuthSourceByID", n)
  216. return nil, nil
  217. },
  218. }
  219. // Create a copy of command to test
  220. app := cli.NewApp()
  221. app.Flags = cmdAuthAddLdapBindDn.Flags
  222. app.Action = service.addLdapBindDn
  223. // Run it
  224. err := app.Run(c.args)
  225. if c.errMsg != "" {
  226. assert.EqualError(t, err, c.errMsg, "case %d: error should match", n)
  227. } else {
  228. assert.NoError(t, err, "case %d: should have no errors", n)
  229. assert.Equal(t, c.source, createdAuthSource, "case %d: wrong authSource", n)
  230. }
  231. }
  232. }
  233. func TestAddLdapSimpleAuth(t *testing.T) {
  234. // Mock cli functions to do not exit on error
  235. osExiter := cli.OsExiter
  236. defer func() { cli.OsExiter = osExiter }()
  237. cli.OsExiter = func(code int) {}
  238. // Test cases
  239. cases := []struct {
  240. args []string
  241. authSource *auth.Source
  242. errMsg string
  243. }{
  244. // case 0
  245. {
  246. args: []string{
  247. "ldap-test",
  248. "--name", "ldap (simple auth) source full",
  249. "--not-active",
  250. "--security-protocol", "starttls",
  251. "--skip-tls-verify",
  252. "--host", "ldap-simple-server full",
  253. "--port", "987",
  254. "--user-search-base", "ou=Users,dc=full-domain-simple,dc=org",
  255. "--user-filter", "(&(objectClass=posixAccount)(full-simple-cn=%s))",
  256. "--admin-filter", "(memberOf=cn=admin-group,ou=example,dc=full-domain-simple,dc=org)",
  257. "--restricted-filter", "(memberOf=cn=restricted-group,ou=example,dc=full-domain-simple,dc=org)",
  258. "--username-attribute", "uid-simple full",
  259. "--firstname-attribute", "givenName-simple full",
  260. "--surname-attribute", "sn-simple full",
  261. "--email-attribute", "mail-simple full",
  262. "--public-ssh-key-attribute", "publickey-simple full",
  263. "--avatar-attribute", "avatar-simple full",
  264. "--user-dn", "cn=%s,ou=Users,dc=full-domain-simple,dc=org",
  265. },
  266. authSource: &auth.Source{
  267. Type: auth.DLDAP,
  268. Name: "ldap (simple auth) source full",
  269. IsActive: false,
  270. Cfg: &ldap.Source{
  271. Name: "ldap (simple auth) source full",
  272. Host: "ldap-simple-server full",
  273. Port: 987,
  274. SecurityProtocol: ldap.SecurityProtocol(2),
  275. SkipVerify: true,
  276. UserDN: "cn=%s,ou=Users,dc=full-domain-simple,dc=org",
  277. UserBase: "ou=Users,dc=full-domain-simple,dc=org",
  278. AttributeUsername: "uid-simple full",
  279. AttributeName: "givenName-simple full",
  280. AttributeSurname: "sn-simple full",
  281. AttributeMail: "mail-simple full",
  282. AttributeSSHPublicKey: "publickey-simple full",
  283. AttributeAvatar: "avatar-simple full",
  284. Filter: "(&(objectClass=posixAccount)(full-simple-cn=%s))",
  285. AdminFilter: "(memberOf=cn=admin-group,ou=example,dc=full-domain-simple,dc=org)",
  286. RestrictedFilter: "(memberOf=cn=restricted-group,ou=example,dc=full-domain-simple,dc=org)",
  287. Enabled: true,
  288. },
  289. },
  290. },
  291. // case 1
  292. {
  293. args: []string{
  294. "ldap-test",
  295. "--name", "ldap (simple auth) source min",
  296. "--security-protocol", "unencrypted",
  297. "--host", "ldap-simple-server min",
  298. "--port", "123",
  299. "--user-filter", "(&(objectClass=posixAccount)(min-simple-cn=%s))",
  300. "--email-attribute", "mail-simple min",
  301. "--user-dn", "cn=%s,ou=Users,dc=min-domain-simple,dc=org",
  302. },
  303. authSource: &auth.Source{
  304. Type: auth.DLDAP,
  305. Name: "ldap (simple auth) source min",
  306. IsActive: true,
  307. Cfg: &ldap.Source{
  308. Name: "ldap (simple auth) source min",
  309. Host: "ldap-simple-server min",
  310. Port: 123,
  311. SecurityProtocol: ldap.SecurityProtocol(0),
  312. UserDN: "cn=%s,ou=Users,dc=min-domain-simple,dc=org",
  313. AttributeMail: "mail-simple min",
  314. Filter: "(&(objectClass=posixAccount)(min-simple-cn=%s))",
  315. Enabled: true,
  316. },
  317. },
  318. },
  319. // case 2
  320. {
  321. args: []string{
  322. "ldap-test",
  323. "--name", "ldap (simple auth) source",
  324. "--security-protocol", "zzzzz",
  325. "--host", "ldap-server",
  326. "--port", "123",
  327. "--user-filter", "(&(objectClass=posixAccount)(cn=%s))",
  328. "--email-attribute", "mail",
  329. "--user-dn", "cn=%s,ou=Users,dc=domain,dc=org",
  330. },
  331. errMsg: "Unknown security protocol name: zzzzz",
  332. },
  333. // case 3
  334. {
  335. args: []string{
  336. "ldap-test",
  337. "--security-protocol", "unencrypted",
  338. "--host", "ldap-server",
  339. "--port", "123",
  340. "--user-filter", "(&(objectClass=posixAccount)(cn=%s))",
  341. "--email-attribute", "mail",
  342. "--user-dn", "cn=%s,ou=Users,dc=domain,dc=org",
  343. },
  344. errMsg: "name is not set",
  345. },
  346. // case 4
  347. {
  348. args: []string{
  349. "ldap-test",
  350. "--name", "ldap (simple auth) source",
  351. "--host", "ldap-server",
  352. "--port", "123",
  353. "--user-filter", "(&(objectClass=posixAccount)(cn=%s))",
  354. "--email-attribute", "mail",
  355. "--user-dn", "cn=%s,ou=Users,dc=domain,dc=org",
  356. },
  357. errMsg: "security-protocol is not set",
  358. },
  359. // case 5
  360. {
  361. args: []string{
  362. "ldap-test",
  363. "--name", "ldap (simple auth) source",
  364. "--security-protocol", "unencrypted",
  365. "--port", "123",
  366. "--user-filter", "(&(objectClass=posixAccount)(cn=%s))",
  367. "--email-attribute", "mail",
  368. "--user-dn", "cn=%s,ou=Users,dc=domain,dc=org",
  369. },
  370. errMsg: "host is not set",
  371. },
  372. // case 6
  373. {
  374. args: []string{
  375. "ldap-test",
  376. "--name", "ldap (simple auth) source",
  377. "--security-protocol", "unencrypted",
  378. "--host", "ldap-server",
  379. "--user-filter", "(&(objectClass=posixAccount)(cn=%s))",
  380. "--email-attribute", "mail",
  381. "--user-dn", "cn=%s,ou=Users,dc=domain,dc=org",
  382. },
  383. errMsg: "port is not set",
  384. },
  385. // case 7
  386. {
  387. args: []string{
  388. "ldap-test",
  389. "--name", "ldap (simple auth) source",
  390. "--security-protocol", "unencrypted",
  391. "--host", "ldap-server",
  392. "--port", "123",
  393. "--email-attribute", "mail",
  394. "--user-dn", "cn=%s,ou=Users,dc=domain,dc=org",
  395. },
  396. errMsg: "user-filter is not set",
  397. },
  398. // case 8
  399. {
  400. args: []string{
  401. "ldap-test",
  402. "--name", "ldap (simple auth) source",
  403. "--security-protocol", "unencrypted",
  404. "--host", "ldap-server",
  405. "--port", "123",
  406. "--user-filter", "(&(objectClass=posixAccount)(cn=%s))",
  407. "--user-dn", "cn=%s,ou=Users,dc=domain,dc=org",
  408. },
  409. errMsg: "email-attribute is not set",
  410. },
  411. // case 9
  412. {
  413. args: []string{
  414. "ldap-test",
  415. "--name", "ldap (simple auth) source",
  416. "--security-protocol", "unencrypted",
  417. "--host", "ldap-server",
  418. "--port", "123",
  419. "--user-filter", "(&(objectClass=posixAccount)(cn=%s))",
  420. "--email-attribute", "mail",
  421. },
  422. errMsg: "user-dn is not set",
  423. },
  424. }
  425. for n, c := range cases {
  426. // Mock functions.
  427. var createdAuthSource *auth.Source
  428. service := &authService{
  429. initDB: func(context.Context) error {
  430. return nil
  431. },
  432. createAuthSource: func(authSource *auth.Source) error {
  433. createdAuthSource = authSource
  434. return nil
  435. },
  436. updateAuthSource: func(authSource *auth.Source) error {
  437. assert.FailNow(t, "case %d: should not call updateAuthSource", n)
  438. return nil
  439. },
  440. getAuthSourceByID: func(id int64) (*auth.Source, error) {
  441. assert.FailNow(t, "case %d: should not call getAuthSourceByID", n)
  442. return nil, nil
  443. },
  444. }
  445. // Create a copy of command to test
  446. app := cli.NewApp()
  447. app.Flags = cmdAuthAddLdapSimpleAuth.Flags
  448. app.Action = service.addLdapSimpleAuth
  449. // Run it
  450. err := app.Run(c.args)
  451. if c.errMsg != "" {
  452. assert.EqualError(t, err, c.errMsg, "case %d: error should match", n)
  453. } else {
  454. assert.NoError(t, err, "case %d: should have no errors", n)
  455. assert.Equal(t, c.authSource, createdAuthSource, "case %d: wrong authSource", n)
  456. }
  457. }
  458. }
  459. func TestUpdateLdapBindDn(t *testing.T) {
  460. // Mock cli functions to do not exit on error
  461. osExiter := cli.OsExiter
  462. defer func() { cli.OsExiter = osExiter }()
  463. cli.OsExiter = func(code int) {}
  464. // Test cases
  465. cases := []struct {
  466. args []string
  467. id int64
  468. existingAuthSource *auth.Source
  469. authSource *auth.Source
  470. errMsg string
  471. }{
  472. // case 0
  473. {
  474. args: []string{
  475. "ldap-test",
  476. "--id", "23",
  477. "--name", "ldap (via Bind DN) source full",
  478. "--not-active",
  479. "--security-protocol", "LDAPS",
  480. "--skip-tls-verify",
  481. "--host", "ldap-bind-server full",
  482. "--port", "9876",
  483. "--user-search-base", "ou=Users,dc=full-domain-bind,dc=org",
  484. "--user-filter", "(memberOf=cn=user-group,ou=example,dc=full-domain-bind,dc=org)",
  485. "--admin-filter", "(memberOf=cn=admin-group,ou=example,dc=full-domain-bind,dc=org)",
  486. "--restricted-filter", "(memberOf=cn=restricted-group,ou=example,dc=full-domain-bind,dc=org)",
  487. "--username-attribute", "uid-bind full",
  488. "--firstname-attribute", "givenName-bind full",
  489. "--surname-attribute", "sn-bind full",
  490. "--email-attribute", "mail-bind full",
  491. "--public-ssh-key-attribute", "publickey-bind full",
  492. "--avatar-attribute", "avatar-bind full",
  493. "--bind-dn", "cn=readonly,dc=full-domain-bind,dc=org",
  494. "--bind-password", "secret-bind-full",
  495. "--synchronize-users",
  496. "--page-size", "99",
  497. },
  498. id: 23,
  499. existingAuthSource: &auth.Source{
  500. Type: auth.LDAP,
  501. IsActive: true,
  502. Cfg: &ldap.Source{
  503. Enabled: true,
  504. },
  505. },
  506. authSource: &auth.Source{
  507. Type: auth.LDAP,
  508. Name: "ldap (via Bind DN) source full",
  509. IsActive: false,
  510. IsSyncEnabled: true,
  511. Cfg: &ldap.Source{
  512. Name: "ldap (via Bind DN) source full",
  513. Host: "ldap-bind-server full",
  514. Port: 9876,
  515. SecurityProtocol: ldap.SecurityProtocol(1),
  516. SkipVerify: true,
  517. BindDN: "cn=readonly,dc=full-domain-bind,dc=org",
  518. BindPassword: "secret-bind-full",
  519. UserBase: "ou=Users,dc=full-domain-bind,dc=org",
  520. AttributeUsername: "uid-bind full",
  521. AttributeName: "givenName-bind full",
  522. AttributeSurname: "sn-bind full",
  523. AttributeMail: "mail-bind full",
  524. AttributesInBind: false,
  525. AttributeSSHPublicKey: "publickey-bind full",
  526. AttributeAvatar: "avatar-bind full",
  527. SearchPageSize: 99,
  528. Filter: "(memberOf=cn=user-group,ou=example,dc=full-domain-bind,dc=org)",
  529. AdminFilter: "(memberOf=cn=admin-group,ou=example,dc=full-domain-bind,dc=org)",
  530. RestrictedFilter: "(memberOf=cn=restricted-group,ou=example,dc=full-domain-bind,dc=org)",
  531. Enabled: true,
  532. },
  533. },
  534. },
  535. // case 1
  536. {
  537. args: []string{
  538. "ldap-test",
  539. "--id", "1",
  540. },
  541. authSource: &auth.Source{
  542. Type: auth.LDAP,
  543. Cfg: &ldap.Source{},
  544. },
  545. },
  546. // case 2
  547. {
  548. args: []string{
  549. "ldap-test",
  550. "--id", "1",
  551. "--name", "ldap (via Bind DN) source",
  552. },
  553. authSource: &auth.Source{
  554. Type: auth.LDAP,
  555. Name: "ldap (via Bind DN) source",
  556. Cfg: &ldap.Source{
  557. Name: "ldap (via Bind DN) source",
  558. },
  559. },
  560. },
  561. // case 3
  562. {
  563. args: []string{
  564. "ldap-test",
  565. "--id", "1",
  566. "--not-active",
  567. },
  568. existingAuthSource: &auth.Source{
  569. Type: auth.LDAP,
  570. IsActive: true,
  571. Cfg: &ldap.Source{},
  572. },
  573. authSource: &auth.Source{
  574. Type: auth.LDAP,
  575. IsActive: false,
  576. Cfg: &ldap.Source{},
  577. },
  578. },
  579. // case 4
  580. {
  581. args: []string{
  582. "ldap-test",
  583. "--id", "1",
  584. "--security-protocol", "LDAPS",
  585. },
  586. authSource: &auth.Source{
  587. Type: auth.LDAP,
  588. Cfg: &ldap.Source{
  589. SecurityProtocol: ldap.SecurityProtocol(1),
  590. },
  591. },
  592. },
  593. // case 5
  594. {
  595. args: []string{
  596. "ldap-test",
  597. "--id", "1",
  598. "--skip-tls-verify",
  599. },
  600. authSource: &auth.Source{
  601. Type: auth.LDAP,
  602. Cfg: &ldap.Source{
  603. SkipVerify: true,
  604. },
  605. },
  606. },
  607. // case 6
  608. {
  609. args: []string{
  610. "ldap-test",
  611. "--id", "1",
  612. "--host", "ldap-server",
  613. },
  614. authSource: &auth.Source{
  615. Type: auth.LDAP,
  616. Cfg: &ldap.Source{
  617. Host: "ldap-server",
  618. },
  619. },
  620. },
  621. // case 7
  622. {
  623. args: []string{
  624. "ldap-test",
  625. "--id", "1",
  626. "--port", "389",
  627. },
  628. authSource: &auth.Source{
  629. Type: auth.LDAP,
  630. Cfg: &ldap.Source{
  631. Port: 389,
  632. },
  633. },
  634. },
  635. // case 8
  636. {
  637. args: []string{
  638. "ldap-test",
  639. "--id", "1",
  640. "--user-search-base", "ou=Users,dc=domain,dc=org",
  641. },
  642. authSource: &auth.Source{
  643. Type: auth.LDAP,
  644. Cfg: &ldap.Source{
  645. UserBase: "ou=Users,dc=domain,dc=org",
  646. },
  647. },
  648. },
  649. // case 9
  650. {
  651. args: []string{
  652. "ldap-test",
  653. "--id", "1",
  654. "--user-filter", "(memberOf=cn=user-group,ou=example,dc=domain,dc=org)",
  655. },
  656. authSource: &auth.Source{
  657. Type: auth.LDAP,
  658. Cfg: &ldap.Source{
  659. Filter: "(memberOf=cn=user-group,ou=example,dc=domain,dc=org)",
  660. },
  661. },
  662. },
  663. // case 10
  664. {
  665. args: []string{
  666. "ldap-test",
  667. "--id", "1",
  668. "--admin-filter", "(memberOf=cn=admin-group,ou=example,dc=domain,dc=org)",
  669. },
  670. authSource: &auth.Source{
  671. Type: auth.LDAP,
  672. Cfg: &ldap.Source{
  673. AdminFilter: "(memberOf=cn=admin-group,ou=example,dc=domain,dc=org)",
  674. },
  675. },
  676. },
  677. // case 11
  678. {
  679. args: []string{
  680. "ldap-test",
  681. "--id", "1",
  682. "--username-attribute", "uid",
  683. },
  684. authSource: &auth.Source{
  685. Type: auth.LDAP,
  686. Cfg: &ldap.Source{
  687. AttributeUsername: "uid",
  688. },
  689. },
  690. },
  691. // case 12
  692. {
  693. args: []string{
  694. "ldap-test",
  695. "--id", "1",
  696. "--firstname-attribute", "givenName",
  697. },
  698. authSource: &auth.Source{
  699. Type: auth.LDAP,
  700. Cfg: &ldap.Source{
  701. AttributeName: "givenName",
  702. },
  703. },
  704. },
  705. // case 13
  706. {
  707. args: []string{
  708. "ldap-test",
  709. "--id", "1",
  710. "--surname-attribute", "sn",
  711. },
  712. authSource: &auth.Source{
  713. Type: auth.LDAP,
  714. Cfg: &ldap.Source{
  715. AttributeSurname: "sn",
  716. },
  717. },
  718. },
  719. // case 14
  720. {
  721. args: []string{
  722. "ldap-test",
  723. "--id", "1",
  724. "--email-attribute", "mail",
  725. },
  726. authSource: &auth.Source{
  727. Type: auth.LDAP,
  728. Cfg: &ldap.Source{
  729. AttributeMail: "mail",
  730. },
  731. },
  732. },
  733. // case 15
  734. {
  735. args: []string{
  736. "ldap-test",
  737. "--id", "1",
  738. "--attributes-in-bind",
  739. },
  740. authSource: &auth.Source{
  741. Type: auth.LDAP,
  742. Cfg: &ldap.Source{
  743. AttributesInBind: true,
  744. },
  745. },
  746. },
  747. // case 16
  748. {
  749. args: []string{
  750. "ldap-test",
  751. "--id", "1",
  752. "--public-ssh-key-attribute", "publickey",
  753. },
  754. authSource: &auth.Source{
  755. Type: auth.LDAP,
  756. Cfg: &ldap.Source{
  757. AttributeSSHPublicKey: "publickey",
  758. },
  759. },
  760. },
  761. // case 17
  762. {
  763. args: []string{
  764. "ldap-test",
  765. "--id", "1",
  766. "--bind-dn", "cn=readonly,dc=domain,dc=org",
  767. },
  768. authSource: &auth.Source{
  769. Type: auth.LDAP,
  770. Cfg: &ldap.Source{
  771. BindDN: "cn=readonly,dc=domain,dc=org",
  772. },
  773. },
  774. },
  775. // case 18
  776. {
  777. args: []string{
  778. "ldap-test",
  779. "--id", "1",
  780. "--bind-password", "secret",
  781. },
  782. authSource: &auth.Source{
  783. Type: auth.LDAP,
  784. Cfg: &ldap.Source{
  785. BindPassword: "secret",
  786. },
  787. },
  788. },
  789. // case 19
  790. {
  791. args: []string{
  792. "ldap-test",
  793. "--id", "1",
  794. "--synchronize-users",
  795. },
  796. authSource: &auth.Source{
  797. Type: auth.LDAP,
  798. IsSyncEnabled: true,
  799. Cfg: &ldap.Source{},
  800. },
  801. },
  802. // case 20
  803. {
  804. args: []string{
  805. "ldap-test",
  806. "--id", "1",
  807. "--page-size", "12",
  808. },
  809. authSource: &auth.Source{
  810. Type: auth.LDAP,
  811. Cfg: &ldap.Source{
  812. SearchPageSize: 12,
  813. },
  814. },
  815. },
  816. // case 21
  817. {
  818. args: []string{
  819. "ldap-test",
  820. "--id", "1",
  821. "--security-protocol", "xxxxx",
  822. },
  823. errMsg: "Unknown security protocol name: xxxxx",
  824. },
  825. // case 22
  826. {
  827. args: []string{
  828. "ldap-test",
  829. },
  830. errMsg: "id is not set",
  831. },
  832. // case 23
  833. {
  834. args: []string{
  835. "ldap-test",
  836. "--id", "1",
  837. },
  838. existingAuthSource: &auth.Source{
  839. Type: auth.OAuth2,
  840. Cfg: &ldap.Source{},
  841. },
  842. errMsg: "Invalid authentication type. expected: LDAP (via BindDN), actual: OAuth2",
  843. },
  844. // case 24
  845. {
  846. args: []string{
  847. "ldap-test",
  848. "--id", "24",
  849. "--name", "ldap (via Bind DN) flip 'active' and 'user sync' attributes",
  850. "--active",
  851. "--disable-synchronize-users",
  852. },
  853. id: 24,
  854. existingAuthSource: &auth.Source{
  855. Type: auth.LDAP,
  856. IsActive: false,
  857. IsSyncEnabled: true,
  858. Cfg: &ldap.Source{
  859. Name: "ldap (via Bind DN) flip 'active' and 'user sync' attributes",
  860. Enabled: true,
  861. },
  862. },
  863. authSource: &auth.Source{
  864. Type: auth.LDAP,
  865. Name: "ldap (via Bind DN) flip 'active' and 'user sync' attributes",
  866. IsActive: true,
  867. IsSyncEnabled: false,
  868. Cfg: &ldap.Source{
  869. Name: "ldap (via Bind DN) flip 'active' and 'user sync' attributes",
  870. Enabled: true,
  871. },
  872. },
  873. },
  874. }
  875. for n, c := range cases {
  876. // Mock functions.
  877. var updatedAuthSource *auth.Source
  878. service := &authService{
  879. initDB: func(context.Context) error {
  880. return nil
  881. },
  882. createAuthSource: func(authSource *auth.Source) error {
  883. assert.FailNow(t, "case %d: should not call createAuthSource", n)
  884. return nil
  885. },
  886. updateAuthSource: func(authSource *auth.Source) error {
  887. updatedAuthSource = authSource
  888. return nil
  889. },
  890. getAuthSourceByID: func(id int64) (*auth.Source, error) {
  891. if c.id != 0 {
  892. assert.Equal(t, c.id, id, "case %d: wrong id", n)
  893. }
  894. if c.existingAuthSource != nil {
  895. return c.existingAuthSource, nil
  896. }
  897. return &auth.Source{
  898. Type: auth.LDAP,
  899. Cfg: &ldap.Source{},
  900. }, nil
  901. },
  902. }
  903. // Create a copy of command to test
  904. app := cli.NewApp()
  905. app.Flags = cmdAuthUpdateLdapBindDn.Flags
  906. app.Action = service.updateLdapBindDn
  907. // Run it
  908. err := app.Run(c.args)
  909. if c.errMsg != "" {
  910. assert.EqualError(t, err, c.errMsg, "case %d: error should match", n)
  911. } else {
  912. assert.NoError(t, err, "case %d: should have no errors", n)
  913. assert.Equal(t, c.authSource, updatedAuthSource, "case %d: wrong authSource", n)
  914. }
  915. }
  916. }
  917. func TestUpdateLdapSimpleAuth(t *testing.T) {
  918. // Mock cli functions to do not exit on error
  919. osExiter := cli.OsExiter
  920. defer func() { cli.OsExiter = osExiter }()
  921. cli.OsExiter = func(code int) {}
  922. // Test cases
  923. cases := []struct {
  924. args []string
  925. id int64
  926. existingAuthSource *auth.Source
  927. authSource *auth.Source
  928. errMsg string
  929. }{
  930. // case 0
  931. {
  932. args: []string{
  933. "ldap-test",
  934. "--id", "7",
  935. "--name", "ldap (simple auth) source full",
  936. "--not-active",
  937. "--security-protocol", "starttls",
  938. "--skip-tls-verify",
  939. "--host", "ldap-simple-server full",
  940. "--port", "987",
  941. "--user-search-base", "ou=Users,dc=full-domain-simple,dc=org",
  942. "--user-filter", "(&(objectClass=posixAccount)(full-simple-cn=%s))",
  943. "--admin-filter", "(memberOf=cn=admin-group,ou=example,dc=full-domain-simple,dc=org)",
  944. "--restricted-filter", "(memberOf=cn=restricted-group,ou=example,dc=full-domain-simple,dc=org)",
  945. "--username-attribute", "uid-simple full",
  946. "--firstname-attribute", "givenName-simple full",
  947. "--surname-attribute", "sn-simple full",
  948. "--email-attribute", "mail-simple full",
  949. "--public-ssh-key-attribute", "publickey-simple full",
  950. "--avatar-attribute", "avatar-simple full",
  951. "--user-dn", "cn=%s,ou=Users,dc=full-domain-simple,dc=org",
  952. },
  953. id: 7,
  954. authSource: &auth.Source{
  955. Type: auth.DLDAP,
  956. Name: "ldap (simple auth) source full",
  957. IsActive: false,
  958. Cfg: &ldap.Source{
  959. Name: "ldap (simple auth) source full",
  960. Host: "ldap-simple-server full",
  961. Port: 987,
  962. SecurityProtocol: ldap.SecurityProtocol(2),
  963. SkipVerify: true,
  964. UserDN: "cn=%s,ou=Users,dc=full-domain-simple,dc=org",
  965. UserBase: "ou=Users,dc=full-domain-simple,dc=org",
  966. AttributeUsername: "uid-simple full",
  967. AttributeName: "givenName-simple full",
  968. AttributeSurname: "sn-simple full",
  969. AttributeMail: "mail-simple full",
  970. AttributeSSHPublicKey: "publickey-simple full",
  971. AttributeAvatar: "avatar-simple full",
  972. Filter: "(&(objectClass=posixAccount)(full-simple-cn=%s))",
  973. AdminFilter: "(memberOf=cn=admin-group,ou=example,dc=full-domain-simple,dc=org)",
  974. RestrictedFilter: "(memberOf=cn=restricted-group,ou=example,dc=full-domain-simple,dc=org)",
  975. },
  976. },
  977. },
  978. // case 1
  979. {
  980. args: []string{
  981. "ldap-test",
  982. "--id", "1",
  983. },
  984. authSource: &auth.Source{
  985. Type: auth.DLDAP,
  986. Cfg: &ldap.Source{},
  987. },
  988. },
  989. // case 2
  990. {
  991. args: []string{
  992. "ldap-test",
  993. "--id", "1",
  994. "--name", "ldap (simple auth) source",
  995. },
  996. authSource: &auth.Source{
  997. Type: auth.DLDAP,
  998. Name: "ldap (simple auth) source",
  999. Cfg: &ldap.Source{
  1000. Name: "ldap (simple auth) source",
  1001. },
  1002. },
  1003. },
  1004. // case 3
  1005. {
  1006. args: []string{
  1007. "ldap-test",
  1008. "--id", "1",
  1009. "--not-active",
  1010. },
  1011. existingAuthSource: &auth.Source{
  1012. Type: auth.DLDAP,
  1013. IsActive: true,
  1014. Cfg: &ldap.Source{},
  1015. },
  1016. authSource: &auth.Source{
  1017. Type: auth.DLDAP,
  1018. IsActive: false,
  1019. Cfg: &ldap.Source{},
  1020. },
  1021. },
  1022. // case 4
  1023. {
  1024. args: []string{
  1025. "ldap-test",
  1026. "--id", "1",
  1027. "--security-protocol", "starttls",
  1028. },
  1029. authSource: &auth.Source{
  1030. Type: auth.DLDAP,
  1031. Cfg: &ldap.Source{
  1032. SecurityProtocol: ldap.SecurityProtocol(2),
  1033. },
  1034. },
  1035. },
  1036. // case 5
  1037. {
  1038. args: []string{
  1039. "ldap-test",
  1040. "--id", "1",
  1041. "--skip-tls-verify",
  1042. },
  1043. authSource: &auth.Source{
  1044. Type: auth.DLDAP,
  1045. Cfg: &ldap.Source{
  1046. SkipVerify: true,
  1047. },
  1048. },
  1049. },
  1050. // case 6
  1051. {
  1052. args: []string{
  1053. "ldap-test",
  1054. "--id", "1",
  1055. "--host", "ldap-server",
  1056. },
  1057. authSource: &auth.Source{
  1058. Type: auth.DLDAP,
  1059. Cfg: &ldap.Source{
  1060. Host: "ldap-server",
  1061. },
  1062. },
  1063. },
  1064. // case 7
  1065. {
  1066. args: []string{
  1067. "ldap-test",
  1068. "--id", "1",
  1069. "--port", "987",
  1070. },
  1071. authSource: &auth.Source{
  1072. Type: auth.DLDAP,
  1073. Cfg: &ldap.Source{
  1074. Port: 987,
  1075. },
  1076. },
  1077. },
  1078. // case 8
  1079. {
  1080. args: []string{
  1081. "ldap-test",
  1082. "--id", "1",
  1083. "--user-search-base", "ou=Users,dc=domain,dc=org",
  1084. },
  1085. authSource: &auth.Source{
  1086. Type: auth.DLDAP,
  1087. Cfg: &ldap.Source{
  1088. UserBase: "ou=Users,dc=domain,dc=org",
  1089. },
  1090. },
  1091. },
  1092. // case 9
  1093. {
  1094. args: []string{
  1095. "ldap-test",
  1096. "--id", "1",
  1097. "--user-filter", "(&(objectClass=posixAccount)(cn=%s))",
  1098. },
  1099. authSource: &auth.Source{
  1100. Type: auth.DLDAP,
  1101. Cfg: &ldap.Source{
  1102. Filter: "(&(objectClass=posixAccount)(cn=%s))",
  1103. },
  1104. },
  1105. },
  1106. // case 10
  1107. {
  1108. args: []string{
  1109. "ldap-test",
  1110. "--id", "1",
  1111. "--admin-filter", "(memberOf=cn=admin-group,ou=example,dc=domain,dc=org)",
  1112. },
  1113. authSource: &auth.Source{
  1114. Type: auth.DLDAP,
  1115. Cfg: &ldap.Source{
  1116. AdminFilter: "(memberOf=cn=admin-group,ou=example,dc=domain,dc=org)",
  1117. },
  1118. },
  1119. },
  1120. // case 11
  1121. {
  1122. args: []string{
  1123. "ldap-test",
  1124. "--id", "1",
  1125. "--username-attribute", "uid",
  1126. },
  1127. authSource: &auth.Source{
  1128. Type: auth.DLDAP,
  1129. Cfg: &ldap.Source{
  1130. AttributeUsername: "uid",
  1131. },
  1132. },
  1133. },
  1134. // case 12
  1135. {
  1136. args: []string{
  1137. "ldap-test",
  1138. "--id", "1",
  1139. "--firstname-attribute", "givenName",
  1140. },
  1141. authSource: &auth.Source{
  1142. Type: auth.DLDAP,
  1143. Cfg: &ldap.Source{
  1144. AttributeName: "givenName",
  1145. },
  1146. },
  1147. },
  1148. // case 13
  1149. {
  1150. args: []string{
  1151. "ldap-test",
  1152. "--id", "1",
  1153. "--surname-attribute", "sn",
  1154. },
  1155. authSource: &auth.Source{
  1156. Type: auth.DLDAP,
  1157. Cfg: &ldap.Source{
  1158. AttributeSurname: "sn",
  1159. },
  1160. },
  1161. },
  1162. // case 14
  1163. {
  1164. args: []string{
  1165. "ldap-test",
  1166. "--id", "1",
  1167. "--email-attribute", "mail",
  1168. },
  1169. authSource: &auth.Source{
  1170. Type: auth.DLDAP,
  1171. Cfg: &ldap.Source{
  1172. AttributeMail: "mail",
  1173. },
  1174. },
  1175. },
  1176. // case 15
  1177. {
  1178. args: []string{
  1179. "ldap-test",
  1180. "--id", "1",
  1181. "--public-ssh-key-attribute", "publickey",
  1182. },
  1183. authSource: &auth.Source{
  1184. Type: auth.DLDAP,
  1185. Cfg: &ldap.Source{
  1186. AttributeSSHPublicKey: "publickey",
  1187. },
  1188. },
  1189. },
  1190. // case 16
  1191. {
  1192. args: []string{
  1193. "ldap-test",
  1194. "--id", "1",
  1195. "--user-dn", "cn=%s,ou=Users,dc=domain,dc=org",
  1196. },
  1197. authSource: &auth.Source{
  1198. Type: auth.DLDAP,
  1199. Cfg: &ldap.Source{
  1200. UserDN: "cn=%s,ou=Users,dc=domain,dc=org",
  1201. },
  1202. },
  1203. },
  1204. // case 17
  1205. {
  1206. args: []string{
  1207. "ldap-test",
  1208. "--id", "1",
  1209. "--security-protocol", "xxxxx",
  1210. },
  1211. errMsg: "Unknown security protocol name: xxxxx",
  1212. },
  1213. // case 18
  1214. {
  1215. args: []string{
  1216. "ldap-test",
  1217. },
  1218. errMsg: "id is not set",
  1219. },
  1220. // case 19
  1221. {
  1222. args: []string{
  1223. "ldap-test",
  1224. "--id", "1",
  1225. },
  1226. existingAuthSource: &auth.Source{
  1227. Type: auth.PAM,
  1228. Cfg: &ldap.Source{},
  1229. },
  1230. errMsg: "Invalid authentication type. expected: LDAP (simple auth), actual: PAM",
  1231. },
  1232. // case 20
  1233. {
  1234. args: []string{
  1235. "ldap-test",
  1236. "--id", "20",
  1237. "--name", "ldap (simple auth) flip 'active' attribute",
  1238. "--active",
  1239. },
  1240. id: 20,
  1241. existingAuthSource: &auth.Source{
  1242. Type: auth.DLDAP,
  1243. IsActive: false,
  1244. Cfg: &ldap.Source{
  1245. Name: "ldap (simple auth) flip 'active' attribute",
  1246. Enabled: true,
  1247. },
  1248. },
  1249. authSource: &auth.Source{
  1250. Type: auth.DLDAP,
  1251. Name: "ldap (simple auth) flip 'active' attribute",
  1252. IsActive: true,
  1253. Cfg: &ldap.Source{
  1254. Name: "ldap (simple auth) flip 'active' attribute",
  1255. Enabled: true,
  1256. },
  1257. },
  1258. },
  1259. }
  1260. for n, c := range cases {
  1261. // Mock functions.
  1262. var updatedAuthSource *auth.Source
  1263. service := &authService{
  1264. initDB: func(context.Context) error {
  1265. return nil
  1266. },
  1267. createAuthSource: func(authSource *auth.Source) error {
  1268. assert.FailNow(t, "case %d: should not call createAuthSource", n)
  1269. return nil
  1270. },
  1271. updateAuthSource: func(authSource *auth.Source) error {
  1272. updatedAuthSource = authSource
  1273. return nil
  1274. },
  1275. getAuthSourceByID: func(id int64) (*auth.Source, error) {
  1276. if c.id != 0 {
  1277. assert.Equal(t, c.id, id, "case %d: wrong id", n)
  1278. }
  1279. if c.existingAuthSource != nil {
  1280. return c.existingAuthSource, nil
  1281. }
  1282. return &auth.Source{
  1283. Type: auth.DLDAP,
  1284. Cfg: &ldap.Source{},
  1285. }, nil
  1286. },
  1287. }
  1288. // Create a copy of command to test
  1289. app := cli.NewApp()
  1290. app.Flags = cmdAuthUpdateLdapSimpleAuth.Flags
  1291. app.Action = service.updateLdapSimpleAuth
  1292. // Run it
  1293. err := app.Run(c.args)
  1294. if c.errMsg != "" {
  1295. assert.EqualError(t, err, c.errMsg, "case %d: error should match", n)
  1296. } else {
  1297. assert.NoError(t, err, "case %d: should have no errors", n)
  1298. assert.Equal(t, c.authSource, updatedAuthSource, "case %d: wrong authSource", n)
  1299. }
  1300. }
  1301. }