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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326
  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. // case 24
  846. {
  847. args: []string{
  848. "ldap-test",
  849. "--id", "24",
  850. "--name", "ldap (via Bind DN) flip 'active' and 'user sync' attributes",
  851. "--active",
  852. "--disable-synchronize-users",
  853. },
  854. id: 24,
  855. existingAuthSource: &auth.Source{
  856. Type: auth.LDAP,
  857. IsActive: false,
  858. IsSyncEnabled: true,
  859. Cfg: &ldap.Source{
  860. Name: "ldap (via Bind DN) flip 'active' and 'user sync' attributes",
  861. Enabled: true,
  862. },
  863. },
  864. authSource: &auth.Source{
  865. Type: auth.LDAP,
  866. Name: "ldap (via Bind DN) flip 'active' and 'user sync' attributes",
  867. IsActive: true,
  868. IsSyncEnabled: false,
  869. Cfg: &ldap.Source{
  870. Name: "ldap (via Bind DN) flip 'active' and 'user sync' attributes",
  871. Enabled: true,
  872. },
  873. },
  874. },
  875. }
  876. for n, c := range cases {
  877. // Mock functions.
  878. var updatedAuthSource *auth.Source
  879. service := &authService{
  880. initDB: func(context.Context) error {
  881. return nil
  882. },
  883. createAuthSource: func(authSource *auth.Source) error {
  884. assert.FailNow(t, "case %d: should not call createAuthSource", n)
  885. return nil
  886. },
  887. updateAuthSource: func(authSource *auth.Source) error {
  888. updatedAuthSource = authSource
  889. return nil
  890. },
  891. getAuthSourceByID: func(id int64) (*auth.Source, error) {
  892. if c.id != 0 {
  893. assert.Equal(t, c.id, id, "case %d: wrong id", n)
  894. }
  895. if c.existingAuthSource != nil {
  896. return c.existingAuthSource, nil
  897. }
  898. return &auth.Source{
  899. Type: auth.LDAP,
  900. Cfg: &ldap.Source{},
  901. }, nil
  902. },
  903. }
  904. // Create a copy of command to test
  905. app := cli.NewApp()
  906. app.Flags = cmdAuthUpdateLdapBindDn.Flags
  907. app.Action = service.updateLdapBindDn
  908. // Run it
  909. err := app.Run(c.args)
  910. if c.errMsg != "" {
  911. assert.EqualError(t, err, c.errMsg, "case %d: error should match", n)
  912. } else {
  913. assert.NoError(t, err, "case %d: should have no errors", n)
  914. assert.Equal(t, c.authSource, updatedAuthSource, "case %d: wrong authSource", n)
  915. }
  916. }
  917. }
  918. func TestUpdateLdapSimpleAuth(t *testing.T) {
  919. // Mock cli functions to do not exit on error
  920. osExiter := cli.OsExiter
  921. defer func() { cli.OsExiter = osExiter }()
  922. cli.OsExiter = func(code int) {}
  923. // Test cases
  924. cases := []struct {
  925. args []string
  926. id int64
  927. existingAuthSource *auth.Source
  928. authSource *auth.Source
  929. errMsg string
  930. }{
  931. // case 0
  932. {
  933. args: []string{
  934. "ldap-test",
  935. "--id", "7",
  936. "--name", "ldap (simple auth) source full",
  937. "--not-active",
  938. "--security-protocol", "starttls",
  939. "--skip-tls-verify",
  940. "--host", "ldap-simple-server full",
  941. "--port", "987",
  942. "--user-search-base", "ou=Users,dc=full-domain-simple,dc=org",
  943. "--user-filter", "(&(objectClass=posixAccount)(full-simple-cn=%s))",
  944. "--admin-filter", "(memberOf=cn=admin-group,ou=example,dc=full-domain-simple,dc=org)",
  945. "--restricted-filter", "(memberOf=cn=restricted-group,ou=example,dc=full-domain-simple,dc=org)",
  946. "--username-attribute", "uid-simple full",
  947. "--firstname-attribute", "givenName-simple full",
  948. "--surname-attribute", "sn-simple full",
  949. "--email-attribute", "mail-simple full",
  950. "--public-ssh-key-attribute", "publickey-simple full",
  951. "--avatar-attribute", "avatar-simple full",
  952. "--user-dn", "cn=%s,ou=Users,dc=full-domain-simple,dc=org",
  953. },
  954. id: 7,
  955. authSource: &auth.Source{
  956. Type: auth.DLDAP,
  957. Name: "ldap (simple auth) source full",
  958. IsActive: false,
  959. Cfg: &ldap.Source{
  960. Name: "ldap (simple auth) source full",
  961. Host: "ldap-simple-server full",
  962. Port: 987,
  963. SecurityProtocol: ldap.SecurityProtocol(2),
  964. SkipVerify: true,
  965. UserDN: "cn=%s,ou=Users,dc=full-domain-simple,dc=org",
  966. UserBase: "ou=Users,dc=full-domain-simple,dc=org",
  967. AttributeUsername: "uid-simple full",
  968. AttributeName: "givenName-simple full",
  969. AttributeSurname: "sn-simple full",
  970. AttributeMail: "mail-simple full",
  971. AttributeSSHPublicKey: "publickey-simple full",
  972. AttributeAvatar: "avatar-simple full",
  973. Filter: "(&(objectClass=posixAccount)(full-simple-cn=%s))",
  974. AdminFilter: "(memberOf=cn=admin-group,ou=example,dc=full-domain-simple,dc=org)",
  975. RestrictedFilter: "(memberOf=cn=restricted-group,ou=example,dc=full-domain-simple,dc=org)",
  976. },
  977. },
  978. },
  979. // case 1
  980. {
  981. args: []string{
  982. "ldap-test",
  983. "--id", "1",
  984. },
  985. authSource: &auth.Source{
  986. Type: auth.DLDAP,
  987. Cfg: &ldap.Source{},
  988. },
  989. },
  990. // case 2
  991. {
  992. args: []string{
  993. "ldap-test",
  994. "--id", "1",
  995. "--name", "ldap (simple auth) source",
  996. },
  997. authSource: &auth.Source{
  998. Type: auth.DLDAP,
  999. Name: "ldap (simple auth) source",
  1000. Cfg: &ldap.Source{
  1001. Name: "ldap (simple auth) source",
  1002. },
  1003. },
  1004. },
  1005. // case 3
  1006. {
  1007. args: []string{
  1008. "ldap-test",
  1009. "--id", "1",
  1010. "--not-active",
  1011. },
  1012. existingAuthSource: &auth.Source{
  1013. Type: auth.DLDAP,
  1014. IsActive: true,
  1015. Cfg: &ldap.Source{},
  1016. },
  1017. authSource: &auth.Source{
  1018. Type: auth.DLDAP,
  1019. IsActive: false,
  1020. Cfg: &ldap.Source{},
  1021. },
  1022. },
  1023. // case 4
  1024. {
  1025. args: []string{
  1026. "ldap-test",
  1027. "--id", "1",
  1028. "--security-protocol", "starttls",
  1029. },
  1030. authSource: &auth.Source{
  1031. Type: auth.DLDAP,
  1032. Cfg: &ldap.Source{
  1033. SecurityProtocol: ldap.SecurityProtocol(2),
  1034. },
  1035. },
  1036. },
  1037. // case 5
  1038. {
  1039. args: []string{
  1040. "ldap-test",
  1041. "--id", "1",
  1042. "--skip-tls-verify",
  1043. },
  1044. authSource: &auth.Source{
  1045. Type: auth.DLDAP,
  1046. Cfg: &ldap.Source{
  1047. SkipVerify: true,
  1048. },
  1049. },
  1050. },
  1051. // case 6
  1052. {
  1053. args: []string{
  1054. "ldap-test",
  1055. "--id", "1",
  1056. "--host", "ldap-server",
  1057. },
  1058. authSource: &auth.Source{
  1059. Type: auth.DLDAP,
  1060. Cfg: &ldap.Source{
  1061. Host: "ldap-server",
  1062. },
  1063. },
  1064. },
  1065. // case 7
  1066. {
  1067. args: []string{
  1068. "ldap-test",
  1069. "--id", "1",
  1070. "--port", "987",
  1071. },
  1072. authSource: &auth.Source{
  1073. Type: auth.DLDAP,
  1074. Cfg: &ldap.Source{
  1075. Port: 987,
  1076. },
  1077. },
  1078. },
  1079. // case 8
  1080. {
  1081. args: []string{
  1082. "ldap-test",
  1083. "--id", "1",
  1084. "--user-search-base", "ou=Users,dc=domain,dc=org",
  1085. },
  1086. authSource: &auth.Source{
  1087. Type: auth.DLDAP,
  1088. Cfg: &ldap.Source{
  1089. UserBase: "ou=Users,dc=domain,dc=org",
  1090. },
  1091. },
  1092. },
  1093. // case 9
  1094. {
  1095. args: []string{
  1096. "ldap-test",
  1097. "--id", "1",
  1098. "--user-filter", "(&(objectClass=posixAccount)(cn=%s))",
  1099. },
  1100. authSource: &auth.Source{
  1101. Type: auth.DLDAP,
  1102. Cfg: &ldap.Source{
  1103. Filter: "(&(objectClass=posixAccount)(cn=%s))",
  1104. },
  1105. },
  1106. },
  1107. // case 10
  1108. {
  1109. args: []string{
  1110. "ldap-test",
  1111. "--id", "1",
  1112. "--admin-filter", "(memberOf=cn=admin-group,ou=example,dc=domain,dc=org)",
  1113. },
  1114. authSource: &auth.Source{
  1115. Type: auth.DLDAP,
  1116. Cfg: &ldap.Source{
  1117. AdminFilter: "(memberOf=cn=admin-group,ou=example,dc=domain,dc=org)",
  1118. },
  1119. },
  1120. },
  1121. // case 11
  1122. {
  1123. args: []string{
  1124. "ldap-test",
  1125. "--id", "1",
  1126. "--username-attribute", "uid",
  1127. },
  1128. authSource: &auth.Source{
  1129. Type: auth.DLDAP,
  1130. Cfg: &ldap.Source{
  1131. AttributeUsername: "uid",
  1132. },
  1133. },
  1134. },
  1135. // case 12
  1136. {
  1137. args: []string{
  1138. "ldap-test",
  1139. "--id", "1",
  1140. "--firstname-attribute", "givenName",
  1141. },
  1142. authSource: &auth.Source{
  1143. Type: auth.DLDAP,
  1144. Cfg: &ldap.Source{
  1145. AttributeName: "givenName",
  1146. },
  1147. },
  1148. },
  1149. // case 13
  1150. {
  1151. args: []string{
  1152. "ldap-test",
  1153. "--id", "1",
  1154. "--surname-attribute", "sn",
  1155. },
  1156. authSource: &auth.Source{
  1157. Type: auth.DLDAP,
  1158. Cfg: &ldap.Source{
  1159. AttributeSurname: "sn",
  1160. },
  1161. },
  1162. },
  1163. // case 14
  1164. {
  1165. args: []string{
  1166. "ldap-test",
  1167. "--id", "1",
  1168. "--email-attribute", "mail",
  1169. },
  1170. authSource: &auth.Source{
  1171. Type: auth.DLDAP,
  1172. Cfg: &ldap.Source{
  1173. AttributeMail: "mail",
  1174. },
  1175. },
  1176. },
  1177. // case 15
  1178. {
  1179. args: []string{
  1180. "ldap-test",
  1181. "--id", "1",
  1182. "--public-ssh-key-attribute", "publickey",
  1183. },
  1184. authSource: &auth.Source{
  1185. Type: auth.DLDAP,
  1186. Cfg: &ldap.Source{
  1187. AttributeSSHPublicKey: "publickey",
  1188. },
  1189. },
  1190. },
  1191. // case 16
  1192. {
  1193. args: []string{
  1194. "ldap-test",
  1195. "--id", "1",
  1196. "--user-dn", "cn=%s,ou=Users,dc=domain,dc=org",
  1197. },
  1198. authSource: &auth.Source{
  1199. Type: auth.DLDAP,
  1200. Cfg: &ldap.Source{
  1201. UserDN: "cn=%s,ou=Users,dc=domain,dc=org",
  1202. },
  1203. },
  1204. },
  1205. // case 17
  1206. {
  1207. args: []string{
  1208. "ldap-test",
  1209. "--id", "1",
  1210. "--security-protocol", "xxxxx",
  1211. },
  1212. errMsg: "Unknown security protocol name: xxxxx",
  1213. },
  1214. // case 18
  1215. {
  1216. args: []string{
  1217. "ldap-test",
  1218. },
  1219. errMsg: "id is not set",
  1220. },
  1221. // case 19
  1222. {
  1223. args: []string{
  1224. "ldap-test",
  1225. "--id", "1",
  1226. },
  1227. existingAuthSource: &auth.Source{
  1228. Type: auth.PAM,
  1229. Cfg: &ldap.Source{},
  1230. },
  1231. errMsg: "Invalid authentication type. expected: LDAP (simple auth), actual: PAM",
  1232. },
  1233. // case 20
  1234. {
  1235. args: []string{
  1236. "ldap-test",
  1237. "--id", "20",
  1238. "--name", "ldap (simple auth) flip 'active' attribute",
  1239. "--active",
  1240. },
  1241. id: 20,
  1242. existingAuthSource: &auth.Source{
  1243. Type: auth.DLDAP,
  1244. IsActive: false,
  1245. Cfg: &ldap.Source{
  1246. Name: "ldap (simple auth) flip 'active' attribute",
  1247. Enabled: true,
  1248. },
  1249. },
  1250. authSource: &auth.Source{
  1251. Type: auth.DLDAP,
  1252. Name: "ldap (simple auth) flip 'active' attribute",
  1253. IsActive: true,
  1254. Cfg: &ldap.Source{
  1255. Name: "ldap (simple auth) flip 'active' attribute",
  1256. Enabled: true,
  1257. },
  1258. },
  1259. },
  1260. }
  1261. for n, c := range cases {
  1262. // Mock functions.
  1263. var updatedAuthSource *auth.Source
  1264. service := &authService{
  1265. initDB: func(context.Context) error {
  1266. return nil
  1267. },
  1268. createAuthSource: func(authSource *auth.Source) error {
  1269. assert.FailNow(t, "case %d: should not call createAuthSource", n)
  1270. return nil
  1271. },
  1272. updateAuthSource: func(authSource *auth.Source) error {
  1273. updatedAuthSource = authSource
  1274. return nil
  1275. },
  1276. getAuthSourceByID: func(id int64) (*auth.Source, error) {
  1277. if c.id != 0 {
  1278. assert.Equal(t, c.id, id, "case %d: wrong id", n)
  1279. }
  1280. if c.existingAuthSource != nil {
  1281. return c.existingAuthSource, nil
  1282. }
  1283. return &auth.Source{
  1284. Type: auth.DLDAP,
  1285. Cfg: &ldap.Source{},
  1286. }, nil
  1287. },
  1288. }
  1289. // Create a copy of command to test
  1290. app := cli.NewApp()
  1291. app.Flags = cmdAuthUpdateLdapSimpleAuth.Flags
  1292. app.Action = service.updateLdapSimpleAuth
  1293. // Run it
  1294. err := app.Run(c.args)
  1295. if c.errMsg != "" {
  1296. assert.EqualError(t, err, c.errMsg, "case %d: error should match", n)
  1297. } else {
  1298. assert.NoError(t, err, "case %d: should have no errors", n)
  1299. assert.Equal(t, c.authSource, updatedAuthSource, "case %d: wrong authSource", n)
  1300. }
  1301. }
  1302. }