ldap-rest 0.2.2 → 0.3.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/README.md +1 -1
- package/dist/abstract/ldapFlat.js +1 -1
- package/dist/bin/index.js +1 -1
- package/dist/config/args.js +1 -1
- package/dist/lib/expressFormatedResponses.js +1 -1
- package/dist/plugins/auth/authzDynamic.js +1 -0
- package/dist/plugins/auth/authzDynamicHash.js +1 -0
- package/dist/plugins/ldap/organization.js +1 -1
- package/dist/plugins/ldap/organizations.js +1 -0
- package/dist/plugins/scim/baseResolver.js +1 -0
- package/dist/plugins/scim/bulk.js +1 -0
- package/dist/plugins/scim/discovery.js +1 -0
- package/dist/plugins/scim/errors.js +1 -0
- package/dist/plugins/scim/filter.js +1 -0
- package/dist/plugins/scim/groups.js +1 -0
- package/dist/plugins/scim/mapping.js +1 -0
- package/dist/plugins/scim/patch.js +1 -0
- package/dist/plugins/scim/scim.js +1 -0
- package/dist/plugins/scim/types.js +1 -0
- package/dist/plugins/scim/users.js +1 -0
- package/dist/src/abstract/ldapFlat.d.ts +127 -0
- package/dist/src/config/args.d.ts +24 -0
- package/dist/src/plugins/auth/authzDynamic.d.ts +117 -0
- package/dist/src/plugins/auth/authzDynamicHash.d.ts +27 -0
- package/dist/src/plugins/configApi.d.ts +51 -0
- package/dist/src/plugins/demo/helloworld.d.ts +21 -0
- package/dist/src/plugins/ldap/bulkImport.d.ts +65 -0
- package/dist/src/plugins/ldap/groups.d.ts +68 -0
- package/dist/src/plugins/ldap/organization.d.ts +8 -65
- package/dist/src/plugins/ldap/organizations.d.ts +155 -0
- package/dist/src/plugins/ldap/passwordPolicy.d.ts +178 -0
- package/dist/src/plugins/scim/baseResolver.d.ts +23 -0
- package/dist/src/plugins/scim/bulk.d.ts +43 -0
- package/dist/src/plugins/scim/discovery.d.ts +27 -0
- package/dist/src/plugins/scim/errors.d.ts +37 -0
- package/dist/src/plugins/scim/filter.d.ts +13 -0
- package/dist/src/plugins/scim/groups.d.ts +61 -0
- package/dist/src/plugins/scim/mapping.d.ts +52 -0
- package/dist/src/plugins/scim/patch.d.ts +39 -0
- package/dist/src/plugins/scim/scim.d.ts +412 -0
- package/dist/src/plugins/scim/types.d.ts +222 -0
- package/dist/src/plugins/scim/users.d.ts +58 -0
- package/dist/src/plugins/static.d.ts +33 -0
- package/dist/src/plugins/twake/appAccountsApi.d.ts +63 -0
- package/dist/src/plugins/twake/james.d.ts +47 -0
- package/docs/plugin-development/README.md +2 -1
- package/docs/plugin-development/openapi.md +144 -0
- package/docs/usage/plugins/auth/authz-dynamic.md +183 -0
- package/docs/usage/plugins/integrations/scim.md +567 -0
- package/package.json +72 -1
- package/static/schemas/scim/Group.json +31 -0
- package/static/schemas/scim/User.json +147 -0
- package/static/schemas/scim/default-mapping.json +48 -0
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
import type { Express } from 'express';
|
|
2
|
+
import DmPlugin, { type Role } from '../../abstract/plugin';
|
|
3
|
+
import type { DM } from '../../bin';
|
|
4
|
+
import type ldapActions from '../../lib/ldapActions';
|
|
5
|
+
import { writeScimErrorFromException } from './errors';
|
|
6
|
+
/**
|
|
7
|
+
* Reusable SCIM 2.0 schemas surfaced by this plugin.
|
|
8
|
+
* Picked up by scripts/generate-openapi.ts and merged into `components.schemas`.
|
|
9
|
+
*
|
|
10
|
+
* @openapi-component
|
|
11
|
+
* ScimUser:
|
|
12
|
+
* type: object
|
|
13
|
+
* description: |
|
|
14
|
+
* SCIM 2.0 User resource (RFC 7643 §4.1).
|
|
15
|
+
* required: [schemas, userName]
|
|
16
|
+
* properties:
|
|
17
|
+
* schemas:
|
|
18
|
+
* type: array
|
|
19
|
+
* items: { type: string }
|
|
20
|
+
* example: ['urn:ietf:params:scim:schemas:core:2.0:User']
|
|
21
|
+
* id:
|
|
22
|
+
* type: string
|
|
23
|
+
* description: Opaque server-assigned identifier.
|
|
24
|
+
* example: 2819c223-7f76-453a-919d-413861904646
|
|
25
|
+
* externalId:
|
|
26
|
+
* type: string
|
|
27
|
+
* description: Provisioner-assigned identifier.
|
|
28
|
+
* example: 701984
|
|
29
|
+
* userName:
|
|
30
|
+
* type: string
|
|
31
|
+
* description: Unique user identifier (login name).
|
|
32
|
+
* example: bjensen
|
|
33
|
+
* name:
|
|
34
|
+
* type: object
|
|
35
|
+
* properties:
|
|
36
|
+
* formatted: { type: string, example: Ms. Barbara J Jensen III }
|
|
37
|
+
* familyName: { type: string, example: Jensen }
|
|
38
|
+
* givenName: { type: string, example: Barbara }
|
|
39
|
+
* middleName: { type: string, example: Jane }
|
|
40
|
+
* honorificPrefix: { type: string, example: Ms. }
|
|
41
|
+
* honorificSuffix: { type: string, example: III }
|
|
42
|
+
* displayName:
|
|
43
|
+
* type: string
|
|
44
|
+
* example: Babs Jensen
|
|
45
|
+
* nickName:
|
|
46
|
+
* type: string
|
|
47
|
+
* example: Babs
|
|
48
|
+
* profileUrl:
|
|
49
|
+
* type: string
|
|
50
|
+
* example: https://login.example.com/bjensen
|
|
51
|
+
* title:
|
|
52
|
+
* type: string
|
|
53
|
+
* example: Tour Guide
|
|
54
|
+
* userType:
|
|
55
|
+
* type: string
|
|
56
|
+
* example: Employee
|
|
57
|
+
* preferredLanguage:
|
|
58
|
+
* type: string
|
|
59
|
+
* example: en-US
|
|
60
|
+
* locale:
|
|
61
|
+
* type: string
|
|
62
|
+
* example: en-US
|
|
63
|
+
* timezone:
|
|
64
|
+
* type: string
|
|
65
|
+
* example: America/Los_Angeles
|
|
66
|
+
* active:
|
|
67
|
+
* type: boolean
|
|
68
|
+
* example: true
|
|
69
|
+
* emails:
|
|
70
|
+
* type: array
|
|
71
|
+
* items:
|
|
72
|
+
* type: object
|
|
73
|
+
* properties:
|
|
74
|
+
* value: { type: string }
|
|
75
|
+
* display: { type: string }
|
|
76
|
+
* type: { type: string }
|
|
77
|
+
* primary: { type: boolean }
|
|
78
|
+
* example:
|
|
79
|
+
* - value: bjensen@example.com
|
|
80
|
+
* type: work
|
|
81
|
+
* primary: true
|
|
82
|
+
* phoneNumbers:
|
|
83
|
+
* type: array
|
|
84
|
+
* items:
|
|
85
|
+
* type: object
|
|
86
|
+
* properties:
|
|
87
|
+
* value: { type: string }
|
|
88
|
+
* type: { type: string }
|
|
89
|
+
* primary: { type: boolean }
|
|
90
|
+
* addresses:
|
|
91
|
+
* type: array
|
|
92
|
+
* items:
|
|
93
|
+
* type: object
|
|
94
|
+
* properties:
|
|
95
|
+
* streetAddress: { type: string }
|
|
96
|
+
* locality: { type: string }
|
|
97
|
+
* region: { type: string }
|
|
98
|
+
* postalCode: { type: string }
|
|
99
|
+
* country: { type: string }
|
|
100
|
+
* type: { type: string }
|
|
101
|
+
* primary: { type: boolean }
|
|
102
|
+
* groups:
|
|
103
|
+
* type: array
|
|
104
|
+
* description: Groups the user belongs to (read-only).
|
|
105
|
+
* items:
|
|
106
|
+
* type: object
|
|
107
|
+
* properties:
|
|
108
|
+
* value: { type: string }
|
|
109
|
+
* $ref: { type: string }
|
|
110
|
+
* display: { type: string }
|
|
111
|
+
* meta:
|
|
112
|
+
* type: object
|
|
113
|
+
* properties:
|
|
114
|
+
* resourceType: { type: string, example: User }
|
|
115
|
+
* created: { type: string, format: date-time }
|
|
116
|
+
* lastModified: { type: string, format: date-time }
|
|
117
|
+
* location: { type: string }
|
|
118
|
+
* version: { type: string }
|
|
119
|
+
* ScimGroup:
|
|
120
|
+
* type: object
|
|
121
|
+
* description: |
|
|
122
|
+
* SCIM 2.0 Group resource (RFC 7643 §4.2).
|
|
123
|
+
* required: [schemas, displayName]
|
|
124
|
+
* properties:
|
|
125
|
+
* schemas:
|
|
126
|
+
* type: array
|
|
127
|
+
* items: { type: string }
|
|
128
|
+
* example: ['urn:ietf:params:scim:schemas:core:2.0:Group']
|
|
129
|
+
* id:
|
|
130
|
+
* type: string
|
|
131
|
+
* description: Opaque server-assigned identifier.
|
|
132
|
+
* example: e9e30dba-f08f-4109-8486-d5c6a331660a
|
|
133
|
+
* externalId:
|
|
134
|
+
* type: string
|
|
135
|
+
* example: 00g1emaKYZTWRINFRGETl
|
|
136
|
+
* displayName:
|
|
137
|
+
* type: string
|
|
138
|
+
* example: Tour Guides
|
|
139
|
+
* members:
|
|
140
|
+
* type: array
|
|
141
|
+
* description: Members of the group.
|
|
142
|
+
* items:
|
|
143
|
+
* type: object
|
|
144
|
+
* properties:
|
|
145
|
+
* value: { type: string, description: User or Group id }
|
|
146
|
+
* $ref: { type: string }
|
|
147
|
+
* display: { type: string }
|
|
148
|
+
* example:
|
|
149
|
+
* - value: 2819c223-7f76-453a-919d-413861904646
|
|
150
|
+
* display: Babs Jensen
|
|
151
|
+
* - value: 902c246b-6245-4190-8e05-00816be7344a
|
|
152
|
+
* display: Mandy Pepperidge
|
|
153
|
+
* meta:
|
|
154
|
+
* type: object
|
|
155
|
+
* properties:
|
|
156
|
+
* resourceType: { type: string, example: Group }
|
|
157
|
+
* created: { type: string, format: date-time }
|
|
158
|
+
* lastModified: { type: string, format: date-time }
|
|
159
|
+
* location: { type: string }
|
|
160
|
+
* version: { type: string }
|
|
161
|
+
* ScimListResponse:
|
|
162
|
+
* type: object
|
|
163
|
+
* description: |
|
|
164
|
+
* SCIM 2.0 list query response (urn:ietf:params:scim:api:messages:2.0:ListResponse).
|
|
165
|
+
* required: [schemas, totalResults, Resources]
|
|
166
|
+
* properties:
|
|
167
|
+
* schemas:
|
|
168
|
+
* type: array
|
|
169
|
+
* items: { type: string }
|
|
170
|
+
* example: ['urn:ietf:params:scim:api:messages:2.0:ListResponse']
|
|
171
|
+
* totalResults:
|
|
172
|
+
* type: integer
|
|
173
|
+
* description: Total number of matching resources.
|
|
174
|
+
* example: 2
|
|
175
|
+
* startIndex:
|
|
176
|
+
* type: integer
|
|
177
|
+
* description: 1-based index of the first result returned.
|
|
178
|
+
* example: 1
|
|
179
|
+
* itemsPerPage:
|
|
180
|
+
* type: integer
|
|
181
|
+
* description: Number of resources returned in this page.
|
|
182
|
+
* example: 2
|
|
183
|
+
* Resources:
|
|
184
|
+
* type: array
|
|
185
|
+
* items: {}
|
|
186
|
+
* description: The matching resources.
|
|
187
|
+
* ScimError:
|
|
188
|
+
* type: object
|
|
189
|
+
* description: |
|
|
190
|
+
* SCIM 2.0 error response (urn:ietf:params:scim:api:messages:2.0:Error).
|
|
191
|
+
* required: [schemas, status]
|
|
192
|
+
* properties:
|
|
193
|
+
* schemas:
|
|
194
|
+
* type: array
|
|
195
|
+
* items: { type: string }
|
|
196
|
+
* example: ['urn:ietf:params:scim:api:messages:2.0:Error']
|
|
197
|
+
* status:
|
|
198
|
+
* type: string
|
|
199
|
+
* description: HTTP status code as a string.
|
|
200
|
+
* example: '404'
|
|
201
|
+
* scimType:
|
|
202
|
+
* type: string
|
|
203
|
+
* description: |
|
|
204
|
+
* SCIM error type keyword (RFC 7644 §3.12). One of: invalidFilter,
|
|
205
|
+
* tooMany, uniqueness, mutability, invalidSyntax, invalidPath,
|
|
206
|
+
* noTarget, invalidValue, invalidVers, sensitive.
|
|
207
|
+
* example: mutability
|
|
208
|
+
* detail:
|
|
209
|
+
* type: string
|
|
210
|
+
* description: Human-readable error description.
|
|
211
|
+
* example: Resource 2819c223-7f76-453a-919d-413861904646 not found.
|
|
212
|
+
* example:
|
|
213
|
+
* schemas: ['urn:ietf:params:scim:api:messages:2.0:Error']
|
|
214
|
+
* status: '404'
|
|
215
|
+
* detail: Resource 2819c223-7f76-453a-919d-413861904646 not found.
|
|
216
|
+
* ScimPatchOp:
|
|
217
|
+
* type: object
|
|
218
|
+
* description: |
|
|
219
|
+
* SCIM 2.0 patch request body (urn:ietf:params:scim:api:messages:2.0:PatchOp,
|
|
220
|
+
* RFC 7644 §3.5.2).
|
|
221
|
+
* required: [schemas, Operations]
|
|
222
|
+
* properties:
|
|
223
|
+
* schemas:
|
|
224
|
+
* type: array
|
|
225
|
+
* items: { type: string }
|
|
226
|
+
* example: ['urn:ietf:params:scim:api:messages:2.0:PatchOp']
|
|
227
|
+
* Operations:
|
|
228
|
+
* type: array
|
|
229
|
+
* items:
|
|
230
|
+
* type: object
|
|
231
|
+
* required: [op]
|
|
232
|
+
* properties:
|
|
233
|
+
* op:
|
|
234
|
+
* type: string
|
|
235
|
+
* enum: [add, remove, replace, Add, Remove, Replace]
|
|
236
|
+
* path:
|
|
237
|
+
* type: string
|
|
238
|
+
* description: SCIM attribute path (e.g. "emails[type eq \"work\"].value").
|
|
239
|
+
* value:
|
|
240
|
+
* description: New value for the target attribute.
|
|
241
|
+
* example:
|
|
242
|
+
* schemas: ['urn:ietf:params:scim:api:messages:2.0:PatchOp']
|
|
243
|
+
* Operations:
|
|
244
|
+
* - op: replace
|
|
245
|
+
* path: active
|
|
246
|
+
* value: false
|
|
247
|
+
* - op: replace
|
|
248
|
+
* path: emails[type eq "work"].value
|
|
249
|
+
* value: bjensen@newdomain.example.com
|
|
250
|
+
* ScimBulkRequest:
|
|
251
|
+
* type: object
|
|
252
|
+
* description: |
|
|
253
|
+
* SCIM 2.0 Bulk request (urn:ietf:params:scim:api:messages:2.0:BulkRequest,
|
|
254
|
+
* RFC 7644 §3.7).
|
|
255
|
+
* required: [schemas, Operations]
|
|
256
|
+
* properties:
|
|
257
|
+
* schemas:
|
|
258
|
+
* type: array
|
|
259
|
+
* items: { type: string }
|
|
260
|
+
* example: ['urn:ietf:params:scim:api:messages:2.0:BulkRequest']
|
|
261
|
+
* failOnErrors:
|
|
262
|
+
* type: integer
|
|
263
|
+
* description: |
|
|
264
|
+
* Stop processing after this many errors. Omit or set to 0 to
|
|
265
|
+
* continue on errors and process all operations.
|
|
266
|
+
* example: 1
|
|
267
|
+
* Operations:
|
|
268
|
+
* type: array
|
|
269
|
+
* items:
|
|
270
|
+
* type: object
|
|
271
|
+
* required: [method, path]
|
|
272
|
+
* properties:
|
|
273
|
+
* method:
|
|
274
|
+
* type: string
|
|
275
|
+
* enum: [POST, PUT, PATCH, DELETE]
|
|
276
|
+
* bulkId:
|
|
277
|
+
* type: string
|
|
278
|
+
* description: |
|
|
279
|
+
* Temporary client-assigned identifier for this operation.
|
|
280
|
+
* Subsequent operations in the same request may reference the
|
|
281
|
+
* created resource as "bulkId:<value>".
|
|
282
|
+
* path:
|
|
283
|
+
* type: string
|
|
284
|
+
* description: Resource path relative to the SCIM prefix (e.g. /Users or /Groups/123).
|
|
285
|
+
* data:
|
|
286
|
+
* description: Request body for POST/PUT/PATCH operations.
|
|
287
|
+
* example:
|
|
288
|
+
* schemas: ['urn:ietf:params:scim:api:messages:2.0:BulkRequest']
|
|
289
|
+
* failOnErrors: 1
|
|
290
|
+
* Operations:
|
|
291
|
+
* - method: POST
|
|
292
|
+
* bulkId: qwerty
|
|
293
|
+
* path: /Users
|
|
294
|
+
* data:
|
|
295
|
+
* schemas: ['urn:ietf:params:scim:schemas:core:2.0:User']
|
|
296
|
+
* userName: bjensen
|
|
297
|
+
* name:
|
|
298
|
+
* familyName: Jensen
|
|
299
|
+
* givenName: Barbara
|
|
300
|
+
* - method: DELETE
|
|
301
|
+
* path: /Users/2819c223-7f76-453a-919d-413861904646
|
|
302
|
+
* ScimBulkResponse:
|
|
303
|
+
* type: object
|
|
304
|
+
* description: |
|
|
305
|
+
* SCIM 2.0 Bulk response (urn:ietf:params:scim:api:messages:2.0:BulkResponse).
|
|
306
|
+
* required: [schemas, Operations]
|
|
307
|
+
* properties:
|
|
308
|
+
* schemas:
|
|
309
|
+
* type: array
|
|
310
|
+
* items: { type: string }
|
|
311
|
+
* example: ['urn:ietf:params:scim:api:messages:2.0:BulkResponse']
|
|
312
|
+
* Operations:
|
|
313
|
+
* type: array
|
|
314
|
+
* items:
|
|
315
|
+
* type: object
|
|
316
|
+
* required: [method, status]
|
|
317
|
+
* properties:
|
|
318
|
+
* method:
|
|
319
|
+
* type: string
|
|
320
|
+
* enum: [POST, PUT, PATCH, DELETE]
|
|
321
|
+
* bulkId:
|
|
322
|
+
* type: string
|
|
323
|
+
* location:
|
|
324
|
+
* type: string
|
|
325
|
+
* description: URL of the created/modified resource.
|
|
326
|
+
* version:
|
|
327
|
+
* type: string
|
|
328
|
+
* status:
|
|
329
|
+
* type: string
|
|
330
|
+
* description: HTTP status code for this individual operation.
|
|
331
|
+
* response:
|
|
332
|
+
* $ref: '#/components/schemas/ScimError'
|
|
333
|
+
* description: Present only when the operation failed.
|
|
334
|
+
* example:
|
|
335
|
+
* schemas: ['urn:ietf:params:scim:api:messages:2.0:BulkResponse']
|
|
336
|
+
* Operations:
|
|
337
|
+
* - method: POST
|
|
338
|
+
* bulkId: qwerty
|
|
339
|
+
* location: https://example.com/scim/v2/Users/2819c223-7f76-453a-919d-413861904646
|
|
340
|
+
* status: '201'
|
|
341
|
+
* - method: DELETE
|
|
342
|
+
* status: '204'
|
|
343
|
+
* ScimResourceType:
|
|
344
|
+
* type: object
|
|
345
|
+
* description: SCIM 2.0 ResourceType definition (RFC 7643 §6).
|
|
346
|
+
* required: [schemas, id, name, endpoint, schema]
|
|
347
|
+
* properties:
|
|
348
|
+
* schemas:
|
|
349
|
+
* type: array
|
|
350
|
+
* items: { type: string }
|
|
351
|
+
* example: ['urn:ietf:params:scim:schemas:core:2.0:ResourceType']
|
|
352
|
+
* id: { type: string, example: User }
|
|
353
|
+
* name: { type: string, example: User }
|
|
354
|
+
* endpoint: { type: string, example: /Users }
|
|
355
|
+
* description: { type: string, example: User Account }
|
|
356
|
+
* schema:
|
|
357
|
+
* type: string
|
|
358
|
+
* example: urn:ietf:params:scim:schemas:core:2.0:User
|
|
359
|
+
* schemaExtensions:
|
|
360
|
+
* type: array
|
|
361
|
+
* items:
|
|
362
|
+
* type: object
|
|
363
|
+
* properties:
|
|
364
|
+
* schema: { type: string }
|
|
365
|
+
* required: { type: boolean }
|
|
366
|
+
* meta:
|
|
367
|
+
* type: object
|
|
368
|
+
* properties:
|
|
369
|
+
* resourceType: { type: string, example: ResourceType }
|
|
370
|
+
* location: { type: string }
|
|
371
|
+
* ScimSchema:
|
|
372
|
+
* type: object
|
|
373
|
+
* description: SCIM 2.0 Schema definition (RFC 7643 §7).
|
|
374
|
+
* required: [schemas, id, name, attributes]
|
|
375
|
+
* properties:
|
|
376
|
+
* schemas:
|
|
377
|
+
* type: array
|
|
378
|
+
* items: { type: string }
|
|
379
|
+
* example: ['urn:ietf:params:scim:schemas:core:2.0:Schema']
|
|
380
|
+
* id:
|
|
381
|
+
* type: string
|
|
382
|
+
* example: urn:ietf:params:scim:schemas:core:2.0:User
|
|
383
|
+
* name: { type: string, example: User }
|
|
384
|
+
* description: { type: string, example: User Account }
|
|
385
|
+
* attributes:
|
|
386
|
+
* type: array
|
|
387
|
+
* items: {}
|
|
388
|
+
* description: Schema attribute definitions.
|
|
389
|
+
* meta:
|
|
390
|
+
* type: object
|
|
391
|
+
* properties:
|
|
392
|
+
* resourceType: { type: string, example: Schema }
|
|
393
|
+
* location: { type: string }
|
|
394
|
+
*/
|
|
395
|
+
export default class Scim extends DmPlugin {
|
|
396
|
+
name: string;
|
|
397
|
+
roles: Role[];
|
|
398
|
+
ldap: ldapActions;
|
|
399
|
+
private readonly scimPrefix;
|
|
400
|
+
private readonly users;
|
|
401
|
+
private readonly groups;
|
|
402
|
+
private readonly bulk;
|
|
403
|
+
private readonly discovery;
|
|
404
|
+
private readonly baseResolver;
|
|
405
|
+
constructor(server: DM);
|
|
406
|
+
private scimJson;
|
|
407
|
+
private readScimBody;
|
|
408
|
+
api(app: Express): void;
|
|
409
|
+
private parseListQuery;
|
|
410
|
+
getConfigApiData(): Record<string, unknown>;
|
|
411
|
+
}
|
|
412
|
+
export { writeScimErrorFromException };
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module plugins/scim/types
|
|
3
|
+
* @author Xavier Guimard <xguimard@linagora.com>
|
|
4
|
+
*
|
|
5
|
+
* SCIM 2.0 type definitions (RFC 7643 / RFC 7644).
|
|
6
|
+
*/
|
|
7
|
+
export declare const SCHEMA_USER = "urn:ietf:params:scim:schemas:core:2.0:User";
|
|
8
|
+
export declare const SCHEMA_GROUP = "urn:ietf:params:scim:schemas:core:2.0:Group";
|
|
9
|
+
export declare const SCHEMA_LIST_RESPONSE = "urn:ietf:params:scim:api:messages:2.0:ListResponse";
|
|
10
|
+
export declare const SCHEMA_ERROR = "urn:ietf:params:scim:api:messages:2.0:Error";
|
|
11
|
+
export declare const SCHEMA_PATCH_OP = "urn:ietf:params:scim:api:messages:2.0:PatchOp";
|
|
12
|
+
export declare const SCHEMA_BULK_REQUEST = "urn:ietf:params:scim:api:messages:2.0:BulkRequest";
|
|
13
|
+
export declare const SCHEMA_BULK_RESPONSE = "urn:ietf:params:scim:api:messages:2.0:BulkResponse";
|
|
14
|
+
export declare const SCHEMA_SERVICE_PROVIDER_CONFIG = "urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig";
|
|
15
|
+
export declare const SCHEMA_RESOURCE_TYPE = "urn:ietf:params:scim:schemas:core:2.0:ResourceType";
|
|
16
|
+
export declare const SCHEMA_SCHEMA = "urn:ietf:params:scim:schemas:core:2.0:Schema";
|
|
17
|
+
export interface Meta {
|
|
18
|
+
resourceType: 'User' | 'Group';
|
|
19
|
+
created?: string;
|
|
20
|
+
lastModified?: string;
|
|
21
|
+
location?: string;
|
|
22
|
+
version?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface MultiValued<T extends string = string> {
|
|
25
|
+
value: T;
|
|
26
|
+
display?: string;
|
|
27
|
+
type?: string;
|
|
28
|
+
primary?: boolean;
|
|
29
|
+
$ref?: string;
|
|
30
|
+
}
|
|
31
|
+
export interface ScimName {
|
|
32
|
+
formatted?: string;
|
|
33
|
+
familyName?: string;
|
|
34
|
+
givenName?: string;
|
|
35
|
+
middleName?: string;
|
|
36
|
+
honorificPrefix?: string;
|
|
37
|
+
honorificSuffix?: string;
|
|
38
|
+
}
|
|
39
|
+
export interface ScimUser {
|
|
40
|
+
schemas: string[];
|
|
41
|
+
id?: string;
|
|
42
|
+
externalId?: string;
|
|
43
|
+
userName?: string;
|
|
44
|
+
name?: ScimName;
|
|
45
|
+
displayName?: string;
|
|
46
|
+
nickName?: string;
|
|
47
|
+
profileUrl?: string;
|
|
48
|
+
title?: string;
|
|
49
|
+
userType?: string;
|
|
50
|
+
preferredLanguage?: string;
|
|
51
|
+
locale?: string;
|
|
52
|
+
timezone?: string;
|
|
53
|
+
active?: boolean;
|
|
54
|
+
password?: string;
|
|
55
|
+
emails?: MultiValued[];
|
|
56
|
+
phoneNumbers?: MultiValued[];
|
|
57
|
+
ims?: MultiValued[];
|
|
58
|
+
photos?: MultiValued[];
|
|
59
|
+
addresses?: ScimAddress[];
|
|
60
|
+
groups?: MultiValued[];
|
|
61
|
+
entitlements?: MultiValued[];
|
|
62
|
+
roles?: MultiValued[];
|
|
63
|
+
x509Certificates?: MultiValued[];
|
|
64
|
+
meta?: Meta;
|
|
65
|
+
[ext: string]: unknown;
|
|
66
|
+
}
|
|
67
|
+
export interface ScimAddress {
|
|
68
|
+
formatted?: string;
|
|
69
|
+
streetAddress?: string;
|
|
70
|
+
locality?: string;
|
|
71
|
+
region?: string;
|
|
72
|
+
postalCode?: string;
|
|
73
|
+
country?: string;
|
|
74
|
+
type?: string;
|
|
75
|
+
primary?: boolean;
|
|
76
|
+
}
|
|
77
|
+
export interface ScimGroup {
|
|
78
|
+
schemas: string[];
|
|
79
|
+
id?: string;
|
|
80
|
+
externalId?: string;
|
|
81
|
+
displayName?: string;
|
|
82
|
+
members?: MultiValued[];
|
|
83
|
+
meta?: Meta;
|
|
84
|
+
[ext: string]: unknown;
|
|
85
|
+
}
|
|
86
|
+
export type ScimResource = ScimUser | ScimGroup;
|
|
87
|
+
export interface ListResponse<T> {
|
|
88
|
+
schemas: [typeof SCHEMA_LIST_RESPONSE];
|
|
89
|
+
totalResults: number;
|
|
90
|
+
startIndex: number;
|
|
91
|
+
itemsPerPage: number;
|
|
92
|
+
Resources: T[];
|
|
93
|
+
}
|
|
94
|
+
export type ScimErrorType = 'invalidFilter' | 'tooMany' | 'uniqueness' | 'mutability' | 'invalidSyntax' | 'invalidPath' | 'noTarget' | 'invalidValue' | 'invalidVers' | 'sensitive';
|
|
95
|
+
export interface ScimErrorResponse {
|
|
96
|
+
schemas: [typeof SCHEMA_ERROR];
|
|
97
|
+
status: string;
|
|
98
|
+
scimType?: ScimErrorType;
|
|
99
|
+
detail?: string;
|
|
100
|
+
}
|
|
101
|
+
export interface PatchOperation {
|
|
102
|
+
op: 'add' | 'remove' | 'replace' | 'Add' | 'Remove' | 'Replace';
|
|
103
|
+
path?: string;
|
|
104
|
+
value?: unknown;
|
|
105
|
+
}
|
|
106
|
+
export interface PatchRequest {
|
|
107
|
+
schemas: string[];
|
|
108
|
+
Operations: PatchOperation[];
|
|
109
|
+
}
|
|
110
|
+
export interface BulkOperationRequest {
|
|
111
|
+
method: 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
112
|
+
bulkId?: string;
|
|
113
|
+
version?: string;
|
|
114
|
+
path: string;
|
|
115
|
+
data?: unknown;
|
|
116
|
+
}
|
|
117
|
+
export interface BulkRequest {
|
|
118
|
+
schemas: string[];
|
|
119
|
+
failOnErrors?: number;
|
|
120
|
+
Operations: BulkOperationRequest[];
|
|
121
|
+
}
|
|
122
|
+
export interface BulkOperationResponse {
|
|
123
|
+
method: 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
124
|
+
bulkId?: string;
|
|
125
|
+
version?: string;
|
|
126
|
+
location?: string;
|
|
127
|
+
status: string;
|
|
128
|
+
response?: ScimErrorResponse;
|
|
129
|
+
}
|
|
130
|
+
export interface BulkResponse {
|
|
131
|
+
schemas: [typeof SCHEMA_BULK_RESPONSE];
|
|
132
|
+
Operations: BulkOperationResponse[];
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Internal mapping description: SCIM attribute → LDAP attribute(s).
|
|
136
|
+
*
|
|
137
|
+
* - ldap: one LDAP attribute name (simple mapping)
|
|
138
|
+
* - ldapPrimary/ldapSecondary: primary vs non-primary in multi-valued attr (emails)
|
|
139
|
+
* - sub: nested SCIM attribute name (for name.familyName etc.)
|
|
140
|
+
* - multi: 'single' or 'array' (hint for formatting)
|
|
141
|
+
* - operational: read-only from LDAP operational attribute
|
|
142
|
+
*/
|
|
143
|
+
export interface MappingEntry {
|
|
144
|
+
scim: string;
|
|
145
|
+
ldap?: string;
|
|
146
|
+
ldapPrimary?: string;
|
|
147
|
+
ldapSecondary?: string;
|
|
148
|
+
sub?: Record<string, string>;
|
|
149
|
+
multi?: 'single' | 'array';
|
|
150
|
+
readOnly?: boolean;
|
|
151
|
+
operational?: boolean;
|
|
152
|
+
converter?: 'boolean' | 'number' | 'string';
|
|
153
|
+
}
|
|
154
|
+
export interface ResourceMapping {
|
|
155
|
+
resourceType: 'User' | 'Group';
|
|
156
|
+
schemas: string[];
|
|
157
|
+
entries: MappingEntry[];
|
|
158
|
+
}
|
|
159
|
+
export interface ServiceProviderConfig {
|
|
160
|
+
schemas: [typeof SCHEMA_SERVICE_PROVIDER_CONFIG];
|
|
161
|
+
documentationUri?: string;
|
|
162
|
+
patch: {
|
|
163
|
+
supported: boolean;
|
|
164
|
+
};
|
|
165
|
+
bulk: {
|
|
166
|
+
supported: boolean;
|
|
167
|
+
maxOperations: number;
|
|
168
|
+
maxPayloadSize: number;
|
|
169
|
+
};
|
|
170
|
+
filter: {
|
|
171
|
+
supported: boolean;
|
|
172
|
+
maxResults: number;
|
|
173
|
+
};
|
|
174
|
+
changePassword: {
|
|
175
|
+
supported: boolean;
|
|
176
|
+
};
|
|
177
|
+
sort: {
|
|
178
|
+
supported: boolean;
|
|
179
|
+
};
|
|
180
|
+
etag: {
|
|
181
|
+
supported: boolean;
|
|
182
|
+
};
|
|
183
|
+
authenticationSchemes: Array<{
|
|
184
|
+
name: string;
|
|
185
|
+
description: string;
|
|
186
|
+
specUri?: string;
|
|
187
|
+
documentationUri?: string;
|
|
188
|
+
type: string;
|
|
189
|
+
primary?: boolean;
|
|
190
|
+
}>;
|
|
191
|
+
meta?: {
|
|
192
|
+
resourceType: 'ServiceProviderConfig';
|
|
193
|
+
location?: string;
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
export interface ResourceTypeDefinition {
|
|
197
|
+
schemas: [typeof SCHEMA_RESOURCE_TYPE];
|
|
198
|
+
id: string;
|
|
199
|
+
name: string;
|
|
200
|
+
endpoint: string;
|
|
201
|
+
description?: string;
|
|
202
|
+
schema: string;
|
|
203
|
+
schemaExtensions?: Array<{
|
|
204
|
+
schema: string;
|
|
205
|
+
required: boolean;
|
|
206
|
+
}>;
|
|
207
|
+
meta?: {
|
|
208
|
+
resourceType: 'ResourceType';
|
|
209
|
+
location?: string;
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
export interface SchemaDefinition {
|
|
213
|
+
schemas: [typeof SCHEMA_SCHEMA];
|
|
214
|
+
id: string;
|
|
215
|
+
name: string;
|
|
216
|
+
description?: string;
|
|
217
|
+
attributes: unknown[];
|
|
218
|
+
meta?: {
|
|
219
|
+
resourceType: 'Schema';
|
|
220
|
+
location?: string;
|
|
221
|
+
};
|
|
222
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module plugins/scim/users
|
|
3
|
+
* @author Xavier Guimard <xguimard@linagora.com>
|
|
4
|
+
*
|
|
5
|
+
* SCIM Users resource handler — direct access via ldapActions.
|
|
6
|
+
*/
|
|
7
|
+
import type winston from 'winston';
|
|
8
|
+
import type ldapActions from '../../lib/ldapActions';
|
|
9
|
+
import type { Config } from '../../config/args';
|
|
10
|
+
import type { DmRequest } from '../../lib/auth/base';
|
|
11
|
+
import { BaseResolver } from './baseResolver';
|
|
12
|
+
import { type ResourceMapping, type ScimUser, type ListResponse, type PatchRequest } from './types';
|
|
13
|
+
export interface ListQuery {
|
|
14
|
+
filter?: string;
|
|
15
|
+
startIndex?: number;
|
|
16
|
+
count?: number;
|
|
17
|
+
attributes?: string[];
|
|
18
|
+
excludedAttributes?: string[];
|
|
19
|
+
sortBy?: string;
|
|
20
|
+
sortOrder?: 'ascending' | 'descending';
|
|
21
|
+
}
|
|
22
|
+
export interface ScimUsersOptions {
|
|
23
|
+
ldap: ldapActions;
|
|
24
|
+
config: Config;
|
|
25
|
+
logger: winston.Logger;
|
|
26
|
+
baseResolver: BaseResolver;
|
|
27
|
+
hooks: {
|
|
28
|
+
[K: string]: Function[] | undefined;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export declare class ScimUsers {
|
|
32
|
+
private readonly ldap;
|
|
33
|
+
private readonly config;
|
|
34
|
+
private readonly logger;
|
|
35
|
+
private readonly baseResolver;
|
|
36
|
+
private readonly hooks;
|
|
37
|
+
private readonly mapping;
|
|
38
|
+
private readonly rdnAttribute;
|
|
39
|
+
private readonly objectClass;
|
|
40
|
+
private readonly idAttribute;
|
|
41
|
+
private readonly maxResults;
|
|
42
|
+
private readonly scimPrefix;
|
|
43
|
+
constructor(opts: ScimUsersOptions);
|
|
44
|
+
private ctx;
|
|
45
|
+
private dnForId;
|
|
46
|
+
get(req: DmRequest, id: string): Promise<ScimUser>;
|
|
47
|
+
list(req: DmRequest, query: ListQuery): Promise<ListResponse<ScimUser>>;
|
|
48
|
+
create(req: DmRequest, resource: ScimUser): Promise<ScimUser>;
|
|
49
|
+
replace(req: DmRequest, id: string, resource: ScimUser): Promise<ScimUser>;
|
|
50
|
+
patch(req: DmRequest, id: string, patch: PatchRequest): Promise<ScimUser>;
|
|
51
|
+
delete(req: DmRequest, id: string): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Given a SCIM member value (typically an id), return the LDAP DN.
|
|
54
|
+
* Used by Groups PATCH and Bulk reference resolution.
|
|
55
|
+
*/
|
|
56
|
+
resolveRef(req: DmRequest, value: string): Promise<string | undefined>;
|
|
57
|
+
get userMapping(): ResourceMapping;
|
|
58
|
+
}
|