scimgateway 3.2.8 → 4.0.0
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 +269 -294
- package/config/plugin-api.json +9 -4
- package/config/plugin-azure-ad.json +9 -4
- package/config/plugin-forwardinc.json +19 -11
- package/config/plugin-ldap.json +9 -4
- package/config/plugin-loki.json +9 -4
- package/config/plugin-mongodb.json +101 -0
- package/config/plugin-mssql.json +9 -4
- package/config/plugin-restful.json +9 -4
- package/config/plugin-saphana.json +9 -4
- package/index.js +1 -0
- package/lib/plugin-api.js +1 -1
- package/lib/plugin-azure-ad.js +608 -572
- package/lib/plugin-forwardinc.js +304 -373
- package/lib/plugin-ldap.js +267 -382
- package/lib/plugin-loki.js +232 -177
- package/lib/plugin-mongodb.js +776 -0
- package/lib/plugin-mssql.js +105 -196
- package/lib/plugin-restful.js +171 -314
- package/lib/plugin-saphana.js +96 -131
- package/lib/postinstall.js +10 -8
- package/lib/scimdef-v1.js +18 -6
- package/lib/scimdef-v2.js +19 -5
- package/lib/scimgateway.js +554 -436
- package/lib/utils.js +36 -1
- package/package.json +11 -10
- package/test/index.js +1 -3
- package/test/lib/plugin-loki.js +79 -41
- package/test/lib/plugin-mongodb.js +631 -0
- package/test/lib/plugin-restful.js +66 -33
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# SCIM Gateway
|
|
2
2
|
|
|
3
|
-
[](https://travis-ci.com/jelhub/scimgateway) [](https://www.npmjs.com/package/scimgateway)[](https://www.npmjs.com/package/scimgateway) [](https://elshaug.xyz/docs/scimgateway#disqus_thread) [](https://github.com/jelhub/scimgateway)
|
|
3
|
+
[](https://app.travis-ci.com/github/jelhub/scimgateway) [](https://www.npmjs.com/package/scimgateway)[](https://www.npmjs.com/package/scimgateway) [](https://elshaug.xyz/docs/scimgateway#disqus_thread) [](https://github.com/jelhub/scimgateway)
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
Author: Jarle Elshaug
|
|
@@ -12,13 +12,15 @@ Validated through IdP's:
|
|
|
12
12
|
- OneLogin
|
|
13
13
|
- Okta
|
|
14
14
|
- Omada
|
|
15
|
+
- SailPoint/IdentityNow
|
|
15
16
|
|
|
16
17
|
Latest news:
|
|
17
18
|
|
|
19
|
+
- New major version v4.0.0. getUsers() and getGroups() replacing some deprecated methods. No limitations on filtering/sorting. Admin user access can be limited to specific baseEntities. New MongoDB plugin
|
|
18
20
|
- ipAllowList for restricting access to allowlisted IP addresses or subnets e.g. Azure AD IP-range
|
|
19
|
-
- General LDAP plugin configured for Active Directory
|
|
21
|
+
- General LDAP plugin configured for Active Directory
|
|
20
22
|
- [PlugSSO](https://elshaug.xyz/docs/plugsso) using SCIM Gateway
|
|
21
|
-
-
|
|
23
|
+
- Authentication configuration allowing more than one admin user including option for readOnly
|
|
22
24
|
- Codebase moved from callback of h... to the the promise(d) land of async/await
|
|
23
25
|
- Supports configuration by environments and external files
|
|
24
26
|
- Health monitoring through "/ping" URL, and option for error notifications by email
|
|
@@ -28,7 +30,7 @@ Latest news:
|
|
|
28
30
|
|
|
29
31
|
## Overview
|
|
30
32
|
|
|
31
|
-
With SCIM Gateway we could do user management by using REST based [SCIM](http://www.simplecloud.info/) 1.1 or 2.0 protocol. Gateway will translate incoming SCIM requests and expose CRUD functionality (create, read, update and delete user/group) towards destinations using endpoint specific protocols. Gateway do not require SCIM to be used, it's also an API Gateway that could be used for other things than user provisioning.
|
|
33
|
+
With SCIM Gateway we could do user management by using REST based [SCIM](http://www.simplecloud.info/) 1.1 or 2.0 protocol. Gateway will translate incoming SCIM requests and expose CRUD functionality (create, read, update and delete user/group) towards destinations using endpoint specific protocols. In other words, none SCIM-endpoints will become SCIM-endpoints. Gateway do not require SCIM to be used, it's also an API Gateway that could be used for other things than user provisioning.
|
|
32
34
|
|
|
33
35
|
SCIM Gateway is a standalone product, however this document shows how the gateway could be used by products like Symatec/Broadcom/CA Identity Manager.
|
|
34
36
|
|
|
@@ -43,13 +45,17 @@ SCIM Gateway is based on the popular asynchronous event driven framework [Node.j
|
|
|
43
45
|
**Following example plugins are included:**
|
|
44
46
|
|
|
45
47
|
* **Loki** (NoSQL Document-Oriented Database)
|
|
46
|
-
|
|
48
|
+
SCIM Gateway becomes a standalone SCIM endpoint
|
|
47
49
|
Demonstrates user provisioning towards document-oriented database
|
|
48
|
-
Using [LokiJS](
|
|
50
|
+
Using [LokiJS](https://github.com/techfort/LokiJS) for a fast, in-memory document-oriented database (much like MongoDB/PouchDB)
|
|
49
51
|
Default gives two predefined test users loaded using in-memory only (no persistence)
|
|
50
52
|
Setting `{"persistence": true}` gives persistence file store (no test users)
|
|
51
53
|
Example of a fully functional SCIM Gateway plugin
|
|
52
54
|
|
|
55
|
+
* **MongoDB** (NoSQL Document-Oriented Database)
|
|
56
|
+
Same as plugin "Loki" but using MongoDB
|
|
57
|
+
Shows how to implement a highly configurable multi tenant or multi endpoint solution through `baseEntity` in URL
|
|
58
|
+
|
|
53
59
|
* **RESTful** (REST Webservice)
|
|
54
60
|
Demonstrates user provisioning towards REST-Based endpoint
|
|
55
61
|
Using plugin "Loki" as a REST endpoint
|
|
@@ -57,7 +63,7 @@ Using plugin "Loki" as a REST endpoint
|
|
|
57
63
|
* **Forwardinc** (SOAP Webservice)
|
|
58
64
|
Demonstrates user provisioning towards SOAP-Based endpoint
|
|
59
65
|
Using endpoint Forwardinc that comes with Broadcom/CA IM SDK (SDKWS) - [wiki.ca.com](https://docops.ca.com/ca-identity-manager/12-6-8/EN/programming/connector-programming-reference/sdk-sample-connectors/sdkws-sdk-web-services-connector/sdkws-sample-connector-build-requirements "wiki.ca.com")
|
|
60
|
-
Shows how to implement a highly configurable multi tenant or multi endpoint solution
|
|
66
|
+
Shows how to implement a highly configurable multi tenant or multi endpoint solution through `baseEntity` in URL
|
|
61
67
|
|
|
62
68
|
* **MSSQL** (MSSQL Database)
|
|
63
69
|
Demonstrates user provisioning towards MSSQL database
|
|
@@ -69,7 +75,7 @@ Demonstrates SAP HANA specific user provisioning
|
|
|
69
75
|
Azure AD user provisioning including Azure license management (App Service plans) e.g. Office 365
|
|
70
76
|
Using Microsoft Graph API
|
|
71
77
|
Using customized SCIM attributes according to Microsoft Graph API
|
|
72
|
-
Includes CA ConnectorXpress metafile for creating
|
|
78
|
+
Includes Symantec/Broadcom/CA ConnectorXpress metafile for creating provisioning "Azure - ScimGateway" endpoint type
|
|
73
79
|
|
|
74
80
|
* **LDAP** (Directory)
|
|
75
81
|
Fully functional LDAP plugin
|
|
@@ -100,16 +106,13 @@ Create your own package directory e.g. C:\my-scimgateway and install SCIM Gatewa
|
|
|
100
106
|
mkdir c:\my-scimgateway
|
|
101
107
|
cd c:\my-scimgateway
|
|
102
108
|
npm init -y
|
|
103
|
-
npm install scimgateway
|
|
104
|
-
|
|
105
|
-
Please **ignore any error messages** unless soap WSSecurityCert functionality is needed in your custom plugin code. Module soap installation of optional dependency 'ursa' that also includes 'node-gyp' then needs misc. prerequisites to bee manually installed.
|
|
106
|
-
|
|
109
|
+
npm install scimgateway
|
|
107
110
|
|
|
108
111
|
**c:\\my-scimgateway** will now be `<package-root>`
|
|
109
112
|
|
|
110
113
|
index.js, lib and config directories containing example plugins have been copied to your package from the original scimgateway package located under node_modules.
|
|
111
114
|
|
|
112
|
-
If internet connection is blocked, we could install on another machine and copy the
|
|
115
|
+
If internet connection is blocked, we could install on another machine and copy the `<package-root>` folder.
|
|
113
116
|
|
|
114
117
|
|
|
115
118
|
#### Startup and verify default Loki plugin
|
|
@@ -132,9 +135,12 @@ If internet connection is blocked, we could install on another machine and copy
|
|
|
132
135
|
http://localhost:8880/Groups/Admins
|
|
133
136
|
=> Lists all attributes for specified user/group
|
|
134
137
|
|
|
138
|
+
http://localhost:8880/Groups?filter=displayName eq "Admins"&excludedAttributes=members
|
|
135
139
|
http://localhost:8880/Users?filter=userName eq "bjensen"&attributes=userName,id,name.givenName
|
|
136
|
-
http://localhost:8880/Users?filter=
|
|
137
|
-
|
|
140
|
+
http://localhost:8880/Users?filter=meta.created gte "2010-01-01T00:00:00Z"&attributes=userName,name.familyName,meta.created
|
|
141
|
+
http://localhost:8880/Users?filter=emails.value co "@example.com"&attributes=userName,name.familyName,emails&sortBy=name.familyName&sortOrder=descending
|
|
142
|
+
=> Filtering examples
|
|
143
|
+
|
|
138
144
|
|
|
139
145
|
"Ctrl + c" to stop the SCIM Gateway
|
|
140
146
|
|
|
@@ -172,10 +178,11 @@ To force a major upgrade (version x.\*.\* => y.\*.\*) that will brake compabilit
|
|
|
172
178
|
**index.js** defines one or more plugins to be started. We could comment out those we do not need. Default configuration only starts the loki plugin.
|
|
173
179
|
|
|
174
180
|
const loki = require('./lib/plugin-loki')
|
|
181
|
+
// const mongodb = require('./lib/plugin-mongodb')
|
|
175
182
|
// const restful = require('./lib/plugin-restful')
|
|
176
183
|
// const forwardinc = require('./lib/plugin-forwardinc')
|
|
177
184
|
// const mssql = require('./lib/plugin-mssql')
|
|
178
|
-
// const saphana = require('./lib/plugin-saphana') // prereq: npm install hdb
|
|
185
|
+
// const saphana = require('./lib/plugin-saphana') // prereq: npm install hdb
|
|
179
186
|
// const azureAD = require('./lib/plugin-azure-ad')
|
|
180
187
|
// const ldap = require('./lib/plugin-ldap')
|
|
181
188
|
// const api = require('./lib/plugin-api')
|
|
@@ -209,18 +216,22 @@ Below shows an example of config\plugin-saphana.json
|
|
|
209
216
|
{
|
|
210
217
|
"username": "gwadmin",
|
|
211
218
|
"password": "password",
|
|
212
|
-
"readOnly": false
|
|
219
|
+
"readOnly": false,
|
|
220
|
+
"baseEntities": []
|
|
213
221
|
}
|
|
214
222
|
],
|
|
215
223
|
"bearerToken": [
|
|
216
224
|
{
|
|
217
225
|
"token": null,
|
|
218
|
-
"readOnly": false
|
|
226
|
+
"readOnly": false,
|
|
227
|
+
"baseEntities": []
|
|
219
228
|
}
|
|
220
229
|
],
|
|
221
230
|
"bearerJwtAzure": [
|
|
222
231
|
{
|
|
223
|
-
"tenantIdGUID": null
|
|
232
|
+
"tenantIdGUID": null,
|
|
233
|
+
"readOnly": false,
|
|
234
|
+
"baseEntities": []
|
|
224
235
|
}
|
|
225
236
|
],
|
|
226
237
|
"bearerJwt": [
|
|
@@ -230,7 +241,8 @@ Below shows an example of config\plugin-saphana.json
|
|
|
230
241
|
"options": {
|
|
231
242
|
"issuer": null
|
|
232
243
|
},
|
|
233
|
-
"readOnly": false
|
|
244
|
+
"readOnly": false,
|
|
245
|
+
"baseEntities": []
|
|
234
246
|
}
|
|
235
247
|
]
|
|
236
248
|
},
|
|
@@ -306,7 +318,10 @@ Definitions in `endpoint` object are customized according to our plugin code. Pl
|
|
|
306
318
|
|
|
307
319
|
- **log.customMasking** - array of attributes to be masked e.g. `"customMasking": ["SSN", "weight"]`. By default SCIM Gateway includes masking of some standard attributes like password.
|
|
308
320
|
|
|
309
|
-
- **auth** - Contains one or more authentication/authorization methods used by clients for accessing gateway
|
|
321
|
+
- **auth** - Contains one or more authentication/authorization methods used by clients for accessing gateway - may also include:
|
|
322
|
+
- **auth.xx.readOnly** - true/false, true gives read only access - only allowing `GET` requests for corresponding admin user
|
|
323
|
+
- **auth.xx.baseEntities** - array containing one or more `baseEntity` allowed for this user e.g. ["client-a"] - empty array allowing all.
|
|
324
|
+
**Methods are disabled by setting corresponding admin user to null or remove methods not used**
|
|
310
325
|
|
|
311
326
|
- **auth.basic** - Array of one ore more basic authentication objects - Basic Authentication with **username**/**password**. Note, we set a clear text password that will become encrypted when gateway is started.
|
|
312
327
|
|
|
@@ -362,11 +377,6 @@ Definitions in `endpoint` object are customized according to our plugin code. Pl
|
|
|
362
377
|
- **emailOnError.smtp.sendInterval** - Mail notifications on error are deferred until sendInterval **minutes** have passed since the last notification. Default 15 minutes
|
|
363
378
|
- **emailOnError.smtp.to** - Comma separated list of recipients email addresses e.g: "someone@example.com"
|
|
364
379
|
- **emailOnError.smtp.cc** - Comma separated list of cc email addresses
|
|
365
|
-
- **actions** - Pre and post actions onAddGroups/onRemoveGroups. Needed logic to be defined in plugin method `pre_post_Action`
|
|
366
|
-
- **actions.preAction.onAddGroups** - Array of groups e.g. ["Admins", "Employees"]
|
|
367
|
-
- **actions.preAction.onRemoveGroups** - Array of groups e.g. ["Admins", "Employees"]
|
|
368
|
-
- **actions.postAction.onAddGroups** - Array of groups e.g. ["Admins", "Employees"]
|
|
369
|
-
- **actions.postAction.onRemoveGroups** - Array of groups e.g. ["Admins", "Employees"]
|
|
370
380
|
|
|
371
381
|
- **endpoint** - Contains endpoint specific configuration according to our **plugin code**.
|
|
372
382
|
|
|
@@ -531,7 +541,7 @@ docker-compose**
|
|
|
531
541
|
mkdir /opt/my-scimgateway
|
|
532
542
|
cd /opt/my-scimgateway
|
|
533
543
|
npm init -y
|
|
534
|
-
npm install scimgateway
|
|
544
|
+
npm install scimgateway
|
|
535
545
|
cp ./config/docker/* .
|
|
536
546
|
|
|
537
547
|
**docker-compose.yml** <== Here is where you would set the exposed port and environment
|
|
@@ -594,6 +604,71 @@ To upgrade scimgateway docker image (remove the old stuff before running docker-
|
|
|
594
604
|
docker rm scimgateway
|
|
595
605
|
docker rm $(docker ps -a -q); docker rmi $(docker images -q -f "dangling=true")
|
|
596
606
|
|
|
607
|
+
## Azure Active Directory as IdP using SCIM Gateway
|
|
608
|
+
|
|
609
|
+
Azure AD could do automatic user provisioning by synchronizing users towards SCIM Gateway, and gateway plugins will update endpoints.
|
|
610
|
+
|
|
611
|
+
Plugin configuration file must include **SCIM Version "2.0"** (scimgateway.scim.version) and either **Bearer Token** (scimgateway.auth.bearerToken[x].token) or **Azure Tenant ID GUID** (scimgateway.auth.bearerJwtAzure[x].tenantIdGUID) or both:
|
|
612
|
+
|
|
613
|
+
scimgateway: {
|
|
614
|
+
"scim": {
|
|
615
|
+
"version": "2.0",
|
|
616
|
+
...
|
|
617
|
+
},
|
|
618
|
+
...
|
|
619
|
+
"auth": {
|
|
620
|
+
"bearerToken": [
|
|
621
|
+
{
|
|
622
|
+
"token": "shared-secret"
|
|
623
|
+
}
|
|
624
|
+
],
|
|
625
|
+
"bearerJwtAzure": [
|
|
626
|
+
{
|
|
627
|
+
"tenantIdGUID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
628
|
+
}
|
|
629
|
+
]
|
|
630
|
+
}
|
|
631
|
+
...
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
`token` configuration must correspond with "Secret Token" defined in Azure AD
|
|
635
|
+
`tenantIdGUID` configuration must correspond with Azure Active Directory Tenant ID
|
|
636
|
+
|
|
637
|
+
In Azure Portal:
|
|
638
|
+
`Azure-Azure Active Directory-Enterprise Application-<My Application>-Provisioning-Secret Token`
|
|
639
|
+
Note, when "Secret Token" is left blank, Azure will use JWT (tenantIdGUID)
|
|
640
|
+
|
|
641
|
+
`Azure-Azure Active Directory-Overview-Tenant ID`
|
|
642
|
+
|
|
643
|
+
User mappings attributes between AD and SCIM also needs to be configured
|
|
644
|
+
|
|
645
|
+
`Azure-Azure Active Directory-Enterprise Application-<My Application>-Provisioning-Edit attribute mappings-Mappings`
|
|
646
|
+
|
|
647
|
+
Azure AD default SCIM attribute mapping for **USER** must have:
|
|
648
|
+
|
|
649
|
+
userPrincipalName mapped to userName (matching precedence #1)
|
|
650
|
+
|
|
651
|
+
|
|
652
|
+
Azure AD default SCIM attribute mapping for **GROUP** must have:
|
|
653
|
+
|
|
654
|
+
displayName mapped to displayName (matching precedence #1)
|
|
655
|
+
members mapped to members
|
|
656
|
+
|
|
657
|
+
|
|
658
|
+
|
|
659
|
+
Some notes related to Azure AD:
|
|
660
|
+
|
|
661
|
+
- Azure Active Directory SCIM [documentation](https://docs.microsoft.com/en-us/azure/active-directory/active-directory-scim-provisioning)
|
|
662
|
+
|
|
663
|
+
- For using OAuth/JWT credentials, Azure configuration "Secret Token" (bearer token) should be blank. Plugin configuration must then include bearerJwtAzure.tenantIdGUID. Click "Test Connection" in Azure to verify
|
|
664
|
+
|
|
665
|
+
- Azure AD do a regular check for a "none" existing user/group. This check seems to be a "keep alive" to verify connection.
|
|
666
|
+
|
|
667
|
+
- Azure AD first checks if user/group exists, if not exist they will be created (no explore of all users like CA Identity Manager)
|
|
668
|
+
|
|
669
|
+
- Deleting a user in Azure AD sends a modify user `{"active":"False"}` which means user should be disabled. This logic is default set in attribute mappings expression rule `Switch([IsSoftDeleted], , "False", "True", "True", "False")`. Standard SCIM "DELETE" method seems not to be used.
|
|
670
|
+
|
|
671
|
+
|
|
597
672
|
## CA Identity Manager as IdP using SCIM Gateway
|
|
598
673
|
|
|
599
674
|
Using Symantec/Broadcom/CA Identity Manger, plugin configuration file must include **SCIM Version "1.1"** (scimgateway.scim.version).
|
|
@@ -623,82 +698,15 @@ Username, password and port must correspond with plugin configuration file. For
|
|
|
623
698
|
|
|
624
699
|
"baseEntity" is optional. This is a parameter used for multi tenant or multi endpoint solutions. We could create several endpoints having same base url with unique baseEntity. e.g:
|
|
625
700
|
|
|
626
|
-
http://localhost:8880/
|
|
627
|
-
http://localhost:8880/
|
|
701
|
+
http://localhost:8880/client-a
|
|
702
|
+
http://localhost:8880/client-b
|
|
628
703
|
|
|
629
704
|
Each baseEntity should then be defined in the plugin configuration file with custom attributes needed. Please see examples in plugin-forwardinc.json
|
|
630
705
|
|
|
631
706
|
IM 12.6 SP7 (and above) also supports pagination for SCIM endpoint (data transferred in bulks - endpoint explore of users). Loki plugin supports pagination. Other plugin may ignore this setting.
|
|
632
707
|
|
|
633
|
-
## SCIM Gateway REST API
|
|
634
|
-
|
|
635
|
-
Create = POST http://localhost:8880/Users
|
|
636
|
-
(body contains the user information)
|
|
637
|
-
|
|
638
|
-
Update = PATCH http://localhost:8880/Users/<id>
|
|
639
|
-
(body contains the attributes to be updated)
|
|
640
|
-
|
|
641
|
-
Search/Read = GET http://localhost:8880/Users?userName eq
|
|
642
|
-
"userID"&attributes=<comma separated list of scim-schema defined attributes>
|
|
643
|
-
|
|
644
|
-
Search/explore all users:
|
|
645
|
-
GET http://localhost:8880/Users?attributes=userName
|
|
646
|
-
|
|
647
|
-
Delete = DELETE http://localhost:8880/Users/<id>
|
|
648
|
-
|
|
649
|
-
Discovery:
|
|
650
|
-
|
|
651
|
-
GET http://localhost:8880/ServiceProviderConfigs
|
|
652
|
-
Specification compliance, authentication schemes, data models.
|
|
653
|
-
|
|
654
|
-
GET http://localhost:8880/Schemas
|
|
655
|
-
Introspect resources and attribute extensions.
|
|
656
|
-
|
|
657
|
-
Note:
|
|
658
|
-
|
|
659
|
-
- userName (mandatory) = UserID
|
|
660
|
-
- id (mandatory) = Unique id. Could be set to the same as UserID but don't have to.
|
|
661
|
-
|
|
662
|
-
## SAP Hana endpoint
|
|
663
|
-
|
|
664
|
-
Get all users (explore):
|
|
665
|
-
select USER_NAME from SYS.USERS where IS_SAML_ENABLED like 'TRUE';
|
|
666
|
-
|
|
667
|
-
Get a specific user:
|
|
668
|
-
select USER_NAME, USER_DEACTIVATED from SYS.USERS where USER_NAME like '<UserID>';
|
|
669
|
-
|
|
670
|
-
Create User:
|
|
671
|
-
CREATE USER <UserID> WITH IDENTITY '<UserID>' FOR SAML PROVIDER <SamlProvider>;
|
|
672
|
-
|
|
673
|
-
Delete user:
|
|
674
|
-
DROP USER <UserID>;
|
|
675
|
-
|
|
676
|
-
Modify user (enable user):
|
|
677
|
-
ALTER USER <UserID> ACTIVATE;
|
|
678
|
-
|
|
679
|
-
Modify user (disable user):
|
|
680
|
-
ALTER USER <UserID> DEACTIVATE;
|
|
681
|
-
|
|
682
|
-
Postinstallation:
|
|
683
|
-
|
|
684
|
-
cd c:\my-scimgateway
|
|
685
|
-
npm install hdb --save
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
Only SAML users will be explored and managed
|
|
689
|
-
|
|
690
|
-
Supported template attributes:
|
|
691
708
|
|
|
692
|
-
|
|
693
|
-
- Suspended (Enabled/Disabled)
|
|
694
|
-
|
|
695
|
-
Currently no other attributes needed. Trying to update other attributes will then give an error message. **The SCIM Provisioning template should therefore not include any other global user attribute references.**
|
|
696
|
-
|
|
697
|
-
SAP Hana converts UserID to uppercase. Provisioning use default lowercase. Provisioning template should therefore also convert to uppercase.
|
|
698
|
-
|
|
699
|
-
User Name = %$$TOUPPER(%AC%)%
|
|
700
|
-
|
|
701
|
-
## Azure Active Directory endpoint
|
|
709
|
+
## Azure Active Directory provisioning
|
|
702
710
|
Using plugin-azure-ad we could do user provisioning towards Azure AD including license management e.g. O365
|
|
703
711
|
|
|
704
712
|
For testing purposes we could get an Azure free account and in addition the free Office 365 for testing license management through Azure.
|
|
@@ -773,7 +781,8 @@ Note, for Symantec/Broadcom/CA Provisioning we have to use SCIM version 1.1
|
|
|
773
781
|
{
|
|
774
782
|
"username": "gwadmin",
|
|
775
783
|
"password": "password",
|
|
776
|
-
"readOnly": false
|
|
784
|
+
"readOnly": false,
|
|
785
|
+
"baseEntities": []
|
|
777
786
|
}
|
|
778
787
|
],
|
|
779
788
|
|
|
@@ -805,10 +814,10 @@ For multi-tenant or multi-endpoint support, we may add several entities:
|
|
|
805
814
|
"undefined": {
|
|
806
815
|
...
|
|
807
816
|
},
|
|
808
|
-
"
|
|
817
|
+
"client-a": {
|
|
809
818
|
...
|
|
810
819
|
},
|
|
811
|
-
"
|
|
820
|
+
"client-b": {
|
|
812
821
|
...
|
|
813
822
|
}
|
|
814
823
|
}
|
|
@@ -856,74 +865,39 @@ Endpoint configuration example:
|
|
|
856
865
|
|
|
857
866
|
For details, please see section "CA Identity Manager as IdP using SCIM Gateway"
|
|
858
867
|
|
|
868
|
+
## SCIM Gateway REST API
|
|
869
|
+
|
|
870
|
+
Create = POST http://localhost:8880/Users
|
|
871
|
+
(body contains the user information)
|
|
872
|
+
|
|
873
|
+
Update = PATCH http://localhost:8880/Users/<id>
|
|
874
|
+
(body contains the attributes to be updated)
|
|
875
|
+
|
|
876
|
+
Search/Read = GET http://localhost:8880/Users?userName eq
|
|
877
|
+
"userID"&attributes=<comma separated list of scim-schema defined attributes>
|
|
878
|
+
|
|
879
|
+
Search/explore all users:
|
|
880
|
+
GET http://localhost:8880/Users?attributes=userName
|
|
881
|
+
|
|
882
|
+
Delete = DELETE http://localhost:8880/Users/<id>
|
|
859
883
|
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
Azure AD could do automatic user provisioning by synchronizing users towards SCIM Gateway, and gateway plugins will update endpoints.
|
|
863
|
-
|
|
864
|
-
Plugin configuration file must include **SCIM Version "2.0"** (scimgateway.scim.version) and either **Bearer Token** (scimgateway.auth.bearerToken[x].token) or **Azure Tenant ID GUID** (scimgateway.auth.bearerJwtAzure[x].tenantIdGUID) or both:
|
|
865
|
-
|
|
866
|
-
scimgateway: {
|
|
867
|
-
"scim": {
|
|
868
|
-
"version": "2.0",
|
|
869
|
-
...
|
|
870
|
-
},
|
|
871
|
-
...
|
|
872
|
-
"auth": {
|
|
873
|
-
"bearerToken": [
|
|
874
|
-
{
|
|
875
|
-
"token": "shared-secret"
|
|
876
|
-
}
|
|
877
|
-
],
|
|
878
|
-
"bearerJwtAzure": [
|
|
879
|
-
{
|
|
880
|
-
"tenantIdGUID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
881
|
-
}
|
|
882
|
-
]
|
|
883
|
-
}
|
|
884
|
-
...
|
|
885
|
-
}
|
|
886
|
-
|
|
887
|
-
`token` configuration must correspond with "Secret Token" defined in Azure AD
|
|
888
|
-
`tenantIdGUID` configuration must correspond with Azure Active Directory Tenant ID
|
|
889
|
-
|
|
890
|
-
In Azure Portal:
|
|
891
|
-
`Azure-Azure Active Directory-Enterprise Application-<My Application>-Provisioning-Secret Token`
|
|
892
|
-
Note, when "Secret Token" is left blank, Azure will use JWT (tenantIdGUID)
|
|
893
|
-
|
|
894
|
-
`Azure-Azure Active Directory-Overview-Tenant ID`
|
|
895
|
-
|
|
896
|
-
User mappings attributes between AD and SCIM also needs to be configured
|
|
897
|
-
|
|
898
|
-
`Azure-Azure Active Directory-Enterprise Application-<My Application>-Provisioning-Edit attribute mappings-Mappings`
|
|
899
|
-
|
|
900
|
-
Azure AD default SCIM attribute mapping for **USER** must have:
|
|
901
|
-
|
|
902
|
-
userPrincipalName mapped to userName (matching precedence #1)
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
Azure AD default SCIM attribute mapping for **GROUP** must have:
|
|
906
|
-
|
|
907
|
-
displayName mapped to displayName (matching precedence #1)
|
|
908
|
-
members mapped to members
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
Some notes related to Azure AD:
|
|
913
|
-
|
|
914
|
-
- Azure Active Directory SCIM [documentation](https://docs.microsoft.com/en-us/azure/active-directory/active-directory-scim-provisioning)
|
|
884
|
+
Discovery:
|
|
915
885
|
|
|
916
|
-
|
|
886
|
+
GET http://localhost:8880/ServiceProviderConfigs
|
|
887
|
+
Specification compliance, authentication schemes, data models.
|
|
888
|
+
|
|
889
|
+
GET http://localhost:8880/Schemas
|
|
890
|
+
Introspect resources and attribute extensions.
|
|
917
891
|
|
|
918
|
-
|
|
892
|
+
Note:
|
|
919
893
|
|
|
920
|
-
-
|
|
894
|
+
- userName (mandatory) = UserID
|
|
895
|
+
- id (mandatory) = Unique id. Could be set to the same as UserID but don't have to.
|
|
921
896
|
|
|
922
|
-
- Deleting a user in Azure AD sends a modify user `{"active":"False"}` which means user should be disabled. This logic is default set in attribute mappings expression rule `Switch([IsSoftDeleted], , "False", "True", "True", "False")`. Standard SCIM "DELETE" method seems not to be used.
|
|
923
897
|
|
|
924
898
|
## API Gateway
|
|
925
899
|
|
|
926
|
-
Gateway also works as an API Gateway when using url `/api` or `/<baseEntity>/api`
|
|
900
|
+
SCIM Gateway also works as an API Gateway when using url `/api` or `/<baseEntity>/api`
|
|
927
901
|
|
|
928
902
|
Following methods for the none SCIM based api-plugin are supported:
|
|
929
903
|
|
|
@@ -935,7 +909,7 @@ Following methods for the none SCIM based api-plugin are supported:
|
|
|
935
909
|
PATCH /api/{id} + body
|
|
936
910
|
DELETE /api/{id}
|
|
937
911
|
|
|
938
|
-
|
|
912
|
+
These methods can also be used in standard SCIM plugins
|
|
939
913
|
Please see example plugin: **plugin-api.js**
|
|
940
914
|
|
|
941
915
|
|
|
@@ -944,7 +918,7 @@ For JavaScript coding editor you may use [Visual Studio Code](https://code.visua
|
|
|
944
918
|
|
|
945
919
|
Preparation:
|
|
946
920
|
|
|
947
|
-
* Copy "best matching" example plugin e.g. `lib\plugin-
|
|
921
|
+
* Copy "best matching" example plugin e.g. `lib\plugin-mssql.js` and `config\plugin-mssql.json` and rename both copies to your plugin name prefix e.g. plugin-mine.js and plugin-mine.json (for SOAP Webservice endpoint we might use plugin-forwardinc as a template)
|
|
948
922
|
* Edit plugin-mine.json and define a unique port number for the gateway setting
|
|
949
923
|
* Edit index.js and add a new line for starting your plugin e.g. `let mine = require('./lib/plugin-mine');`
|
|
950
924
|
* Start SCIM Gateway and verify. If using CA Provisioning you could setup a SCIM endpoint using the port number you defined
|
|
@@ -952,20 +926,18 @@ Preparation:
|
|
|
952
926
|
Now we are ready for custom coding by editing plugin-mine.js
|
|
953
927
|
Coding should be done step by step and each step should be verified and tested before starting the next (they are all highlighted by comments in existing code).
|
|
954
928
|
|
|
955
|
-
1. **Turn off group functionality**
|
|
956
|
-
Please see
|
|
957
|
-
2. **
|
|
958
|
-
3. **getUser** (test provisioning retrieve account)
|
|
929
|
+
1. **Turn off group functionality** - getGroups to return empty response
|
|
930
|
+
Please see plugin-saphana that do not use groups.
|
|
931
|
+
2. **getUsers** (test provisioning retrieve accounts)
|
|
959
932
|
4. **createUser** (test provisioning new account)
|
|
960
933
|
5. **deleteUser** (test provisioning delete account)
|
|
961
934
|
6. **modifyUser** (test provisioning modify account)
|
|
962
|
-
7. **
|
|
963
|
-
|
|
964
|
-
8. **
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
12. **createGroup** (test provisioning new group)
|
|
935
|
+
7. **Turn on group functionality** - getGroups having logic for returning groups if groups are supported
|
|
936
|
+
7. **getGroups** (test provisioning retrieve groups)
|
|
937
|
+
8. **modifyGroup** (test provisioning modify group members)
|
|
938
|
+
12. **createGroup** (test provisioning new group)
|
|
939
|
+
13. **deleteGroup** (test provisioning delete account)
|
|
940
|
+
|
|
969
941
|
|
|
970
942
|
Template used by CA Provisioning role should only include endpoint supported attributes defined in our plugin. Template should therefore have no links to global user for none supported attributes (e.g. remove %UT% from "Job Title" if our endpoint/code do not support title)
|
|
971
943
|
|
|
@@ -1035,9 +1007,9 @@ Plugins should have following initialization:
|
|
|
1035
1007
|
// mandatory plugin initialization - end
|
|
1036
1008
|
|
|
1037
1009
|
|
|
1038
|
-
###
|
|
1010
|
+
### getUsers
|
|
1039
1011
|
|
|
1040
|
-
scimgateway.
|
|
1012
|
+
scimgateway.getUsers = async (baseEntity, getObj, attributes) => {
|
|
1041
1013
|
let ret = {
|
|
1042
1014
|
"Resources": [],
|
|
1043
1015
|
"totalResults": null
|
|
@@ -1047,54 +1019,15 @@ Plugins should have following initialization:
|
|
|
1047
1019
|
}
|
|
1048
1020
|
|
|
1049
1021
|
* baseEntity = Optional for multi-tenant or multi-endpoint support (defined in base url e.g. `<baseurl>/client1` gives baseEntity=client1)
|
|
1050
|
-
*
|
|
1051
|
-
*
|
|
1022
|
+
* getObj = { attribute: <>, operator: <>, value: <>, rawFilter: <>, startIndex: <>, count: <> }
|
|
1023
|
+
* attribute, operator and value are set when using "simpel filtering", e.g. getObj.attribute='userName', getObj.operator='eq' and getObj.value='bjensen', but not for advanced filtering having and/or/not
|
|
1024
|
+
* rawFilter is always set when filtering is used
|
|
1025
|
+
* startIndex = Pagination - The 1-based index of the first result in the current set of search results
|
|
1026
|
+
* count = Pagination - Number of elements to be returned in the current set of search results
|
|
1027
|
+
* attributes = array of attributes to be returned - if empty, all supported attributes should be returned
|
|
1052
1028
|
* ret:
|
|
1053
|
-
ret.Resources = array filled with user objects
|
|
1054
|
-
ret.totalResults = if supporting pagination, then
|
|
1055
|
-
|
|
1056
|
-
### exploreGroups
|
|
1057
|
-
|
|
1058
|
-
scimgateway.exploreGroups = async (baseEntity, attributes, startIndex, count) => {
|
|
1059
|
-
let ret = {
|
|
1060
|
-
"Resources": [],
|
|
1061
|
-
"totalResults": null
|
|
1062
|
-
}
|
|
1063
|
-
...
|
|
1064
|
-
return ret
|
|
1065
|
-
}
|
|
1066
|
-
|
|
1067
|
-
* ret:
|
|
1068
|
-
ret.Resources = array filled with group objects containing group attributes where displayName is mandatory e.g [{"displayName":"Admins"}, {"displayName":"Employees"}]
|
|
1069
|
-
ret.totalResults = if supporting pagination attribute should be set to the total numbers of elements (groups) at the endpoint else set to null
|
|
1070
|
-
|
|
1071
|
-
### getUser
|
|
1072
|
-
|
|
1073
|
-
scimgateway.getUser = async (baseEntity, getObj, attributes) => {
|
|
1074
|
-
...
|
|
1075
|
-
return userObj
|
|
1076
|
-
}
|
|
1077
|
-
|
|
1078
|
-
* getObj = `{ filter: <filterAttribute>, identifier: <identifier> }`
|
|
1079
|
-
e.g: getObj = { "filter": "userName", "identifier": "bjensen"}
|
|
1080
|
-
filter: **userName** and **id** must be supported
|
|
1081
|
-
* attributes = scim attributes to be returned. If no attributes defined, all should be returned.
|
|
1082
|
-
* return userObj: userObj containing scim userattributes/values
|
|
1083
|
-
eg:
|
|
1084
|
-
{"id":"bjensen","name":{"formatted":"Ms. Barbara J Jensen III","familyName":"Jensen","givenName":"Barbara"}}
|
|
1085
|
-
|
|
1086
|
-
Note, the value of the **id** attribute returned will be used by modifyUser and deleteUser
|
|
1087
|
-
|
|
1088
|
-
### createUser
|
|
1089
|
-
|
|
1090
|
-
scimgateway.createUser = async (baseEntity, userObj) => {
|
|
1091
|
-
...
|
|
1092
|
-
return null
|
|
1093
|
-
}
|
|
1094
|
-
|
|
1095
|
-
* userObj = user object containing userattributes according to scim standard
|
|
1096
|
-
Note, multi-value attributes excluding user attribute 'groups' are customized from array to object based on type
|
|
1097
|
-
* return null: null if OK, else throw error
|
|
1029
|
+
ret.Resources = array filled with user objects according to getObj/attributes, we could normally include all attributes having id and userName as mandatory e.g [{"id": "bjensen", "userName": "bjensen"}, {"id":"jsmith", "userName":"jsmith"}]
|
|
1030
|
+
ret.totalResults = if supporting pagination, then it should be set to the total numbers of elements (users), else set to null
|
|
1098
1031
|
|
|
1099
1032
|
### deleteUser
|
|
1100
1033
|
|
|
@@ -1119,73 +1052,28 @@ Note, multi-value attributes excluding user attribute 'groups' are customized fr
|
|
|
1119
1052
|
Note, multi-value attributes excluding user attribute 'groups' are customized from array to object based on type
|
|
1120
1053
|
* return null: null if OK, else throw error
|
|
1121
1054
|
|
|
1122
|
-
###
|
|
1123
|
-
|
|
1124
|
-
scimgateway.getGroup = async (baseEntity, getObj, attributes) => {
|
|
1125
|
-
...
|
|
1126
|
-
return retObj
|
|
1127
|
-
}
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
* getObj = `{ filter: <filterAttribute>, identifier: <identifier> }`
|
|
1131
|
-
e.g: getObj = { "filter": "displayName", "identifier": "GroupA" }
|
|
1132
|
-
filter: **displayName** and **id** must be supported
|
|
1133
|
-
* attributes = scim attributes to be returned. If no attributes defined, all should be returned.
|
|
1134
|
-
* return retObj: retObj containing group displayName and id (+ members if using default "users are member of group")
|
|
1135
|
-
|
|
1136
|
-
eg. using default "users are member of group":
|
|
1137
|
-
{"displayName":"Admins","id":"Admins","members":[{"value":"bjensen","display":"bjensen"]}
|
|
1138
|
-
|
|
1139
|
-
eg. using "groups are member of user":
|
|
1140
|
-
{"displayName":"Admins","id":"Admins"}
|
|
1141
|
-
|
|
1142
|
-
If we do not support groups, callback(null, null)
|
|
1143
|
-
|
|
1144
|
-
### getGroupMembers
|
|
1145
|
-
|
|
1146
|
-
scimgateway.getGroupMembers = async (baseEntity, id, attributes) => {
|
|
1147
|
-
let arrRet = []
|
|
1148
|
-
...
|
|
1149
|
-
return arrRet
|
|
1150
|
-
}
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
Retrieve all groups for user id WHEN **"user member of groups"**. This setting is default SCIM behaviour. This means Group having multivalue attribute members containing id of users.
|
|
1154
|
-
|
|
1155
|
-
* id = user id (eg. bjensen)
|
|
1156
|
-
* attributes = scim attributes to be returned as object in array
|
|
1157
|
-
* arrRet = array containing the objects of id, displayName and members where members value only include current user id on the format:
|
|
1158
|
-
{ id: <id-group>> , displayName: <displayName-group>, members [{value: <id-user>}] }
|
|
1159
|
-
|
|
1160
|
-
[
|
|
1161
|
-
{"id": "Admins", "displayName: "Admins", "members": [{"value": "bjensen"}]},
|
|
1162
|
-
{"id": "Employees", "displayName: "Employees", "members": [{"value": "bjensen"}]}
|
|
1163
|
-
]
|
|
1055
|
+
### getGroups
|
|
1164
1056
|
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
scimgateway.getGroupUsers = async (baseEntity, id, attributes) => {
|
|
1172
|
-
let arrRet = []
|
|
1057
|
+
scimgateway.getGroups = async (baseEntity, getObj, attributes) => {
|
|
1058
|
+
let ret = {
|
|
1059
|
+
"Resources": [],
|
|
1060
|
+
"totalResults": null
|
|
1061
|
+
}
|
|
1173
1062
|
...
|
|
1174
|
-
|
|
1175
|
-
}
|
|
1176
|
-
|
|
1177
|
-
Retrieve all users for a spesific group id WHEN **"group member of users"**. This means user having multivalue attribute groups having value set to group id
|
|
1178
|
-
|
|
1179
|
-
* id = group id (eg. UserGroup-1)
|
|
1180
|
-
* attributes = scim attributes to be returned as object in array
|
|
1181
|
-
* arrRet = array containing the objects of userName and groups.value e.g:
|
|
1063
|
+
return ret
|
|
1064
|
+
}
|
|
1182
1065
|
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1066
|
+
* baseEntity = Optional for multi-tenant or multi-endpoint support (defined in base url e.g. `<baseurl>/client1` gives baseEntity=client1)
|
|
1067
|
+
* getObj = { attribute: <>, operator: <>, value: <>, rawFilter: <>, startIndex: <>, count: <> }
|
|
1068
|
+
* attribute, operator and value are set when using "simpel filtering", e.g. getObj.attribute='displayName', getObj.operator='eq' and getObj.value='Admins', but not for advanced filtering having and/or/not
|
|
1069
|
+
* rawFilter is always set when filtering is used
|
|
1070
|
+
* startIndex = Pagination - The 1-based index of the first result in the current set of search results
|
|
1071
|
+
* count = Pagination - Number of elements to be returned in the current set of search results
|
|
1072
|
+
* attributes = array of attributes to be returned - if empty, all supported attributes should be returned
|
|
1073
|
+
* ret:
|
|
1074
|
+
ret.Resources = array filled with group objects according to getObj/attributes, we could normally include all attributes having id, displayName and members as mandatory e.g [{"id":"Admins", "displayName":"Admins", members":[{"value":"bjensen"}]}, {"id":"Employees", "displayName":"Employees"}, "members":[{"value":"jsmith","display":"John Smith"}]]
|
|
1075
|
+
ret.totalResults = if supporting pagination, then it should be set to the total numbers of elements (users), else set to null
|
|
1187
1076
|
|
|
1188
|
-
If "group member of users" not supported, then return []
|
|
1189
1077
|
|
|
1190
1078
|
### createGroup
|
|
1191
1079
|
scimgateway.createGroup = async (baseEntity, groupObj) => {
|
|
@@ -1222,15 +1110,6 @@ eg: {"value":"bjensen"},{"operation":"delete","value":"jsmith"}
|
|
|
1222
1110
|
If we do not support groups, then return null
|
|
1223
1111
|
|
|
1224
1112
|
|
|
1225
|
-
## Known limitations
|
|
1226
|
-
|
|
1227
|
-
* Installation gives error messages related to the module soap optional dependency to 'ursa' that also includes 'node-gyp'. These error messages can be ignored unless soap WSSecurityCert functionality is needed in custom plugin code.
|
|
1228
|
-
|
|
1229
|
-
* SCIM filtering only supports operator 'eq' returning unique object only, example:
|
|
1230
|
-
/Users?**filter**=userName **eq** "bjensen"&attributes=userName,id,name.givenName
|
|
1231
|
-
/Users?**filter**=emails.value **eq** "bjensen@example.com"&attributes=userName,phoneNumbers
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
1113
|
## License
|
|
1235
1114
|
|
|
1236
1115
|
MIT © [Jarle Elshaug](https://www.elshaug.xyz)
|
|
@@ -1238,6 +1117,102 @@ MIT © [Jarle Elshaug](https://www.elshaug.xyz)
|
|
|
1238
1117
|
|
|
1239
1118
|
## Change log
|
|
1240
1119
|
|
|
1120
|
+
### v4.0.0
|
|
1121
|
+
**[MAJOR]**
|
|
1122
|
+
|
|
1123
|
+
- New `getUsers()` replacing deprecated exploreUsers(), getUser() and getGroupUsers()
|
|
1124
|
+
- New `getGroups()` replacing deprecated exploreGroups(), getGroup() and getGroupMembers()
|
|
1125
|
+
- Fully filter and sort support
|
|
1126
|
+
- Authentication configuration may now include a baseEntities array containing one or more `baseEntity` allowed for corresponding admin user
|
|
1127
|
+
- New plugin-mongodb, **thanks to Filipe Ribeiro and Miguel Ferreira (KEEP SOLUTIONS)**
|
|
1128
|
+
|
|
1129
|
+
Note, using this major version **require existing custom plugins to be upgraded**. If you do not want to upgrade your custom plugins, the old version have to be installed using: `npm install scimgateway@3.2.11`
|
|
1130
|
+
|
|
1131
|
+
How to upgrade your custom plugins:
|
|
1132
|
+
|
|
1133
|
+
Replace: scimgateway.exploreUsers = async (baseEntity, attributes, startIndex, count) => {
|
|
1134
|
+
With: scimgateway.getUsers = async (baseEntity, getObj, attributes) => {
|
|
1135
|
+
|
|
1136
|
+
See comments in provided plugins regarding the new `getObj`. Also note that `attributes` is now an array and not a comma separated string like previous versions
|
|
1137
|
+
|
|
1138
|
+
In the very beginning, add:
|
|
1139
|
+
|
|
1140
|
+
// mandatory if-else logic - start
|
|
1141
|
+
if (getObj.operator) {
|
|
1142
|
+
if (getObj.operator === 'eq' && ['id', 'userName', 'externalId'].includes(getObj.attribute)) {
|
|
1143
|
+
// mandatory - unique filtering - single unique user to be returned - correspond to getUser() in versions < 4.x.x
|
|
1144
|
+
} else if (getObj.operator === 'eq' && getObj.attribute === 'group.value') {
|
|
1145
|
+
// optional - only used when groups are member of users, not default behavior - correspond to getGroupUsers() in versions < 4.x.x
|
|
1146
|
+
throw new Error(`${action} error: not supporting groups member of user filtering: ${getObj.rawFilter}`)
|
|
1147
|
+
} else {
|
|
1148
|
+
// optional - simpel filtering
|
|
1149
|
+
throw new Error(`${action} error: not supporting simpel filtering: ${getObj.rawFilter}`)
|
|
1150
|
+
}
|
|
1151
|
+
} else if (getObj.rawFilter) {
|
|
1152
|
+
// optional - advanced filtering having and/or/not - use getObj.rawFilter
|
|
1153
|
+
throw new Error(`${action} error: not supporting advanced filtering: ${getObj.rawFilter}`)
|
|
1154
|
+
} else {
|
|
1155
|
+
// mandatory - no filtering (!getObj.operator && !getObj.rawFilter) - all users to be returned - correspond to exploreUsers() in versions < 4.x.x
|
|
1156
|
+
}
|
|
1157
|
+
// mandatory if-else logic - end
|
|
1158
|
+
|
|
1159
|
+
|
|
1160
|
+
In the new getUsers() replacing exploreUsers() "as-is", we then need some logic in the last "else" statement listed above.
|
|
1161
|
+
We also need to add logic from existing getGroup() and getGroupMembers()
|
|
1162
|
+
**Please have a look at provieded plugins to see different ways of doing this logic.**
|
|
1163
|
+
|
|
1164
|
+
|
|
1165
|
+
Replace: scimgateway.exploreGroups = async (baseEntity, attributes, startIndex, count) => {
|
|
1166
|
+
With: scimgateway.getGroups = async (baseEntity, getObj, attributes) => {
|
|
1167
|
+
|
|
1168
|
+
In the very beginning, add:
|
|
1169
|
+
|
|
1170
|
+
// mandatory if-else logic - start
|
|
1171
|
+
if (getObj.operator) {
|
|
1172
|
+
if (getObj.operator === 'eq' && ['id', 'displayName', 'externalId'].includes(getObj.attribute)) {
|
|
1173
|
+
// mandatory - unique filtering - single unique user to be returned - correspond to getUser() in versions < 4.x.x
|
|
1174
|
+
} else if (getObj.operator === 'eq' && getObj.attribute === 'members.value') {
|
|
1175
|
+
// mandatory - return all groups the user 'id' (getObj.value) is member of - correspond to getGroupMembers() in versions < 4.x.x
|
|
1176
|
+
// Resources = [{ id: <id-group>> , displayName: <displayName-group>, members [{value: <id-user>}] }]
|
|
1177
|
+
} else {
|
|
1178
|
+
// optional - simpel filtering
|
|
1179
|
+
throw new Error(`${action} error: not supporting simpel filtering: ${getObj.rawFilter}`)
|
|
1180
|
+
}
|
|
1181
|
+
} else if (getObj.rawFilter) {
|
|
1182
|
+
// optional - advanced filtering having and/or/not - use getObj.rawFilter
|
|
1183
|
+
throw new Error(`${action} error: not supporting advanced filtering: ${getObj.rawFilter}`)
|
|
1184
|
+
} else {
|
|
1185
|
+
// mandatory - no filtering (!getObj.operator && !getObj.rawFilter) - all groups to be returned - correspond to exploreGroups() in versions < 4.x.x
|
|
1186
|
+
}
|
|
1187
|
+
// mandatory if-else logic - end
|
|
1188
|
+
|
|
1189
|
+
|
|
1190
|
+
In the new getGroups() replacing exploreGroups() "as-is", we then need some logic in the last "else" statement listed above.
|
|
1191
|
+
We also need to add logic from existing getGroup() and getGroupMembers()
|
|
1192
|
+
**Please have a look at provieded plugins to see different ways of doing this logic.**
|
|
1193
|
+
|
|
1194
|
+
|
|
1195
|
+
Delete deprecated exploreUsers(), getUser(), getGroupUsers(), exploreGroups(), getGroup() and getGroupMembers()
|
|
1196
|
+
|
|
1197
|
+
|
|
1198
|
+
### v3.2.11
|
|
1199
|
+
[Fixed]
|
|
1200
|
+
|
|
1201
|
+
- errorhandling related to running scimgateway as unikernel
|
|
1202
|
+
|
|
1203
|
+
### v3.2.10
|
|
1204
|
+
[Fixed]
|
|
1205
|
+
|
|
1206
|
+
- for SCIM 2.0 exploreUsers/exploreGroups now includes schemas/resourceType on each object in the Resources response. This may be required by som IdP's.
|
|
1207
|
+
|
|
1208
|
+
[Added]
|
|
1209
|
+
- Dependencies bump
|
|
1210
|
+
|
|
1211
|
+
### v3.2.9
|
|
1212
|
+
[Fixed]
|
|
1213
|
+
|
|
1214
|
+
- plugin-loki pagination fix
|
|
1215
|
+
|
|
1241
1216
|
### v3.2.8
|
|
1242
1217
|
[Fixed]
|
|
1243
1218
|
|