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,1237 @@
1
+ # REST API Guide
2
+
3
+ This guide covers the LDAP-Rest REST API for managing LDAP users, groups, and organizations. The API follows REST conventions and returns JSON responses.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Getting Started](#getting-started)
8
+ - [Authentication](#authentication)
9
+ - [Configuration API](#configuration-api)
10
+ - [Organizations API](#organizations-api)
11
+ - [Users API](#users-api)
12
+ - [Groups API](#groups-api)
13
+ - [Error Handling](#error-handling)
14
+
15
+ ---
16
+
17
+ ## Getting Started
18
+
19
+ ### Base URL
20
+
21
+ All API endpoints are prefixed with `/api/v1` by default:
22
+
23
+ ```
24
+ http://localhost:8081/api/v1
25
+ ```
26
+
27
+ ### Content Type
28
+
29
+ All requests and responses use JSON:
30
+
31
+ ```
32
+ Content-Type: application/json
33
+ ```
34
+
35
+ ### Request Headers
36
+
37
+ Required headers for all requests:
38
+
39
+ ```http
40
+ Accept: application/json
41
+ ```
42
+
43
+ For authenticated endpoints, include the authentication token:
44
+
45
+ ```http
46
+ Authorization: Bearer your-token-here
47
+ ```
48
+
49
+ ---
50
+
51
+ ## Authentication
52
+
53
+ LDAP-Rest supports multiple authentication methods. Choose the one that fits your infrastructure.
54
+
55
+ ### 1. No Authentication (Development Only)
56
+
57
+ For development and testing, you can run LDAP-Rest without authentication:
58
+
59
+ ```bash
60
+ npx ldap-rest \
61
+ --ldap-url ldap://localhost:389 \
62
+ --ldap-dn cn=admin,dc=example,dc=com \
63
+ --ldap-pwd admin \
64
+ --ldap-base dc=example,dc=com
65
+ ```
66
+
67
+ **Warning:** Never use this in production environments.
68
+
69
+ ### 2. Token Bearer Authentication
70
+
71
+ Simple stateless authentication using bearer tokens.
72
+
73
+ **Configuration:**
74
+
75
+ ```bash
76
+ --plugin core/auth/token \
77
+ --auth-token "secret-token-1" \
78
+ --auth-token "secret-token-2"
79
+ ```
80
+
81
+ **Usage:**
82
+
83
+ ```bash
84
+ curl -H "Authorization: Bearer secret-token-1" \
85
+ -H "Accept: application/json" \
86
+ http://localhost:8081/api/v1/ldap/users
87
+ ```
88
+
89
+ **Use Cases:**
90
+
91
+ - Development and testing
92
+ - Service-to-service communication
93
+ - CI/CD pipelines
94
+ - Simple deployments without SSO
95
+
96
+ ### 3. OpenID Connect
97
+
98
+ OAuth 2.0 / OpenID Connect authentication for modern web applications.
99
+
100
+ **Configuration:**
101
+
102
+ ```bash
103
+ --plugin core/auth/openidconnect \
104
+ --oidc-issuer https://auth.example.com \
105
+ --oidc-client-id ldap-rest \
106
+ --oidc-client-secret your-secret
107
+ ```
108
+
109
+ > **NB**: the `redirect_uri` is `https://ldap-rest-server/callback`
110
+
111
+ **Usage:**
112
+
113
+ After authentication you can access to the whole API:
114
+
115
+ ```bash
116
+ curl -H "Authorization: Bearer oidc-access-token" \
117
+ -H "Accept: application/json" \
118
+ http://localhost:8081/api/v1/ldap/users
119
+ ```
120
+
121
+ ### 4. LemonLDAP::NG _(Native)_
122
+
123
+ Integration with LemonLDAP::NG Web SSO solution if not using OpenID-Connect.
124
+
125
+ **Configuration:**
126
+
127
+ ```bash
128
+ --plugin core/auth/llng \
129
+ --llng-ini /etc/lemonldap-ng/lemonldap-ng.ini
130
+ ```
131
+
132
+ The plugin reads user information from the `Lm-Remote-User` header set by LemonLDAP::NG.
133
+
134
+ ---
135
+
136
+ ## Configuration API
137
+
138
+ The Configuration API exposes available features, endpoints, and schemas. Your application can discover capabilities at runtime.
139
+
140
+ ### Get Configuration
141
+
142
+ Retrieve the complete API configuration including all available resources and their endpoints.
143
+
144
+ **Endpoint:** `GET /api/v1/config`
145
+
146
+ **Example Request:**
147
+
148
+ ```bash
149
+ curl -H "Accept: application/json" \
150
+ http://localhost:8081/api/v1/config
151
+ ```
152
+
153
+ **Example Response:**
154
+
155
+ ```json
156
+ {
157
+ "apiPrefix": "/api",
158
+ "ldapBase": "dc=example,dc=com",
159
+ "features": {
160
+ "flatResources": [
161
+ {
162
+ "name": "standardUser",
163
+ "singularName": "user",
164
+ "pluralName": "users",
165
+ "mainAttribute": "uid",
166
+ "objectClass": [
167
+ "top",
168
+ "inetOrgPerson",
169
+ "organizationalPerson",
170
+ "person"
171
+ ],
172
+ "base": "ou=users,dc=example,dc=com",
173
+ "schema": {
174
+ "strict": true,
175
+ "attributes": {
176
+ "uid": {
177
+ "type": "string",
178
+ "required": true,
179
+ "role": "identifier"
180
+ },
181
+ "cn": {
182
+ "type": "string",
183
+ "required": true
184
+ },
185
+ "sn": {
186
+ "type": "string",
187
+ "required": true
188
+ },
189
+ "mail": {
190
+ "type": "string",
191
+ "required": false,
192
+ "role": "primaryEmail"
193
+ }
194
+ }
195
+ },
196
+ "schemaUrl": "/static/schemas/standard/users.json",
197
+ "endpoints": {
198
+ "list": "/api/v1/ldap/users",
199
+ "get": "/api/v1/ldap/users/:id",
200
+ "create": "/api/v1/ldap/users",
201
+ "update": "/api/v1/ldap/users/:id",
202
+ "delete": "/api/v1/ldap/users/:id"
203
+ }
204
+ }
205
+ ],
206
+ "groups": {
207
+ "enabled": true,
208
+ "base": "ou=groups,dc=example,dc=com",
209
+ "mainAttribute": "cn",
210
+ "objectClass": ["top", "groupOfNames"],
211
+ "endpoints": {
212
+ "list": "/api/v1/ldap/groups",
213
+ "get": "/api/v1/ldap/groups/:id",
214
+ "create": "/api/v1/ldap/groups",
215
+ "update": "/api/v1/ldap/groups/:id",
216
+ "delete": "/api/v1/ldap/groups/:id",
217
+ "addMember": "/api/v1/ldap/groups/:id/members",
218
+ "removeMember": "/api/v1/ldap/groups/:id/members/:memberId"
219
+ }
220
+ },
221
+ "organizations": {
222
+ "enabled": true,
223
+ "topOrganization": "ou=organization,dc=example,dc=com",
224
+ "organizationClass": ["top", "organizationalUnit"],
225
+ "linkAttribute": "departmentNumber",
226
+ "pathAttribute": "displayName",
227
+ "pathSeparator": " / ",
228
+ "maxSubnodes": 50,
229
+ "endpoints": {
230
+ "getTop": "/api/v1/ldap/organizations",
231
+ "get": "/api/v1/ldap/organizations/:dn",
232
+ "getSubnodes": "/api/v1/ldap/organizations/:dn/subnodes",
233
+ "searchSubnodes": "/api/v1/ldap/organizations/:dn/subnodes/search"
234
+ }
235
+ }
236
+ }
237
+ }
238
+ ```
239
+
240
+ **Response Fields:**
241
+
242
+ - `apiPrefix`: API URL prefix (default: `/api`)
243
+ - `ldapBase`: LDAP base DN
244
+ - `features.ldapFlatGeneric.flatResources`: Array of flat LDAP resources (users, positions, etc.)
245
+ - `features.ldapGroups`: Group management configuration (if enabled)
246
+ - `features.ldapOrganizations`: Organization tree configuration (if enabled)
247
+
248
+ ---
249
+
250
+ ## Organizations API
251
+
252
+ Manage hierarchical organizational units (OUs) in your LDAP directory.
253
+
254
+ ### Get Top Organization
255
+
256
+ Retrieve the top-level organization entry.
257
+
258
+ **Endpoint:** `GET /api/v1/ldap/organizations/top`
259
+
260
+ **Example Request:**
261
+
262
+ ```bash
263
+ curl -H "Accept: application/json" \
264
+ http://localhost:8081/api/v1/ldap/organizations/top
265
+ ```
266
+
267
+ **Example Response:**
268
+
269
+ ```json
270
+ {
271
+ "dn": "ou=organization,dc=example,dc=com",
272
+ "objectClass": ["organizationalUnit", "top"],
273
+ "ou": "organization",
274
+ "description": "Root organization"
275
+ }
276
+ ```
277
+
278
+ ### Get Organization by DN
279
+
280
+ Retrieve a specific organization by its Distinguished Name.
281
+
282
+ **Endpoint:** `GET /api/v1/ldap/organizations/:dn`
283
+
284
+ **Parameters:**
285
+
286
+ - `:dn` - URL-encoded Distinguished Name
287
+
288
+ **Example Request:**
289
+
290
+ ```bash
291
+ curl -H "Accept: application/json" \
292
+ http://localhost:8081/api/v1/ldap/organizations/ou%3Dit%2Cou%3Dorganization%2Cdc%3Dexample%2Cdc%3Dcom
293
+ ```
294
+
295
+ **Example Response:**
296
+
297
+ ```json
298
+ {
299
+ "dn": "ou=it,ou=organization,dc=example,dc=com",
300
+ "objectClass": ["organizationalUnit", "top"],
301
+ "ou": "it",
302
+ "description": "IT Department"
303
+ }
304
+ ```
305
+
306
+ ### Get Organization Subnodes
307
+
308
+ Retrieve all child organizational units and linked entities (users/groups) for an organization.
309
+
310
+ **Endpoint:** `GET /api/v1/ldap/organizations/:dn/subnodes?objectClass={class}`
311
+
312
+ **Parameters:**
313
+
314
+ - `:dn` - URL-encoded Distinguished Name
315
+ - `objectClass` (optional) - Filter results by LDAP objectClass (e.g., `twakeAccount`, `groupOfNames`, `organizationalUnit`)
316
+
317
+ **Response Limit:** Returns up to 50 linked entities by default (configurable via `--ldap-organization-max-subnodes`)
318
+
319
+ **Example Requests:**
320
+
321
+ ```bash
322
+ # Get all subnodes (users, groups, and sub-OUs)
323
+ curl -H "Accept: application/json" \
324
+ http://localhost:8081/api/v1/ldap/organizations/ou%3Dit%2Cou%3Dorganization%2Cdc%3Dexample%2Cdc%3Dcom/subnodes
325
+
326
+ # Get only users
327
+ curl -H "Accept: application/json" \
328
+ "http://localhost:8081/api/v1/ldap/organizations/ou%3Dit%2Cou%3Dorganization%2Cdc%3Dexample%2Cdc%3Dcom/subnodes?objectClass=twakeAccount"
329
+
330
+ # Get only groups
331
+ curl -H "Accept: application/json" \
332
+ "http://localhost:8081/api/v1/ldap/organizations/ou%3Dit%2Cou%3Dorganization%2Cdc%3Dexample%2Cdc%3Dcom/subnodes?objectClass=groupOfNames"
333
+ ```
334
+
335
+ **Example Response:**
336
+
337
+ ```json
338
+ [
339
+ {
340
+ "dn": "ou=engineering,ou=it,ou=organization,dc=example,dc=com",
341
+ "objectClass": ["organizationalUnit", "top"],
342
+ "ou": "engineering",
343
+ "description": "Engineering Team"
344
+ },
345
+ {
346
+ "dn": "uid=john.doe,ou=users,dc=example,dc=com",
347
+ "objectClass": ["inetOrgPerson", "top"],
348
+ "uid": "john.doe",
349
+ "cn": "John Doe",
350
+ "departmentNumber": "ou=it,ou=organization,dc=example,dc=com"
351
+ }
352
+ ]
353
+ ```
354
+
355
+ ### Search Organization Subnodes
356
+
357
+ Search for subnodes matching a query string within an organization.
358
+
359
+ **Endpoint:** `GET /api/v1/ldap/organizations/:dn/subnodes/search?q=query`
360
+
361
+ **Parameters:**
362
+
363
+ - `:dn` - URL-encoded Distinguished Name
364
+ - `q` - Search query (required)
365
+
366
+ **Example Request:**
367
+
368
+ ```bash
369
+ curl -H "Accept: application/json" \
370
+ "http://localhost:8081/api/v1/ldap/organizations/ou%3Dit%2Cou%3Dorganization%2Cdc%3Dexample%2Cdc%3Dcom/subnodes/search?q=john"
371
+ ```
372
+
373
+ **Example Response:**
374
+
375
+ ```json
376
+ [
377
+ {
378
+ "dn": "uid=john.doe,ou=users,dc=example,dc=com",
379
+ "objectClass": ["inetOrgPerson", "top"],
380
+ "uid": "john.doe",
381
+ "cn": "John Doe",
382
+ "mail": "john.doe@example.com",
383
+ "departmentNumber": "ou=it,ou=organization,dc=example,dc=com"
384
+ }
385
+ ]
386
+ ```
387
+
388
+ ### Create Organization
389
+
390
+ Create a new organizational unit.
391
+
392
+ **Endpoint:** `POST /api/v1/ldap/organizations`
393
+
394
+ **Request Body:**
395
+
396
+ ```json
397
+ {
398
+ "ou": "marketing",
399
+ "parentDn": "ou=organization,dc=example,dc=com",
400
+ "description": "Marketing Department"
401
+ }
402
+ ```
403
+
404
+ **Required Fields:**
405
+
406
+ - `ou` - Organizational unit name
407
+
408
+ **Optional Fields:**
409
+
410
+ - `parentDn` - Parent organization DN (defaults to top organization)
411
+ - Additional LDAP attributes as needed
412
+
413
+ **Example Request:**
414
+
415
+ ```bash
416
+ curl -X POST \
417
+ -H "Content-Type: application/json" \
418
+ -H "Accept: application/json" \
419
+ -d '{
420
+ "ou": "marketing",
421
+ "parentDn": "ou=organization,dc=example,dc=com",
422
+ "description": "Marketing Department"
423
+ }' \
424
+ http://localhost:8081/api/v1/ldap/organizations
425
+ ```
426
+
427
+ **Example Response:**
428
+
429
+ ```json
430
+ {
431
+ "success": true,
432
+ "dn": "ou=marketing,ou=organization,dc=example,dc=com"
433
+ }
434
+ ```
435
+
436
+ ### Update Organization
437
+
438
+ Modify an existing organization using LDAP modify operations.
439
+
440
+ **Endpoint:** `PUT /api/v1/ldap/organizations/:dn`
441
+
442
+ **Parameters:**
443
+
444
+ - `:dn` - URL-encoded Distinguished Name
445
+
446
+ **Request Body Format:**
447
+
448
+ ```json
449
+ {
450
+ "replace": {
451
+ "description": "Updated Marketing Department"
452
+ },
453
+ "add": {
454
+ "telephoneNumber": "+1-555-0100"
455
+ },
456
+ "delete": ["postalCode"]
457
+ }
458
+ ```
459
+
460
+ **Operations:**
461
+
462
+ - `replace` - Replace attribute values
463
+ - `add` - Add new attribute values
464
+ - `delete` - Remove attributes (array of attribute names) or specific values (object)
465
+
466
+ **Example Request:**
467
+
468
+ ```bash
469
+ curl -X PUT \
470
+ -H "Content-Type: application/json" \
471
+ -H "Accept: application/json" \
472
+ -d '{
473
+ "replace": {
474
+ "description": "Marketing and Communications"
475
+ }
476
+ }' \
477
+ http://localhost:8081/api/v1/ldap/organizations/ou%3Dmarketing%2Cou%3Dorganization%2Cdc%3Dexample%2Cdc%3Dcom
478
+ ```
479
+
480
+ **Example Response:**
481
+
482
+ ```json
483
+ {
484
+ "success": true
485
+ }
486
+ ```
487
+
488
+ ### Delete Organization
489
+
490
+ Delete an organizational unit. The organization must be empty (no linked users/groups).
491
+
492
+ **Endpoint:** `DELETE /api/v1/ldap/organizations/:dn`
493
+
494
+ **Parameters:**
495
+
496
+ - `:dn` - URL-encoded Distinguished Name
497
+
498
+ **Example Request:**
499
+
500
+ ```bash
501
+ curl -X DELETE \
502
+ -H "Accept: application/json" \
503
+ http://localhost:8081/api/v1/ldap/organizations/ou%3Dmarketing%2Cou%3Dorganization%2Cdc%3Dexample%2Cdc%3Dcom
504
+ ```
505
+
506
+ **Example Response:**
507
+
508
+ ```json
509
+ {
510
+ "success": true
511
+ }
512
+ ```
513
+
514
+ **Error Response (non-empty organization):**
515
+
516
+ ```json
517
+ {
518
+ "error": "Organization ou=marketing,ou=organization,dc=example,dc=com is not empty"
519
+ }
520
+ ```
521
+
522
+ ---
523
+
524
+ ## Users API
525
+
526
+ Manage user entries in your LDAP directory. User endpoints are dynamically configured based on loaded schemas.
527
+
528
+ ### List Users
529
+
530
+ Retrieve all users or filter by attributes.
531
+
532
+ **Endpoint:** `GET /api/v1/ldap/users`
533
+
534
+ **Query Parameters:**
535
+
536
+ - `match` - Filter value (partial match with wildcards)
537
+ - `attribute` - Attribute name to filter on
538
+ - `attributes` - Comma-separated list of attributes to return
539
+
540
+ **Example Request (all users):**
541
+
542
+ ```bash
543
+ curl -H "Accept: application/json" \
544
+ http://localhost:8081/api/v1/ldap/users
545
+ ```
546
+
547
+ **Example Request (filtered):**
548
+
549
+ ```bash
550
+ curl -H "Accept: application/json" \
551
+ "http://localhost:8081/api/v1/ldap/users?match=john&attribute=cn"
552
+ ```
553
+
554
+ **Example Response:**
555
+
556
+ ```json
557
+ [
558
+ {
559
+ "dn": "uid=john.doe,ou=users,dc=example,dc=com",
560
+ "uid": "john.doe",
561
+ "cn": "John Doe",
562
+ "sn": "Doe",
563
+ "givenName": "John",
564
+ "mail": "john.doe@example.com",
565
+ "telephoneNumber": "+1-555-0123"
566
+ },
567
+ {
568
+ "dn": "uid=jane.smith,ou=users,dc=example,dc=com",
569
+ "uid": "jane.smith",
570
+ "cn": "Jane Smith",
571
+ "sn": "Smith",
572
+ "givenName": "Jane",
573
+ "mail": "jane.smith@example.com"
574
+ }
575
+ ]
576
+ ```
577
+
578
+ ### Get User
579
+
580
+ Retrieve a specific user by UID or DN.
581
+
582
+ **Endpoint:** `GET /api/v1/ldap/users/:id`
583
+
584
+ **Parameters:**
585
+
586
+ - `:id` - User UID or URL-encoded DN
587
+
588
+ **Example Request (by UID):**
589
+
590
+ ```bash
591
+ curl -H "Accept: application/json" \
592
+ http://localhost:8081/api/v1/ldap/users/john.doe
593
+ ```
594
+
595
+ **Example Request (by DN):**
596
+
597
+ ```bash
598
+ curl -H "Accept: application/json" \
599
+ http://localhost:8081/api/v1/ldap/users/uid%3Djohn.doe%2Cou%3Dusers%2Cdc%3Dexample%2Cdc%3Dcom
600
+ ```
601
+
602
+ **Example Response:**
603
+
604
+ ```json
605
+ {
606
+ "dn": "uid=john.doe,ou=users,dc=example,dc=com",
607
+ "objectClass": ["inetOrgPerson", "organizationalPerson", "person", "top"],
608
+ "uid": "john.doe",
609
+ "cn": "John Doe",
610
+ "sn": "Doe",
611
+ "givenName": "John",
612
+ "mail": "john.doe@example.com",
613
+ "telephoneNumber": "+1-555-0123",
614
+ "departmentNumber": "ou=it,ou=organization,dc=example,dc=com"
615
+ }
616
+ ```
617
+
618
+ ### Create User
619
+
620
+ Add a new user to the LDAP directory.
621
+
622
+ **Endpoint:** `POST /api/v1/ldap/users`
623
+
624
+ **Request Body:**
625
+
626
+ ```json
627
+ {
628
+ "uid": "alice.johnson",
629
+ "cn": "Alice Johnson",
630
+ "sn": "Johnson",
631
+ "givenName": "Alice",
632
+ "mail": "alice.johnson@example.com",
633
+ "telephoneNumber": "+1-555-0124",
634
+ "userPassword": "{SSHA}hashedpassword"
635
+ }
636
+ ```
637
+
638
+ **Required Fields:** Depends on your schema. Typically:
639
+
640
+ - `uid` - User identifier
641
+ - `cn` - Common name
642
+ - `sn` - Surname
643
+
644
+ **Example Request:**
645
+
646
+ ```bash
647
+ curl -X POST \
648
+ -H "Content-Type: application/json" \
649
+ -H "Accept: application/json" \
650
+ -d '{
651
+ "uid": "alice.johnson",
652
+ "cn": "Alice Johnson",
653
+ "sn": "Johnson",
654
+ "givenName": "Alice",
655
+ "mail": "alice.johnson@example.com"
656
+ }' \
657
+ http://localhost:8081/api/v1/ldap/users
658
+ ```
659
+
660
+ **Example Response:**
661
+
662
+ ```json
663
+ {
664
+ "success": true,
665
+ "dn": "uid=alice.johnson,ou=users,dc=example,dc=com"
666
+ }
667
+ ```
668
+
669
+ ### Update User
670
+
671
+ Modify an existing user using LDAP modify operations.
672
+
673
+ **Endpoint:** `PUT /api/v1/ldap/users/:id`
674
+
675
+ **Parameters:**
676
+
677
+ - `:id` - User UID or URL-encoded DN
678
+
679
+ **Request Body Format:**
680
+
681
+ ```json
682
+ {
683
+ "replace": {
684
+ "mail": "alice.j@example.com",
685
+ "telephoneNumber": "+1-555-0199"
686
+ },
687
+ "add": {
688
+ "mailAlternateAddress": ["alice.johnson@example.com"]
689
+ },
690
+ "delete": ["mobile"]
691
+ }
692
+ ```
693
+
694
+ **Operations:**
695
+
696
+ - `replace` - Replace attribute values
697
+ - `add` - Add new attribute values (for multi-valued attributes)
698
+ - `delete` - Remove attributes (array) or specific values (object)
699
+
700
+ **Example Request:**
701
+
702
+ ```bash
703
+ curl -X PUT \
704
+ -H "Content-Type: application/json" \
705
+ -H "Accept: application/json" \
706
+ -d '{
707
+ "replace": {
708
+ "telephoneNumber": "+1-555-0200"
709
+ }
710
+ }' \
711
+ http://localhost:8081/api/v1/ldap/users/alice.johnson
712
+ ```
713
+
714
+ **Example Response:**
715
+
716
+ ```json
717
+ {
718
+ "success": true
719
+ }
720
+ ```
721
+
722
+ ### Delete User
723
+
724
+ Remove a user from the LDAP directory. The user is automatically removed from all groups.
725
+
726
+ **Endpoint:** `DELETE /api/v1/ldap/users/:id`
727
+
728
+ **Parameters:**
729
+
730
+ - `:id` - User UID or URL-encoded DN
731
+
732
+ **Example Request:**
733
+
734
+ ```bash
735
+ curl -X DELETE \
736
+ -H "Accept: application/json" \
737
+ http://localhost:8081/api/v1/ldap/users/alice.johnson
738
+ ```
739
+
740
+ **Example Response:**
741
+
742
+ ```json
743
+ {
744
+ "success": true
745
+ }
746
+ ```
747
+
748
+ ---
749
+
750
+ ## Groups API
751
+
752
+ Manage LDAP groups and their members.
753
+
754
+ ### List Groups
755
+
756
+ Retrieve all groups or filter by name.
757
+
758
+ **Endpoint:** `GET /api/v1/ldap/groups`
759
+
760
+ **Query Parameters:**
761
+
762
+ - `match` - Filter groups by CN (supports LDAP filter format or simple string)
763
+ - `attributes` - Comma-separated list of attributes to return
764
+
765
+ **Example Request (all groups):**
766
+
767
+ ```bash
768
+ curl -H "Accept: application/json" \
769
+ http://localhost:8081/api/v1/ldap/groups
770
+ ```
771
+
772
+ **Example Request (filtered):**
773
+
774
+ ```bash
775
+ curl -H "Accept: application/json" \
776
+ "http://localhost:8081/api/v1/ldap/groups?match=admin*"
777
+ ```
778
+
779
+ **Example Response:**
780
+
781
+ ```json
782
+ {
783
+ "admins": {
784
+ "dn": "cn=admins,ou=groups,dc=example,dc=com",
785
+ "cn": "admins",
786
+ "member": [
787
+ "uid=john.doe,ou=users,dc=example,dc=com",
788
+ "uid=jane.smith,ou=users,dc=example,dc=com"
789
+ ]
790
+ },
791
+ "developers": {
792
+ "dn": "cn=developers,ou=groups,dc=example,dc=com",
793
+ "cn": "developers",
794
+ "member": ["uid=alice.johnson,ou=users,dc=example,dc=com"]
795
+ }
796
+ }
797
+ ```
798
+
799
+ ### Get Group
800
+
801
+ Retrieve a specific group by CN or DN.
802
+
803
+ **Endpoint:** `GET /api/v1/ldap/groups/:cn`
804
+
805
+ **Parameters:**
806
+
807
+ - `:cn` - Group CN or URL-encoded DN
808
+
809
+ **Example Request:**
810
+
811
+ ```bash
812
+ curl -H "Accept: application/json" \
813
+ http://localhost:8081/api/v1/ldap/groups/admins
814
+ ```
815
+
816
+ **Example Response:**
817
+
818
+ ```json
819
+ {
820
+ "dn": "cn=admins,ou=groups,dc=example,dc=com",
821
+ "objectClass": ["groupOfNames", "top"],
822
+ "cn": "admins",
823
+ "description": "System Administrators",
824
+ "member": [
825
+ "uid=john.doe,ou=users,dc=example,dc=com",
826
+ "uid=jane.smith,ou=users,dc=example,dc=com"
827
+ ]
828
+ }
829
+ ```
830
+
831
+ ### Create Group
832
+
833
+ Add a new group to the LDAP directory.
834
+
835
+ **Endpoint:** `POST /api/v1/ldap/groups`
836
+
837
+ **Request Body:**
838
+
839
+ ```json
840
+ {
841
+ "cn": "developers",
842
+ "description": "Development Team",
843
+ "member": ["uid=alice.johnson,ou=users,dc=example,dc=com"]
844
+ }
845
+ ```
846
+
847
+ **Required Fields:**
848
+
849
+ - `cn` - Group common name
850
+
851
+ **Optional Fields:**
852
+
853
+ - `member` - Array of member DNs
854
+ - `description` - Group description
855
+ - Additional LDAP attributes as needed
856
+
857
+ **Note:** Groups require at least one member. If no members are provided, a dummy member is automatically added.
858
+
859
+ **Example Request:**
860
+
861
+ ```bash
862
+ curl -X POST \
863
+ -H "Content-Type: application/json" \
864
+ -H "Accept: application/json" \
865
+ -d '{
866
+ "cn": "developers",
867
+ "description": "Development Team",
868
+ "member": ["uid=alice.johnson,ou=users,dc=example,dc=com"]
869
+ }' \
870
+ http://localhost:8081/api/v1/ldap/groups
871
+ ```
872
+
873
+ **Example Response:**
874
+
875
+ ```json
876
+ {
877
+ "success": true,
878
+ "dn": "cn=developers,ou=groups,dc=example,dc=com"
879
+ }
880
+ ```
881
+
882
+ ### Update Group
883
+
884
+ Modify an existing group using LDAP modify operations.
885
+
886
+ **Endpoint:** `PUT /api/v1/ldap/groups/:cn`
887
+
888
+ **Parameters:**
889
+
890
+ - `:cn` - Group CN or URL-encoded DN
891
+
892
+ **Request Body Format:**
893
+
894
+ ```json
895
+ {
896
+ "replace": {
897
+ "description": "Software Development Team"
898
+ },
899
+ "add": {
900
+ "businessCategory": "Engineering"
901
+ },
902
+ "delete": ["seeAlso"]
903
+ }
904
+ ```
905
+
906
+ **Important:** Do not use this endpoint to add/remove members. Use the dedicated member management endpoints instead.
907
+
908
+ **Example Request:**
909
+
910
+ ```bash
911
+ curl -X PUT \
912
+ -H "Content-Type: application/json" \
913
+ -H "Accept: application/json" \
914
+ -d '{
915
+ "replace": {
916
+ "description": "Software Development Team"
917
+ }
918
+ }' \
919
+ http://localhost:8081/api/v1/ldap/groups/developers
920
+ ```
921
+
922
+ **Example Response:**
923
+
924
+ ```json
925
+ {
926
+ "success": true
927
+ }
928
+ ```
929
+
930
+ ### Delete Group
931
+
932
+ Remove a group from the LDAP directory.
933
+
934
+ **Endpoint:** `DELETE /api/v1/ldap/groups/:cn`
935
+
936
+ **Parameters:**
937
+
938
+ - `:cn` - Group CN or URL-encoded DN
939
+
940
+ **Example Request:**
941
+
942
+ ```bash
943
+ curl -X DELETE \
944
+ -H "Accept: application/json" \
945
+ http://localhost:8081/api/v1/ldap/groups/developers
946
+ ```
947
+
948
+ **Example Response:**
949
+
950
+ ```json
951
+ {
952
+ "success": true
953
+ }
954
+ ```
955
+
956
+ ### Add Group Member
957
+
958
+ Add one or more users to a group.
959
+
960
+ **Endpoint:** `POST /api/v1/ldap/groups/:cn/members`
961
+
962
+ **Parameters:**
963
+
964
+ - `:cn` - Group CN or URL-encoded DN
965
+
966
+ **Request Body:**
967
+
968
+ ```json
969
+ {
970
+ "member": "uid=bob.wilson,ou=users,dc=example,dc=com"
971
+ }
972
+ ```
973
+
974
+ Or multiple members:
975
+
976
+ ```json
977
+ {
978
+ "member": [
979
+ "uid=bob.wilson,ou=users,dc=example,dc=com",
980
+ "uid=carol.white,ou=users,dc=example,dc=com"
981
+ ]
982
+ }
983
+ ```
984
+
985
+ **Example Request:**
986
+
987
+ ```bash
988
+ curl -X POST \
989
+ -H "Content-Type: application/json" \
990
+ -H "Accept: application/json" \
991
+ -d '{
992
+ "member": "uid=bob.wilson,ou=users,dc=example,dc=com"
993
+ }' \
994
+ http://localhost:8081/api/v1/ldap/groups/developers/members
995
+ ```
996
+
997
+ **Example Response:**
998
+
999
+ ```json
1000
+ {
1001
+ "success": true
1002
+ }
1003
+ ```
1004
+
1005
+ ### Remove Group Member
1006
+
1007
+ Remove a user from a group.
1008
+
1009
+ **Endpoint:** `DELETE /api/v1/ldap/groups/:cn/members/:memberId`
1010
+
1011
+ **Parameters:**
1012
+
1013
+ - `:cn` - Group CN or URL-encoded DN
1014
+ - `:memberId` - URL-encoded member DN
1015
+
1016
+ **Example Request:**
1017
+
1018
+ ```bash
1019
+ curl -X DELETE \
1020
+ -H "Accept: application/json" \
1021
+ http://localhost:8081/api/v1/ldap/groups/developers/members/uid%3Dbob.wilson%2Cou%3Dusers%2Cdc%3Dexample%2Cdc%3Dcom
1022
+ ```
1023
+
1024
+ **Example Response:**
1025
+
1026
+ ```json
1027
+ {
1028
+ "success": true
1029
+ }
1030
+ ```
1031
+
1032
+ ---
1033
+
1034
+ ## Error Handling
1035
+
1036
+ ### HTTP Status Codes
1037
+
1038
+ | Status Code | Description |
1039
+ | ----------- | -------------------------------------- |
1040
+ | 200 | Success |
1041
+ | 201 | Created |
1042
+ | 400 | Bad Request - Invalid input |
1043
+ | 401 | Unauthorized - Authentication required |
1044
+ | 403 | Forbidden - Insufficient permissions |
1045
+ | 404 | Not Found - Resource doesn't exist |
1046
+ | 409 | Conflict - Resource already exists |
1047
+ | 500 | Internal Server Error |
1048
+
1049
+ ### Error Response Format
1050
+
1051
+ All errors return a JSON object with an error message:
1052
+
1053
+ ```json
1054
+ {
1055
+ "error": "Description of the error"
1056
+ }
1057
+ ```
1058
+
1059
+ ### Common Errors
1060
+
1061
+ #### 400 Bad Request
1062
+
1063
+ **Missing Required Fields:**
1064
+
1065
+ ```json
1066
+ {
1067
+ "error": "Attribute \"sn\" is required"
1068
+ }
1069
+ ```
1070
+
1071
+ **Invalid Attribute Format:**
1072
+
1073
+ ```json
1074
+ {
1075
+ "error": "Invalid value for attribute \"uid\": must match ^[a-zA-Z0-9._-]{1,255}$"
1076
+ }
1077
+ ```
1078
+
1079
+ **Invalid LDAP Filter:**
1080
+
1081
+ ```json
1082
+ {
1083
+ "error": "Invalid match query"
1084
+ }
1085
+ ```
1086
+
1087
+ #### 401 Unauthorized
1088
+
1089
+ **Missing Authentication:**
1090
+
1091
+ ```json
1092
+ {
1093
+ "error": "Unauthorized"
1094
+ }
1095
+ ```
1096
+
1097
+ **Invalid Token:**
1098
+
1099
+ ```json
1100
+ {
1101
+ "error": "Unauthorized"
1102
+ }
1103
+ ```
1104
+
1105
+ #### 404 Not Found
1106
+
1107
+ **User Not Found:**
1108
+
1109
+ ```json
1110
+ {
1111
+ "error": "User not found"
1112
+ }
1113
+ ```
1114
+
1115
+ **Group Not Found:**
1116
+
1117
+ ```json
1118
+ {
1119
+ "error": "Group not found"
1120
+ }
1121
+ ```
1122
+
1123
+ **Organization Not Found:**
1124
+
1125
+ ```json
1126
+ {
1127
+ "error": "Organization ou=marketing,ou=organization,dc=example,dc=com not found"
1128
+ }
1129
+ ```
1130
+
1131
+ #### 409 Conflict
1132
+
1133
+ **Duplicate Entry:**
1134
+
1135
+ ```json
1136
+ {
1137
+ "error": "Failed to add user uid=john.doe,ou=users,dc=example,dc=com: Entry Already Exists"
1138
+ }
1139
+ ```
1140
+
1141
+ #### 500 Internal Server Error
1142
+
1143
+ **LDAP Connection Error:**
1144
+
1145
+ ```json
1146
+ {
1147
+ "error": "LDAP bind error"
1148
+ }
1149
+ ```
1150
+
1151
+ **General Server Error:**
1152
+
1153
+ ```json
1154
+ {
1155
+ "error": "Internal server error: <details>"
1156
+ }
1157
+ ```
1158
+
1159
+ ---
1160
+
1161
+ ## Tips and Best Practices
1162
+
1163
+ ### URL Encoding
1164
+
1165
+ Always URL-encode DNs when using them in URL paths:
1166
+
1167
+ ```javascript
1168
+ const dn = 'uid=john.doe,ou=users,dc=example,dc=com';
1169
+ const encoded = encodeURIComponent(dn);
1170
+ // Result: uid%3Djohn.doe%2Cou%3Dusers%2Cdc%3Dexample%2Cdc%3Dcom
1171
+ ```
1172
+
1173
+ ### LDAP Attributes are Arrays
1174
+
1175
+ LDAP attributes are always returned as arrays, even for single-valued attributes:
1176
+
1177
+ ```json
1178
+ {
1179
+ "uid": "john.doe", // Actually stored as ["john.doe"]
1180
+ "cn": "John Doe", // Actually stored as ["John Doe"]
1181
+ "mail": "john@example.com" // Actually stored as ["john@example.com"]
1182
+ }
1183
+ ```
1184
+
1185
+ When sending data, you can use either format:
1186
+
1187
+ ```json
1188
+ {
1189
+ "uid": "john.doe",
1190
+ "cn": ["John Doe"],
1191
+ "mail": ["john@example.com", "jdoe@example.com"]
1192
+ }
1193
+ ```
1194
+
1195
+ ### Modify Operations
1196
+
1197
+ Use the correct operation type:
1198
+
1199
+ - **replace**: Change an existing value (creates if doesn't exist)
1200
+ - **add**: Add values to multi-valued attributes (error if already exists)
1201
+ - **delete**: Remove attributes or specific values
1202
+
1203
+ ### Pagination
1204
+
1205
+ For large result sets, consider implementing client-side pagination or use LDAP paging (controlled server-side).
1206
+
1207
+ ### Schema Validation
1208
+
1209
+ Always check the schema via `/api/v1/config` to understand:
1210
+
1211
+ - Required attributes
1212
+ - Attribute types and formats
1213
+ - Allowed values and patterns
1214
+
1215
+ ### Testing
1216
+
1217
+ Use the Configuration API to discover available endpoints before making requests:
1218
+
1219
+ ```bash
1220
+ # 1. Get configuration
1221
+ CONFIG=$(curl -s http://localhost:8081/api/v1/config)
1222
+
1223
+ # 2. Extract users endpoint
1224
+ USERS_ENDPOINT=$(echo $CONFIG | jq -r '.features.ldapFlatGeneric.flatResources[0].endpoints.list')
1225
+
1226
+ # 3. Use endpoint
1227
+ curl -s $USERS_ENDPOINT
1228
+ ```
1229
+
1230
+ ---
1231
+
1232
+ ## Next Steps
1233
+
1234
+ - **[API Reference](./REFERENCE.md)** - Complete reference with all HTTP status codes and formats
1235
+ - **[Browser Libraries](../browser/LIBRARIES.md)** - Pre-built JavaScript clients
1236
+ - **[Examples](../examples/EXAMPLES.md)** - Integration examples for React, Vue, and Vanilla JS
1237
+ - **[Schemas](../schemas/SCHEMAS.md)** - Understanding and creating JSON schemas