ldap-rest 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (296) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +48 -0
  3. package/bin/cleanup-external-users.mjs +219 -0
  4. package/bin/index.mjs +54 -0
  5. package/bin/sync-james.mjs +190 -0
  6. package/dist/abstract/ldapFlat.js +1 -0
  7. package/dist/abstract/plugin.js +1 -0
  8. package/dist/abstract/twakePlugin.js +1 -0
  9. package/dist/bin/index.js +1 -0
  10. package/dist/config/args.js +1 -0
  11. package/dist/lib/auth/base.js +1 -0
  12. package/dist/lib/authz/base.js +1 -0
  13. package/dist/lib/expressFormatedResponses.js +1 -0
  14. package/dist/lib/ldapActions.js +1 -0
  15. package/dist/lib/parseConfig.js +1 -0
  16. package/dist/lib/utils.js +1 -0
  17. package/dist/logger/winston.js +1 -0
  18. package/dist/plugins/auth/authzLinid1.js +1 -0
  19. package/dist/plugins/auth/authzPerBranch.js +1 -0
  20. package/dist/plugins/auth/crowdsec.js +1 -0
  21. package/dist/plugins/auth/llng.js +1 -0
  22. package/dist/plugins/auth/openidconnect.js +1 -0
  23. package/dist/plugins/auth/rateLimit.js +1 -0
  24. package/dist/plugins/auth/token.js +1 -0
  25. package/dist/plugins/configApi.js +1 -0
  26. package/dist/plugins/demo/helloworld.js +1 -0
  27. package/dist/plugins/ldap/bulkImport.js +1 -0
  28. package/dist/plugins/ldap/departmentSync.js +1 -0
  29. package/dist/plugins/ldap/externalUsersInGroups.js +1 -0
  30. package/dist/plugins/ldap/flatGeneric.js +1 -0
  31. package/dist/plugins/ldap/groups.js +1 -0
  32. package/dist/plugins/ldap/onChange.js +1 -0
  33. package/dist/plugins/ldap/organization.js +1 -0
  34. package/dist/plugins/ldap/trash.js +1 -0
  35. package/dist/plugins/priority.json.js +1 -0
  36. package/dist/plugins/static.js +1 -0
  37. package/dist/plugins/twake/calendarResources.js +1 -0
  38. package/dist/plugins/twake/james.js +1 -0
  39. package/dist/plugins/weblogs.js +1 -0
  40. package/dist/src/abstract/ldapFlat.d.ts +94 -0
  41. package/dist/src/abstract/plugin.d.ts +43 -0
  42. package/dist/src/abstract/twakePlugin.d.ts +90 -0
  43. package/dist/src/bin/index.d.ts +43 -0
  44. package/dist/src/browser/ldap-group-editor/LdapGroupEditor.d.ts +31 -0
  45. package/dist/src/browser/ldap-group-editor/api/GroupApiClient.d.ts +23 -0
  46. package/dist/src/browser/ldap-group-editor/components/CreateGroupModal.d.ts +19 -0
  47. package/dist/src/browser/ldap-group-editor/components/GroupPropertyEditor.d.ts +30 -0
  48. package/dist/src/browser/ldap-group-editor/components/GroupTree.d.ts +17 -0
  49. package/dist/src/browser/ldap-group-editor/components/MoveGroupModal.d.ts +20 -0
  50. package/dist/src/browser/ldap-group-editor/index.d.ts +6 -0
  51. package/dist/src/browser/ldap-group-editor/types.d.ts +58 -0
  52. package/dist/src/browser/ldap-resource-editor/api/ResourceApiClient.d.ts +53 -0
  53. package/dist/src/browser/ldap-resource-editor/cache/CacheManager.d.ts +65 -0
  54. package/dist/src/browser/ldap-resource-editor/index.d.ts +6 -0
  55. package/dist/src/browser/ldap-resource-editor/types.d.ts +78 -0
  56. package/dist/src/browser/ldap-tree-viewer/LdapTreeViewer.d.ts +26 -0
  57. package/dist/src/browser/ldap-tree-viewer/api/LdapApiClient.d.ts +30 -0
  58. package/dist/src/browser/ldap-tree-viewer/components/TreeNode.d.ts +17 -0
  59. package/dist/src/browser/ldap-tree-viewer/components/TreeRoot.d.ts +14 -0
  60. package/dist/src/browser/ldap-tree-viewer/index.d.ts +7 -0
  61. package/dist/src/browser/ldap-tree-viewer/store/Store.d.ts +18 -0
  62. package/dist/src/browser/ldap-tree-viewer/store/actions.d.ts +28 -0
  63. package/dist/src/browser/ldap-tree-viewer/store/reducers.d.ts +7 -0
  64. package/dist/src/browser/ldap-tree-viewer/types.d.ts +34 -0
  65. package/dist/src/browser/ldap-unit-editor/LdapUnitEditor.d.ts +27 -0
  66. package/dist/src/browser/ldap-unit-editor/api/UnitApiClient.d.ts +24 -0
  67. package/dist/src/browser/ldap-unit-editor/components/MoveUnitModal.d.ts +28 -0
  68. package/dist/src/browser/ldap-unit-editor/components/UnitPropertyEditor.d.ts +28 -0
  69. package/dist/src/browser/ldap-unit-editor/components/UnitTree.d.ts +18 -0
  70. package/dist/src/browser/ldap-unit-editor/index.d.ts +6 -0
  71. package/dist/src/browser/ldap-unit-editor/types.d.ts +55 -0
  72. package/dist/src/browser/ldap-user-editor/LdapUserEditor.d.ts +32 -0
  73. package/dist/src/browser/ldap-user-editor/api/UserApiClient.d.ts +55 -0
  74. package/dist/src/browser/ldap-user-editor/cache/CacheManager.d.ts +65 -0
  75. package/dist/src/browser/ldap-user-editor/components/MoveUserModal.d.ts +28 -0
  76. package/dist/src/browser/ldap-user-editor/components/PointerField.d.ts +22 -0
  77. package/dist/src/browser/ldap-user-editor/components/UserEditor.d.ts +46 -0
  78. package/dist/src/browser/ldap-user-editor/components/UserList.d.ts +24 -0
  79. package/dist/src/browser/ldap-user-editor/components/UserTree.d.ts +24 -0
  80. package/dist/src/browser/ldap-user-editor/index.d.ts +7 -0
  81. package/dist/src/browser/ldap-user-editor/types.d.ts +67 -0
  82. package/dist/src/browser/shared/components/Modal.d.ts +38 -0
  83. package/dist/src/browser/shared/components/StatusMessage.d.ts +48 -0
  84. package/dist/src/browser/shared/index.d.ts +10 -0
  85. package/dist/src/browser/shared/types/index.d.ts +65 -0
  86. package/dist/src/browser/shared/utils/dom.d.ts +33 -0
  87. package/dist/src/browser/shared/utils/form.d.ts +28 -0
  88. package/dist/src/browser/shared/utils/schema.d.ts +29 -0
  89. package/dist/src/config/args.d.ts +128 -0
  90. package/dist/src/config/schema.d.ts +18 -0
  91. package/dist/src/hooks.d.ts +76 -0
  92. package/dist/src/lib/auth/base.d.ts +9 -0
  93. package/dist/src/lib/authz/base.d.ts +63 -0
  94. package/dist/src/lib/expressFormatedResponses.d.ts +26 -0
  95. package/dist/src/lib/ldapActions.d.ts +91 -0
  96. package/dist/src/lib/parseConfig.d.ts +23 -0
  97. package/dist/src/lib/utils.d.ts +73 -0
  98. package/dist/src/logger/winston.d.ts +3 -0
  99. package/dist/src/plugins/auth/authzLinid1.d.ts +46 -0
  100. package/dist/src/plugins/auth/authzPerBranch.d.ts +59 -0
  101. package/dist/src/plugins/auth/crowdsec.d.ts +29 -0
  102. package/dist/src/plugins/auth/llng.d.ts +8 -0
  103. package/dist/src/plugins/auth/openidconnect.d.ts +11 -0
  104. package/dist/src/plugins/auth/rateLimit.d.ts +24 -0
  105. package/dist/src/plugins/auth/token.d.ts +17 -0
  106. package/dist/src/plugins/configApi.d.ts +24 -0
  107. package/dist/src/plugins/demo/helloworld.d.ts +12 -0
  108. package/dist/src/plugins/ldap/bulkImport.d.ts +48 -0
  109. package/dist/src/plugins/ldap/departmentSync.d.ts +35 -0
  110. package/dist/src/plugins/ldap/externalUsersInGroups.d.ts +21 -0
  111. package/dist/src/plugins/ldap/flatGeneric.d.ts +31 -0
  112. package/dist/src/plugins/ldap/groups.d.ts +95 -0
  113. package/dist/src/plugins/ldap/onChange.d.ts +32 -0
  114. package/dist/src/plugins/ldap/organization.d.ts +65 -0
  115. package/dist/src/plugins/ldap/trash.d.ts +52 -0
  116. package/dist/src/plugins/static.d.ts +7 -0
  117. package/dist/src/plugins/twake/calendarResources.d.ts +31 -0
  118. package/dist/src/plugins/twake/james.d.ts +83 -0
  119. package/dist/src/plugins/weblogs.d.ts +8 -0
  120. package/docs/DEVELOPER_GUIDE.md +298 -0
  121. package/docs/OPENAPI.md +440 -0
  122. package/docs/PLUGIN_DEPENDENCIES.md +612 -0
  123. package/docs/README.md +466 -0
  124. package/docs/api/REFERENCE.md +983 -0
  125. package/docs/api/REST_API.md +1237 -0
  126. package/docs/authentication.md +469 -0
  127. package/docs/authzLinid1.md +521 -0
  128. package/docs/authzPerBranch.md +596 -0
  129. package/docs/browser/LIBRARIES.md +1196 -0
  130. package/docs/examples/EXAMPLES.md +1659 -0
  131. package/docs/examples/twake-mailbox-type-nomenclature.ldif +37 -0
  132. package/docs/examples/twake-mailbox-type-schema-amendment.ldif +30 -0
  133. package/docs/jamesTeamMailboxes.md +343 -0
  134. package/docs/ldapBulkImport.md +722 -0
  135. package/docs/ldapExternalUsersInGroups.md +325 -0
  136. package/docs/ldapFlatGeneric.md +444 -0
  137. package/docs/ldapGroups.md +589 -0
  138. package/docs/ldapOrganizations.md +659 -0
  139. package/docs/ldapTrash.md +260 -0
  140. package/docs/linagora.png +0 -0
  141. package/docs/onChange.md +318 -0
  142. package/docs/plugins/DEVELOPMENT.md +1219 -0
  143. package/docs/presenterm-fr.md +721 -0
  144. package/docs/presenterm.md +721 -0
  145. package/docs/schemas/SCHEMAS.md +1212 -0
  146. package/docs/static.md +410 -0
  147. package/docs/twakeCalendarResources.md +148 -0
  148. package/docs/twakeJames.md +661 -0
  149. package/docs/weblogs.md +399 -0
  150. package/examples/web/ldap-group-editor.html +113 -0
  151. package/examples/web/ldap-tree-viewer.html +368 -0
  152. package/examples/web/ldap-unit-editor.html +108 -0
  153. package/examples/web/ldap-user-editor.html +412 -0
  154. package/package.json +458 -0
  155. package/static/browser/common-demo.css +450 -0
  156. package/static/browser/ldap-group-editor/LdapGroupEditor.js +207 -0
  157. package/static/browser/ldap-group-editor/LdapGroupEditor.js.map +1 -0
  158. package/static/browser/ldap-group-editor/api/GroupApiClient.js +112 -0
  159. package/static/browser/ldap-group-editor/api/GroupApiClient.js.map +1 -0
  160. package/static/browser/ldap-group-editor/components/CreateGroupModal.js +212 -0
  161. package/static/browser/ldap-group-editor/components/CreateGroupModal.js.map +1 -0
  162. package/static/browser/ldap-group-editor/components/GroupPropertyEditor.js +497 -0
  163. package/static/browser/ldap-group-editor/components/GroupPropertyEditor.js.map +1 -0
  164. package/static/browser/ldap-group-editor/components/GroupTree.js +153 -0
  165. package/static/browser/ldap-group-editor/components/GroupTree.js.map +1 -0
  166. package/static/browser/ldap-group-editor/components/MoveGroupModal.js +235 -0
  167. package/static/browser/ldap-group-editor/components/MoveGroupModal.js.map +1 -0
  168. package/static/browser/ldap-group-editor/index.js +2 -0
  169. package/static/browser/ldap-group-editor/index.js.map +1 -0
  170. package/static/browser/ldap-group-editor/types.js +2 -0
  171. package/static/browser/ldap-group-editor/types.js.map +1 -0
  172. package/static/browser/ldap-group-editor.esm.js +1399 -0
  173. package/static/browser/ldap-group-editor.esm.js.map +1 -0
  174. package/static/browser/ldap-group-editor.js +1407 -0
  175. package/static/browser/ldap-group-editor.js.map +1 -0
  176. package/static/browser/ldap-group-editor.min.js +2 -0
  177. package/static/browser/ldap-group-editor.min.js.map +1 -0
  178. package/static/browser/ldap-resource-editor/api/ResourceApiClient.js +226 -0
  179. package/static/browser/ldap-resource-editor/api/ResourceApiClient.js.map +1 -0
  180. package/static/browser/ldap-resource-editor/cache/CacheManager.js +123 -0
  181. package/static/browser/ldap-resource-editor/cache/CacheManager.js.map +1 -0
  182. package/static/browser/ldap-resource-editor/index.js +2 -0
  183. package/static/browser/ldap-resource-editor/index.js.map +1 -0
  184. package/static/browser/ldap-resource-editor/types.js +2 -0
  185. package/static/browser/ldap-resource-editor/types.js.map +1 -0
  186. package/static/browser/ldap-tree-viewer/LdapTreeViewer.js +187 -0
  187. package/static/browser/ldap-tree-viewer/LdapTreeViewer.js.map +1 -0
  188. package/static/browser/ldap-tree-viewer/api/LdapApiClient.js +50 -0
  189. package/static/browser/ldap-tree-viewer/api/LdapApiClient.js.map +1 -0
  190. package/static/browser/ldap-tree-viewer/components/TreeNode.js +140 -0
  191. package/static/browser/ldap-tree-viewer/components/TreeNode.js.map +1 -0
  192. package/static/browser/ldap-tree-viewer/components/TreeRoot.js +98 -0
  193. package/static/browser/ldap-tree-viewer/components/TreeRoot.js.map +1 -0
  194. package/static/browser/ldap-tree-viewer/index.js +2 -0
  195. package/static/browser/ldap-tree-viewer/index.js.map +1 -0
  196. package/static/browser/ldap-tree-viewer/store/Store.js +29 -0
  197. package/static/browser/ldap-tree-viewer/store/Store.js.map +1 -0
  198. package/static/browser/ldap-tree-viewer/store/actions.js +53 -0
  199. package/static/browser/ldap-tree-viewer/store/actions.js.map +1 -0
  200. package/static/browser/ldap-tree-viewer/store/reducers.js +79 -0
  201. package/static/browser/ldap-tree-viewer/store/reducers.js.map +1 -0
  202. package/static/browser/ldap-tree-viewer/types.js +2 -0
  203. package/static/browser/ldap-tree-viewer/types.js.map +1 -0
  204. package/static/browser/ldap-tree-viewer.css +2 -0
  205. package/static/browser/ldap-tree-viewer.css.map +1 -0
  206. package/static/browser/ldap-tree-viewer.esm.js +606 -0
  207. package/static/browser/ldap-tree-viewer.esm.js.map +1 -0
  208. package/static/browser/ldap-tree-viewer.js +614 -0
  209. package/static/browser/ldap-tree-viewer.js.map +1 -0
  210. package/static/browser/ldap-tree-viewer.min.js +2 -0
  211. package/static/browser/ldap-tree-viewer.min.js.map +1 -0
  212. package/static/browser/ldap-unit-editor/LdapUnitEditor.js +119 -0
  213. package/static/browser/ldap-unit-editor/LdapUnitEditor.js.map +1 -0
  214. package/static/browser/ldap-unit-editor/api/UnitApiClient.js +95 -0
  215. package/static/browser/ldap-unit-editor/api/UnitApiClient.js.map +1 -0
  216. package/static/browser/ldap-unit-editor/components/MoveUnitModal.js +295 -0
  217. package/static/browser/ldap-unit-editor/components/MoveUnitModal.js.map +1 -0
  218. package/static/browser/ldap-unit-editor/components/UnitPropertyEditor.js +321 -0
  219. package/static/browser/ldap-unit-editor/components/UnitPropertyEditor.js.map +1 -0
  220. package/static/browser/ldap-unit-editor/components/UnitTree.js +197 -0
  221. package/static/browser/ldap-unit-editor/components/UnitTree.js.map +1 -0
  222. package/static/browser/ldap-unit-editor/index.js +2 -0
  223. package/static/browser/ldap-unit-editor/index.js.map +1 -0
  224. package/static/browser/ldap-unit-editor/types.js +2 -0
  225. package/static/browser/ldap-unit-editor/types.js.map +1 -0
  226. package/static/browser/ldap-unit-editor.esm.js +1013 -0
  227. package/static/browser/ldap-unit-editor.esm.js.map +1 -0
  228. package/static/browser/ldap-unit-editor.js +1021 -0
  229. package/static/browser/ldap-unit-editor.js.map +1 -0
  230. package/static/browser/ldap-unit-editor.min.js +2 -0
  231. package/static/browser/ldap-unit-editor.min.js.map +1 -0
  232. package/static/browser/ldap-user-editor/LdapUserEditor.js +184 -0
  233. package/static/browser/ldap-user-editor/LdapUserEditor.js.map +1 -0
  234. package/static/browser/ldap-user-editor/api/UserApiClient.js +209 -0
  235. package/static/browser/ldap-user-editor/api/UserApiClient.js.map +1 -0
  236. package/static/browser/ldap-user-editor/cache/CacheManager.js +123 -0
  237. package/static/browser/ldap-user-editor/cache/CacheManager.js.map +1 -0
  238. package/static/browser/ldap-user-editor/components/MoveUserModal.js +302 -0
  239. package/static/browser/ldap-user-editor/components/MoveUserModal.js.map +1 -0
  240. package/static/browser/ldap-user-editor/components/PointerField.js +152 -0
  241. package/static/browser/ldap-user-editor/components/PointerField.js.map +1 -0
  242. package/static/browser/ldap-user-editor/components/UserEditor.js +608 -0
  243. package/static/browser/ldap-user-editor/components/UserEditor.js.map +1 -0
  244. package/static/browser/ldap-user-editor/components/UserList.js +181 -0
  245. package/static/browser/ldap-user-editor/components/UserList.js.map +1 -0
  246. package/static/browser/ldap-user-editor/components/UserTree.js +164 -0
  247. package/static/browser/ldap-user-editor/components/UserTree.js.map +1 -0
  248. package/static/browser/ldap-user-editor/index.js +2 -0
  249. package/static/browser/ldap-user-editor/index.js.map +1 -0
  250. package/static/browser/ldap-user-editor/types.js +2 -0
  251. package/static/browser/ldap-user-editor/types.js.map +1 -0
  252. package/static/browser/ldap-user-editor.css +2 -0
  253. package/static/browser/ldap-user-editor.css.map +1 -0
  254. package/static/browser/ldap-user-editor.esm.js +1897 -0
  255. package/static/browser/ldap-user-editor.esm.js.map +1 -0
  256. package/static/browser/ldap-user-editor.js +1905 -0
  257. package/static/browser/ldap-user-editor.js.map +1 -0
  258. package/static/browser/ldap-user-editor.min.js +2 -0
  259. package/static/browser/ldap-user-editor.min.js.map +1 -0
  260. package/static/browser/shared/components/Modal.js +121 -0
  261. package/static/browser/shared/components/Modal.js.map +1 -0
  262. package/static/browser/shared/components/StatusMessage.js +119 -0
  263. package/static/browser/shared/components/StatusMessage.js.map +1 -0
  264. package/static/browser/shared/index.js +7 -0
  265. package/static/browser/shared/index.js.map +1 -0
  266. package/static/browser/shared/types/index.js +37 -0
  267. package/static/browser/shared/types/index.js.map +1 -0
  268. package/static/browser/shared/utils/dom.js +78 -0
  269. package/static/browser/shared/utils/dom.js.map +1 -0
  270. package/static/browser/shared/utils/form.js +234 -0
  271. package/static/browser/shared/utils/form.js.map +1 -0
  272. package/static/browser/shared/utils/schema.js +121 -0
  273. package/static/browser/shared/utils/schema.js.map +1 -0
  274. package/static/browser/shared.esm.js +694 -0
  275. package/static/browser/shared.esm.js.map +1 -0
  276. package/static/browser/shared.js +723 -0
  277. package/static/browser/shared.js.map +1 -0
  278. package/static/browser/shared.min.js +2 -0
  279. package/static/browser/shared.min.js.map +1 -0
  280. package/static/schemas/ad/computers.json +92 -0
  281. package/static/schemas/ad/groups.json +55 -0
  282. package/static/schemas/ad/organizations.json +66 -0
  283. package/static/schemas/ad/users.json +116 -0
  284. package/static/schemas/standard/devices.json +72 -0
  285. package/static/schemas/standard/groups.json +54 -0
  286. package/static/schemas/standard/organizations.json +49 -0
  287. package/static/schemas/standard/users.json +86 -0
  288. package/static/schemas/twake/groups.json +75 -0
  289. package/static/schemas/twake/nomenclature/twakeAccountStatus.json +31 -0
  290. package/static/schemas/twake/nomenclature/twakeDeliveryMode.json +31 -0
  291. package/static/schemas/twake/nomenclature/twakeListType.json +31 -0
  292. package/static/schemas/twake/nomenclature/twakeMailboxType.json +31 -0
  293. package/static/schemas/twake/nomenclature/twakeTitle.json +31 -0
  294. package/static/schemas/twake/organizations.json +52 -0
  295. package/static/schemas/twake/positions.json +32 -0
  296. package/static/schemas/twake/users.json +112 -0
