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,128 @@
|
|
|
1
|
+
import type { AttributesList } from '../lib/ldapActions';
|
|
2
|
+
import type { ConfigTemplate } from '../lib/parseConfig';
|
|
3
|
+
export interface BranchPermissions {
|
|
4
|
+
read?: boolean;
|
|
5
|
+
write?: boolean;
|
|
6
|
+
delete?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface AuthConfig {
|
|
9
|
+
default?: BranchPermissions;
|
|
10
|
+
users?: {
|
|
11
|
+
[uid: string]: {
|
|
12
|
+
[branch: string]: BranchPermissions;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
groups?: {
|
|
16
|
+
[groupDn: string]: {
|
|
17
|
+
[branch: string]: BranchPermissions;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Typescript declaration of config
|
|
23
|
+
*
|
|
24
|
+
* See below for config arguments, corresponding environment variables,
|
|
25
|
+
* default value, type and optional plural name
|
|
26
|
+
*/
|
|
27
|
+
export interface Config {
|
|
28
|
+
port: number;
|
|
29
|
+
plugin?: string[];
|
|
30
|
+
schemas_path: string;
|
|
31
|
+
log_level: 'error' | 'warn' | 'notice' | 'info' | 'debug';
|
|
32
|
+
logger: 'console';
|
|
33
|
+
api_prefix: string;
|
|
34
|
+
mail_domain?: string[];
|
|
35
|
+
ldap_base?: string;
|
|
36
|
+
ldap_dn?: string;
|
|
37
|
+
ldap_pwd?: string;
|
|
38
|
+
ldap_url?: string;
|
|
39
|
+
ldap_user_main_attribute?: string;
|
|
40
|
+
ldap_cache_max?: number;
|
|
41
|
+
ldap_cache_ttl?: number;
|
|
42
|
+
ldap_pool_size?: number;
|
|
43
|
+
ldap_connection_ttl?: number;
|
|
44
|
+
user_class?: string[];
|
|
45
|
+
ldap_group_base?: string;
|
|
46
|
+
ldap_groups_main_attribute?: string;
|
|
47
|
+
group_class?: string[];
|
|
48
|
+
group_classes?: string[];
|
|
49
|
+
group_default_attributes?: AttributesList;
|
|
50
|
+
groups_allow_unexistent_members?: boolean;
|
|
51
|
+
group_dummy_user?: string;
|
|
52
|
+
group_schema?: string;
|
|
53
|
+
ldap_top_organization?: string;
|
|
54
|
+
ldap_organization_class?: string[];
|
|
55
|
+
ldap_organization_link_attribute?: string;
|
|
56
|
+
ldap_organization_path_attribute?: string;
|
|
57
|
+
ldap_organization_path_separator?: string;
|
|
58
|
+
ldap_organization_max_subnodes?: number;
|
|
59
|
+
organization_schema?: string;
|
|
60
|
+
ldap_flat_schema?: string[];
|
|
61
|
+
bulk_import_schemas?: string;
|
|
62
|
+
bulk_import_max_file_size?: string;
|
|
63
|
+
bulk_import_batch_size?: string;
|
|
64
|
+
external_members_branch?: string;
|
|
65
|
+
external_branch_class?: string[];
|
|
66
|
+
static_path?: string;
|
|
67
|
+
static_name?: string;
|
|
68
|
+
llng_ini?: string;
|
|
69
|
+
auth_token?: string[];
|
|
70
|
+
oidc_server?: string;
|
|
71
|
+
oidc_client_id?: string;
|
|
72
|
+
oidc_client_secret?: string;
|
|
73
|
+
base_url?: string;
|
|
74
|
+
authz_per_branch_config?: AuthConfig;
|
|
75
|
+
authz_per_branch_cache_ttl?: number;
|
|
76
|
+
authz_local_admin_attribute?: string;
|
|
77
|
+
rate_limit_window_ms?: number;
|
|
78
|
+
rate_limit_max?: number;
|
|
79
|
+
crowdsec_url?: string;
|
|
80
|
+
crowdsec_api_key?: string;
|
|
81
|
+
crowdsec_cache_ttl?: number;
|
|
82
|
+
mail_attribute?: string;
|
|
83
|
+
quota_attribute?: string;
|
|
84
|
+
delegation_attribute?: string;
|
|
85
|
+
alias_attribute?: string;
|
|
86
|
+
forward_attribute?: string;
|
|
87
|
+
display_name_attribute?: string;
|
|
88
|
+
james_webadmin_url?: string;
|
|
89
|
+
james_webadmin_token?: string;
|
|
90
|
+
james_signature_template?: string;
|
|
91
|
+
ldap_concurrency?: number;
|
|
92
|
+
james_concurrency?: number;
|
|
93
|
+
james_init_delay?: number;
|
|
94
|
+
james_mailing_list_branch?: string[];
|
|
95
|
+
james_mailbox_type_attribute?: string;
|
|
96
|
+
calendar_webadmin_url?: string;
|
|
97
|
+
calendar_webadmin_token?: string;
|
|
98
|
+
calendar_concurrency?: number;
|
|
99
|
+
calendar_resource_base?: string;
|
|
100
|
+
calendar_resource_objectclass?: string;
|
|
101
|
+
calendar_resource_creator?: string;
|
|
102
|
+
calendar_resource_domain?: string;
|
|
103
|
+
trash_base?: string;
|
|
104
|
+
trash_watched_bases?: string;
|
|
105
|
+
trash_add_metadata?: string;
|
|
106
|
+
trash_auto_create?: string;
|
|
107
|
+
[key: string]: string | string[] | boolean | number | AttributesList | AuthConfig | undefined;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Config arguments
|
|
111
|
+
*
|
|
112
|
+
* Format:
|
|
113
|
+
* [ command-line-option, env-variable, default-value, type?, plural? ]
|
|
114
|
+
*
|
|
115
|
+
* type can be one of:
|
|
116
|
+
* - string (default value)
|
|
117
|
+
* - boolean:
|
|
118
|
+
* * --option is enough
|
|
119
|
+
* * env variable must be set to "true" to be considered as truthy
|
|
120
|
+
* - number
|
|
121
|
+
* - json: parameter s a string that will be converted into an object during configuration parsing
|
|
122
|
+
*
|
|
123
|
+
* Additional command-line:
|
|
124
|
+
* to permit to non-core plugin to use command-line, all command-line pairs `--key-name value`
|
|
125
|
+
* are stored into config (string only) as `config.key_name = value`
|
|
126
|
+
*/
|
|
127
|
+
declare const configArgs: ConfigTemplate;
|
|
128
|
+
export default configArgs;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { AttributeValue } from '../lib/ldapActions';
|
|
2
|
+
export interface Schema {
|
|
3
|
+
strict: boolean;
|
|
4
|
+
attributes: {
|
|
5
|
+
[key: string]: {
|
|
6
|
+
type: 'string' | 'array' | 'pointer';
|
|
7
|
+
items?: {
|
|
8
|
+
type: string;
|
|
9
|
+
test?: string | RegExp;
|
|
10
|
+
};
|
|
11
|
+
default?: AttributeValue;
|
|
12
|
+
required?: boolean;
|
|
13
|
+
test?: string | RegExp;
|
|
14
|
+
branch?: string[];
|
|
15
|
+
fixed?: boolean;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for hooks
|
|
3
|
+
* @author Xavier Guimard <xguimard@linagora.com>
|
|
4
|
+
*/
|
|
5
|
+
import type { SearchOptions, SearchResult } from 'ldapts';
|
|
6
|
+
import type { Request, Response } from 'express';
|
|
7
|
+
import type { ModifyRequest, AttributesList } from './lib/ldapActions';
|
|
8
|
+
import type { ChangesToNotify } from './plugins/ldap/onChange';
|
|
9
|
+
import * as utils from './lib/utils';
|
|
10
|
+
export type MaybePromise<T> = Promise<T> | T;
|
|
11
|
+
export type ChainedHook<T> = (arg: T) => MaybePromise<T>;
|
|
12
|
+
export type VoidHook<T extends unknown[]> = (...args: T) => MaybePromise<void>;
|
|
13
|
+
export type OtherHook = Function;
|
|
14
|
+
export { utils };
|
|
15
|
+
/**
|
|
16
|
+
* All available hooks
|
|
17
|
+
*/
|
|
18
|
+
export interface Hooks {
|
|
19
|
+
/**
|
|
20
|
+
* Libraries
|
|
21
|
+
*/
|
|
22
|
+
ldapsearchopts?: ChainedHook<SearchOptions>;
|
|
23
|
+
ldapsearchrequest?: ChainedHook<[string, SearchOptions, Request?]>;
|
|
24
|
+
ldapsearchresult?: ChainedHook<SearchResult>;
|
|
25
|
+
ldapaddrequest?: ChainedHook<[string, AttributesList, Request?]>;
|
|
26
|
+
ldapadddone?: (args: [string, AttributesList]) => MaybePromise<void>;
|
|
27
|
+
ldapmodifyrequest?: ChainedHook<[string, ModifyRequest, number, Request?]>;
|
|
28
|
+
ldapmodifydone?: (args: [string, ModifyRequest, number]) => MaybePromise<void>;
|
|
29
|
+
ldapdeleterequest?: ChainedHook<string | string[]>;
|
|
30
|
+
ldapdeletedone?: (dn: string | string[]) => MaybePromise<void>;
|
|
31
|
+
ldaprenamerequest?: ChainedHook<[string, string, Request?]>;
|
|
32
|
+
ldaprenamedone?: (args: [string, string]) => MaybePromise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Plugins
|
|
35
|
+
*/
|
|
36
|
+
/** Demo plugin */
|
|
37
|
+
hello?: () => string;
|
|
38
|
+
/** LdapGroups plugin */
|
|
39
|
+
ldapgroupvalidatemembers?: ChainedHook<[string, string[]]>;
|
|
40
|
+
ldapgroupadd?: ChainedHook<[string, AttributesList]>;
|
|
41
|
+
ldapgroupadddone?: (args: [string, AttributesList]) => MaybePromise<void>;
|
|
42
|
+
ldapgroupmodify?: ChainedHook<[string, ModifyRequest, number]>;
|
|
43
|
+
ldapgroupmodifydone?: (args: [string, ModifyRequest, number]) => MaybePromise<void>;
|
|
44
|
+
ldapgroupdelete?: ChainedHook<string>;
|
|
45
|
+
ldapgroupdeletedone?: (dn: string) => MaybePromise<void>;
|
|
46
|
+
ldapgroupaddmember?: ChainedHook<[string, string[]]>;
|
|
47
|
+
ldapgroupdeletemember?: ChainedHook<[string, string[]]>;
|
|
48
|
+
_ldapgrouplist?: ChainedHook<AsyncGenerator<SearchResult>>;
|
|
49
|
+
/** "onLdapChange" */
|
|
50
|
+
onLdapChange?: (dn: string, changes: ChangesToNotify) => MaybePromise<void>;
|
|
51
|
+
onLdapMailChange?: (dn: string, oldMail: string, newMail: string) => MaybePromise<void>;
|
|
52
|
+
onLdapAliasChange?: (dn: string, mail: string, oldAliases: string[], newAliases: string[]) => MaybePromise<void>;
|
|
53
|
+
onLdapQuotaChange?: (dn: string, mail: string, oldQuota: number, newQuota: number) => MaybePromise<void>;
|
|
54
|
+
onLdapForwardChange?: (dn: string, mail: string, oldForwards: string[], newForwards: string[]) => MaybePromise<void>;
|
|
55
|
+
onLdapDisplayNameChange?: (dn: string, oldDisplayName: string | null, newDisplayName: string | null) => MaybePromise<void>;
|
|
56
|
+
/** externalUsersInGroup */
|
|
57
|
+
externaluserentry?: ChainedHook<[string, AttributesList]>;
|
|
58
|
+
externaluseradded?: (dn: string, mail: string) => MaybePromise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* Generic flat resource move hooks
|
|
61
|
+
* Pattern: {hookPrefix}move
|
|
62
|
+
* Examples: ldapusermove, ldappositionmove, etc.
|
|
63
|
+
*
|
|
64
|
+
* move: before moving - can modify target or cancel
|
|
65
|
+
* Note: After move, onLdapChange is triggered automatically by modifyEntry()
|
|
66
|
+
*/
|
|
67
|
+
[K: string]: ChainedHook<unknown> | VoidHook<unknown[]> | OtherHook | undefined;
|
|
68
|
+
/** Common authentication hooks */
|
|
69
|
+
beforeAuth?: ChainedHook<[Request, Response]>;
|
|
70
|
+
afterAuth?: ChainedHook<[Request, Response]>;
|
|
71
|
+
/** Organization hooks */
|
|
72
|
+
getOrganisationTop?: ChainedHook<[
|
|
73
|
+
Request | undefined,
|
|
74
|
+
AttributesList | null
|
|
75
|
+
]>;
|
|
76
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Express, Request, Response } from 'express';
|
|
2
|
+
export type DmRequest = Request & {
|
|
3
|
+
user?: string;
|
|
4
|
+
};
|
|
5
|
+
import DmPlugin from '../../abstract/plugin';
|
|
6
|
+
export default abstract class AuthBase extends DmPlugin {
|
|
7
|
+
abstract authMethod(req: DmRequest, res: Response, next: () => void): void;
|
|
8
|
+
api(app: Express): void;
|
|
9
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module lib/authz/base
|
|
3
|
+
* @author Xavier Guimard <xguimard@linagora.com>
|
|
4
|
+
*
|
|
5
|
+
* Base class for authorization plugins
|
|
6
|
+
* Provides common functionality for permission-based access control
|
|
7
|
+
* @group Libraries
|
|
8
|
+
*/
|
|
9
|
+
import type { SearchOptions } from 'ldapts';
|
|
10
|
+
import DmPlugin, { type Role } from '../../abstract/plugin';
|
|
11
|
+
import type { BranchPermissions } from '../../config/args';
|
|
12
|
+
import type { DmRequest } from '../auth/base';
|
|
13
|
+
import type { AttributesList, ModifyRequest } from '../ldapActions';
|
|
14
|
+
/**
|
|
15
|
+
* Abstract base class for authorization plugins
|
|
16
|
+
* Provides common utility methods and interface for LDAP-based authorization
|
|
17
|
+
*/
|
|
18
|
+
export default abstract class AuthzBase extends DmPlugin {
|
|
19
|
+
roles: Role[];
|
|
20
|
+
cacheTTL: number;
|
|
21
|
+
/**
|
|
22
|
+
* Extract the branch DN to check permissions against
|
|
23
|
+
* For a DN like "uid=user,ou=users,ou=org,dc=example,dc=com"
|
|
24
|
+
* we need to check permissions on the parent branch
|
|
25
|
+
*
|
|
26
|
+
* Handles escaped commas in DN values (e.g., "cn=Smith\, John")
|
|
27
|
+
*/
|
|
28
|
+
extractBranchDn(dn: string): string;
|
|
29
|
+
/**
|
|
30
|
+
* Resolve user identifier to the format expected by getUserPermissions
|
|
31
|
+
* This allows different implementations:
|
|
32
|
+
* - authzLinid1: converts uid to userDn via LDAP
|
|
33
|
+
* - authzPerBranch: uses uid directly
|
|
34
|
+
*
|
|
35
|
+
* Returns null if user cannot be resolved (will skip authorization)
|
|
36
|
+
*/
|
|
37
|
+
abstract resolveUser(uid: string): Promise<string | null>;
|
|
38
|
+
/**
|
|
39
|
+
* Get user's permissions for a specific branch
|
|
40
|
+
* Must be implemented by subclasses
|
|
41
|
+
*/
|
|
42
|
+
abstract getUserPermissions(user: string, branch: string): Promise<BranchPermissions>;
|
|
43
|
+
/**
|
|
44
|
+
* Get list of branches user has access to (for read permission by default)
|
|
45
|
+
* Must be implemented by subclasses
|
|
46
|
+
*/
|
|
47
|
+
abstract getAuthorizedBranches(user: string): Promise<string[]>;
|
|
48
|
+
/**
|
|
49
|
+
* Check if authorization should be skipped for this request
|
|
50
|
+
* Can be overridden by subclasses for custom logic
|
|
51
|
+
*/
|
|
52
|
+
protected shouldSkipAuthorization(req?: DmRequest): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Common hooks for all authorization plugins
|
|
55
|
+
*/
|
|
56
|
+
hooks: {
|
|
57
|
+
ldapmodifyrequest: ([dn, changes, opNumber, req]: [string, ModifyRequest, number, DmRequest?]) => Promise<[string, ModifyRequest, number, DmRequest?]>;
|
|
58
|
+
ldapaddrequest: ([dn, entry, req]: [string, AttributesList, DmRequest?]) => Promise<[string, AttributesList, DmRequest?]>;
|
|
59
|
+
ldapsearchrequest: ([base, opts, req]: [string, SearchOptions, DmRequest?]) => Promise<[string, SearchOptions, DmRequest?]>;
|
|
60
|
+
getOrganisationTop: ([req, defaultTop]: [DmRequest | undefined, AttributesList | null]) => Promise<[DmRequest | undefined, AttributesList | null]>;
|
|
61
|
+
ldaprenamerequest: ([oldDn, newDn, req]: [string, string, DmRequest?]) => Promise<[string, string, DmRequest?]>;
|
|
62
|
+
};
|
|
63
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standard express responses and express utilities
|
|
3
|
+
* @author Xavier Guimard <xguimard@linagora.com>
|
|
4
|
+
*/
|
|
5
|
+
import type { Request, Response } from 'express';
|
|
6
|
+
import type winston from 'winston';
|
|
7
|
+
export declare const setLogger: (logger: winston.Logger) => void;
|
|
8
|
+
export declare const getLogger: () => winston.Logger;
|
|
9
|
+
export declare const tryMethod: (res: Response, method: Function, ...args: unknown[]) => Promise<void>;
|
|
10
|
+
export declare const tryMethodData: (res: Response, method: Function, ...args: unknown[]) => Promise<void>;
|
|
11
|
+
export declare const ok: (res: Response, data?: object) => void;
|
|
12
|
+
export declare const created: (res: Response, data?: object) => void;
|
|
13
|
+
export declare const noContent: (res: Response) => void;
|
|
14
|
+
export declare const badRequest: (res: Response, message?: string) => void;
|
|
15
|
+
export declare const unauthorized: (res: Response, message?: string) => void;
|
|
16
|
+
export declare const forbidden: (res: Response, message?: string) => void;
|
|
17
|
+
export declare const notFound: (res: Response, message?: string) => void;
|
|
18
|
+
export declare const conflict: (res: Response, message?: string) => void;
|
|
19
|
+
export declare const uriTooLong: (res: Response, message?: string) => void;
|
|
20
|
+
export declare const tooManyRequests: (res: Response, message?: string) => void;
|
|
21
|
+
export declare const serverError: (res: Response, err: unknown) => void;
|
|
22
|
+
export declare const badGateway: (res: Response, message?: string) => void;
|
|
23
|
+
export declare const serviceUnavailable: (res: Response, message?: string) => void;
|
|
24
|
+
export declare const gatewayTimeout: (res: Response, message?: string) => void;
|
|
25
|
+
export declare const wantJson: (req: Request, res: Response) => boolean;
|
|
26
|
+
export declare const jsonBody: (req: Request, res: Response, ...requiredFields: string[]) => object | false;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LDAP low-level library
|
|
3
|
+
* @author Xavier Guimard <xguimard@linagora.com>
|
|
4
|
+
*/
|
|
5
|
+
import type { Request } from 'express';
|
|
6
|
+
import { Client } from 'ldapts';
|
|
7
|
+
import type { ClientOptions, SearchResult, SearchOptions } from 'ldapts';
|
|
8
|
+
import type winston from 'winston';
|
|
9
|
+
import pLimit from 'p-limit';
|
|
10
|
+
import { type Config } from '../config/args';
|
|
11
|
+
import { type DM } from '../bin';
|
|
12
|
+
export type AttributeValue = Buffer | Buffer[] | string[] | string;
|
|
13
|
+
export type AttributesList = Record<string, AttributeValue>;
|
|
14
|
+
export type LdapList = Record<string, AttributesList>;
|
|
15
|
+
export type { SearchOptions, SearchResult };
|
|
16
|
+
export interface ModifyRequest {
|
|
17
|
+
add?: AttributesList;
|
|
18
|
+
replace?: AttributesList;
|
|
19
|
+
delete?: string[] | AttributesList;
|
|
20
|
+
}
|
|
21
|
+
declare class ldapActions {
|
|
22
|
+
config: Config;
|
|
23
|
+
options: ClientOptions;
|
|
24
|
+
dn: string;
|
|
25
|
+
pwd: string;
|
|
26
|
+
base: string;
|
|
27
|
+
parent: DM;
|
|
28
|
+
logger: winston.Logger;
|
|
29
|
+
private searchCache;
|
|
30
|
+
queryLimit: ReturnType<typeof pLimit>;
|
|
31
|
+
private connectionPool;
|
|
32
|
+
private poolSize;
|
|
33
|
+
private connectionTtl;
|
|
34
|
+
constructor(server: DM);
|
|
35
|
+
/**
|
|
36
|
+
* Create a new LDAP connection
|
|
37
|
+
*/
|
|
38
|
+
private createConnection;
|
|
39
|
+
/**
|
|
40
|
+
* Clean up expired connections from the pool
|
|
41
|
+
*/
|
|
42
|
+
private cleanupExpiredConnections;
|
|
43
|
+
/**
|
|
44
|
+
* Acquire a connection from the pool or create a new one
|
|
45
|
+
*/
|
|
46
|
+
private acquireConnection;
|
|
47
|
+
/**
|
|
48
|
+
* Release a connection back to the pool
|
|
49
|
+
*/
|
|
50
|
+
private releaseConnection;
|
|
51
|
+
/**
|
|
52
|
+
* Legacy connect method for backward compatibility
|
|
53
|
+
* @deprecated Use acquireConnection/releaseConnection instead
|
|
54
|
+
*/
|
|
55
|
+
connect(): Promise<Client>;
|
|
56
|
+
/**
|
|
57
|
+
* Generate cache key for LDAP search
|
|
58
|
+
*/
|
|
59
|
+
private getCacheKey;
|
|
60
|
+
/**
|
|
61
|
+
* Invalidate cache entries for a specific DN
|
|
62
|
+
* Called after modifications to ensure cache consistency
|
|
63
|
+
*/
|
|
64
|
+
invalidateCache(dn: string): void;
|
|
65
|
+
search(options: SearchOptions, base?: string, req?: Request): Promise<SearchResult | AsyncGenerator<SearchResult>>;
|
|
66
|
+
/**
|
|
67
|
+
* Wrap paginated search to ensure connection is released when done
|
|
68
|
+
*/
|
|
69
|
+
private wrapPaginatedSearch;
|
|
70
|
+
add(dn: string, entry: AttributesList, req?: Request): Promise<boolean>;
|
|
71
|
+
modify(dn: string, changes: ModifyRequest, req?: Request): Promise<boolean>;
|
|
72
|
+
rename(dn: string, newRdn: string, req?: Request): Promise<boolean>;
|
|
73
|
+
/**
|
|
74
|
+
* Move an entry to a new location (different parent)
|
|
75
|
+
* Uses LDAP modifyDN with full DN to change both RDN and parent
|
|
76
|
+
*
|
|
77
|
+
* Note: ldapts provides a high-level API that accepts a full DN as the second parameter,
|
|
78
|
+
* unlike the standard LDAP modifyDN which expects (newRDN, deleteOldRDN, newSuperior).
|
|
79
|
+
* ldapts automatically parses the full DN and extracts the newRDN and newSuperior components
|
|
80
|
+
* before sending the proper LDAP modifyDN request to the server.
|
|
81
|
+
*
|
|
82
|
+
* @param dn - Current DN (e.g., "uid=user1,ou=users,dc=example,dc=com")
|
|
83
|
+
* @param newDn - Full new DN (e.g., "uid=user1,ou=trash,dc=example,dc=com")
|
|
84
|
+
* ldapts will extract newRDN="uid=user1" and newSuperior="ou=trash,dc=example,dc=com"
|
|
85
|
+
*/
|
|
86
|
+
move(dn: string, newDn: string): Promise<boolean>;
|
|
87
|
+
delete(dn: string | string[]): Promise<boolean>;
|
|
88
|
+
private setDn;
|
|
89
|
+
opNumber(): number;
|
|
90
|
+
}
|
|
91
|
+
export default ldapActions;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration parser
|
|
3
|
+
* Order: default < env < cli
|
|
4
|
+
* @author Xavier Guimard <xguimard@linagora.com>
|
|
5
|
+
*/
|
|
6
|
+
import type { Config } from '../config/args';
|
|
7
|
+
export type ConfigTemplate = ConfigEntry[];
|
|
8
|
+
export type ConfigEntry = [
|
|
9
|
+
string,
|
|
10
|
+
string,
|
|
11
|
+
// env value
|
|
12
|
+
string | string[] | boolean | number | Record<string, any>,
|
|
13
|
+
('string' | 'number' | 'boolean' | 'array' | 'json' | null | undefined)?,
|
|
14
|
+
(string | null | undefined)?
|
|
15
|
+
];
|
|
16
|
+
export declare class ConfigParser {
|
|
17
|
+
private config;
|
|
18
|
+
constructor(config: ConfigTemplate);
|
|
19
|
+
parse(argv?: string[]): Config;
|
|
20
|
+
private parseCliArgs;
|
|
21
|
+
private getKeyFromCliArg;
|
|
22
|
+
}
|
|
23
|
+
export declare function parseConfig(config: ConfigEntry[], argv?: string[]): Config;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions
|
|
3
|
+
* @author Xavier Guimard <xguimard@linagora.com>
|
|
4
|
+
*/
|
|
5
|
+
import type { Config } from '../bin';
|
|
6
|
+
export declare const launchHooks: (hooks: Function[] | undefined, ...args: unknown[]) => Promise<void>;
|
|
7
|
+
export declare const launchHooksChained: <T>(hooks: Function[] | undefined, args: T) => Promise<T>;
|
|
8
|
+
export declare const transformSchemas: (schemas: string | Buffer, config: Config) => string;
|
|
9
|
+
/**
|
|
10
|
+
* Parse a Distinguished Name (DN) into its component parts (RDNs)
|
|
11
|
+
* Handles escaped commas and other special characters
|
|
12
|
+
*
|
|
13
|
+
* @param dn - The DN to parse
|
|
14
|
+
* @returns Array of RDN components
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* parseDn('uid=user,ou=users,dc=example,dc=com')
|
|
19
|
+
* // => ['uid=user', 'ou=users', 'dc=example', 'dc=com']
|
|
20
|
+
*
|
|
21
|
+
* parseDn('cn=Smith\\, John,ou=users,dc=example,dc=com')
|
|
22
|
+
* // => ['cn=Smith\\, John', 'ou=users', 'dc=example', 'dc=com']
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare function parseDn(dn: string): string[];
|
|
26
|
+
/**
|
|
27
|
+
* Extract the parent DN from a DN
|
|
28
|
+
* Removes the first RDN component to get the parent branch
|
|
29
|
+
*
|
|
30
|
+
* @param dn - The DN to extract parent from
|
|
31
|
+
* @returns The parent DN, or the original DN if it has no parent
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```typescript
|
|
35
|
+
* getParentDn('uid=user,ou=users,dc=example,dc=com')
|
|
36
|
+
* // => 'ou=users,dc=example,dc=com'
|
|
37
|
+
*
|
|
38
|
+
* getParentDn('dc=com')
|
|
39
|
+
* // => 'dc=com'
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export declare function getParentDn(dn: string): string;
|
|
43
|
+
/**
|
|
44
|
+
* Extract the RDN (Relative Distinguished Name) from a DN
|
|
45
|
+
* Returns the first component of the DN
|
|
46
|
+
*
|
|
47
|
+
* @param dn - The DN to extract RDN from
|
|
48
|
+
* @returns The RDN component
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* getRdn('uid=user,ou=users,dc=example,dc=com')
|
|
53
|
+
* // => 'uid=user'
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export declare function getRdn(dn: string): string;
|
|
57
|
+
/**
|
|
58
|
+
* Check if a DN is a child of another DN
|
|
59
|
+
*
|
|
60
|
+
* @param dn - The DN to check
|
|
61
|
+
* @param parentDn - The potential parent DN
|
|
62
|
+
* @returns True if dn is a child of parentDn
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* isChildOf('uid=user,ou=users,dc=example,dc=com', 'ou=users,dc=example,dc=com')
|
|
67
|
+
* // => true
|
|
68
|
+
*
|
|
69
|
+
* isChildOf('uid=user,ou=users,dc=example,dc=com', 'ou=groups,dc=example,dc=com')
|
|
70
|
+
* // => false
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
export declare function isChildOf(dn: string, parentDn: string): boolean;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module plugins/auth/authzLinid1
|
|
3
|
+
* @author Xavier Guimard <xguimard@linagora.com>
|
|
4
|
+
*
|
|
5
|
+
* Authorization plugin based on twakeLocalAdminLink LDAP attribute
|
|
6
|
+
* Grants permissions to users referenced in organization's twakeLocalAdminLink
|
|
7
|
+
* @group Plugins
|
|
8
|
+
*/
|
|
9
|
+
import type { DM } from '../../bin';
|
|
10
|
+
import type { BranchPermissions } from '../../config/args';
|
|
11
|
+
import AuthzBase from '../../lib/authz/base';
|
|
12
|
+
interface CachedPermissions {
|
|
13
|
+
branches: Map<string, BranchPermissions>;
|
|
14
|
+
timestamp: number;
|
|
15
|
+
}
|
|
16
|
+
export default class AuthzLinid1 extends AuthzBase {
|
|
17
|
+
name: string;
|
|
18
|
+
permissionsCache: Map<string, CachedPermissions>;
|
|
19
|
+
constructor(server: DM);
|
|
20
|
+
/**
|
|
21
|
+
* Resolve user - for authzLinid1, convert uid to userDn via LDAP
|
|
22
|
+
*/
|
|
23
|
+
resolveUser(uid: string): Promise<string | null>;
|
|
24
|
+
/**
|
|
25
|
+
* Get user DN from uid
|
|
26
|
+
*/
|
|
27
|
+
getUserDn(uid: string): Promise<string | null>;
|
|
28
|
+
/**
|
|
29
|
+
* Get user's permissions for a specific branch
|
|
30
|
+
* Searches LDAP for organizations with twakeLocalAdminLink containing the user's DN
|
|
31
|
+
*/
|
|
32
|
+
getUserPermissions(userDn: string, branch: string): Promise<BranchPermissions>;
|
|
33
|
+
/**
|
|
34
|
+
* Refresh user permissions from LDAP
|
|
35
|
+
*/
|
|
36
|
+
refreshUserPermissions(userDn: string): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Get list of branches user has access to
|
|
39
|
+
*/
|
|
40
|
+
getAuthorizedBranches(userDn: string): Promise<string[]>;
|
|
41
|
+
/**
|
|
42
|
+
* Find permissions for a branch (supports sub-branch matching)
|
|
43
|
+
*/
|
|
44
|
+
private findBranchPermissions;
|
|
45
|
+
}
|
|
46
|
+
export {};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module plugins/auth/authzPerBranch
|
|
3
|
+
* @author Xavier Guimard <xguimard@linagora.com>
|
|
4
|
+
*
|
|
5
|
+
* Authorization plugin that restricts LDAP access by branch
|
|
6
|
+
* Supports user and group-based permissions with configurable defaults
|
|
7
|
+
* @group Plugins
|
|
8
|
+
*/
|
|
9
|
+
import type { DM } from '../../bin';
|
|
10
|
+
import type { AuthConfig, BranchPermissions } from '../../config/args';
|
|
11
|
+
import type { DmRequest } from '../../lib/auth/base';
|
|
12
|
+
import AuthzBase from '../../lib/authz/base';
|
|
13
|
+
interface CachedGroups {
|
|
14
|
+
groups: string[];
|
|
15
|
+
timestamp: number;
|
|
16
|
+
}
|
|
17
|
+
export default class AuthzPerBranch extends AuthzBase {
|
|
18
|
+
name: string;
|
|
19
|
+
authConfig?: AuthConfig;
|
|
20
|
+
groupCache: Map<string, CachedGroups>;
|
|
21
|
+
constructor(server: DM);
|
|
22
|
+
/**
|
|
23
|
+
* Resolve user - for authzPerBranch, we use uid directly
|
|
24
|
+
*/
|
|
25
|
+
resolveUser(uid: string): Promise<string | null>;
|
|
26
|
+
/**
|
|
27
|
+
* Override to add authConfig check
|
|
28
|
+
*/
|
|
29
|
+
protected shouldSkipAuthorization(req?: DmRequest): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Get user's permissions for a specific branch
|
|
32
|
+
*/
|
|
33
|
+
getUserPermissions(uid: string, branch: string): Promise<BranchPermissions>;
|
|
34
|
+
/**
|
|
35
|
+
* Get list of branches user has read access to (base class implementation)
|
|
36
|
+
*/
|
|
37
|
+
getAuthorizedBranches(uid: string): Promise<string[]>;
|
|
38
|
+
/**
|
|
39
|
+
* Get list of branches user has access to for a given permission type
|
|
40
|
+
*/
|
|
41
|
+
getAuthorizedBranchesForPermission(uid: string, permissionType: 'read' | 'write' | 'delete'): Promise<string[]>;
|
|
42
|
+
/**
|
|
43
|
+
* Find permissions for a branch (supports sub-branch matching)
|
|
44
|
+
*/
|
|
45
|
+
private findBranchPermissions;
|
|
46
|
+
/**
|
|
47
|
+
* Merge permissions (OR logic - grant if any source grants)
|
|
48
|
+
*/
|
|
49
|
+
private mergePermissions;
|
|
50
|
+
/**
|
|
51
|
+
* Build LDAP filter for authorized branches
|
|
52
|
+
*/
|
|
53
|
+
private buildBranchFilter;
|
|
54
|
+
/**
|
|
55
|
+
* Get user's group memberships with caching
|
|
56
|
+
*/
|
|
57
|
+
getUserGroups(uid: string): Promise<string[]>;
|
|
58
|
+
}
|
|
59
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module core/auth/crowdsec
|
|
3
|
+
* CrowdSec integration plugin to block banned IPs
|
|
4
|
+
*
|
|
5
|
+
* This plugin integrates with CrowdSec Local API to check if incoming
|
|
6
|
+
* requests are from IPs with active ban decisions. It should be loaded
|
|
7
|
+
* BEFORE authentication plugins to block malicious IPs early.
|
|
8
|
+
*
|
|
9
|
+
* Configuration:
|
|
10
|
+
* - crowdsec_url: CrowdSec Local API URL (default: http://localhost:8080)
|
|
11
|
+
* - crowdsec_api_key: API key for bouncer authentication (required)
|
|
12
|
+
* - crowdsec_cache_ttl: Cache TTL in seconds for decisions (default: 60)
|
|
13
|
+
*
|
|
14
|
+
* @author Xavier Guimard <xguimard@linagora.com>
|
|
15
|
+
*/
|
|
16
|
+
import type { Express } from 'express';
|
|
17
|
+
import DmPlugin, { Role } from '../../abstract/plugin';
|
|
18
|
+
export default class CrowdSec extends DmPlugin {
|
|
19
|
+
name: string;
|
|
20
|
+
roles: Role[];
|
|
21
|
+
private apiUrl;
|
|
22
|
+
private apiKey;
|
|
23
|
+
private cacheTtl;
|
|
24
|
+
private cache;
|
|
25
|
+
constructor(...args: ConstructorParameters<typeof DmPlugin>);
|
|
26
|
+
api(app: Express): void;
|
|
27
|
+
private checkIpBanned;
|
|
28
|
+
private getClientIp;
|
|
29
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Response } from 'express';
|
|
2
|
+
import AuthBase, { DmRequest } from '../../lib/auth/base';
|
|
3
|
+
import type { Role } from '../../abstract/plugin';
|
|
4
|
+
export default class AuthLLNG extends AuthBase {
|
|
5
|
+
name: string;
|
|
6
|
+
roles: Role[];
|
|
7
|
+
authMethod(req: DmRequest, res: Response, next: () => void): void;
|
|
8
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Express, Response } from 'express';
|
|
2
|
+
import { DmRequest } from '../../lib/auth/base';
|
|
3
|
+
import DmPlugin, { type Role } from '../../abstract/plugin';
|
|
4
|
+
import { DM } from '../../bin';
|
|
5
|
+
export default class OpenIDConnect extends DmPlugin {
|
|
6
|
+
name: string;
|
|
7
|
+
roles: Role[];
|
|
8
|
+
constructor(server: DM);
|
|
9
|
+
api(app: Express): void;
|
|
10
|
+
authMethod(req: DmRequest, res: Response, next: () => void): void;
|
|
11
|
+
}
|