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.
- package/LICENSE +661 -0
- package/README.md +48 -0
- package/bin/cleanup-external-users.mjs +219 -0
- package/bin/index.mjs +54 -0
- package/bin/sync-james.mjs +190 -0
- package/dist/abstract/ldapFlat.js +1 -0
- package/dist/abstract/plugin.js +1 -0
- package/dist/abstract/twakePlugin.js +1 -0
- package/dist/bin/index.js +1 -0
- package/dist/config/args.js +1 -0
- package/dist/lib/auth/base.js +1 -0
- package/dist/lib/authz/base.js +1 -0
- package/dist/lib/expressFormatedResponses.js +1 -0
- package/dist/lib/ldapActions.js +1 -0
- package/dist/lib/parseConfig.js +1 -0
- package/dist/lib/utils.js +1 -0
- package/dist/logger/winston.js +1 -0
- package/dist/plugins/auth/authzLinid1.js +1 -0
- package/dist/plugins/auth/authzPerBranch.js +1 -0
- package/dist/plugins/auth/crowdsec.js +1 -0
- package/dist/plugins/auth/llng.js +1 -0
- package/dist/plugins/auth/openidconnect.js +1 -0
- package/dist/plugins/auth/rateLimit.js +1 -0
- package/dist/plugins/auth/token.js +1 -0
- package/dist/plugins/configApi.js +1 -0
- package/dist/plugins/demo/helloworld.js +1 -0
- package/dist/plugins/ldap/bulkImport.js +1 -0
- package/dist/plugins/ldap/departmentSync.js +1 -0
- package/dist/plugins/ldap/externalUsersInGroups.js +1 -0
- package/dist/plugins/ldap/flatGeneric.js +1 -0
- package/dist/plugins/ldap/groups.js +1 -0
- package/dist/plugins/ldap/onChange.js +1 -0
- package/dist/plugins/ldap/organization.js +1 -0
- package/dist/plugins/ldap/trash.js +1 -0
- package/dist/plugins/priority.json.js +1 -0
- package/dist/plugins/static.js +1 -0
- package/dist/plugins/twake/calendarResources.js +1 -0
- package/dist/plugins/twake/james.js +1 -0
- package/dist/plugins/weblogs.js +1 -0
- package/dist/src/abstract/ldapFlat.d.ts +94 -0
- package/dist/src/abstract/plugin.d.ts +43 -0
- package/dist/src/abstract/twakePlugin.d.ts +90 -0
- package/dist/src/bin/index.d.ts +43 -0
- package/dist/src/browser/ldap-group-editor/LdapGroupEditor.d.ts +31 -0
- package/dist/src/browser/ldap-group-editor/api/GroupApiClient.d.ts +23 -0
- package/dist/src/browser/ldap-group-editor/components/CreateGroupModal.d.ts +19 -0
- package/dist/src/browser/ldap-group-editor/components/GroupPropertyEditor.d.ts +30 -0
- package/dist/src/browser/ldap-group-editor/components/GroupTree.d.ts +17 -0
- package/dist/src/browser/ldap-group-editor/components/MoveGroupModal.d.ts +20 -0
- package/dist/src/browser/ldap-group-editor/index.d.ts +6 -0
- package/dist/src/browser/ldap-group-editor/types.d.ts +58 -0
- package/dist/src/browser/ldap-resource-editor/api/ResourceApiClient.d.ts +53 -0
- package/dist/src/browser/ldap-resource-editor/cache/CacheManager.d.ts +65 -0
- package/dist/src/browser/ldap-resource-editor/index.d.ts +6 -0
- package/dist/src/browser/ldap-resource-editor/types.d.ts +78 -0
- package/dist/src/browser/ldap-tree-viewer/LdapTreeViewer.d.ts +26 -0
- package/dist/src/browser/ldap-tree-viewer/api/LdapApiClient.d.ts +30 -0
- package/dist/src/browser/ldap-tree-viewer/components/TreeNode.d.ts +17 -0
- package/dist/src/browser/ldap-tree-viewer/components/TreeRoot.d.ts +14 -0
- package/dist/src/browser/ldap-tree-viewer/index.d.ts +7 -0
- package/dist/src/browser/ldap-tree-viewer/store/Store.d.ts +18 -0
- package/dist/src/browser/ldap-tree-viewer/store/actions.d.ts +28 -0
- package/dist/src/browser/ldap-tree-viewer/store/reducers.d.ts +7 -0
- package/dist/src/browser/ldap-tree-viewer/types.d.ts +34 -0
- package/dist/src/browser/ldap-unit-editor/LdapUnitEditor.d.ts +27 -0
- package/dist/src/browser/ldap-unit-editor/api/UnitApiClient.d.ts +24 -0
- package/dist/src/browser/ldap-unit-editor/components/MoveUnitModal.d.ts +28 -0
- package/dist/src/browser/ldap-unit-editor/components/UnitPropertyEditor.d.ts +28 -0
- package/dist/src/browser/ldap-unit-editor/components/UnitTree.d.ts +18 -0
- package/dist/src/browser/ldap-unit-editor/index.d.ts +6 -0
- package/dist/src/browser/ldap-unit-editor/types.d.ts +55 -0
- package/dist/src/browser/ldap-user-editor/LdapUserEditor.d.ts +32 -0
- package/dist/src/browser/ldap-user-editor/api/UserApiClient.d.ts +55 -0
- package/dist/src/browser/ldap-user-editor/cache/CacheManager.d.ts +65 -0
- package/dist/src/browser/ldap-user-editor/components/MoveUserModal.d.ts +28 -0
- package/dist/src/browser/ldap-user-editor/components/PointerField.d.ts +22 -0
- package/dist/src/browser/ldap-user-editor/components/UserEditor.d.ts +46 -0
- package/dist/src/browser/ldap-user-editor/components/UserList.d.ts +24 -0
- package/dist/src/browser/ldap-user-editor/components/UserTree.d.ts +24 -0
- package/dist/src/browser/ldap-user-editor/index.d.ts +7 -0
- package/dist/src/browser/ldap-user-editor/types.d.ts +67 -0
- package/dist/src/browser/shared/components/Modal.d.ts +38 -0
- package/dist/src/browser/shared/components/StatusMessage.d.ts +48 -0
- package/dist/src/browser/shared/index.d.ts +10 -0
- package/dist/src/browser/shared/types/index.d.ts +65 -0
- package/dist/src/browser/shared/utils/dom.d.ts +33 -0
- package/dist/src/browser/shared/utils/form.d.ts +28 -0
- package/dist/src/browser/shared/utils/schema.d.ts +29 -0
- package/dist/src/config/args.d.ts +128 -0
- package/dist/src/config/schema.d.ts +18 -0
- package/dist/src/hooks.d.ts +76 -0
- package/dist/src/lib/auth/base.d.ts +9 -0
- package/dist/src/lib/authz/base.d.ts +63 -0
- package/dist/src/lib/expressFormatedResponses.d.ts +26 -0
- package/dist/src/lib/ldapActions.d.ts +91 -0
- package/dist/src/lib/parseConfig.d.ts +23 -0
- package/dist/src/lib/utils.d.ts +73 -0
- package/dist/src/logger/winston.d.ts +3 -0
- package/dist/src/plugins/auth/authzLinid1.d.ts +46 -0
- package/dist/src/plugins/auth/authzPerBranch.d.ts +59 -0
- package/dist/src/plugins/auth/crowdsec.d.ts +29 -0
- package/dist/src/plugins/auth/llng.d.ts +8 -0
- package/dist/src/plugins/auth/openidconnect.d.ts +11 -0
- package/dist/src/plugins/auth/rateLimit.d.ts +24 -0
- package/dist/src/plugins/auth/token.d.ts +17 -0
- package/dist/src/plugins/configApi.d.ts +24 -0
- package/dist/src/plugins/demo/helloworld.d.ts +12 -0
- package/dist/src/plugins/ldap/bulkImport.d.ts +48 -0
- package/dist/src/plugins/ldap/departmentSync.d.ts +35 -0
- package/dist/src/plugins/ldap/externalUsersInGroups.d.ts +21 -0
- package/dist/src/plugins/ldap/flatGeneric.d.ts +31 -0
- package/dist/src/plugins/ldap/groups.d.ts +95 -0
- package/dist/src/plugins/ldap/onChange.d.ts +32 -0
- package/dist/src/plugins/ldap/organization.d.ts +65 -0
- package/dist/src/plugins/ldap/trash.d.ts +52 -0
- package/dist/src/plugins/static.d.ts +7 -0
- package/dist/src/plugins/twake/calendarResources.d.ts +31 -0
- package/dist/src/plugins/twake/james.d.ts +83 -0
- package/dist/src/plugins/weblogs.d.ts +8 -0
- package/docs/DEVELOPER_GUIDE.md +298 -0
- package/docs/OPENAPI.md +440 -0
- package/docs/PLUGIN_DEPENDENCIES.md +612 -0
- package/docs/README.md +466 -0
- package/docs/api/REFERENCE.md +983 -0
- package/docs/api/REST_API.md +1237 -0
- package/docs/authentication.md +469 -0
- package/docs/authzLinid1.md +521 -0
- package/docs/authzPerBranch.md +596 -0
- package/docs/browser/LIBRARIES.md +1196 -0
- package/docs/examples/EXAMPLES.md +1659 -0
- package/docs/examples/twake-mailbox-type-nomenclature.ldif +37 -0
- package/docs/examples/twake-mailbox-type-schema-amendment.ldif +30 -0
- package/docs/jamesTeamMailboxes.md +343 -0
- package/docs/ldapBulkImport.md +722 -0
- package/docs/ldapExternalUsersInGroups.md +325 -0
- package/docs/ldapFlatGeneric.md +444 -0
- package/docs/ldapGroups.md +589 -0
- package/docs/ldapOrganizations.md +659 -0
- package/docs/ldapTrash.md +260 -0
- package/docs/linagora.png +0 -0
- package/docs/onChange.md +318 -0
- package/docs/plugins/DEVELOPMENT.md +1219 -0
- package/docs/presenterm-fr.md +721 -0
- package/docs/presenterm.md +721 -0
- package/docs/schemas/SCHEMAS.md +1212 -0
- package/docs/static.md +410 -0
- package/docs/twakeCalendarResources.md +148 -0
- package/docs/twakeJames.md +661 -0
- package/docs/weblogs.md +399 -0
- package/examples/web/ldap-group-editor.html +113 -0
- package/examples/web/ldap-tree-viewer.html +368 -0
- package/examples/web/ldap-unit-editor.html +108 -0
- package/examples/web/ldap-user-editor.html +412 -0
- package/package.json +458 -0
- package/static/browser/common-demo.css +450 -0
- package/static/browser/ldap-group-editor/LdapGroupEditor.js +207 -0
- package/static/browser/ldap-group-editor/LdapGroupEditor.js.map +1 -0
- package/static/browser/ldap-group-editor/api/GroupApiClient.js +112 -0
- package/static/browser/ldap-group-editor/api/GroupApiClient.js.map +1 -0
- package/static/browser/ldap-group-editor/components/CreateGroupModal.js +212 -0
- package/static/browser/ldap-group-editor/components/CreateGroupModal.js.map +1 -0
- package/static/browser/ldap-group-editor/components/GroupPropertyEditor.js +497 -0
- package/static/browser/ldap-group-editor/components/GroupPropertyEditor.js.map +1 -0
- package/static/browser/ldap-group-editor/components/GroupTree.js +153 -0
- package/static/browser/ldap-group-editor/components/GroupTree.js.map +1 -0
- package/static/browser/ldap-group-editor/components/MoveGroupModal.js +235 -0
- package/static/browser/ldap-group-editor/components/MoveGroupModal.js.map +1 -0
- package/static/browser/ldap-group-editor/index.js +2 -0
- package/static/browser/ldap-group-editor/index.js.map +1 -0
- package/static/browser/ldap-group-editor/types.js +2 -0
- package/static/browser/ldap-group-editor/types.js.map +1 -0
- package/static/browser/ldap-group-editor.esm.js +1399 -0
- package/static/browser/ldap-group-editor.esm.js.map +1 -0
- package/static/browser/ldap-group-editor.js +1407 -0
- package/static/browser/ldap-group-editor.js.map +1 -0
- package/static/browser/ldap-group-editor.min.js +2 -0
- package/static/browser/ldap-group-editor.min.js.map +1 -0
- package/static/browser/ldap-resource-editor/api/ResourceApiClient.js +226 -0
- package/static/browser/ldap-resource-editor/api/ResourceApiClient.js.map +1 -0
- package/static/browser/ldap-resource-editor/cache/CacheManager.js +123 -0
- package/static/browser/ldap-resource-editor/cache/CacheManager.js.map +1 -0
- package/static/browser/ldap-resource-editor/index.js +2 -0
- package/static/browser/ldap-resource-editor/index.js.map +1 -0
- package/static/browser/ldap-resource-editor/types.js +2 -0
- package/static/browser/ldap-resource-editor/types.js.map +1 -0
- package/static/browser/ldap-tree-viewer/LdapTreeViewer.js +187 -0
- package/static/browser/ldap-tree-viewer/LdapTreeViewer.js.map +1 -0
- package/static/browser/ldap-tree-viewer/api/LdapApiClient.js +50 -0
- package/static/browser/ldap-tree-viewer/api/LdapApiClient.js.map +1 -0
- package/static/browser/ldap-tree-viewer/components/TreeNode.js +140 -0
- package/static/browser/ldap-tree-viewer/components/TreeNode.js.map +1 -0
- package/static/browser/ldap-tree-viewer/components/TreeRoot.js +98 -0
- package/static/browser/ldap-tree-viewer/components/TreeRoot.js.map +1 -0
- package/static/browser/ldap-tree-viewer/index.js +2 -0
- package/static/browser/ldap-tree-viewer/index.js.map +1 -0
- package/static/browser/ldap-tree-viewer/store/Store.js +29 -0
- package/static/browser/ldap-tree-viewer/store/Store.js.map +1 -0
- package/static/browser/ldap-tree-viewer/store/actions.js +53 -0
- package/static/browser/ldap-tree-viewer/store/actions.js.map +1 -0
- package/static/browser/ldap-tree-viewer/store/reducers.js +79 -0
- package/static/browser/ldap-tree-viewer/store/reducers.js.map +1 -0
- package/static/browser/ldap-tree-viewer/types.js +2 -0
- package/static/browser/ldap-tree-viewer/types.js.map +1 -0
- package/static/browser/ldap-tree-viewer.css +2 -0
- package/static/browser/ldap-tree-viewer.css.map +1 -0
- package/static/browser/ldap-tree-viewer.esm.js +606 -0
- package/static/browser/ldap-tree-viewer.esm.js.map +1 -0
- package/static/browser/ldap-tree-viewer.js +614 -0
- package/static/browser/ldap-tree-viewer.js.map +1 -0
- package/static/browser/ldap-tree-viewer.min.js +2 -0
- package/static/browser/ldap-tree-viewer.min.js.map +1 -0
- package/static/browser/ldap-unit-editor/LdapUnitEditor.js +119 -0
- package/static/browser/ldap-unit-editor/LdapUnitEditor.js.map +1 -0
- package/static/browser/ldap-unit-editor/api/UnitApiClient.js +95 -0
- package/static/browser/ldap-unit-editor/api/UnitApiClient.js.map +1 -0
- package/static/browser/ldap-unit-editor/components/MoveUnitModal.js +295 -0
- package/static/browser/ldap-unit-editor/components/MoveUnitModal.js.map +1 -0
- package/static/browser/ldap-unit-editor/components/UnitPropertyEditor.js +321 -0
- package/static/browser/ldap-unit-editor/components/UnitPropertyEditor.js.map +1 -0
- package/static/browser/ldap-unit-editor/components/UnitTree.js +197 -0
- package/static/browser/ldap-unit-editor/components/UnitTree.js.map +1 -0
- package/static/browser/ldap-unit-editor/index.js +2 -0
- package/static/browser/ldap-unit-editor/index.js.map +1 -0
- package/static/browser/ldap-unit-editor/types.js +2 -0
- package/static/browser/ldap-unit-editor/types.js.map +1 -0
- package/static/browser/ldap-unit-editor.esm.js +1013 -0
- package/static/browser/ldap-unit-editor.esm.js.map +1 -0
- package/static/browser/ldap-unit-editor.js +1021 -0
- package/static/browser/ldap-unit-editor.js.map +1 -0
- package/static/browser/ldap-unit-editor.min.js +2 -0
- package/static/browser/ldap-unit-editor.min.js.map +1 -0
- package/static/browser/ldap-user-editor/LdapUserEditor.js +184 -0
- package/static/browser/ldap-user-editor/LdapUserEditor.js.map +1 -0
- package/static/browser/ldap-user-editor/api/UserApiClient.js +209 -0
- package/static/browser/ldap-user-editor/api/UserApiClient.js.map +1 -0
- package/static/browser/ldap-user-editor/cache/CacheManager.js +123 -0
- package/static/browser/ldap-user-editor/cache/CacheManager.js.map +1 -0
- package/static/browser/ldap-user-editor/components/MoveUserModal.js +302 -0
- package/static/browser/ldap-user-editor/components/MoveUserModal.js.map +1 -0
- package/static/browser/ldap-user-editor/components/PointerField.js +152 -0
- package/static/browser/ldap-user-editor/components/PointerField.js.map +1 -0
- package/static/browser/ldap-user-editor/components/UserEditor.js +608 -0
- package/static/browser/ldap-user-editor/components/UserEditor.js.map +1 -0
- package/static/browser/ldap-user-editor/components/UserList.js +181 -0
- package/static/browser/ldap-user-editor/components/UserList.js.map +1 -0
- package/static/browser/ldap-user-editor/components/UserTree.js +164 -0
- package/static/browser/ldap-user-editor/components/UserTree.js.map +1 -0
- package/static/browser/ldap-user-editor/index.js +2 -0
- package/static/browser/ldap-user-editor/index.js.map +1 -0
- package/static/browser/ldap-user-editor/types.js +2 -0
- package/static/browser/ldap-user-editor/types.js.map +1 -0
- package/static/browser/ldap-user-editor.css +2 -0
- package/static/browser/ldap-user-editor.css.map +1 -0
- package/static/browser/ldap-user-editor.esm.js +1897 -0
- package/static/browser/ldap-user-editor.esm.js.map +1 -0
- package/static/browser/ldap-user-editor.js +1905 -0
- package/static/browser/ldap-user-editor.js.map +1 -0
- package/static/browser/ldap-user-editor.min.js +2 -0
- package/static/browser/ldap-user-editor.min.js.map +1 -0
- package/static/browser/shared/components/Modal.js +121 -0
- package/static/browser/shared/components/Modal.js.map +1 -0
- package/static/browser/shared/components/StatusMessage.js +119 -0
- package/static/browser/shared/components/StatusMessage.js.map +1 -0
- package/static/browser/shared/index.js +7 -0
- package/static/browser/shared/index.js.map +1 -0
- package/static/browser/shared/types/index.js +37 -0
- package/static/browser/shared/types/index.js.map +1 -0
- package/static/browser/shared/utils/dom.js +78 -0
- package/static/browser/shared/utils/dom.js.map +1 -0
- package/static/browser/shared/utils/form.js +234 -0
- package/static/browser/shared/utils/form.js.map +1 -0
- package/static/browser/shared/utils/schema.js +121 -0
- package/static/browser/shared/utils/schema.js.map +1 -0
- package/static/browser/shared.esm.js +694 -0
- package/static/browser/shared.esm.js.map +1 -0
- package/static/browser/shared.js +723 -0
- package/static/browser/shared.js.map +1 -0
- package/static/browser/shared.min.js +2 -0
- package/static/browser/shared.min.js.map +1 -0
- package/static/schemas/ad/computers.json +92 -0
- package/static/schemas/ad/groups.json +55 -0
- package/static/schemas/ad/organizations.json +66 -0
- package/static/schemas/ad/users.json +116 -0
- package/static/schemas/standard/devices.json +72 -0
- package/static/schemas/standard/groups.json +54 -0
- package/static/schemas/standard/organizations.json +49 -0
- package/static/schemas/standard/users.json +86 -0
- package/static/schemas/twake/groups.json +75 -0
- package/static/schemas/twake/nomenclature/twakeAccountStatus.json +31 -0
- package/static/schemas/twake/nomenclature/twakeDeliveryMode.json +31 -0
- package/static/schemas/twake/nomenclature/twakeListType.json +31 -0
- package/static/schemas/twake/nomenclature/twakeMailboxType.json +31 -0
- package/static/schemas/twake/nomenclature/twakeTitle.json +31 -0
- package/static/schemas/twake/organizations.json +52 -0
- package/static/schemas/twake/positions.json +32 -0
- 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
|