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

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270
  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. var osExiter = cli.OsExiter
  16. defer func() { cli.OsExiter = osExiter }()
  17. cli.OsExiter = func(code int) {}
  18. // Test cases
  19. var 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. var osExiter = cli.OsExiter
  237. defer func() { cli.OsExiter = osExiter }()
  238. cli.OsExiter = func(code int) {}
  239. // Test cases
  240. var 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. var osExiter = cli.OsExiter
  463. defer func() { cli.OsExiter = osExiter }()
  464. cli.OsExiter = func(code int) {}
  465. // Test cases
  466. var 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. var osExiter = cli.OsExiter
  891. defer func() { cli.OsExiter = osExiter }()
  892. cli.OsExiter = func(code int) {}
  893. // Test cases
  894. var 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. }