Connect to DS with ScriptedREST
The PingDS (DS) Rest2ldap HTTP endpoint has been removed as of DS 8.0. You can use this sample with DS 7.5. |
This sample uses the scripted REST connector and Groovy scripts to interact with the DS REST API. It demonstrates reconciliation, implicit sync, and liveSync between the IDM repository and a DS instance.
The scripted REST connector is bundled with IDM in the JAR openidm/connectors/scriptedrest-connector-1.5.20.29.jar
.
The Groovy scripts for this sample are in the samples/scripted-rest-with-dj/tools
directory. Use the scripts as a starting point that you can customize for your deployment.
Set up DS
-
Set up DS, but remove the line
--set ds-user-data/ldifFile:Example.ldif
. -
Optionally, enable an HTTP access logger on the DS server.
-
Import the data required for the sample:
/path/to/opendj/bin/ldapmodify \ --port 1636 \ --useSSL \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePassword:file /path/to/opendj/config/keystore.pin \ --hostname localhost \ --bindDN uid=admin \ --bindPassword password \ --filename /path/to/openidm/samples/scripted-rest-with-dj/data/ldap.ldif # ADD operation successful for DN dc=example,dc=com # ADD operation successful for DN ou=Administrators,dc=example,dc=com # ADD operation successful for DN uid=idm,ou=Administrators,dc=example,dc=com # ADD operation successful for DN ou=People,dc=example,dc=com # ADD operation successful for DN ou=Groups,dc=example,dc=com
-
Set up the access control instructions (ACIs) that enable the IDM administrator user to read the DS external change log:
/path/to/opendj/bin/dsconfig set-access-control-handler-prop \ --port 4444 \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePassword:file /path/to/opendj/config/keystore.pin \ --hostname localhost \ --bindDN uid=admin \ --bindPassword password \ --add global-aci:"(target=\"ldap:///cn=changelog\")(targetattr=\"*||+\") \ (version 3.0; acl \"IDM can access cn=changelog\"; \ allow (read,search,compare) \ userdn=\"ldap:///uid=idm,ou=Administrators,dc=example,dc=com\";)" \ --no-prompt
/path/to/opendj/bin/dsconfig set-access-control-handler-prop \ --port 4444 \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePassword:file /path/to/opendj/config/keystore.pin \ --hostname localhost \ --bindDN uid=admin \ --bindPassword password \ --add global-aci:"(targetcontrol=\"1.3.6.1.4.1.26027.1.5.4\") \ (version 3.0; acl \"IDM changelog control access\"; \ allow (read) \ userdn=\"ldap:///uid=idm,ou=Administrators,dc=example,dc=com\";)" \ --no-prompt
-
Enable the default Rest2ldap HTTP endpoint:
/path/to/opendj/bin/dsconfig set-http-endpoint-prop \ --port 4444 \ --usePkcs12TrustStore /path/to/opendj/config/keystore \ --trustStorePassword:file /path/to/opendj/config/keystore.pin \ --hostname localhost \ --bindDN uid=admin \ --bindPassword password \ --endpoint-name /api \ --set authorization-mechanism:"HTTP Basic" \ --set config-directory:config/rest2ldap/endpoints/api \ --set enabled:true \ --no-prompt
For more information, refer to HTTP User APIs in the DS Configuration Guide.
-
Replace the default DS REST to LDAP configuration with the configuration for this sample:
cp /path/to/openidm/samples/scripted-rest-with-dj/data/example-v1.json /path/to/opendj/config/rest2ldap/endpoints/api/
-
Restart DS to apply the configuration changes.
/path/to/opendj/bin/stop-ds --restart Stopping Server... ... The Directory Server has started successfully
Run the sample
This section illustrates the basic CRUD operations on users and groups using the ScriptedREST connector and the DS REST API. Note that the power of the Groovy connector is in the associated Groovy scripts, and their application in your particular deployment. The scripts provided with this sample are specific to the sample and customization of the scripts is required.
-
Start IDM with the configuration for the ScriptedREST sample:
cd /path/to/openidm/ ./startup.sh -p samples/scripted-rest-with-dj
-
Check that the scripted REST connector can reach the DS instance by obtaining the connector status over REST:
curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --request POST \ "http://localhost:8080/openidm/system/scriptedrest?_action=test" { "name": "scriptedrest", "enabled": true, "config": "config/provisioner.openicf/scriptedrest", "connectorRef": { "bundleVersion": "[1.5.0.0,1.6.0.0)", "bundleName": "org.forgerock.openicf.connectors.scriptedrest-connector", "connectorName": "org.forgerock.openicf.connectors.scriptedrest.ScriptedRESTConnector" }, "displayName": "Scripted REST Connector", "objectTypes": [ "__ALL__", "account", "group" ], "ok": true }
-
Create a group entry on the DS server:
curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --request POST \ --data '{ "cn": "group1" }' \ "http://localhost:8080/openidm/system/scriptedrest/group?_action=create" { "_id": "group1", "members": null, "created": "2020-07-21T23:04:25Z", "cn": "group1", "displayName": "group1" }
-
Create a user entry on the DS server. This command creates a user with the
uid
scarter
:curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --request POST \ --data '{ "givenName": "Steven", "familyName": "Carter", "emailAddress": "scarter@example.com", "telephoneNumber": "444-444-4444", "password": "5up35tr0ng", "displayName": "Steven.Carter", "uid": "scarter" }' \ "http://localhost:8080/openidm/system/scriptedrest/account?_action=create" { "_id": "scarter", "givenName": "Steven", "groups": null, "displayName": "Steven.Carter", "emailAddress": "scarter@example.com", "uid": "scarter", "created": "2020-07-21T23:07:13Z", "familyName": "Carter", "telephoneNumber": "444-444-4444" }
Notice that the user is not a member of any group.
-
Reconcile the DS server with the managed user repository:
curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --request POST \ "http://localhost:8080/openidm/recon?_action=recon&mapping=systemRestLdapUser_managedUser&waitForCompletion=true" { "_id": "ee7534bd-ccfd-4f6a-bdc3-49caa6d2043c-547", "state": "SUCCESS" }
-
The reconciliation creates a managed user with a server-assigned ID. To retrieve the ID, run the following query:
curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --request GET \ "http://localhost:8080/openidm/managed/user?_queryFilter=true&_fields=_id" { "result": [ { "_id": "4657a420-6608-410e-baa7-f64668cc500c", "_rev": "000000007995f006" } ], ... }
-
To initialize liveSync set the sync token by running one liveSync operation over REST:
curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --request POST \ "http://localhost:8080/openidm/system/scriptedrest/account?_action=liveSync" { "connectorData": { "nativeType": "string", "syncToken": "8" } }
-
Update the
scarter
managed user entry by changing the telephone number. Specify the user ID that you retrieved previously:curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --request PATCH \ --data '[ { "operation": "replace", "field": "telephoneNumber", "value": "555-555-5555" } ]' \ "http://localhost:8080/openidm/managed/user/4657a420-6608-410e-baa7-f64668cc500c" { "_id": "4657a420-6608-410e-baa7-f64668cc500c", "_rev": "0000000096edf021", "userName": "scarter", "mail": "scarter@example.com", "displayName": "Steven.Carter", "telephoneNumber": "555-555-5555", "givenName": "Steven", "sn": "Carter", "accountStatus": "active", "effectiveRoles": [], "effectiveAssignments": [] }
-
Implicit synchronization propagates the change to DS. You can verify this change by reading the
scarter
user entry in DS and noting the newtelephoneNumber
:curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "http://localhost:8080/openidm/system/scriptedrest/account/scarter" { "_id": "scarter", "familyName": "Carter", "givenName": "Steven", "created": "2018-02-07T10:14:31Z", "uid": "scarter", "groups": null, "emailAddress": "scarter@example.com", "displayName": "Steven.Carter", "telephoneNumber": "555-555-5555" }
-
Now, update the
scarter
entry on the DS server by changing thegivenName
:curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --request PATCH \ --data '[ { "operation": "replace", "field": "givenName", "value": "Steve" } ]' \ "http://localhost:8080/openidm/system/scriptedrest/account/scarter" { "_id": "scarter", "givenName": "Steve", "groups": null, "displayName": "Steven.Carter", "emailAddress": "scarter@example.com", "uid": "scarter", "created": "2020-07-21T23:07:13Z", "familyName": "Carter", "telephoneNumber": "555-555-5555" }
-
To propagate the change from DS to the managed user entry, run a liveSync operation. You can define a schedule for liveSync, or run it over REST as shown in the following command:
curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --request POST \ "http://localhost:8080/openidm/system/scriptedrest/account?_action=liveSync" { "connectorData": { "nativeType": "string", "syncToken": "9" }, "_rev": "000000000a585336", "_id": "SYSTEMSCRIPTEDRESTACCOUNT" }
-
Verify that the changes propagated by reading scarter’s managed user entry and noting the changed
givenName
:curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "http://localhost:8080/openidm/managed/user/4657a420-6608-410e-baa7-f64668cc500c" { "_id": "4657a420-6608-410e-baa7-f64668cc500c", "_rev": "000000007937efb7", "userName": "scarter", "mail": "scarter@example.com", "displayName": "Steven.Carter", "telephoneNumber": "555-555-5555", "givenName": "Steve", "sn": "Carter", "accountStatus": "active", "effectiveRoles": [], "effectiveAssignments": [] }
-
Add user
scarter
to the group you created previously, by updating the group entry:curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --header "If-Match: *" \ --request PUT \ --data '{ "_id": "group1", "members": [{"_id": "scarter"}] }' \ "http://localhost:8080/openidm/system/scriptedrest/group/group1" { "_id": "group1", "displayName": "group1", "created": "2018-02-07T10:14:12Z", "members": [ { "_id": "scarter", "displayName": "Steven.Carter" } ], "cn": "group1", "lastModified": "2018-02-07T10:20:22Z" }
-
Read the
scarter
user entry in DS to verify that the user is now a member ofgroup1
:curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "http://localhost:8080/openidm/system/scriptedrest/account/scarter" { "_id": "scarter", "givenName": "Steve", "groups": [ { "_id": "group1" } ], "displayName": "Steven.Carter", "emailAddress": "scarter@example.com", "uid": "scarter", "created": "2020-07-21T23:07:13Z", "familyName": "Carter", "telephoneNumber": "555-555-5555" }
-
Read the group entry to verify its members:
curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "http://localhost:8080/openidm/system/scriptedrest/group/group1" { "_id": "group1", "lastModified": "2020-07-21T23:17:09Z", "members": [ { "_id": "scarter", "displayName": "Steven.Carter" } ], "created": "2020-07-21T23:04:25Z", "cn": "group1", "displayName": "group1" }
-
Reconcile the DS groups with the managed group repository:
curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --request POST \ "http://localhost:8080/openidm/recon?_action=recon&mapping=systemRestLdapGroup_managedGroup&waitForCompletion=true" { "_id": "ee7534bd-ccfd-4f6a-bdc3-49caa6d2043c-1477", "state": "SUCCESS" }
-
The reconciliation creates a managed group with a server-assigned ID. To retrieve the group ID, run the following query:
curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --request GET \ "http://localhost:8080/openidm/managed/group?_queryId=query-all-ids" { "result": [ { "_id": "67b5ec50-d5a6-4bfa-bb19-17965447ad00", "_rev": "00000000b0e95e9b" } ], ... }
-
Read the managed group to verify that the DS group and its members were reconciled. Specify the ID that you retrieved in the previous step:
curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "http://localhost:8080/openidm/managed/group/67b5ec50-d5a6-4bfa-bb19-17965447ad00" { "_id": "67b5ec50-d5a6-4bfa-bb19-17965447ad00", "_rev": "00000000b0e95e9b", "members": [ { "_id": "scarter", "displayName": "Steven.Carter" } ], "displayName": "group1" }
-
Delete the user and group entries from DS to return the server to its initial state.
curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --request DELETE \ "http://localhost:8080/openidm/system/scriptedrest/account/scarter" { "_id": "scarter", "givenName": "Steve", "groups": [ { "_id": "group1" } ], "displayName": "Steven.Carter", "emailAddress": "scarter@example.com", "uid": "scarter", "created": "2020-07-21T23:07:13Z", "familyName": "Carter", "telephoneNumber": "555-555-5555" }
curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --request DELETE \ "http://localhost:8080/openidm/system/scriptedrest/group/group1" { "_id": "group1", "lastModified": "2020-07-21T23:17:09Z", "members": null, "created": "2020-07-21T23:04:25Z", "cn": "group1", "displayName": "group1" }