[SYNCOPE-978] REST resource provided, consolidated wssample into syncope-fit-build-tools
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/5af8e4a4 Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/5af8e4a4 Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/5af8e4a4 Branch: refs/heads/master Commit: 5af8e4a4eed8e4bc0113d59641ef19aadf502ca0 Parents: e7e8e92 Author: Francesco Chicchiriccò <ilgro...@apache.org> Authored: Thu Dec 1 09:27:28 2016 +0100 Committer: Francesco Chicchiriccò <ilgro...@apache.org> Committed: Thu Dec 1 09:29:10 2016 +0100 ---------------------------------------------------------------------- archetype/pom.xml | 4 + .../archetype-resources/console/pom.xml | 14 - .../archetype-resources/enduser/pom.xml | 14 - .../persistence/jpa/inner/ResourceTest.java | 2 +- .../test/resources/domains/MasterContent.xml | 44 +- fit/build-tools/pom.xml | 103 ++++ .../fit/buildtools/ConnIdStartStopListener.java | 1 + .../fit/buildtools/cxf/ProvisioningImpl.java | 586 +++++++++++++++++++ .../apache/syncope/fit/buildtools/cxf/User.java | 88 +++ .../syncope/fit/buildtools/cxf/UserService.java | 66 +++ .../fit/buildtools/cxf/UserServiceImpl.java | 114 ++++ .../src/main/resources/buildToolsContext.xml | 3 + .../src/main/resources/cxfContext.xml | 50 ++ fit/build-tools/src/main/resources/testdb.sql | 32 + .../src/main/webapp/WEB-INF/glassfish-web.xml | 28 + .../WEB-INF/jboss-deployment-structure.xml | 35 ++ fit/build-tools/src/main/webapp/WEB-INF/web.xml | 13 +- fit/console-reference/pom.xml | 14 - fit/core-reference/pom.xml | 14 - .../syncope/fit/core/ConnectorITCase.java | 6 +- .../org/apache/syncope/fit/core/UserITCase.java | 52 ++ .../resources/rest/AuthenticateScript.groovy | 55 ++ .../src/test/resources/rest/CreateScript.groovy | 65 ++ .../src/test/resources/rest/DeleteScript.groovy | 44 ++ .../src/test/resources/rest/SchemaScript.groovy | 51 ++ .../src/test/resources/rest/SearchScript.groovy | 100 ++++ .../src/test/resources/rest/SyncScript.groovy | 106 ++++ .../src/test/resources/rest/TestScript.groovy | 35 ++ .../src/test/resources/rest/UpdateScript.groovy | 98 ++++ fit/enduser-reference/pom.xml | 14 - pom.xml | 13 +- src/main/asciidoc/getting-started/obtain.adoc | 7 +- standalone/pom.xml | 24 +- 33 files changed, 1793 insertions(+), 102 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/archetype/pom.xml ---------------------------------------------------------------------- diff --git a/archetype/pom.xml b/archetype/pom.xml index 79b0c12..0b1fcaf 100644 --- a/archetype/pom.xml +++ b/archetype/pom.xml @@ -176,6 +176,10 @@ under the License. <targetPath>${project.build.outputDirectory}/archetype-resources/core/src/test/resources/scriptedsql</targetPath> </resource> <resource> + <directory>../fit/core-reference/src/test/resources/rest</directory> + <targetPath>${project.build.outputDirectory}/archetype-resources/core/src/test/resources/rest</targetPath> + </resource> + <resource> <directory>../fit/core-reference/src/main/resources</directory> <targetPath>${project.build.outputDirectory}/archetype-resources/core/src/test/resources</targetPath> <includes> http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/archetype/src/main/resources/archetype-resources/console/pom.xml ---------------------------------------------------------------------- diff --git a/archetype/src/main/resources/archetype-resources/console/pom.xml b/archetype/src/main/resources/archetype-resources/console/pom.xml index 8b38e29..144757d 100644 --- a/archetype/src/main/resources/archetype-resources/console/pom.xml +++ b/archetype/src/main/resources/archetype-resources/console/pom.xml @@ -209,12 +209,6 @@ ORYX.Editor.createByUrl = function(modelUrl){"/> <scope>test</scope> </dependency> <dependency> - <groupId>net.tirasa.connid.bundles.soap</groupId> - <artifactId>wssample</artifactId> - <type>war</type> - <scope>test</scope> - </dependency> - <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>test</scope> @@ -283,14 +277,6 @@ ORYX.Editor.createByUrl = function(modelUrl){"/> </configuration> <deployables> <deployable> - <groupId>net.tirasa.connid.bundles.soap</groupId> - <artifactId>wssample</artifactId> - <type>war</type> - <properties> - <context>wssample</context> - </properties> - </deployable> - <deployable> <groupId>org.apache.syncope.fit</groupId> <artifactId>syncope-fit-build-tools</artifactId> <type>war</type> http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/archetype/src/main/resources/archetype-resources/enduser/pom.xml ---------------------------------------------------------------------- diff --git a/archetype/src/main/resources/archetype-resources/enduser/pom.xml b/archetype/src/main/resources/archetype-resources/enduser/pom.xml index f3ba241..6bbcfeb 100644 --- a/archetype/src/main/resources/archetype-resources/enduser/pom.xml +++ b/archetype/src/main/resources/archetype-resources/enduser/pom.xml @@ -152,12 +152,6 @@ under the License. <scope>test</scope> </dependency> <dependency> - <groupId>net.tirasa.connid.bundles.soap</groupId> - <artifactId>wssample</artifactId> - <type>war</type> - <scope>test</scope> - </dependency> - <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>test</scope> @@ -226,14 +220,6 @@ under the License. </configuration> <deployables> <deployable> - <groupId>net.tirasa.connid.bundles.soap</groupId> - <artifactId>wssample</artifactId> - <type>war</type> - <properties> - <context>wssample</context> - </properties> - </deployable> - <deployable> <groupId>org.apache.syncope.fit</groupId> <artifactId>syncope-fit-build-tools</artifactId> <type>war</type> http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java index 6698bf7..3fcf4ae 100644 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ResourceTest.java @@ -87,7 +87,7 @@ public class ResourceTest extends AbstractTest { public void findAll() { List<ExternalResource> resources = resourceDAO.findAll(); assertNotNull(resources); - assertEquals(20, resources.size()); + assertEquals(21, resources.size()); } @Test http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/core/persistence-jpa/src/test/resources/domains/MasterContent.xml ---------------------------------------------------------------------- diff --git a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml index 40a2e63..50b8e47 100644 --- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml +++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml @@ -583,7 +583,7 @@ under the License. bundleName="net.tirasa.connid.bundles.soap" connectorName="net.tirasa.connid.bundles.soap.WebServiceConnector" version="${connid.soap.version}" - jsonConf='[{"schema":{"name":"endpoint","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["http://localhost:${cargo.servlet.port}/wssample/services/provisioning"]},{"schema":{"name":"servicename","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["net.tirasa.connid.bundles.soap.provisioning.interfaces.Provisioning"]}]'/> + jsonConf='[{"schema":{"name":"endpoint","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["http://localhost:${cargo.servlet.port}/syncope-fit-build-tools/cxf/soap/provisioning"]},{"schema":{"name":"servicename","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["net.tirasa.connid.bundles.soap.provisioning.interfaces.Provisioning"]}]'/> <ConnInstance_capabilities connInstance_id="88a7a819-dab5-46b4-9b90-0b9769eabdb8" capability="CREATE"/> <ConnInstance_capabilities connInstance_id="88a7a819-dab5-46b4-9b90-0b9769eabdb8" capability="UPDATE"/> <ConnInstance_capabilities connInstance_id="88a7a819-dab5-46b4-9b90-0b9769eabdb8" capability="DELETE"/> @@ -608,7 +608,7 @@ under the License. connectorName="net.tirasa.connid.bundles.soap.WebServiceConnector" version="${connid.soap.version}" connRequestTimeout="10" - jsonConf='[{"schema":{"name":"servicename","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["net.tirasa.connid.bundles.soap.provisioning.interfaces.Provisioning"]},{"schema":{"name":"endpoint","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":true,"values":["http://localhost:${cargo.servlet.port}/wssample/services/provisioning"]}]'/> + jsonConf='[{"schema":{"name":"servicename","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["net.tirasa.connid.bundles.soap.provisioning.interfaces.Provisioning"]},{"schema":{"name":"endpoint","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":true,"values":["http://localhost:${cargo.servlet.port}/syncope-fit-build-tools/cxf/soap/provisioning"]}]'/> <ConnInstance_capabilities connInstance_id="5ffbb4ac-a8c3-4b44-b699-11b398a1ba08" capability="CREATE"/> <ConnInstance_capabilities connInstance_id="5ffbb4ac-a8c3-4b44-b699-11b398a1ba08" capability="UPDATE"/> <ConnInstance_capabilities connInstance_id="5ffbb4ac-a8c3-4b44-b699-11b398a1ba08" capability="DELETE"/> @@ -619,7 +619,7 @@ under the License. bundleName="net.tirasa.connid.bundles.soap" connectorName="net.tirasa.connid.bundles.soap.WebServiceConnector" version="${connid.soap.version}" - jsonConf='[{"schema":{"name":"endpoint","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["http://localhost:${cargo.servlet.port}/wssample/services/provisioning"]},{"schema":{"name":"servicename","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["net.tirasa.connid.bundles.soap.provisioning.interfaces.Provisioning"]}]'/> + jsonConf='[{"schema":{"name":"endpoint","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["http://localhost:${cargo.servlet.port}/syncope-fit-build-tools/cxf/soap/provisioning"]},{"schema":{"name":"servicename","displayName":null,"helpMessage":null,"type":"java.lang.String","required":true,"order":0,"confidential":false,"defaultValues":null},"overridable":false,"values":["net.tirasa.connid.bundles.soap.provisioning.interfaces.Provisioning"]}]'/> <ConnInstance id="6c2acf1b-b052-46f0-8c56-7a8ad6905edf" displayName="CSVDir" location="${connid.location}" @@ -675,6 +675,18 @@ under the License. <ConnInstance_capabilities connInstance_id="a6d017fd-a705-4507-bb7c-6ab6a6745997" capability="SEARCH"/> <ConnInstance_capabilities connInstance_id="a6d017fd-a705-4507-bb7c-6ab6a6745997" capability="SYNC"/> + <ConnInstance id="44c02549-19c3-483c-8025-4919c3283c37" bundlename="net.tirasa.connid.bundles.rest" + location="connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}" + connectorname="net.tirasa.connid.bundles.rest.RESTConnector" + displayname="REST" version="${connid.rest.version}" + jsonconf="[{"schema":{"name":"authenticateScript","displayName":"authenticateScript","helpMessage":"authenticateScript","type":"java.lang.String","required":false,"order":6,"confidential":false,"defaultValues":[""]},"overridable":false,"values":[]},{"schema":{"name":"contentType","displayName":"contentType","helpMessage":"contentType","type":"java.lang.String","required":true,"order":-1,"confidential":false,"defaultValues":["application/json"]},"overridable":false,"values":["application/json"]},{"schema":{"name":"resolveUsernameScriptFileName","displayName":"resolveUsernameScriptFileName"," ;helpMessage":"resolveUsernameScriptFileName","type":"java.lang.String","required":false,"order":15,"confidential":false,"defaultValues":[]},"overridable":false,"values":[]},{"schema":{"name":"createScriptFileName","displayName":"createScriptFileName","helpMessage":"createScriptFileName","type":"java.lang.String","required":false,"order":10,"confidential":false,"defaultValues":[]},"overridable":false,"values":["${conf.directory}/rest/CreateScript.groovy"]},{"schema":{"name":"username","displayName":"username","helpMessage":"username","type":"java.lang.String","required":false,"order":0,"confidential":false,"de faultValues":[]},"overridable":false,"values":[]},{"schema":{"name":"updateScript","displayName":"updateScript","helpMessage":"updateScript","type":"java.lang.String","required":false,"order":4,"confidential":false,"defaultValues":[""]},"overridable":false,"values":[]},{"schema":{"name":"searchScript","displayName":"searchScript","helpMessage":"searchScript","type":"java.lang.String","required":false,"order":6,"confidential":false,"defaultValues":[""]},"overridable":false,"values":[]},{"schema":{"name":"clearTextPasswordToScript","displayName":"clearTextPasswordToScript","helpMessage": "clearTextPasswordToScript","type":"boolean","required":false,"order":1,"confidential":false,"defaultValues":[true]},"overridable":false,"values":[true]},{"schema":{"name":"syncScript","displayName":"syncScript","helpMessage":"syncScript","type":"java.lang.String","required":false,"order":7,"confidential":false,"defaultValues":[""]},"overridable":false,"values":[]},{"schema":{"name":"deleteScriptFileName","displayName":"deleteScriptFileName","helpMessage":"deleteScriptFileName","type":"java.lang.String","required":false,"order":12,"confidential":false,"defaultValues":[]},"overridable":false,"val ues":["${conf.directory}/rest/DeleteScript.groovy"]},{"schema":{"name":"resolveUsernameScript","displayName":"resolveUsernameScript","helpMessage":"resolveUsernameScript","type":"java.lang.String","required":false,"order":6,"confidential":false,"defaultValues":[""]},"overridable":false,"values":[]},{"schema":{"name":"searchScriptFileName","displayName":"searchScriptFileName","helpMessage":"searchScriptFileName","type":"java.lang.String","required":false,"order":13,"confidential":false,"defaultValues":[]},"overridable":false,"values":["${conf.directory}/rest/SearchScript.groovy"]},{"schema":{"name":"syncScriptFileName"," displayName":"syncScriptFileName","helpMessage":"syncScriptFileName","type":"java.lang.String","required":false,"order":16,"confidential":false,"defaultValues":[]},"overridable":false,"values":["${conf.directory}/rest/SyncScript.groovy"]},{"schema":{"name":"schemaScriptFileName","displayName":"schemaScriptFileName","helpMessage":"schemaScriptFileName","type":"java.lang.String","required":false,"order":17,"confidential":false,"defaultValues":[]},"overridable":false,"values":["${conf.directory}/rest/SchemaScript.groovy"]},{"schema":{"name":"password","displayName":"password","helpMessage":"password","type":"org.identityco nnectors.common.security.GuardedString","required":false,"order":1,"confidential":true,"defaultValues":[]},"overridable":false,"values":[]},{"schema":{"name":"updateScriptFileName","displayName":"updateScriptFileName","helpMessage":"updateScriptFileName","type":"java.lang.String","required":false,"order":11,"confidential":false,"defaultValues":[]},"overridable":false,"values":["${conf.directory}/rest/UpdateScript.groovy"]},{"schema":{"name":"testScriptFileName","displayName":"testScriptFileName","helpMessage":"testScriptFileName","type":"java.lang.String","required":false,"order":18,"confidential":false,"defaultValues":[]},"overr idable":false,"values":["${conf.directory}/rest/TestScript.groovy"]},{"schema":{"name":"accept","displayName":"accept","helpMessage":"accept","type":"java.lang.String","required":true,"order":-2,"confidential":false,"defaultValues":["application/json"]},"overridable":false,"values":["application/json"]},{"schema":{"name":"baseAddress","displayName":"baseAddress","helpMessage":"baseAddress","type":"java.lang.String","required":true,"order":-3,"confidential":false,"defaultValues":[]},"overridable":false,"values":["http://localhost:9080/syncope-fit-build-tools/cxf/rest"]},{"schema":{"name":"authenticateScriptFile Name","displayName":"authenticateScriptFileName","helpMessage":"authenticateScriptFileName","type":"java.lang.String","required":false,"order":14,"confidential":false,"defaultValues":[]},"overridable":false,"values":["${conf.directory}/rest/AuthenticateScript.groovy"]},{"schema":{"name":"deleteScript","displayName":"deleteScript","helpMessage":"deleteScript","type":"java.lang.String","required":false,"order":5,"confidential":false,"defaultValues":[""]},"overridable":false,"values":[]},{"schema":{"name":"schemaScript","displayName":"schemaScript","helpMessage":"schemaScript","type":"java.lang.String"," ;required":false,"order":8,"confidential":false,"defaultValues":[""]},"overridable":false,"values":[]},{"schema":{"name":"createScript","displayName":"createScript","helpMessage":"createScript","type":"java.lang.String","required":false,"order":3,"confidential":false,"defaultValues":[""]},"overridable":false,"values":[]},{"schema":{"name":"scriptingLanguage","displayName":"scriptingLanguage","helpMessage":"scriptingLanguage","type":"java.lang.String","required":false,"order":0,"confidential":false,"defaultValues":["GROOVY"]},"overridable":false,"values":["GROOVY"]},{"schema":{"nam e":"testScript","displayName":"testScript","helpMessage":"testScript","type":"java.lang.String","required":false,"order":9,"confidential":false,"defaultValues":[""]},"overridable":false,"values":[]},{"schema":{"name":"reloadScriptOnExecution","displayName":"reloadScriptOnExecution","helpMessage":"reloadScriptOnExecution","type":"boolean","required":false,"order":2,"confidential":false,"defaultValues":[false]},"overridable":false,"values":[false]}]"/> + <ConnInstance_capabilities connInstance_id="44c02549-19c3-483c-8025-4919c3283c37" capability="AUTHENTICATE"/> + <ConnInstance_capabilities connInstance_id="44c02549-19c3-483c-8025-4919c3283c37" capability="SYNC"/> + <ConnInstance_capabilities connInstance_id="44c02549-19c3-483c-8025-4919c3283c37" capability="CREATE"/> + <ConnInstance_capabilities connInstance_id="44c02549-19c3-483c-8025-4919c3283c37" capability="DELETE"/> + <ConnInstance_capabilities connInstance_id="44c02549-19c3-483c-8025-4919c3283c37" capability="SEARCH"/> + <ConnInstance_capabilities connInstance_id="44c02549-19c3-483c-8025-4919c3283c37" capability="UPDATE"/> + <ExternalResource id="ws-target-resource-1" connector_id="88a7a819-dab5-46b4-9b90-0b9769eabdb8" randomPwdIfNotProvided="0" enforceMandatoryCondition="0" overrideCapabilities="0" propagationPriority="1" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" provisioningTraceLevel="ALL"/> @@ -753,6 +765,11 @@ under the License. randomPwdIfNotProvided="0" createTraceLevel="ALL" deleteTraceLevel="ALL" provisioningTraceLevel="ALL" updateTraceLevel="ALL" enforceMandatoryCondition="0" overrideCapabilities="0"/> + <ExternalResource id="rest-target-resource" connector_id="44c02549-19c3-483c-8025-4919c3283c37" + createTraceLevel="ALL" updateTraceLevel="ALL" deleteTraceLevel="ALL" provisioningTraceLevel="ALL" + enforceMandatoryCondition="1" overrideCapabilities="0" + propagationPriority="0" randomPwdIfNotProvided="0"/> + <!-- Use resource-testdb for passthrough authentication (SYNCOPE-164) --> <AccountPolicy_ExternalResource accountPolicy_id="20ab5a8c-4b0c-432c-b957-f7fb9784d9f7" resource_id="resource-testdb"/> @@ -1040,6 +1057,27 @@ under the License. intAttrName="location" mandatoryCondition="false" connObjectKey="0" password="0" purpose="BOTH"/> + <Provision id="2e372858-f43c-4e1c-b728-58f43c5e1c23" objectClass="__ACCOUNT__" anyType_id="USER" resource_id="rest-target-resource"/> + <Mapping id="e6b64584-94a2-4890-b645-8494a2089011" provision_id="2e372858-f43c-4e1c-b728-58f43c5e1c23"/> + <MappingItem id="14726efb-09e1-441e-b26e-fb09e1841eb2" connObjectKey="0" + extAttrName="firstName" intAttrName="firstname" mandatoryCondition="true" password="0" purpose="BOTH" + mapping_id="e6b64584-94a2-4890-b645-8494a2089011"/> + <MappingItem id="4cdd1fd5-80cd-4fc1-9d1f-d580cd1fc11e" connObjectKey="1" + extAttrName="key" intAttrName="key" mandatoryCondition="true" password="0" purpose="BOTH" + mapping_id="e6b64584-94a2-4890-b645-8494a2089011"/> + <MappingItem id="4d7581b5-fe9b-49e6-b581-b5fe9bf9e60b" connObjectKey="0" + extAttrName="__PASSWORD__" intAttrName="password" mandatoryCondition="true" password="1" purpose="BOTH" + mapping_id="e6b64584-94a2-4890-b645-8494a2089011"/> + <MappingItem id="98f96cf4-fba2-4c68-b96c-f4fba2fc6834" connObjectKey="0" + extAttrName="username" intAttrName="username" mandatoryCondition="true" password="0" purpose="BOTH" + mapping_id="e6b64584-94a2-4890-b645-8494a2089011"/> + <MappingItem id="f3312f8f-1c94-493a-b12f-8f1c94093aa9" connObjectKey="0" + extAttrName="email" intAttrName="email" mandatoryCondition="true" password="0" purpose="BOTH" + mapping_id="e6b64584-94a2-4890-b645-8494a2089011"/> + <MappingItem id="ff49e982-fe60-4c1e-89e9-82fe60dc1ef9" connObjectKey="0" + extAttrName="surname" intAttrName="surname" mandatoryCondition="true" password="0" PURPOSE="BOTH" + mapping_id="e6b64584-94a2-4890-b645-8494a2089011"/> + <Task DTYPE="PropagationTask" id="1e697572-b896-484c-ae7f-0c8f63fcbc6c" operation="UPDATE" objectClassName="__ACCOUNT__" resource_id="ws-target-resource-2" anyTypeKind="USER" entityKey="1417acbe-cbf6-4277-9372-e75e04f97000" attributes='[{"name":"__PASSWORD__","value":[{"readOnly":false,"disposed":false,"encryptedBytes":"m9nh2US0Sa6m+cXccCq0Xw==","base64SHA1Hash":"GFJ69qfjxEOdrmt+9q+0Cw2uz60="}]},{"name":"__NAME__","value":["userId"],"nameValue":"userId"},{"name":"fullname","value":["fullname"]},{"name":"type","value":["type"]}]'/> http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/build-tools/pom.xml ---------------------------------------------------------------------- diff --git a/fit/build-tools/pom.xml b/fit/build-tools/pom.xml index 7eda7de..878ef5e 100644 --- a/fit/build-tools/pom.xml +++ b/fit/build-tools/pom.xml @@ -50,6 +50,56 @@ under the License. </dependency> <dependency> + <groupId>javax.xml.ws</groupId> + <artifactId>jaxws-api</artifactId> + <version>2.2.11</version> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-core</artifactId> + <version>${cxf.version}</version> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-transports-http</artifactId> + <version>${cxf.version}</version> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-ws-policy</artifactId> + <version>${cxf.version}</version> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-wsdl</artifactId> + <version>${cxf.version}</version> + </dependency> + + <dependency> + <groupId>net.tirasa.connid.bundles.soap</groupId> + <artifactId>soap-utilities</artifactId> + <version>${connid.soap.version}</version> + </dependency> + + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-frontend-jaxrs</artifactId> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-rs-service-description</artifactId> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.jaxrs</groupId> + <artifactId>jackson-jaxrs-json-provider</artifactId> + </dependency> + + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-core</artifactId> + <version>${spring.version}</version> + </dependency> + <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> </dependency> @@ -99,6 +149,12 @@ under the License. <version>${connid.database.version}</version> <scope>runtime</scope> </dependency> + <dependency> + <groupId>net.tirasa.connid.bundles</groupId> + <artifactId>net.tirasa.connid.bundles.rest</artifactId> + <version>${connid.rest.version}</version> + <scope>runtime</scope> + </dependency> <dependency> <groupId>org.slf4j</groupId> @@ -150,4 +206,51 @@ under the License. </resource> </resources> </build> + + <profiles> + <profile> + <id>debug</id> + + <build> + <defaultGoal>clean verify cargo:run</defaultGoal> + + <plugins> + <plugin> + <groupId>org.codehaus.cargo</groupId> + <artifactId>cargo-maven2-plugin</artifactId> + <inherited>true</inherited> + <configuration> + <container> + <dependencies> + <dependency> + <groupId>com.h2database</groupId> + <artifactId>h2</artifactId> + </dependency> + </dependencies> + </container> + <configuration> + <type>standalone</type> + <properties> + <cargo.servlet.port>${cargo.servlet.port}</cargo.servlet.port> + <cargo.tomcat.ajp.port>${cargo.tomcat.ajp.port}</cargo.tomcat.ajp.port> + <cargo.rmi.port>${cargo.rmi.port}</cargo.rmi.port> + + <cargo.jvmargs>-Xdebug -Djaxb.debug=true -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n + -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -XX:MaxPermSize=512m -Xmx1024m -Xms512m</cargo.jvmargs> + </properties> + </configuration> + <deployables> + <deployable> + <location>${project.build.directory}/${project.build.finalName}</location> + <properties> + <context>syncope-fit-build-tools</context> + </properties> + </deployable> + </deployables> + </configuration> + </plugin> + </plugins> + </build> + </profile> + </profiles> </project> http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ConnIdStartStopListener.java ---------------------------------------------------------------------- diff --git a/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ConnIdStartStopListener.java b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ConnIdStartStopListener.java index 67567ec..1cb8370 100644 --- a/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ConnIdStartStopListener.java +++ b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/ConnIdStartStopListener.java @@ -49,6 +49,7 @@ public class ConnIdStartStopListener implements ServletContextListener { for (String bundleFile : new String[] { "testconnectorserver.soap.bundle", + "testconnectorserver.rest.bundle", "testconnectorserver.dbtable.bundle", "testconnectorserver.scriptedsql.bundle", "testconnectorserver.csvdir.bundle", http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/ProvisioningImpl.java ---------------------------------------------------------------------- diff --git a/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/ProvisioningImpl.java b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/ProvisioningImpl.java new file mode 100644 index 0000000..e5854d7 --- /dev/null +++ b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/ProvisioningImpl.java @@ -0,0 +1,586 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.fit.buildtools.cxf; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import javax.jws.WebService; +import javax.sql.DataSource; +import net.tirasa.connid.bundles.soap.exceptions.ProvisioningException; +import net.tirasa.connid.bundles.soap.provisioning.interfaces.Provisioning; +import net.tirasa.connid.bundles.soap.to.WSAttribute; +import net.tirasa.connid.bundles.soap.to.WSAttributeValue; +import net.tirasa.connid.bundles.soap.to.WSChange; +import net.tirasa.connid.bundles.soap.to.WSUser; +import net.tirasa.connid.bundles.soap.utilities.Operand; +import org.identityconnectors.common.StringUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.datasource.DataSourceUtils; +import org.springframework.stereotype.Service; + +@WebService( + endpointInterface = "net.tirasa.connid.bundles.soap.provisioning.interfaces.Provisioning", + serviceName = "Provisioning") +@Service +public class ProvisioningImpl implements Provisioning { + + private static final Logger LOG = LoggerFactory.getLogger(Provisioning.class); + + @Autowired + private DataSource dataSource; + + @Override + public String delete(final String accountid) throws ProvisioningException { + LOG.debug("Delete request received"); + + Connection conn = null; + try { + conn = DataSourceUtils.getConnection(dataSource); + + Statement statement = conn.createStatement(); + + String query = "DELETE FROM user WHERE userId='" + accountid + "';"; + LOG.debug("Execute query: " + query); + + statement.executeUpdate(query); + + return accountid; + } catch (SQLException e) { + throw new ProvisioningException("Delete operation failed", e); + } finally { + DataSourceUtils.releaseConnection(conn, dataSource); + } + } + + @Override + public Boolean isSyncSupported() { + LOG.debug("isSyncSupported request received"); + + return Boolean.FALSE; + } + + @Override + public String checkAlive() { + return "OK"; + } + + @Override + public String update(final String accountid, final List<WSAttributeValue> data) + throws ProvisioningException { + + LOG.debug("Update request received"); + + if (data == null || data.isEmpty()) { + LOG.warn("Empty data recevied"); + return accountid; + } + + List<WSAttribute> schema = schema(); + Set<String> schemaNames = new HashSet<>(); + for (WSAttribute attr : schema) { + schemaNames.add(attr.getName()); + } + schemaNames.add("__NAME__"); + schemaNames.add("__PASSWORD__"); + + Connection conn = null; + + try { + conn = DataSourceUtils.getConnection(dataSource); + final Statement statement = conn.createStatement(); + + String value; + + StringBuilder set = new StringBuilder(); + for (WSAttributeValue attr : data) { + if (schemaNames.contains(attr.getName())) { + if (attr.getValues() == null || attr.getValues().isEmpty()) { + value = null; + } else if (attr.getValues().size() == 1) { + value = attr.getValues().get(0).toString(); + } else { + value = attr.getValues().toString(); + } + + if (!attr.isKey() || !accountid.equals(value)) { + if (set.length() > 0) { + set.append(","); + } + + if (null == attr.getName()) { + set.append(attr.getName()).append('='); + } else { + switch (attr.getName()) { + case "__NAME__": + set.append("userId="); + break; + case "__PASSWORD__": + set.append("password="); + break; + default: + set.append(attr.getName()).append('='); + break; + } + } + + set.append(value == null ? null : "'" + value + "'"); + } + } + } + + if (set.length() > 0) { + String query = "UPDATE user SET " + set.toString() + " WHERE userId='" + accountid + "';"; + LOG.debug("Execute query: " + query); + + statement.executeUpdate(query); + } + + return accountid; + } catch (SQLException e) { + LOG.error("Update failed", e); + throw new ProvisioningException("Update operation failed", e); + } finally { + DataSourceUtils.releaseConnection(conn, dataSource); + } + } + + @Override + public List<WSUser> query(final Operand query) { + LOG.debug("Query request received"); + + List<WSUser> results = new ArrayList<>(); + + Connection conn = null; + try { + + String queryString = "SELECT * FROM user" + (query == null ? "" : " WHERE " + query.toString()); + + queryString = queryString.replaceAll("__NAME__", "userId"). + replaceAll("__UID__", "userId"). + replaceAll("__PASSWORD__", "password"); + + LOG.debug("Execute query: {}", queryString); + + if (queryString == null || queryString.length() == 0) { + throw new SQLException("Invalid query [" + queryString + "]"); + } + + conn = DataSourceUtils.getConnection(dataSource); + Statement statement = conn.createStatement(); + + ResultSet rs = statement.executeQuery(queryString); + + ResultSetMetaData metaData = rs.getMetaData(); + LOG.debug("Metadata: {}", metaData); + + while (rs.next()) { + WSUser user = new WSUser(); + + for (int i = 0; i < metaData.getColumnCount(); i++) { + WSAttributeValue attr = new WSAttributeValue(); + attr.setName(metaData.getColumnLabel(i + 1)); + if (StringUtil.isNotBlank(rs.getString(i + 1))) { + attr.addValue(rs.getString(i + 1)); + } + if ("userId".equalsIgnoreCase(metaData.getColumnName(i + 1))) { + attr.setKey(true); + user.setAccountid(rs.getString(i + 1)); + } + + user.addAttribute(attr); + } + + results.add(user); + } + + LOG.debug("Retrieved users: {}", results); + } catch (SQLException e) { + LOG.error("Search operation failed", e); + } finally { + DataSourceUtils.releaseConnection(conn, dataSource); + } + + return results; + } + + @Override + public String create(final List<WSAttributeValue> data) throws ProvisioningException { + LOG.debug("Create request received with data {}", data); + + final List<WSAttribute> schema = schema(); + final Set<String> schemaNames = new HashSet<>(); + for (WSAttribute attr : schema) { + schemaNames.add(attr.getName()); + } + schemaNames.add("__NAME__"); + schemaNames.add("__PASSWORD__"); + + Connection conn = null; + String query = null; + try { + conn = DataSourceUtils.getConnection(dataSource); + final Statement statement = conn.createStatement(); + + final StringBuilder keys = new StringBuilder(); + final StringBuilder values = new StringBuilder(); + + String accountid = null; + String value; + for (WSAttributeValue attr : data) { + if (schemaNames.contains(attr.getName())) { + LOG.debug("Bind attribute: {}", attr); + + if (attr.getValues() == null || attr.getValues().isEmpty()) { + value = null; + } else if (attr.getValues().size() == 1) { + value = attr.getValues().get(0).toString(); + } else { + value = attr.getValues().toString(); + } + + if (keys.length() > 0) { + keys.append(","); + } + + if (null == attr.getName()) { + keys.append(attr.getName()); + } else { + switch (attr.getName()) { + case "__NAME__": + keys.append("userId"); + break; + case "__PASSWORD__": + keys.append("password"); + break; + default: + keys.append(attr.getName()); + break; + } + } + + if (values.length() > 0) { + values.append(","); + } + + values.append(value == null ? null : "'" + value + "'"); + + if (attr.isKey() && !attr.getValues().isEmpty()) { + accountid = attr.getValues().get(0).toString(); + } + } + } + + query = "INSERT INTO user (" + keys.toString() + ") VALUES (" + values.toString() + ")"; + + LOG.debug("Execute query: " + query); + + statement.executeUpdate(query); + + return accountid; + } catch (SQLException e) { + LOG.error("Creation failed:\n" + query, e); + throw new ProvisioningException("Create operation failed", e); + } finally { + DataSourceUtils.releaseConnection(conn, dataSource); + } + } + + @Override + public int getLatestChangeNumber() + throws ProvisioningException { + + LOG.debug("getLatestChangeNumber request received"); + + return 0; + } + + @Override + public List<WSChange> sync() + throws ProvisioningException { + + LOG.debug("sync request received"); + + return Collections.<WSChange>emptyList(); + } + + @Override + public String resolve(final String username) throws ProvisioningException { + + LOG.debug("Resolve request operation received: " + username); + + String resolved = ""; + + Connection conn = null; + try { + conn = DataSourceUtils.getConnection(dataSource); + Statement statement = conn.createStatement(); + + final String query = "SELECT userId FROM user WHERE userId='" + username + "';"; + + LOG.debug("Execute query: " + query); + + ResultSet rs = statement.executeQuery(query); + + resolved = rs.next() ? rs.getString(1) : null; + + if (resolved == null) { + statement = conn.createStatement(); + final String roleQuery = "SELECT roleName FROM role WHERE roleName='" + username + "';"; + LOG.debug("Execute query: " + roleQuery); + + rs = statement.executeQuery(roleQuery); + + resolved = rs.next() ? rs.getString(1) : null; + } + } catch (SQLException e) { + throw new ProvisioningException("Resolve operation failed", e); + } finally { + DataSourceUtils.releaseConnection(conn, dataSource); + } + + return resolved; + } + + @Override + public List<WSAttribute> schema() { + LOG.debug("schema request received"); + + final List<WSAttribute> attrs = new ArrayList<>(); + + WSAttribute attr = new WSAttribute(); + attr.setName("userId"); + attr.setNullable(false); + attr.setPassword(false); + attr.setKey(true); + attr.setType("String"); + attrs.add(attr); + + attr = new WSAttribute(); + attr.setName("password"); + attr.setNullable(false); + attr.setPassword(true); + attr.setKey(false); + attr.setType("String"); + attrs.add(attr); + + attr = new WSAttribute(); + attr.setName("type"); + attr.setNullable(false); + attr.setPassword(false); + attr.setKey(false); + attr.setType("String"); + attrs.add(attr); + + attr = new WSAttribute(); + attr.setName("residence"); + attr.setNullable(true); + attr.setPassword(false); + attr.setKey(false); + attr.setType("String"); + attrs.add(attr); + + attr = new WSAttribute(); + attr.setName("telephone"); + attr.setNullable(true); + attr.setPassword(false); + attr.setKey(false); + attr.setType("String"); + attrs.add(attr); + + attr = new WSAttribute(); + attr.setName("fax"); + attr.setNullable(true); + attr.setPassword(false); + attr.setKey(false); + attr.setType("String"); + attrs.add(attr); + + attr = new WSAttribute(); + attr.setName("preference"); + attr.setNullable(true); + attr.setPassword(false); + attr.setKey(false); + attr.setType("String"); + attrs.add(attr); + + attr = new WSAttribute(); + attr.setName("name"); + attr.setNullable(true); + attr.setPassword(false); + attr.setKey(false); + attr.setType("String"); + attrs.add(attr); + + attr = new WSAttribute(); + attr.setName("surname"); + attr.setNullable(true); + attr.setPassword(false); + attr.setKey(false); + attr.setType("String"); + attrs.add(attr); + + attr = new WSAttribute(); + attr.setName("fullname"); + attr.setNullable(false); + attr.setPassword(false); + attr.setKey(false); + attr.setType("String"); + attrs.add(attr); + + attr = new WSAttribute(); + attr.setName("birthdate"); + attr.setNullable(true); + attr.setPassword(false); + attr.setKey(false); + attr.setType("Date"); + attrs.add(attr); + + attr = new WSAttribute(); + attr.setName("telephone"); + attr.setNullable(true); + attr.setPassword(false); + attr.setKey(false); + attr.setType("String"); + attrs.add(attr); + + attr = new WSAttribute(); + attr.setName("gender"); + attr.setNullable(true); + attr.setPassword(false); + attr.setKey(false); + attr.setType("String"); + attrs.add(attr); + + attr = new WSAttribute(); + attr.setName("taxNumber"); + attr.setNullable(true); + attr.setPassword(false); + attr.setKey(false); + attr.setType("String"); + attrs.add(attr); + + attr = new WSAttribute(); + attr.setName("state"); + attr.setNullable(true); + attr.setPassword(false); + attr.setKey(false); + attr.setType("String"); + attrs.add(attr); + + attr = new WSAttribute(); + attr.setName("studyTitle"); + attr.setNullable(true); + attr.setPassword(false); + attr.setKey(false); + attr.setType("String"); + attrs.add(attr); + + attr = new WSAttribute(); + attr.setName("studyArea"); + attr.setNullable(true); + attr.setPassword(false); + attr.setKey(false); + attr.setType("String"); + attrs.add(attr); + + attr = new WSAttribute(); + attr.setName("job"); + attr.setNullable(true); + attr.setPassword(false); + attr.setKey(false); + attr.setType("String"); + attrs.add(attr); + + attr = new WSAttribute(); + attr.setName("companyType"); + attr.setNullable(true); + attr.setPassword(false); + attr.setKey(false); + attr.setType("String"); + attrs.add(attr); + + attr = new WSAttribute(); + attr.setName("companyName"); + attr.setNullable(true); + attr.setPassword(false); + attr.setKey(false); + attr.setType("String"); + attrs.add(attr); + + attr = new WSAttribute(); + attr.setName("vatNumber"); + attr.setNullable(true); + attr.setPassword(false); + attr.setKey(false); + attr.setType("String"); + attrs.add(attr); + + attr = new WSAttribute(); + attr.setName("mandatoryDisclaimer"); + attr.setNullable(true); + attr.setPassword(false); + attr.setKey(false); + attr.setType("Boolean"); + attrs.add(attr); + + attr = new WSAttribute(); + attr.setName("promoRCSDisclaimer"); + attr.setNullable(true); + attr.setPassword(false); + attr.setKey(false); + attr.setType("Boolean"); + attrs.add(attr); + + attr = new WSAttribute(); + attr.setName("promoThirdPartyDisclaimer"); + attr.setNullable(true); + attr.setPassword(false); + attr.setKey(false); + attr.setType("Boolean"); + attrs.add(attr); + + return attrs; + } + + @Override + public String authenticate(final String username, final String password) + throws ProvisioningException { + + LOG.debug("authenticate request received"); + + return username; + } + + @Override + public Boolean isAuthenticationSupported() { + LOG.debug("isAuthenticationSupported request received"); + + return Boolean.FALSE; + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/User.java ---------------------------------------------------------------------- diff --git a/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/User.java b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/User.java new file mode 100644 index 0000000..18b3c7b --- /dev/null +++ b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/User.java @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.fit.buildtools.cxf; + +import java.io.Serializable; +import java.util.UUID; + +public class User implements Serializable { + + private static final long serialVersionUID = -7906946710921162676L; + + private UUID key; + + private String username; + + private String password; + + private String firstName; + + private String surname; + + private String email; + + public UUID getKey() { + return key; + } + + public void setKey(final UUID key) { + this.key = key; + } + + public String getUsername() { + return username; + } + + public void setUsername(final String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(final String password) { + this.password = password; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(final String firstName) { + this.firstName = firstName; + } + + public String getSurname() { + return surname; + } + + public void setSurname(final String surname) { + this.surname = surname; + } + + public String getEmail() { + return email; + } + + public void setEmail(final String email) { + this.email = email; + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/UserService.java ---------------------------------------------------------------------- diff --git a/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/UserService.java b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/UserService.java new file mode 100644 index 0000000..5d64cfc --- /dev/null +++ b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/UserService.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.fit.buildtools.cxf; + +import java.util.List; +import java.util.UUID; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; + +@Path("users") +public interface UserService { + + @GET + List<User> list(); + + @GET + @Path("{key}") + @Produces({ MediaType.APPLICATION_JSON }) + User read(@PathParam("key") UUID key); + + @POST + @Consumes({ MediaType.APPLICATION_JSON }) + void create(User user); + + @PUT + @Path("{key}") + @Consumes({ MediaType.APPLICATION_JSON }) + void update(@PathParam("key") UUID key, User user); + + @DELETE + @Path("{key}") + void delete(@PathParam("key") UUID key); + + @POST + @Path("authenticate") + @Produces({ MediaType.APPLICATION_JSON }) + User authenticate(@QueryParam("username") String username, @QueryParam("password") String password); + + @POST + @Path("clear") + void clear(); +} http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/UserServiceImpl.java ---------------------------------------------------------------------- diff --git a/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/UserServiceImpl.java b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/UserServiceImpl.java new file mode 100644 index 0000000..dea0f63 --- /dev/null +++ b/fit/build-tools/src/main/java/org/apache/syncope/fit/buildtools/cxf/UserServiceImpl.java @@ -0,0 +1,114 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.fit.buildtools.cxf; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import javax.ws.rs.ForbiddenException; +import javax.ws.rs.NotFoundException; +import org.springframework.stereotype.Service; + +@Service +public class UserServiceImpl implements UserService { + + private static final Map<UUID, User> USERS = new HashMap<UUID, User>(); + + @Override + public List<User> list() { + return new ArrayList<>(USERS.values()); + } + + @Override + public User read(final UUID key) { + User user = USERS.get(key); + if (user == null) { + throw new NotFoundException(key.toString()); + } + return user; + } + + @Override + public void create(final User user) { + if (user.getKey() == null) { + user.setKey(UUID.randomUUID()); + } + if (USERS.containsKey(user.getKey())) { + throw new IllegalArgumentException("User already exists: " + user.getKey()); + } + USERS.put(user.getKey(), user); + } + + @Override + public void update(final UUID key, final User updatedUser) { + if (!USERS.containsKey(key)) { + throw new NotFoundException(updatedUser.getKey().toString()); + } + User user = USERS.get(key); + if (updatedUser.getUsername() != null) { + user.setUsername(updatedUser.getUsername()); + } + if (updatedUser.getPassword() != null) { + user.setPassword(updatedUser.getPassword()); + } + if (updatedUser.getFirstName() != null) { + user.setFirstName(updatedUser.getFirstName()); + } + if (updatedUser.getSurname() != null) { + user.setSurname(updatedUser.getSurname()); + } + if (updatedUser.getEmail() != null) { + user.setEmail(updatedUser.getEmail()); + } + } + + @Override + public void delete(final UUID key) { + if (!USERS.containsKey(key)) { + throw new NotFoundException(key.toString()); + } + USERS.remove(key); + } + + @Override + public User authenticate(final String username, final String password) { + User user = null; + for (User entry : USERS.values()) { + if (username.equals(entry.getUsername())) { + user = entry; + } + } + if (user == null) { + throw new NotFoundException(username); + } + if (!password.equals(user.getPassword())) { + throw new ForbiddenException(); + } + + return user; + } + + @Override + public void clear() { + USERS.clear(); + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/build-tools/src/main/resources/buildToolsContext.xml ---------------------------------------------------------------------- diff --git a/fit/build-tools/src/main/resources/buildToolsContext.xml b/fit/build-tools/src/main/resources/buildToolsContext.xml index e0f5678..a4433c9 100644 --- a/fit/build-tools/src/main/resources/buildToolsContext.xml +++ b/fit/build-tools/src/main/resources/buildToolsContext.xml @@ -45,6 +45,9 @@ under the License. <bean id="testconnectorserver.soap.bundle" class="java.lang.String"> <constructor-arg value="net.tirasa.connid.bundles.soap-${connid.soap.version}.jar"/> </bean> + <bean id="testconnectorserver.rest.bundle" class="java.lang.String"> + <constructor-arg value="net.tirasa.connid.bundles.rest-${connid.rest.version}.jar"/> + </bean> <bean id="testconnectorserver.dbtable.bundle" class="java.lang.String"> <constructor-arg value="net.tirasa.connid.bundles.db.table-${connid.database.version}.jar"/> </bean> http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/build-tools/src/main/resources/cxfContext.xml ---------------------------------------------------------------------- diff --git a/fit/build-tools/src/main/resources/cxfContext.xml b/fit/build-tools/src/main/resources/cxfContext.xml new file mode 100644 index 0000000..9a6c959 --- /dev/null +++ b/fit/build-tools/src/main/resources/cxfContext.xml @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:jaxws="http://cxf.apache.org/jaxws" + xmlns:jaxrs="http://cxf.apache.org/jaxrs" + xmlns:context="http://www.springframework.org/schema/context" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd + http://cxf.apache.org/jaxws + http://cxf.apache.org/schemas/jaxws.xsd + http://cxf.apache.org/jaxrs + http://cxf.apache.org/schemas/jaxrs.xsd + http://www.springframework.org/schema/context + http://www.springframework.org/schema/context/spring-context.xsd"> + + <import resource="classpath:META-INF/cxf/cxf.xml"/> + <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/> + + <context:component-scan base-package="org.apache.syncope.fit.buildtools.cxf"/> + + <jaxws:endpoint id="soapProvisioning" address="/soap" implementor="#provisioningImpl"/> + + <bean id="jsonProvider" class="com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider"/> + <jaxrs:server id="restProvisioning" address="/rest" + basePackages="org.apache.syncope.fit.buildtools.cxf" + staticSubresourceResolution="true"> + <jaxrs:providers> + <ref bean="jsonProvider"/> + </jaxrs:providers> + </jaxrs:server> + +</beans> http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/build-tools/src/main/resources/testdb.sql ---------------------------------------------------------------------- diff --git a/fit/build-tools/src/main/resources/testdb.sql b/fit/build-tools/src/main/resources/testdb.sql index 36d228b..0eb42e8 100644 --- a/fit/build-tools/src/main/resources/testdb.sql +++ b/fit/build-tools/src/main/resources/testdb.sql @@ -49,3 +49,35 @@ printername VARCHAR(80), location VARCHAR(80), deleted BOOLEAN DEFAULT FALSE, lastModification TIMESTAMP); + +CREATE TABLE user ( +capsId INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1) PRIMARY KEY, +userId VARCHAR(30) NOT NULL, +password VARCHAR(255) NOT NULL, +type VARCHAR(17) NOT NULL, +residence VARCHAR(60), +telephone VARCHAR(20), +fax VARCHAR(20), +preference VARCHAR(120), +name VARCHAR(30), +surname VARCHAR(35), +fullname VARCHAR(35) NOT NULL, +birthdate VARCHAR(30), +gender VARCHAR(1), +taxNumber VARCHAR(30), +state VARCHAR(15), +studyTitle VARCHAR(30), +studyArea VARCHAR(30), +job VARCHAR(30), +companyType VARCHAR(30), +companyName VARCHAR(30), +vatNumber VARCHAR(30), +mandatoryDisclaimer BOOLEAN, +promoRCSDisclaimer BOOLEAN, +promoThirdPartyDisclaimer BOOLEAN, +UNIQUE(userId)); + +CREATE TABLE role ( +roleId INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1) PRIMARY KEY, +roleName VARCHAR(120), +UNIQUE(roleName)); http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/build-tools/src/main/webapp/WEB-INF/glassfish-web.xml ---------------------------------------------------------------------- diff --git a/fit/build-tools/src/main/webapp/WEB-INF/glassfish-web.xml b/fit/build-tools/src/main/webapp/WEB-INF/glassfish-web.xml new file mode 100644 index 0000000..aca226e --- /dev/null +++ b/fit/build-tools/src/main/webapp/WEB-INF/glassfish-web.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> +<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD +GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd"> +<glassfish-web-app> + <context-root>/syncope</context-root> + <class-loader delegate="false"/> + <jsp-config> + <property name="httpMethods" value="GET,POST,HEAD,PUT,DELETE"/> + </jsp-config> +</glassfish-web-app> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/build-tools/src/main/webapp/WEB-INF/jboss-deployment-structure.xml ---------------------------------------------------------------------- diff --git a/fit/build-tools/src/main/webapp/WEB-INF/jboss-deployment-structure.xml b/fit/build-tools/src/main/webapp/WEB-INF/jboss-deployment-structure.xml new file mode 100644 index 0000000..388b98b --- /dev/null +++ b/fit/build-tools/src/main/webapp/WEB-INF/jboss-deployment-structure.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> +<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2"> + <deployment> + <exclude-subsystems> + <subsystem name="webservices"/> + </exclude-subsystems> + <dependencies> + <module name="org.apache.xalan"/> + </dependencies> + <exclusions> + <module name="org.apache.cxf"/> + <module name="org.apache.cxf.impl"/> + <module name="org.slf4j"/> + <module name="org.slf4j.impl"/> + </exclusions> + </deployment> +</jboss-deployment-structure> http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/build-tools/src/main/webapp/WEB-INF/web.xml ---------------------------------------------------------------------- diff --git a/fit/build-tools/src/main/webapp/WEB-INF/web.xml b/fit/build-tools/src/main/webapp/WEB-INF/web.xml index df3438d..b1b6ec7 100644 --- a/fit/build-tools/src/main/webapp/WEB-INF/web.xml +++ b/fit/build-tools/src/main/webapp/WEB-INF/web.xml @@ -25,7 +25,7 @@ under the License. <context-param> <param-name>contextConfigLocation</param-name> - <param-value>classpath*:/buildToolsContext.xml</param-value> + <param-value>classpath:/*Context.xml</param-value> </context-param> <listener> @@ -40,6 +40,12 @@ under the License. <listener> <listener-class>org.apache.syncope.fit.buildtools.ConnIdStartStopListener</listener-class> </listener> + + <servlet> + <servlet-name>CXFServlet</servlet-name> + <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> + <load-on-startup>1</load-on-startup> + </servlet> <servlet> <servlet-name>ApacheDSRootDseServlet</servlet-name> <servlet-class>org.apache.syncope.fit.buildtools.ApacheDSRootDseServlet</servlet-class> @@ -48,6 +54,11 @@ under the License. <servlet-name>ServiceTimeoutServlet</servlet-name> <servlet-class>org.apache.syncope.fit.buildtools.ServiceTimeoutServlet</servlet-class> </servlet> + + <servlet-mapping> + <servlet-name>CXFServlet</servlet-name> + <url-pattern>/cxf/*</url-pattern> + </servlet-mapping> <servlet-mapping> <servlet-name>ApacheDSRootDseServlet</servlet-name> <url-pattern>/apacheDS</url-pattern> http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/console-reference/pom.xml ---------------------------------------------------------------------- diff --git a/fit/console-reference/pom.xml b/fit/console-reference/pom.xml index 7fc1c44..6377efd 100644 --- a/fit/console-reference/pom.xml +++ b/fit/console-reference/pom.xml @@ -117,12 +117,6 @@ under the License. <scope>test</scope> </dependency> <dependency> - <groupId>net.tirasa.connid.bundles.soap</groupId> - <artifactId>wssample</artifactId> - <type>war</type> - <scope>test</scope> - </dependency> - <dependency> <groupId>org.apache.syncope.fit</groupId> <artifactId>syncope-fit-core-reference</artifactId> <version>${project.version}</version> @@ -204,14 +198,6 @@ under the License. </configuration> <deployables> <deployable> - <groupId>net.tirasa.connid.bundles.soap</groupId> - <artifactId>wssample</artifactId> - <type>war</type> - <properties> - <context>wssample</context> - </properties> - </deployable> - <deployable> <groupId>org.apache.syncope.fit</groupId> <artifactId>syncope-fit-build-tools</artifactId> <type>war</type> http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/core-reference/pom.xml ---------------------------------------------------------------------- diff --git a/fit/core-reference/pom.xml b/fit/core-reference/pom.xml index 789e6f9..44a5fda 100644 --- a/fit/core-reference/pom.xml +++ b/fit/core-reference/pom.xml @@ -120,12 +120,6 @@ under the License. <scope>test</scope> </dependency> <dependency> - <groupId>net.tirasa.connid.bundles.soap</groupId> - <artifactId>wssample</artifactId> - <type>war</type> - <scope>test</scope> - </dependency> - <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>test</scope> @@ -267,14 +261,6 @@ under the License. </configuration> <deployables> <deployable> - <groupId>net.tirasa.connid.bundles.soap</groupId> - <artifactId>wssample</artifactId> - <type>war</type> - <properties> - <context>wssample</context> - </properties> - </deployable> - <deployable> <groupId>org.apache.syncope.fit</groupId> <artifactId>syncope-fit-build-tools</artifactId> <type>war</type> http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java index 45616f8..65f37f4 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ConnectorITCase.java @@ -132,7 +132,7 @@ public class ConnectorITCase extends AbstractITCase { endpointSchema.setRequired(true); ConnConfProperty endpoint = new ConnConfProperty(); endpoint.setSchema(endpointSchema); - endpoint.getValues().add("http://localhost:8888/wssample/services"); + endpoint.getValues().add("http://localhost:8888/syncope-fit-build-tools/cxf/soap"); endpoint.getValues().add("Provisioning"); conf.add(endpoint); @@ -239,7 +239,7 @@ public class ConnectorITCase extends AbstractITCase { endpointSchema.setRequired(true); ConnConfProperty endpoint = new ConnConfProperty(); endpoint.setSchema(endpointSchema); - endpoint.getValues().add("http://localhost:8888/wssample/services"); + endpoint.getValues().add("http://localhost:8888/syncope-fit-build-tools/cxf/soap"); conf.add(endpoint); ConnConfPropSchema servicenameSchema = new ConnConfPropSchema(); @@ -652,7 +652,7 @@ public class ConnectorITCase extends AbstractITCase { conf = new HashSet<>(); endpoint.getValues().clear(); - endpoint.getValues().add("http://localhost:9080/wssample/services/provisioning"); + endpoint.getValues().add("http://localhost:9080/syncope-fit-build-tools/cxf/soap/provisioning"); conf.add(endpoint); resourceTO.getConfOverride().addAll(conf); http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java index 456c728..9cea62a 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java @@ -41,6 +41,7 @@ import org.apache.commons.collections4.Transformer; import org.apache.commons.lang3.time.DateFormatUtils; import org.apache.commons.lang3.time.FastDateFormat; import org.apache.commons.lang3.tuple.Pair; +import org.apache.cxf.jaxrs.client.WebClient; import org.apache.syncope.common.lib.SyncopeClientException; import org.apache.syncope.common.lib.SyncopeConstants; import org.apache.syncope.common.lib.patch.AssociationPatch; @@ -1309,4 +1310,55 @@ public class UserITCase extends AbstractITCase { } } + @Test + public void restResource() { + UserTO userTO = getUniqueSampleTO("r...@syncope.apache.org"); + userTO.getResources().clear(); + userTO.getResources().add("rest-target-resource"); + + // 1. create + ProvisioningResult<UserTO> result = userService.create(userTO).readEntity( + new GenericType<ProvisioningResult<UserTO>>() { + }); + assertEquals(1, result.getPropagationStatuses().size()); + assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus()); + assertEquals("rest-target-resource", result.getPropagationStatuses().get(0).getResource()); + assertEquals("surname", userTO.getPlainAttrMap().get("surname").getValues().get(0)); + + // verify user exists on the backend REST service + WebClient webClient = WebClient.create( + "http://localhost:9080/syncope-fit-build-tools/cxf/rest/users/" + result.getEntity().getKey()); + Response response = webClient.get(); + assertEquals(200, response.getStatus()); + assertNotNull(response.getEntity()); + + // 2. update + UserPatch patch = new UserPatch(); + patch.setKey(result.getEntity().getKey()); + patch.getPlainAttrs().add(new AttrPatch.Builder(). + attrTO(new AttrTO.Builder().schema("surname").value("surname2").build()).build()); + result = userService.update(patch).readEntity( + new GenericType<ProvisioningResult<UserTO>>() { + }); + assertEquals(1, result.getPropagationStatuses().size()); + assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus()); + assertEquals("rest-target-resource", result.getPropagationStatuses().get(0).getResource()); + assertEquals("surname2", result.getEntity().getPlainAttrMap().get("surname").getValues().get(0)); + + // verify user still exists on the backend REST service + response = webClient.get(); + assertEquals(200, response.getStatus()); + assertNotNull(response.getEntity()); + + // 3. delete + result = userService.delete(result.getEntity().getKey()).readEntity( + new GenericType<ProvisioningResult<UserTO>>() { + }); + assertEquals(1, result.getPropagationStatuses().size()); + assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus()); + assertEquals("rest-target-resource", result.getPropagationStatuses().get(0).getResource()); + + // verify user was removed by the backend REST service + assertEquals(404, webClient.get().getStatus()); + } } http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/core-reference/src/test/resources/rest/AuthenticateScript.groovy ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/test/resources/rest/AuthenticateScript.groovy b/fit/core-reference/src/test/resources/rest/AuthenticateScript.groovy new file mode 100644 index 0000000..8ec4128 --- /dev/null +++ b/fit/core-reference/src/test/resources/rest/AuthenticateScript.groovy @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.databind.node.ObjectNode +import org.apache.cxf.jaxrs.client.WebClient +import org.identityconnectors.framework.common.objects.Uid + +// Parameters: +// The connector sends us the following: +// client : CXF WebClient +// action: String correponding to the action ("AUTHENTICATE" here) +// log: a handler to the Log facility +// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other) +// username: username +// password: password string, clear text or GuardedString depending on configuration +// options: a handler to the OperationOptions Map + +log.info("Entering " + action + " Script"); + +WebClient webClient = client; +ObjectMapper mapper = new ObjectMapper(); + +String key; + +switch (objectClass) { +case "__ACCOUNT__": + webClient.path("/users/authenticate").query("username", username).query("password", password); + response = webClient.post(null); + if (response.getStatus() == 200) { + ObjectNode node = mapper.readTree(response.getEntity()); + return node.get("key").textValue(); + } else { + throw new RuntimeException("Could not authenticate " + username); + } + break + +default: + throw new RuntimeException(); +} http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/core-reference/src/test/resources/rest/CreateScript.groovy ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/test/resources/rest/CreateScript.groovy b/fit/core-reference/src/test/resources/rest/CreateScript.groovy new file mode 100644 index 0000000..f97961e --- /dev/null +++ b/fit/core-reference/src/test/resources/rest/CreateScript.groovy @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.databind.node.ObjectNode +import org.apache.cxf.jaxrs.client.WebClient +import org.identityconnectors.framework.common.objects.Uid + +// Parameters: +// The connector sends us the following: +// client : CXF WebClient +// action: String correponding to the action ("CREATE" here) +// log: a handler to the Log facility +// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other) +// id: The entry identifier (ConnId's "Name" atribute. (most often matches the uid)) +// attributes: an Attribute Map, containg the <String> attribute name as a key +// and the <List> attribute value(s) as value. +// password: password string, clear text +// options: a handler to the OperationOptions Map + +log.info("Entering " + action + " Script"); + +WebClient webClient = client; +ObjectMapper mapper = new ObjectMapper(); + +String key; + +switch (objectClass) { +case "__ACCOUNT__": + ObjectNode node = mapper.createObjectNode(); + node.set("key", node.textNode(id)); + node.set("username", node.textNode(attributes.get("username").get(0))); + node.set("password", node.textNode(password)); + node.set("firstName", node.textNode(attributes.get("firstName").get(0))); + node.set("surname", node.textNode(attributes.get("surname").get(0))); + node.set("email", node.textNode(attributes.get("email").get(0))); + + String payload = mapper.writeValueAsString(node); + + webClient.path("/users"); + webClient.post(payload); + + key = node.get("key").textValue(); + break + +default: + key = id; +} + +return key;