scimgateway 4.1.14 → 4.2.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 +77 -11
- package/config/plugin-api.json +14 -2
- package/config/plugin-azure-ad.json +11 -1
- package/config/plugin-forwardinc.json +11 -1
- package/config/plugin-ldap.json +11 -1
- package/config/plugin-loki.json +11 -1
- package/config/plugin-mongodb.json +11 -1
- package/config/plugin-mssql.json +11 -1
- package/config/plugin-saphana.json +11 -1
- package/config/plugin-scim.json +17 -3
- package/lib/plugin-api.js +6 -5
- package/lib/plugin-azure-ad.js +15 -14
- package/lib/plugin-forwardinc.js +10 -9
- package/lib/plugin-ldap.js +10 -9
- package/lib/plugin-loki.js +10 -9
- package/lib/plugin-mongodb.js +9 -8
- package/lib/plugin-mssql.js +9 -8
- package/lib/plugin-saphana.js +9 -8
- package/lib/plugin-scim.js +9 -8
- package/lib/scimgateway.js +100 -31
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -16,9 +16,10 @@ Validated through IdP's:
|
|
|
16
16
|
|
|
17
17
|
Latest news:
|
|
18
18
|
|
|
19
|
+
- Authentication PassThrough letting plugin pass authentication directly to endpoint for avoid maintaining secrets at the gateway. Kubernetes health checks and shutdown handler support
|
|
19
20
|
- **BREAKING**: [SCIM Stream](https://elshaug.xyz/docs/scim-stream) is the modern way of user provisioning letting clients subscribe to messages instead of traditional IGA top-down provisioning. SCIM Stream includes **SCIM Stream Gateway**, the next generation SCIM Gateway that supports message subscription and automated provisioning
|
|
20
21
|
- Supports OAuth Client Credentials authentication
|
|
21
|
-
- Major version v4.0.0. getUsers() and getGroups() replacing some deprecated methods. No limitations on filtering/sorting. Admin user access can be linked to specific baseEntities. New MongoDB plugin
|
|
22
|
+
- Major version v4.0.0. getUsers() and getGroups() replacing some deprecated methods. No limitations on filtering/sorting. Admin user access can be linked to specific baseEntities. New MongoDB plugin
|
|
22
23
|
- ipAllowList for restricting access to allowlisted IP addresses or subnets e.g. Azure AD IP-range
|
|
23
24
|
- General LDAP plugin configured for Active Directory
|
|
24
25
|
- [PlugSSO](https://elshaug.xyz/docs/plugsso) using SCIM Gateway
|
|
@@ -261,7 +262,12 @@ Below shows an example of config\plugin-saphana.json
|
|
|
261
262
|
"readOnly": false,
|
|
262
263
|
"baseEntities": []
|
|
263
264
|
}
|
|
264
|
-
]
|
|
265
|
+
],
|
|
266
|
+
"passThrough": {
|
|
267
|
+
"enabled": false,
|
|
268
|
+
"readOnly": false,
|
|
269
|
+
"baseEntities": []
|
|
270
|
+
}
|
|
265
271
|
},
|
|
266
272
|
"certificate": {
|
|
267
273
|
"key": null,
|
|
@@ -286,7 +292,12 @@ Below shows an example of config\plugin-saphana.json
|
|
|
286
292
|
"to": null,
|
|
287
293
|
"cc": null
|
|
288
294
|
}
|
|
289
|
-
}
|
|
295
|
+
},
|
|
296
|
+
"kubernetes": {
|
|
297
|
+
"enabled": false,
|
|
298
|
+
"shutdownTimeout": 15000,
|
|
299
|
+
"forceExitTimeout": 1000
|
|
300
|
+
}
|
|
290
301
|
},
|
|
291
302
|
"endpoint": {
|
|
292
303
|
"host": "hostname",
|
|
@@ -300,7 +311,7 @@ Below shows an example of config\plugin-saphana.json
|
|
|
300
311
|
|
|
301
312
|
Configuration file have two main JSON objects: `scimgateway` and `endpoint`
|
|
302
313
|
|
|
303
|
-
Definitions in `scimgateway` object have fixed attributes, but values can be modified. This object is used by the core functionality of the SCIM Gateway.
|
|
314
|
+
Definitions in `scimgateway` object have fixed attributes, but values can be modified. Sections not used/configured can be removed. This object is used by the core functionality of the SCIM Gateway.
|
|
304
315
|
|
|
305
316
|
Definitions in `endpoint` object are customized according to our plugin code. Plugin typically need this information for communicating with endpoint
|
|
306
317
|
|
|
@@ -354,6 +365,8 @@ Definitions in `endpoint` object are customized according to our plugin code. Pl
|
|
|
354
365
|
|
|
355
366
|
- **auth.bearerOAuth** - Array of one or more Client Credentials OAuth configuration objects. **`client_id`** and **`client_secret`** are mandatory. client_secret value will become encrypted when gateway is started. OAuth token request url is **/oauth/token** e.g. http://localhost:8880/oauth/token
|
|
356
367
|
|
|
368
|
+
- **auth.passThrough** - Setting **auth.passThrough.enabled=true** will bypass SCIM Gateway authentication. Gateway will instead pass ctx containing authentication header to the plugin. Plugin could then use this information for endpoint authentication and we don't have any password/token stored at the gateway. Note, this also requires plugin binary having `scimgateway.authPassThroughAllowed = true` and endpoint logic for handling/passing ctx.request.header.authorization
|
|
369
|
+
|
|
357
370
|
- **certificate** - If not using TLS certificate, set "key", "cert" and "ca" to **null**. When using TLS, "key" and "cert" have to be defined with the filename corresponding to the primary-key and public-certificate. Both files must be located in the `<package-root>\config\certs` directory e.g:
|
|
358
371
|
|
|
359
372
|
"certificate": {
|
|
@@ -401,6 +414,11 @@ Definitions in `endpoint` object are customized according to our plugin code. Pl
|
|
|
401
414
|
- **emailOnError.smtp.to** - Comma separated list of recipients email addresses e.g: "someone@example.com"
|
|
402
415
|
- **emailOnError.smtp.cc** - Comma separated list of cc email addresses
|
|
403
416
|
|
|
417
|
+
- **kubernetes** - Enable Kubernetes support for healthchecks and graceful shutdown.
|
|
418
|
+
- **kubernetes.enabled** - true or false, true will enable Kubernets health checks and shutdown handler
|
|
419
|
+
- **kubernetes.shutdownTimeout** - Number of milliseconds to wait before shutting down (default 15000).
|
|
420
|
+
- **kubernetes.forceExitTimeout** - Number of milliseconds before forceful exiting (default 1000).
|
|
421
|
+
|
|
404
422
|
- **endpoint** - Contains endpoint specific configuration according to our **plugin code**.
|
|
405
423
|
|
|
406
424
|
#### Configuration notes
|
|
@@ -1033,12 +1051,13 @@ Plugins should have following initialization:
|
|
|
1033
1051
|
let validScimAttr = [] // empty array - all attrbutes are supported by endpoint
|
|
1034
1052
|
// add any external config process.env and process.file
|
|
1035
1053
|
config = scimgateway.processExtConfig(pluginName, config)
|
|
1054
|
+
scimgateway.authPassThroughAllowed = false
|
|
1036
1055
|
// mandatory plugin initialization - end
|
|
1037
1056
|
|
|
1038
1057
|
|
|
1039
1058
|
### getUsers
|
|
1040
1059
|
|
|
1041
|
-
scimgateway.getUsers = async (baseEntity, getObj, attributes) => {
|
|
1060
|
+
scimgateway.getUsers = async (baseEntity, getObj, attributes, ctx) => {
|
|
1042
1061
|
let ret = {
|
|
1043
1062
|
"Resources": [],
|
|
1044
1063
|
"totalResults": null
|
|
@@ -1060,7 +1079,7 @@ ret.totalResults = if supporting pagination, then it should be set to the total
|
|
|
1060
1079
|
|
|
1061
1080
|
### deleteUser
|
|
1062
1081
|
|
|
1063
|
-
scimgateway.deleteUser = async (baseEntity, id) => {
|
|
1082
|
+
scimgateway.deleteUser = async (baseEntity, id, ctx) => {
|
|
1064
1083
|
...
|
|
1065
1084
|
return null
|
|
1066
1085
|
}
|
|
@@ -1070,7 +1089,7 @@ ret.totalResults = if supporting pagination, then it should be set to the total
|
|
|
1070
1089
|
|
|
1071
1090
|
### modifyUser
|
|
1072
1091
|
|
|
1073
|
-
scimgateway.modifyUser = async (baseEntity, id, attrObj) => {
|
|
1092
|
+
scimgateway.modifyUser = async (baseEntity, id, attrObj, ctx) => {
|
|
1074
1093
|
...
|
|
1075
1094
|
return null
|
|
1076
1095
|
}
|
|
@@ -1083,7 +1102,7 @@ Note, multi-value attributes excluding user attribute 'groups' are customized fr
|
|
|
1083
1102
|
|
|
1084
1103
|
### getGroups
|
|
1085
1104
|
|
|
1086
|
-
scimgateway.getGroups = async (baseEntity, getObj, attributes) => {
|
|
1105
|
+
scimgateway.getGroups = async (baseEntity, getObj, attributes, ctx) => {
|
|
1087
1106
|
let ret = {
|
|
1088
1107
|
"Resources": [],
|
|
1089
1108
|
"totalResults": null
|
|
@@ -1105,7 +1124,7 @@ ret.totalResults = if supporting pagination, then it should be set to the total
|
|
|
1105
1124
|
|
|
1106
1125
|
|
|
1107
1126
|
### createGroup
|
|
1108
|
-
scimgateway.createGroup = async (baseEntity, groupObj) => {
|
|
1127
|
+
scimgateway.createGroup = async (baseEntity, groupObj, ctx) => {
|
|
1109
1128
|
...
|
|
1110
1129
|
return null
|
|
1111
1130
|
})
|
|
@@ -1115,7 +1134,7 @@ groupObj.displayName contains the group name to be created
|
|
|
1115
1134
|
* return null: null if OK, else throw error
|
|
1116
1135
|
|
|
1117
1136
|
### deleteGroup
|
|
1118
|
-
scimgateway.deleteGroup = async (baseEntity, id) => {
|
|
1137
|
+
scimgateway.deleteGroup = async (baseEntity, id, ctx) => {
|
|
1119
1138
|
...
|
|
1120
1139
|
return null
|
|
1121
1140
|
}
|
|
@@ -1125,7 +1144,7 @@ groupObj.displayName contains the group name to be created
|
|
|
1125
1144
|
|
|
1126
1145
|
### modifyGroup
|
|
1127
1146
|
|
|
1128
|
-
scimgateway.modifyGroup = async (baseEntity, id, attrObj) => {
|
|
1147
|
+
scimgateway.modifyGroup = async (baseEntity, id, attrObj, ctx) => {
|
|
1129
1148
|
...
|
|
1130
1149
|
return null
|
|
1131
1150
|
}
|
|
@@ -1146,6 +1165,53 @@ MIT © [Jarle Elshaug](https://www.elshaug.xyz)
|
|
|
1146
1165
|
|
|
1147
1166
|
## Change log
|
|
1148
1167
|
|
|
1168
|
+
### v4.2.0
|
|
1169
|
+
|
|
1170
|
+
[Added]
|
|
1171
|
+
|
|
1172
|
+
- Kubernetes health checks and shutdown handler support
|
|
1173
|
+
|
|
1174
|
+
Plugin configuration prerequisite: **kubernetes.enabled=true**
|
|
1175
|
+
|
|
1176
|
+
"kubernetes": {
|
|
1177
|
+
"enabled": true,
|
|
1178
|
+
"shutdownTimeout": 15000,
|
|
1179
|
+
"forceExitTimeout": 1000
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
**Thanks to Kevin Osborn**
|
|
1183
|
+
|
|
1184
|
+
### v4.1.15
|
|
1185
|
+
|
|
1186
|
+
[Added]
|
|
1187
|
+
|
|
1188
|
+
- Authentication PassThrough for passing the authentication directly to plugin without being processed by scimgateway. Plugin can then pass this authentication to endpoint for avoid maintaining secrets at the gateway.
|
|
1189
|
+
|
|
1190
|
+
Plugin configuration prerequisites: **auth.passThrough.enabled=true**
|
|
1191
|
+
|
|
1192
|
+
"auth": {
|
|
1193
|
+
...
|
|
1194
|
+
"passThrough": {
|
|
1195
|
+
"enabled": true,
|
|
1196
|
+
"readOnly": false,
|
|
1197
|
+
"baseEntities": []
|
|
1198
|
+
}
|
|
1199
|
+
...
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
Plugin binary prerequisites:
|
|
1203
|
+
|
|
1204
|
+
scimgateway.authPassThroughAllowed = true
|
|
1205
|
+
// also need endpoint logic for handling/passing ctx.request.header.authorization
|
|
1206
|
+
|
|
1207
|
+
|
|
1208
|
+
For upgrading existing custom plugins, above mention prerequisites needs to be included and in addition all plugin methods must include the `ctx` parameter e.g.:
|
|
1209
|
+
|
|
1210
|
+
scimgateway.getUsers = async (baseEntity, getObj, attributes, ctx)
|
|
1211
|
+
// tip, see provided example plugins
|
|
1212
|
+
|
|
1213
|
+
**Thanks to Kevin Osborn**
|
|
1214
|
+
|
|
1149
1215
|
### v4.1.14
|
|
1150
1216
|
|
|
1151
1217
|
[Fixed]
|
package/config/plugin-api.json
CHANGED
|
@@ -57,7 +57,12 @@
|
|
|
57
57
|
"readOnly": false,
|
|
58
58
|
"baseEntities": []
|
|
59
59
|
}
|
|
60
|
-
]
|
|
60
|
+
],
|
|
61
|
+
"passThrough": {
|
|
62
|
+
"enabled": false,
|
|
63
|
+
"readOnly": false,
|
|
64
|
+
"baseEntities": []
|
|
65
|
+
}
|
|
61
66
|
},
|
|
62
67
|
"certificate": {
|
|
63
68
|
"key": null,
|
|
@@ -82,12 +87,19 @@
|
|
|
82
87
|
"to": null,
|
|
83
88
|
"cc": null
|
|
84
89
|
}
|
|
90
|
+
},
|
|
91
|
+
"kubernetes": {
|
|
92
|
+
"enabled": false,
|
|
93
|
+
"shutdownTimeout": 15000,
|
|
94
|
+
"forceExitTimeout": 1000
|
|
85
95
|
}
|
|
86
96
|
},
|
|
87
97
|
"endpoint": {
|
|
88
98
|
"entity": {
|
|
89
99
|
"undefined": {
|
|
90
|
-
"baseUrls": [
|
|
100
|
+
"baseUrls": [
|
|
101
|
+
"http://fakerestapi.azurewebsites.net"
|
|
102
|
+
],
|
|
91
103
|
"username": "endpointuser",
|
|
92
104
|
"password": "password",
|
|
93
105
|
"proxy": {
|
|
@@ -57,7 +57,12 @@
|
|
|
57
57
|
"readOnly": false,
|
|
58
58
|
"baseEntities": []
|
|
59
59
|
}
|
|
60
|
-
]
|
|
60
|
+
],
|
|
61
|
+
"passThrough": {
|
|
62
|
+
"enabled": false,
|
|
63
|
+
"readOnly": false,
|
|
64
|
+
"baseEntities": []
|
|
65
|
+
}
|
|
61
66
|
},
|
|
62
67
|
"certificate": {
|
|
63
68
|
"key": null,
|
|
@@ -82,6 +87,11 @@
|
|
|
82
87
|
"to": null,
|
|
83
88
|
"cc": null
|
|
84
89
|
}
|
|
90
|
+
},
|
|
91
|
+
"kubernetes": {
|
|
92
|
+
"enabled": false,
|
|
93
|
+
"shutdownTimeout": 15000,
|
|
94
|
+
"forceExitTimeout": 1000
|
|
85
95
|
}
|
|
86
96
|
},
|
|
87
97
|
"endpoint": {
|
|
@@ -57,7 +57,12 @@
|
|
|
57
57
|
"readOnly": false,
|
|
58
58
|
"baseEntities": []
|
|
59
59
|
}
|
|
60
|
-
]
|
|
60
|
+
],
|
|
61
|
+
"passThrough": {
|
|
62
|
+
"enabled": false,
|
|
63
|
+
"readOnly": false,
|
|
64
|
+
"baseEntities": []
|
|
65
|
+
}
|
|
61
66
|
},
|
|
62
67
|
"certificate": {
|
|
63
68
|
"key": null,
|
|
@@ -82,6 +87,11 @@
|
|
|
82
87
|
"to": null,
|
|
83
88
|
"cc": null
|
|
84
89
|
}
|
|
90
|
+
},
|
|
91
|
+
"kubernetes": {
|
|
92
|
+
"enabled": false,
|
|
93
|
+
"shutdownTimeout": 15000,
|
|
94
|
+
"forceExitTimeout": 1000
|
|
85
95
|
}
|
|
86
96
|
},
|
|
87
97
|
"endpoint": {
|
package/config/plugin-ldap.json
CHANGED
|
@@ -57,7 +57,12 @@
|
|
|
57
57
|
"readOnly": false,
|
|
58
58
|
"baseEntities": []
|
|
59
59
|
}
|
|
60
|
-
]
|
|
60
|
+
],
|
|
61
|
+
"passThrough": {
|
|
62
|
+
"enabled": false,
|
|
63
|
+
"readOnly": false,
|
|
64
|
+
"baseEntities": []
|
|
65
|
+
}
|
|
61
66
|
},
|
|
62
67
|
"certificate": {
|
|
63
68
|
"key": null,
|
|
@@ -82,6 +87,11 @@
|
|
|
82
87
|
"to": null,
|
|
83
88
|
"cc": null
|
|
84
89
|
}
|
|
90
|
+
},
|
|
91
|
+
"kubernetes": {
|
|
92
|
+
"enabled": false,
|
|
93
|
+
"shutdownTimeout": 15000,
|
|
94
|
+
"forceExitTimeout": 1000
|
|
85
95
|
}
|
|
86
96
|
},
|
|
87
97
|
"endpoint": {
|
package/config/plugin-loki.json
CHANGED
|
@@ -57,7 +57,12 @@
|
|
|
57
57
|
"readOnly": false,
|
|
58
58
|
"baseEntities": []
|
|
59
59
|
}
|
|
60
|
-
]
|
|
60
|
+
],
|
|
61
|
+
"passThrough": {
|
|
62
|
+
"enabled": false,
|
|
63
|
+
"readOnly": false,
|
|
64
|
+
"baseEntities": []
|
|
65
|
+
}
|
|
61
66
|
},
|
|
62
67
|
"certificate": {
|
|
63
68
|
"key": null,
|
|
@@ -82,6 +87,11 @@
|
|
|
82
87
|
"to": null,
|
|
83
88
|
"cc": null
|
|
84
89
|
}
|
|
90
|
+
},
|
|
91
|
+
"kubernetes": {
|
|
92
|
+
"enabled": false,
|
|
93
|
+
"shutdownTimeout": 15000,
|
|
94
|
+
"forceExitTimeout": 1000
|
|
85
95
|
}
|
|
86
96
|
},
|
|
87
97
|
"endpoint": {
|
|
@@ -63,7 +63,12 @@
|
|
|
63
63
|
"readOnly": false,
|
|
64
64
|
"baseEntities": []
|
|
65
65
|
}
|
|
66
|
-
]
|
|
66
|
+
],
|
|
67
|
+
"passThrough": {
|
|
68
|
+
"enabled": false,
|
|
69
|
+
"readOnly": false,
|
|
70
|
+
"baseEntities": []
|
|
71
|
+
}
|
|
67
72
|
},
|
|
68
73
|
"certificate": {
|
|
69
74
|
"key": null,
|
|
@@ -88,6 +93,11 @@
|
|
|
88
93
|
"to": null,
|
|
89
94
|
"cc": null
|
|
90
95
|
}
|
|
96
|
+
},
|
|
97
|
+
"kubernetes": {
|
|
98
|
+
"enabled": false,
|
|
99
|
+
"shutdownTimeout": 15000,
|
|
100
|
+
"forceExitTimeout": 1000
|
|
91
101
|
}
|
|
92
102
|
},
|
|
93
103
|
"endpoint": {
|
package/config/plugin-mssql.json
CHANGED
|
@@ -57,7 +57,12 @@
|
|
|
57
57
|
"readOnly": false,
|
|
58
58
|
"baseEntities": []
|
|
59
59
|
}
|
|
60
|
-
]
|
|
60
|
+
],
|
|
61
|
+
"passThrough": {
|
|
62
|
+
"enabled": false,
|
|
63
|
+
"readOnly": false,
|
|
64
|
+
"baseEntities": []
|
|
65
|
+
}
|
|
61
66
|
},
|
|
62
67
|
"certificate": {
|
|
63
68
|
"key": null,
|
|
@@ -82,6 +87,11 @@
|
|
|
82
87
|
"to": null,
|
|
83
88
|
"cc": null
|
|
84
89
|
}
|
|
90
|
+
},
|
|
91
|
+
"kubernetes": {
|
|
92
|
+
"enabled": false,
|
|
93
|
+
"shutdownTimeout": 15000,
|
|
94
|
+
"forceExitTimeout": 1000
|
|
85
95
|
}
|
|
86
96
|
},
|
|
87
97
|
"endpoint": {
|
|
@@ -57,7 +57,12 @@
|
|
|
57
57
|
"readOnly": false,
|
|
58
58
|
"baseEntities": []
|
|
59
59
|
}
|
|
60
|
-
]
|
|
60
|
+
],
|
|
61
|
+
"passThrough": {
|
|
62
|
+
"enabled": false,
|
|
63
|
+
"readOnly": false,
|
|
64
|
+
"baseEntities": []
|
|
65
|
+
}
|
|
61
66
|
},
|
|
62
67
|
"certificate": {
|
|
63
68
|
"key": null,
|
|
@@ -82,6 +87,11 @@
|
|
|
82
87
|
"to": null,
|
|
83
88
|
"cc": null
|
|
84
89
|
}
|
|
90
|
+
},
|
|
91
|
+
"kubernetes": {
|
|
92
|
+
"enabled": false,
|
|
93
|
+
"shutdownTimeout": 15000,
|
|
94
|
+
"forceExitTimeout": 1000
|
|
85
95
|
}
|
|
86
96
|
},
|
|
87
97
|
"endpoint": {
|
package/config/plugin-scim.json
CHANGED
|
@@ -57,7 +57,12 @@
|
|
|
57
57
|
"readOnly": false,
|
|
58
58
|
"baseEntities": []
|
|
59
59
|
}
|
|
60
|
-
]
|
|
60
|
+
],
|
|
61
|
+
"passThrough": {
|
|
62
|
+
"enabled": false,
|
|
63
|
+
"readOnly": false,
|
|
64
|
+
"baseEntities": []
|
|
65
|
+
}
|
|
61
66
|
},
|
|
62
67
|
"certificate": {
|
|
63
68
|
"key": null,
|
|
@@ -82,12 +87,19 @@
|
|
|
82
87
|
"to": null,
|
|
83
88
|
"cc": null
|
|
84
89
|
}
|
|
90
|
+
},
|
|
91
|
+
"kubernetes": {
|
|
92
|
+
"enabled": false,
|
|
93
|
+
"shutdownTimeout": 15000,
|
|
94
|
+
"forceExitTimeout": 1000
|
|
85
95
|
}
|
|
86
96
|
},
|
|
87
97
|
"endpoint": {
|
|
88
98
|
"entity": {
|
|
89
99
|
"undefined": {
|
|
90
|
-
"baseUrls": [
|
|
100
|
+
"baseUrls": [
|
|
101
|
+
"http://localhost:8880"
|
|
102
|
+
],
|
|
91
103
|
"scimVersion": "2.0",
|
|
92
104
|
"username": "gwadmin",
|
|
93
105
|
"password": "password",
|
|
@@ -98,7 +110,9 @@
|
|
|
98
110
|
}
|
|
99
111
|
},
|
|
100
112
|
"clientA": {
|
|
101
|
-
"baseUrls": [
|
|
113
|
+
"baseUrls": [
|
|
114
|
+
"http://localhost:8880"
|
|
115
|
+
],
|
|
102
116
|
"scimVersion": "2.0",
|
|
103
117
|
"username": "gwadmin",
|
|
104
118
|
"password": "password",
|
package/lib/plugin-api.js
CHANGED
|
@@ -46,6 +46,7 @@ const configDir = path.join(__dirname, '..', 'config')
|
|
|
46
46
|
const configFile = path.join(`${configDir}`, `${pluginName}.json`)
|
|
47
47
|
let config = require(configFile).endpoint
|
|
48
48
|
config = scimgateway.processExtConfig(pluginName, config) // add any external config process.env and process.file
|
|
49
|
+
scimgateway.authPassThroughAllowed = false // true enables auth passThrough (no scimgateway authentication). scimgateway instead includes ctx (ctx.request.header) in plugin methods. Note, requires plugin-logic for handling/passing ctx.request.header.authorization to be used in endpoint communication
|
|
49
50
|
// mandatory plugin initialization - end
|
|
50
51
|
|
|
51
52
|
const _serviceClient = {}
|
|
@@ -58,7 +59,7 @@ const _serviceClient = {}
|
|
|
58
59
|
// post http://localhost:8890/api
|
|
59
60
|
// body = {"eventName":"AssignAccessRoleEvent","subjectName":"RACF_System-B","userID":"peter01"}
|
|
60
61
|
//
|
|
61
|
-
scimgateway.postApi = async (baseEntity, apiObj) => {
|
|
62
|
+
scimgateway.postApi = async (baseEntity, apiObj, ctx) => {
|
|
62
63
|
const action = 'postApi'
|
|
63
64
|
scimgateway.logger.debug(`${pluginName} handling "${action}" apiObj=${JSON.stringify(apiObj)}`)
|
|
64
65
|
|
|
@@ -92,7 +93,7 @@ scimgateway.postApi = async (baseEntity, apiObj) => {
|
|
|
92
93
|
// put http://localhost:8890/api/1
|
|
93
94
|
// body = {"eventName":"AssignAccessRoleEvent","subjectName":"RACF_System-B","userID":"peter01"}
|
|
94
95
|
//
|
|
95
|
-
scimgateway.putApi = async (baseEntity, id, apiObj) => {
|
|
96
|
+
scimgateway.putApi = async (baseEntity, id, apiObj, ctx) => {
|
|
96
97
|
const action = 'putApi'
|
|
97
98
|
scimgateway.logger.debug(`${pluginName}[${baseEntity}] handling "${action}" id=${id} apiObj=${JSON.stringify(apiObj)}`)
|
|
98
99
|
|
|
@@ -126,7 +127,7 @@ scimgateway.putApi = async (baseEntity, id, apiObj) => {
|
|
|
126
127
|
// patch http://localhost:8890/api/1
|
|
127
128
|
// body = {"eventName":"AssignAccessRoleEvent","subjectName":"RACF_System-B","userID":"peter01"}
|
|
128
129
|
//
|
|
129
|
-
scimgateway.patchApi = async (baseEntity, id, apiObj) => {
|
|
130
|
+
scimgateway.patchApi = async (baseEntity, id, apiObj, ctx) => {
|
|
130
131
|
const action = 'patchApi'
|
|
131
132
|
scimgateway.logger.debug(`${pluginName}[${baseEntity}] handling "${action}" id=${id} apiObj=${JSON.stringify(apiObj)}`)
|
|
132
133
|
|
|
@@ -160,7 +161,7 @@ scimgateway.patchApi = async (baseEntity, id, apiObj) => {
|
|
|
160
161
|
// get http://localhost:8890/api/1
|
|
161
162
|
// get http://localhost:8890/api?queries
|
|
162
163
|
//
|
|
163
|
-
scimgateway.getApi = async (baseEntity, id, apiQuery, apiObj) => {
|
|
164
|
+
scimgateway.getApi = async (baseEntity, id, apiQuery, apiObj, ctx) => {
|
|
164
165
|
const action = 'getApi'
|
|
165
166
|
scimgateway.logger.debug(`${pluginName}[${baseEntity}] handling "${action}" id=${id} apiQuery=${JSON.stringify(apiQuery)} apiObj=${JSON.stringify(apiObj)}`)
|
|
166
167
|
|
|
@@ -191,7 +192,7 @@ scimgateway.getApi = async (baseEntity, id, apiQuery, apiObj) => {
|
|
|
191
192
|
// example:
|
|
192
193
|
// delete http://localhost:8890/api/1
|
|
193
194
|
//
|
|
194
|
-
scimgateway.deleteApi = async (baseEntity, id) => {
|
|
195
|
+
scimgateway.deleteApi = async (baseEntity, id, ctx) => {
|
|
195
196
|
const action = 'deleteApi'
|
|
196
197
|
scimgateway.logger.debug(`${pluginName}[${baseEntity}] handling "${action}" id=${id}`)
|
|
197
198
|
|
package/lib/plugin-azure-ad.js
CHANGED
|
@@ -87,6 +87,7 @@ const configDir = path.join(__dirname, '..', 'config')
|
|
|
87
87
|
const configFile = path.join(`${configDir}`, `${pluginName}.json`)
|
|
88
88
|
let config = require(configFile).endpoint
|
|
89
89
|
config = scimgateway.processExtConfig(pluginName, config) // add any external config process.env and process.file
|
|
90
|
+
scimgateway.authPassThroughAllowed = false // true enables auth passThrough (no scimgateway authentication). scimgateway instead includes ctx (ctx.request.header) in plugin methods. Note, requires plugin-logic for handling/passing ctx.request.header.authorization to be used in endpoint communication
|
|
90
91
|
// mandatory plugin initialization - end
|
|
91
92
|
|
|
92
93
|
if (config.map) { // having licensDetails map here instead of config file
|
|
@@ -135,7 +136,7 @@ const lock = new scimgateway.Lock()
|
|
|
135
136
|
// =================================================
|
|
136
137
|
// getUsers
|
|
137
138
|
// =================================================
|
|
138
|
-
scimgateway.getUsers = async (baseEntity, getObj, attributes) => {
|
|
139
|
+
scimgateway.getUsers = async (baseEntity, getObj, attributes, ctx) => {
|
|
139
140
|
//
|
|
140
141
|
// "getObj" = { attribute: <>, operator: <>, value: <>, rawFilter: <>, startIndex: <>, count: <> }
|
|
141
142
|
// rawFilter is always included when filtering
|
|
@@ -238,7 +239,7 @@ scimgateway.getUsers = async (baseEntity, getObj, attributes) => {
|
|
|
238
239
|
// =================================================
|
|
239
240
|
// createUser
|
|
240
241
|
// =================================================
|
|
241
|
-
scimgateway.createUser = async (baseEntity, userObj) => {
|
|
242
|
+
scimgateway.createUser = async (baseEntity, userObj, ctx) => {
|
|
242
243
|
const action = 'createUser'
|
|
243
244
|
scimgateway.logger.debug(`${pluginName}[${baseEntity}] handling "${action}" userObj=${JSON.stringify(userObj)}`)
|
|
244
245
|
|
|
@@ -255,7 +256,7 @@ scimgateway.createUser = async (baseEntity, userObj) => {
|
|
|
255
256
|
try {
|
|
256
257
|
await doRequest(baseEntity, method, path, body)
|
|
257
258
|
if (attrObj.servicePlan) {
|
|
258
|
-
await scimgateway.modifyUser(baseEntity, userObj.userName, attrObj)
|
|
259
|
+
await scimgateway.modifyUser(baseEntity, userObj.userName, attrObj, ctx)
|
|
259
260
|
return null
|
|
260
261
|
} else return (null)
|
|
261
262
|
} catch (err) {
|
|
@@ -268,7 +269,7 @@ scimgateway.createUser = async (baseEntity, userObj) => {
|
|
|
268
269
|
// =================================================
|
|
269
270
|
// deleteUser
|
|
270
271
|
// =================================================
|
|
271
|
-
scimgateway.deleteUser = async (baseEntity, id) => {
|
|
272
|
+
scimgateway.deleteUser = async (baseEntity, id, ctx) => {
|
|
272
273
|
const action = 'deleteUser'
|
|
273
274
|
scimgateway.logger.debug(`${pluginName}[${baseEntity}] handling "${action}" id=${id}`)
|
|
274
275
|
const method = 'DELETE'
|
|
@@ -285,7 +286,7 @@ scimgateway.deleteUser = async (baseEntity, id) => {
|
|
|
285
286
|
// =================================================
|
|
286
287
|
// modifyUser
|
|
287
288
|
// =================================================
|
|
288
|
-
scimgateway.modifyUser = async (baseEntity, id, attrObj) => {
|
|
289
|
+
scimgateway.modifyUser = async (baseEntity, id, attrObj, ctx) => {
|
|
289
290
|
const action = 'modifyUser'
|
|
290
291
|
scimgateway.logger.debug(`${pluginName}[${baseEntity}] handling "${action}" id=${id} attrObj=${JSON.stringify(attrObj)}`)
|
|
291
292
|
const arrLicAdd = []
|
|
@@ -517,7 +518,7 @@ scimgateway.modifyUser = async (baseEntity, id, attrObj) => {
|
|
|
517
518
|
// =================================================
|
|
518
519
|
// getGroups
|
|
519
520
|
// =================================================
|
|
520
|
-
scimgateway.getGroups = async (baseEntity, getObj, attributes) => {
|
|
521
|
+
scimgateway.getGroups = async (baseEntity, getObj, attributes, ctx) => {
|
|
521
522
|
//
|
|
522
523
|
// "getObj" = { attribute: <>, operator: <>, value: <>, rawFilter: <>, startIndex: <>, count: <> }
|
|
523
524
|
// rawFilter is always included when filtering
|
|
@@ -652,7 +653,7 @@ scimgateway.getGroups = async (baseEntity, getObj, attributes) => {
|
|
|
652
653
|
// =================================================
|
|
653
654
|
// createGroup
|
|
654
655
|
// =================================================
|
|
655
|
-
scimgateway.createGroup = async (baseEntity, groupObj) => {
|
|
656
|
+
scimgateway.createGroup = async (baseEntity, groupObj, ctx) => {
|
|
656
657
|
const action = 'createGroup'
|
|
657
658
|
scimgateway.logger.debug(`${pluginName}[${baseEntity}] handling "${action}" groupObj=${JSON.stringify(groupObj)}`)
|
|
658
659
|
const body = { displayName: groupObj.displayName }
|
|
@@ -663,7 +664,7 @@ scimgateway.createGroup = async (baseEntity, groupObj) => {
|
|
|
663
664
|
const path = '/Groups'
|
|
664
665
|
|
|
665
666
|
try {
|
|
666
|
-
const res = await scimgateway.getGroups(baseEntity, { attribute: 'displayName', operator: 'eq', value: groupObj.displayName }, ['id', 'displayName'])
|
|
667
|
+
const res = await scimgateway.getGroups(baseEntity, { attribute: 'displayName', operator: 'eq', value: groupObj.displayName }, ['id', 'displayName'], ctx)
|
|
667
668
|
if (res && res.Resources && res.Resources.length > 0) {
|
|
668
669
|
throw new Error(`group ${groupObj.displayName} already exist`)
|
|
669
670
|
}
|
|
@@ -679,7 +680,7 @@ scimgateway.createGroup = async (baseEntity, groupObj) => {
|
|
|
679
680
|
// =================================================
|
|
680
681
|
// deleteGroup
|
|
681
682
|
// =================================================
|
|
682
|
-
scimgateway.deleteGroup = async (baseEntity, id) => {
|
|
683
|
+
scimgateway.deleteGroup = async (baseEntity, id, ctx) => {
|
|
683
684
|
const action = 'deleteGroup'
|
|
684
685
|
scimgateway.logger.debug(`${pluginName}[${baseEntity}] handling "${action}" id=${id}`)
|
|
685
686
|
throw new Error(`${action} error: ${action} is not supported`)
|
|
@@ -688,7 +689,7 @@ scimgateway.deleteGroup = async (baseEntity, id) => {
|
|
|
688
689
|
// =================================================
|
|
689
690
|
// modifyGroup
|
|
690
691
|
// =================================================
|
|
691
|
-
scimgateway.modifyGroup = async (baseEntity, id, attrObj) => {
|
|
692
|
+
scimgateway.modifyGroup = async (baseEntity, id, attrObj, ctx) => {
|
|
692
693
|
const action = 'modifyGroup'
|
|
693
694
|
scimgateway.logger.debug(`${pluginName}[${baseEntity}] handling "${action}" id=${id} attrObj=${JSON.stringify(attrObj)}`)
|
|
694
695
|
|
|
@@ -755,7 +756,7 @@ scimgateway.modifyGroup = async (baseEntity, id, attrObj) => {
|
|
|
755
756
|
// =================================================
|
|
756
757
|
// getServicePlans
|
|
757
758
|
// =================================================
|
|
758
|
-
scimgateway.getServicePlans = async (baseEntity, getObj, attributes) => {
|
|
759
|
+
scimgateway.getServicePlans = async (baseEntity, getObj, attributes, ctx) => {
|
|
759
760
|
//
|
|
760
761
|
// "getObj" = { attribute: <>, operator: <>, value: <>, rawFilter: <>, startIndex: <>, count: <> }
|
|
761
762
|
// rawFilter is always included when filtering - attribute, operator and value are included when requesting unique object or simpel filtering
|
|
@@ -875,7 +876,7 @@ scimgateway.getServicePlans = async (baseEntity, getObj, attributes) => {
|
|
|
875
876
|
// =================================================
|
|
876
877
|
// createServicePlan
|
|
877
878
|
// =================================================
|
|
878
|
-
scimgateway.createServicePlan = async (baseEntity, id) => {
|
|
879
|
+
scimgateway.createServicePlan = async (baseEntity, id, ctx) => {
|
|
879
880
|
const action = 'createServicePlan'
|
|
880
881
|
scimgateway.logger.debug(`${pluginName}[${baseEntity}] handling "${action}" id=${id}`)
|
|
881
882
|
throw new Error(`${action} error: ${action} is not supported`)
|
|
@@ -884,7 +885,7 @@ scimgateway.createServicePlan = async (baseEntity, id) => {
|
|
|
884
885
|
// =================================================
|
|
885
886
|
// deleteServicePlan
|
|
886
887
|
// =================================================
|
|
887
|
-
scimgateway.deleteServicePlan = async (baseEntity, id) => {
|
|
888
|
+
scimgateway.deleteServicePlan = async (baseEntity, id, ctx) => {
|
|
888
889
|
const action = 'deleteServicePlan'
|
|
889
890
|
scimgateway.logger.debug(`${pluginName}[${baseEntity}] handling "${action}" id=${id}`)
|
|
890
891
|
throw new Error(`${action} error: ${action} is not supported`)
|
|
@@ -893,7 +894,7 @@ scimgateway.deleteServicePlan = async (baseEntity, id) => {
|
|
|
893
894
|
// =================================================
|
|
894
895
|
// modifyServicePlan
|
|
895
896
|
// =================================================
|
|
896
|
-
scimgateway.modifyServicePlan = async (baseEntity, id) => {
|
|
897
|
+
scimgateway.modifyServicePlan = async (baseEntity, id, ctx) => {
|
|
897
898
|
const action = 'modifyServicePlan'
|
|
898
899
|
scimgateway.logger.debug(`${pluginName}[${baseEntity}] handling "${action}" id=${id}`)
|
|
899
900
|
throw new Error(`${action} error: ${action} is not supported`)
|