@@ -0,0 +1,722 @@
1
+ # LDAP Bulk Import Plugin
2
+
3
+ Generic CSV-based bulk import plugin for LDAP resources, automatically configured from JSON schemas.
4
+
5
+ ## Overview
6
+
7
+ The `ldapBulkImport` plugin provides CSV import functionality for any LDAP resource type (users, groups, etc.) by reading JSON schema definitions. It automatically:
8
+
9
+ - Generates CSV templates based on schema attributes
10
+ - Excludes fixed attributes from CSV (auto-populated from schema)
11
+ - Auto-calculates organization link and path from a single `organizationDn` column
12
+ - Validates data against schema requirements
13
+ - Supports dry-run mode for testing
14
+ - Provides detailed success/failure reports
15
+
16
+ ## Configuration
17
+
18
+ ### CLI Arguments
19
+
20
+ ```bash
21
+ --plugin core/ldap/bulkImport \
22
+ --bulk-import-schemas "users:./static/schemas/twake/users.json,groups:./static/schemas/twake/groups.json" \
23
+ --bulk-import-max-file-size 10485760 \
24
+ --bulk-import-batch-size 100
25
+ ```
26
+
27
+ ### Configuration Options
28
+
29
+ | Argument | Environment Variable | Default | Description |
30
+ | ----------------------------- | ------------------------------ | ---------- | --------------------------------------------- |
31
+ | `--bulk-import-schemas` | `DM_BULK_IMPORT_SCHEMAS` | (required) | Comma-separated list of resource:schema pairs |
32
+ | `--bulk-import-max-file-size` | `DM_BULK_IMPORT_MAX_FILE_SIZE` | `10485760` | Maximum upload file size in bytes (10MB) |
33
+ | `--bulk-import-batch-size` | `DM_BULK_IMPORT_BATCH_SIZE` | `100` | Number of records to process at once |
34
+
35
+ ### Schema Configuration Format
36
+
37
+ Format: `"resourceName:path/to/schema.json,resourceName2:path/to/schema2.json"`
38
+
39
+ **Example**:
40
+
41
+ ```bash
42
+ --bulk-import-schemas "users:./static/schemas/twake/users.json,groups:./static/schemas/twake/groups.json"
43
+ ```
44
+
45
+ This creates two import APIs:
46
+
47
+ - `/api/v1/ldap/bulk-import/users/*`
48
+ - `/api/v1/ldap/bulk-import/groups/*`
49
+
50
+ ## REST API
51
+
52
+ For each configured schema, the plugin automatically generates two endpoints:
53
+
54
+ ### GET /api/v1/ldap/bulk-import/{resource}/template.csv
55
+
56
+ Downloads a CSV template file with headers based on the schema.
57
+
58
+ **Response**: CSV file with headers
59
+
60
+ **Example**:
61
+
62
+ ```bash
63
+ curl -O "http://localhost:8081/api/v1/ldap/bulk-import/users/template.csv"
64
+ ```
65
+
66
+ **Generated template** (for users):
67
+
68
+ ```csv
69
+ uid,cn,sn,givenName,mail,userPassword,telephoneNumber,organizationDn
70
+ ```
71
+
72
+ **Notes**:
73
+
74
+ - Excludes attributes with `"fixed": true` (auto-populated)
75
+ - Excludes attributes with `"role": ["organizationLink"]` or `"role": ["organizationPath"]` (auto-calculated)
76
+ - Includes special column `organizationDn` for organization assignment
77
+
78
+ ### POST /api/v1/ldap/bulk-import/{resource}
79
+
80
+ Bulk import entries from CSV file.
81
+
82
+ **Request** (multipart/form-data):
83
+
84
+ | Field | Type | Required | Default | Description |
85
+ | ----------------- | ------- | -------- | ------- | --------------------------------------------- |
86
+ | `file` | File | Yes | - | CSV file to import |
87
+ | `dryRun` | Boolean | No | `false` | Validate without creating entries |
88
+ | `updateExisting` | Boolean | No | `false` | Update entries if they already exist |
89
+ | `continueOnError` | Boolean | No | `true` | Continue processing even if some entries fail |
90
+
91
+ **Response (200)**:
92
+
93
+ ```json
94
+ {
95
+ "success": true,
96
+ "total": 100,
97
+ "created": 95,
98
+ "updated": 0,
99
+ "skipped": 3,
100
+ "failed": 2,
101
+ "errors": [
102
+ {
103
+ "line": 15,
104
+ "identifier": "baduser",
105
+ "error": "Missing required attribute: sn"
106
+ },
107
+ {
108
+ "line": 42,
109
+ "identifier": "duplicate",
110
+ "error": "Organization not found: ou=InvalidDept,dc=example,dc=com"
111
+ }
112
+ ],
113
+ "details": {
114
+ "duration": "2.5s",
115
+ "linesProcessed": 100
116
+ }
117
+ }
118
+ ```
119
+
120
+ **Example**:
121
+
122
+ ```bash
123
+ curl -X POST "http://localhost:8081/api/v1/ldap/bulk-import/users" \
124
+ -F "file=@users.csv" \
125
+ -F "dryRun=false" \
126
+ -F "updateExisting=false" \
127
+ -F "continueOnError=true"
128
+ ```
129
+
130
+ ## CSV Format
131
+
132
+ ### Basic Structure
133
+
134
+ ```csv
135
+ uid,cn,sn,givenName,mail,userPassword,organizationDn
136
+ jdoe,John Doe,Doe,John,john.doe@example.com,password123,ou=IT,ou=organization,dc=example,dc=com
137
+ asmith,Alice Smith,Smith,Alice,alice.smith@example.com,secret456,ou=HR,ou=organization,dc=example,dc=com
138
+ ```
139
+
140
+ ### Special Column: `organizationDn`
141
+
142
+ The `organizationDn` column is special and triggers automatic calculation of:
143
+
144
+ 1. **Organization Link** - Attribute with `role: ["organizationLink"]` in schema
145
+ - Automatically set to the value of `organizationDn`
146
+
147
+ 2. **Organization Path** - Attribute with `role: ["organizationPath"]` in schema
148
+ - Automatically fetched from the organization's LDAP entry
149
+ - Example: `"IT / organization"` for `ou=IT,ou=organization,dc=example,dc=com`
150
+
151
+ ### Multi-Value Attributes
152
+
153
+ Use semicolon (`;`) as separator for multi-value attributes:
154
+
155
+ ```csv
156
+ uid,cn,sn,mail,organizationDn
157
+ jdoe,John Doe,Doe,john@example.com;j.doe@example.com;jdoe@company.com,ou=IT,dc=example,dc=com
158
+ ```
159
+
160
+ This creates:
161
+
162
+ ```
163
+ mail: john@example.com
164
+ mail: j.doe@example.com
165
+ mail: jdoe@company.com
166
+ ```
167
+
168
+ ### Fixed Attributes
169
+
170
+ Attributes marked as `"fixed": true` in the schema are automatically added and should NOT be included in the CSV:
171
+
172
+ **Schema**:
173
+
174
+ ```json
175
+ {
176
+ "properties": {
177
+ "objectClass": {
178
+ "type": "array",
179
+ "fixed": true,
180
+ "default": ["inetOrgPerson", "organizationalPerson", "person", "top"]
181
+ }
182
+ }
183
+ }
184
+ ```
185
+
186
+ **CSV** (objectClass NOT included):
187
+
188
+ ```csv
189
+ uid,cn,sn,mail
190
+ jdoe,John Doe,Doe,jdoe@example.com
191
+ ```
192
+
193
+ **Result in LDAP**:
194
+
195
+ ```
196
+ objectClass: inetOrgPerson
197
+ objectClass: organizationalPerson
198
+ objectClass: person
199
+ objectClass: top
200
+ uid: jdoe
201
+ cn: John Doe
202
+ sn: Doe
203
+ mail: jdoe@example.com
204
+ ```
205
+
206
+ ## Complete Example
207
+
208
+ ### Step 1: Configure Plugin
209
+
210
+ ```bash
211
+ --plugin core/ldap/bulkImport \
212
+ --bulk-import-schemas "users:./static/schemas/twake/users.json"
213
+ ```
214
+
215
+ ### Step 2: Download Template
216
+
217
+ ```bash
218
+ curl -O "http://localhost:8081/api/v1/ldap/bulk-import/users/template.csv"
219
+ ```
220
+
221
+ **Generated `users-template.csv`**:
222
+
223
+ ```csv
224
+ uid,cn,sn,givenName,mail,userPassword,telephoneNumber,organizationDn
225
+ ```
226
+
227
+ ### Step 3: Fill CSV File
228
+
229
+ **users.csv**:
230
+
231
+ ```csv
232
+ uid,cn,sn,givenName,mail,userPassword,telephoneNumber,organizationDn
233
+ jdoe,John Doe,Doe,John,john.doe@example.com,SecurePass123,+1-555-0100,ou=Engineering,ou=organization,dc=example,dc=com
234
+ asmith,Alice Smith,Smith,Alice,alice.smith@example.com,SecretPass456,+1-555-0101,ou=Marketing,ou=organization,dc=example,dc=com
235
+ bwilson,Bob Wilson,Wilson,Bob,bob.wilson@example.com,MyPass789,+1-555-0102,ou=Engineering,ou=organization,dc=example,dc=com
236
+ ```
237
+
238
+ ### Step 4: Test with Dry Run
239
+
240
+ ```bash
241
+ curl -X POST "http://localhost:8081/api/v1/ldap/bulk-import/users" \
242
+ -F "file=@users.csv" \
243
+ -F "dryRun=true"
244
+ ```
245
+
246
+ **Response**:
247
+
248
+ ```json
249
+ {
250
+ "success": true,
251
+ "total": 3,
252
+ "created": 3,
253
+ "failed": 0,
254
+ "errors": [],
255
+ "details": {
256
+ "duration": "0.5s",
257
+ "linesProcessed": 3
258
+ }
259
+ }
260
+ ```
261
+
262
+ ### Step 5: Import for Real
263
+
264
+ ```bash
265
+ curl -X POST "http://localhost:8081/api/v1/ldap/bulk-import/users" \
266
+ -F "file=@users.csv" \
267
+ -F "dryRun=false"
268
+ ```
269
+
270
+ ### Step 6: Verify in LDAP
271
+
272
+ ```bash
273
+ ldapsearch -x -b "ou=users,dc=example,dc=com" "(uid=jdoe)"
274
+ ```
275
+
276
+ **Result**:
277
+
278
+ ```
279
+ dn: uid=jdoe,ou=users,dc=example,dc=com
280
+ objectClass: inetOrgPerson
281
+ objectClass: organizationalPerson
282
+ objectClass: person
283
+ objectClass: top
284
+ uid: jdoe
285
+ cn: John Doe
286
+ sn: Doe
287
+ givenName: John
288
+ mail: john.doe@example.com
289
+ userPassword: {SSHA}...
290
+ telephoneNumber: +1-555-0100
291
+ twakeDepartmentLink: ou=Engineering,ou=organization,dc=example,dc=com
292
+ twakeDepartmentPath: Engineering / organization
293
+ ```
294
+
295
+ ## Operation Modes
296
+
297
+ ### Dry Run Mode
298
+
299
+ Validate CSV without creating entries:
300
+
301
+ ```bash
302
+ curl -X POST "http://localhost:8081/api/v1/ldap/bulk-import/users" \
303
+ -F "file=@users.csv" \
304
+ -F "dryRun=true"
305
+ ```
306
+
307
+ **Use cases**:
308
+
309
+ - Test CSV format before actual import
310
+ - Validate required attributes
311
+ - Check organization DNs exist
312
+ - Estimate import duration
313
+
314
+ ### Update Existing Mode
315
+
316
+ Update entries that already exist:
317
+
318
+ ```bash
319
+ curl -X POST "http://localhost:8081/api/v1/ldap/bulk-import/users" \
320
+ -F "file=@users.csv" \
321
+ -F "updateExisting=true"
322
+ ```
323
+
324
+ **Behavior**:
325
+
326
+ - If entry exists: Updates all attributes from CSV
327
+ - If entry doesn't exist: Creates new entry
328
+ - Uses LDAP `modify` operation for updates
329
+
330
+ ### Continue on Error Mode
331
+
332
+ Process all records even if some fail:
333
+
334
+ ```bash
335
+ curl -X POST "http://localhost:8081/api/v1/ldap/bulk-import/users" \
336
+ -F "file=@users.csv" \
337
+ -F "continueOnError=true"
338
+ ```
339
+
340
+ **Behavior** (default: `true`):
341
+
342
+ - Continues processing remaining records after errors
343
+ - Collects all errors in response
344
+ - Reports partial success
345
+ - Successfully created entries remain in LDAP even if later entries fail
346
+
347
+ **Example with 5 entries**:
348
+
349
+ - Entry 1: ✅ Created
350
+ - Entry 2: ✅ Created
351
+ - Entry 3: ❌ Failed (invalid organization)
352
+ - Entry 4: ✅ Created (processed despite previous error)
353
+ - Entry 5: ✅ Created
354
+
355
+ **Result**: 4 created, 1 failed, all errors reported
356
+
357
+ **Opposite** (`continueOnError=false`):
358
+
359
+ - Stops at first error
360
+ - Returns immediately with error
361
+ - Previously created entries remain in LDAP
362
+ - No rollback (LDAP doesn't support transactions)
363
+
364
+ **Example with same 5 entries**:
365
+
366
+ - Entry 1: ✅ Created
367
+ - Entry 2: ✅ Created
368
+ - Entry 3: ❌ Failed → **STOPS HERE**
369
+ - Entry 4: ⏭️ Not processed
370
+ - Entry 5: ⏭️ Not processed
371
+
372
+ **Result**: 2 created, 1 failed, entries 4-5 not processed
373
+
374
+ **Important**: Entries already created are NOT rolled back. If you need to undo, you must manually delete them or re-run with correct data using `updateExisting=true`.
375
+
376
+ ## Error Handling
377
+
378
+ ### Common Errors
379
+
380
+ #### Missing Required Attribute
381
+
382
+ **CSV**:
383
+
384
+ ```csv
385
+ uid,cn,mail
386
+ jdoe,John Doe,jdoe@example.com
387
+ ```
388
+
389
+ **Error**:
390
+
391
+ ```json
392
+ {
393
+ "line": 2,
394
+ "identifier": "jdoe",
395
+ "error": "Missing required attribute: sn"
396
+ }
397
+ ```
398
+
399
+ #### Invalid Organization DN
400
+
401
+ **CSV**:
402
+
403
+ ```csv
404
+ uid,cn,sn,organizationDn
405
+ jdoe,John Doe,Doe,ou=NonExistent,dc=example,dc=com
406
+ ```
407
+
408
+ **Error**:
409
+
410
+ ```json
411
+ {
412
+ "line": 2,
413
+ "identifier": "jdoe",
414
+ "error": "Organization not found: ou=NonExistent,dc=example,dc=com"
415
+ }
416
+ ```
417
+
418
+ #### Duplicate Entry
419
+
420
+ **Scenario**: User already exists in LDAP
421
+
422
+ **CSV**:
423
+
424
+ ```csv
425
+ uid,cn,sn,mail
426
+ existinguser,Updated Name,User,new@example.com
427
+ newuser,New User,User,new2@example.com
428
+ ```
429
+
430
+ **With `updateExisting=false` (default)**:
431
+
432
+ ```json
433
+ {
434
+ "success": true,
435
+ "total": 2,
436
+ "created": 1,
437
+ "skipped": 1,
438
+ "failed": 0,
439
+ "errors": []
440
+ }
441
+ ```
442
+
443
+ - `existinguser`: ⏭️ Skipped (already exists)
444
+ - `newuser`: ✅ Created
445
+
446
+ **With `updateExisting=true`**:
447
+
448
+ ```json
449
+ {
450
+ "success": true,
451
+ "total": 2,
452
+ "created": 1,
453
+ "updated": 1,
454
+ "skipped": 0,
455
+ "failed": 0,
456
+ "errors": []
457
+ }
458
+ ```
459
+
460
+ - `existinguser`: ✏️ Updated with new values
461
+ - `newuser`: ✅ Created
462
+
463
+ **Behavior**:
464
+
465
+ - With `updateExisting=false`: Skipped (not an error)
466
+ - With `updateExisting=true`: Updated
467
+
468
+ ### Error Response Format
469
+
470
+ ```json
471
+ {
472
+ "success": true,
473
+ "total": 10,
474
+ "created": 7,
475
+ "failed": 3,
476
+ "errors": [
477
+ {
478
+ "line": 5,
479
+ "identifier": "user004",
480
+ "error": "Missing required attribute: mail"
481
+ },
482
+ {
483
+ "line": 8,
484
+ "identifier": "user007",
485
+ "error": "Organization not found: ou=Invalid,dc=example,dc=com"
486
+ },
487
+ {
488
+ "line": 10,
489
+ "identifier": "user009",
490
+ "error": "Invalid DN format"
491
+ }
492
+ ]
493
+ }
494
+ ```
495
+
496
+ ## Best Practices
497
+
498
+ ### Handling Partial Failures
499
+
500
+ When importing large batches, some entries may fail while others succeed:
501
+
502
+ **Recommended workflow**:
503
+
504
+ 1. **First import with continueOnError=true**:
505
+
506
+ ```bash
507
+ curl -X POST "http://localhost:8081/api/v1/ldap/bulk-import/users" \
508
+ -F "file=@users.csv" \
509
+ -F "continueOnError=true"
510
+ ```
511
+
512
+ 2. **Check response for errors**:
513
+
514
+ ```json
515
+ {
516
+ "created": 95,
517
+ "failed": 5,
518
+ "errors": [
519
+ { "line": 10, "identifier": "user10", "error": "..." },
520
+ { "line": 25, "identifier": "user25", "error": "..." }
521
+ ]
522
+ }
523
+ ```
524
+
525
+ 3. **Fix failed entries in CSV**:
526
+ - Extract lines 10, 25, etc.
527
+ - Correct the errors
528
+ - Create a new CSV with only failed entries
529
+
530
+ 4. **Re-import fixed entries**:
531
+ ```bash
532
+ curl -X POST "http://localhost:8081/api/v1/ldap/bulk-import/users" \
533
+ -F "file=@failed-users-fixed.csv" \
534
+ -F "continueOnError=true"
535
+ ```
536
+
537
+ **Result**: All entries successfully imported without duplicates.
538
+
539
+ ### Re-running an Import
540
+
541
+ If you need to re-run an import (e.g., after partial failure):
542
+
543
+ **Option 1: Skip existing entries** (default)
544
+
545
+ ```bash
546
+ # Only creates new entries, skips existing ones
547
+ -F "updateExisting=false"
548
+ ```
549
+
550
+ - Safe for re-runs
551
+ - Won't modify existing data
552
+ - Good for: Adding new entries only
553
+
554
+ **Option 2: Update existing entries**
555
+
556
+ ```bash
557
+ # Updates existing entries with CSV data
558
+ -F "updateExisting=true"
559
+ ```
560
+
561
+ - Updates all attributes from CSV
562
+ - Good for: Correcting bulk data, synchronization
563
+
564
+ **Option 3: Delete and re-create**
565
+
566
+ ```bash
567
+ # First, delete all entries manually or via API
568
+ # Then re-import with fresh data
569
+ ```
570
+
571
+ - Clean slate approach
572
+ - Good for: Testing, development
573
+
574
+ ## Authorization
575
+
576
+ The bulk import plugin respects all configured authorization plugins:
577
+
578
+ - Uses `ldapaddrequest` hook for each entry
579
+ - Checks write permissions on target branch
580
+ - Checks organization access permissions
581
+ - Supports `authzPerBranch` plugin
582
+
583
+ **Example with authzPerBranch**:
584
+
585
+ If user only has write permission on `ou=Engineering`:
586
+
587
+ - Can import users to `ou=Engineering`
588
+ - Cannot import users to `ou=Marketing` (fails with permission error)
589
+
590
+ ## Performance
591
+
592
+ ### Batch Processing
593
+
594
+ The plugin processes records in batches (default: 100):
595
+
596
+ ```bash
597
+ --bulk-import-batch-size 100
598
+ ```
599
+
600
+ **Recommendations**:
601
+
602
+ - **Small files (<1000 records)**: Use default batch size
603
+ - **Large files (>10000 records)**: Increase to 500-1000
604
+ - **Slow LDAP server**: Decrease to 50
605
+
606
+ ### File Size Limits
607
+
608
+ Default maximum file size: 10MB
609
+
610
+ ```bash
611
+ --bulk-import-max-file-size 10485760 # 10MB
612
+ --bulk-import-max-file-size 52428800 # 50MB
613
+ ```
614
+
615
+ **File size estimates**:
616
+
617
+ - ~100 bytes per user record
618
+ - 10MB ≈ 100,000 users
619
+ - 50MB ≈ 500,000 users
620
+
621
+ ### Processing Speed
622
+
623
+ Typical performance (depends on LDAP server and network):
624
+
625
+ - **Dry run**: ~1000 records/second
626
+ - **Create**: ~100-500 records/second
627
+ - **Update**: ~50-200 records/second
628
+
629
+ ## Integration with Other Plugins
630
+
631
+ ### With ldapFlat
632
+
633
+ ```bash
634
+ --plugin core/ldap/flatGeneric \
635
+ --flat-resources "users:./static/schemas/twake/users.json" \
636
+ --plugin core/ldap/bulkImport \
637
+ --bulk-import-schemas "users:./static/schemas/twake/users.json"
638
+ ```
639
+
640
+ Both plugins share the same schema for consistency.
641
+
642
+ ### With authzPerBranch
643
+
644
+ ```bash
645
+ --plugin core/auth/authzPerBranch \
646
+ --authz-per-branch-config '{"users":{"admin":{"ou=users,dc=example,dc=com":{"write":true}}}}' \
647
+ --plugin core/ldap/bulkImport \
648
+ --bulk-import-schemas "users:./static/schemas/twake/users.json"
649
+ ```
650
+
651
+ Bulk import respects authorization rules.
652
+
653
+ ### With onChange/James
654
+
655
+ ```bash
656
+ --plugin core/ldap/onChange \
657
+ --plugin twake/james \
658
+ --plugin core/ldap/bulkImport \
659
+ --bulk-import-schemas "users:./static/schemas/twake/users.json"
660
+ ```
661
+
662
+ Each imported user triggers `onChange` hooks (e.g., creates mailbox in James).
663
+
664
+ ## Troubleshooting
665
+
666
+ ### Problem: "No file uploaded"
667
+
668
+ **Cause**: Missing file in request
669
+
670
+ **Solution**:
671
+
672
+ ```bash
673
+ curl -X POST "..." -F "file=@users.csv" # Correct
674
+ curl -X POST "..." -d "file=users.csv" # Wrong
675
+ ```
676
+
677
+ ### Problem: "Only CSV files are allowed"
678
+
679
+ **Cause**: File doesn't have `.csv` extension or correct mimetype
680
+
681
+ **Solution**:
682
+
683
+ - Rename file to `*.csv`
684
+ - Check file mimetype: `file --mime-type users.csv`
685
+
686
+ ### Problem: All records failed with "Missing required attribute"
687
+
688
+ **Cause**: CSV headers don't match schema attribute names
689
+
690
+ **Solution**:
691
+
692
+ - Download template with `GET /template.csv`
693
+ - Ensure CSV headers match exactly (case-sensitive)
694
+ - Check for extra spaces in headers
695
+
696
+ ### Problem: "Organization not found"
697
+
698
+ **Cause**: `organizationDn` in CSV points to non-existent organization
699
+
700
+ **Solution**:
701
+
702
+ - Verify organization exists: `ldapsearch -x -b "ou=IT,..." -s base`
703
+ - Check DN syntax (commas, spaces, escaping)
704
+ - Create missing organizations first
705
+
706
+ ### Problem: Slow import (timeout)
707
+
708
+ **Cause**: Too many records or slow LDAP server
709
+
710
+ **Solution**:
711
+
712
+ - Split large CSV into smaller files
713
+ - Increase timeout in HTTP client
714
+ - Reduce `--bulk-import-batch-size`
715
+ - Use `dryRun` to estimate duration first
716
+
717
+ ## See Also
718
+
719
+ - [LDAP Flat Generic Plugin](ldapFlatGeneric.md) - For individual CRUD operations
720
+ - [Authorization Plugin](authzPerBranch.md) - For access control
721
+ - [JSON Schemas](schemas/SCHEMAS.md) - For schema format reference
722
+ - [LDAP Organizations](ldapOrganizations.md) - For organization management