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 32KB

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