You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2016/12/01 08:29:21 UTC
[1/6] syncope git commit: [SYNCOPE-978] REST resource provided,
consolidated wssample into syncope-fit-build-tools
Repository: syncope
Updated Branches:
refs/heads/2_0_X f9b03e82f -> a60e4bcb6
refs/heads/master e7e8e92da -> 9722c9218
http://git-wip-us.apache.org/repos/asf/syncope/blob/a60e4bcb/fit/core-reference/src/test/resources/rest/DeleteScript.groovy
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/resources/rest/DeleteScript.groovy b/fit/core-reference/src/test/resources/rest/DeleteScript.groovy
new file mode 100644
index 0000000..7cf805a
--- /dev/null
+++ b/fit/core-reference/src/test/resources/rest/DeleteScript.groovy
@@ -0,0 +1,44 @@
+/*
+ * 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 org.apache.cxf.jaxrs.client.WebClient
+
+// Parameters:
+// The connector sends the following:
+// client : CXF WebClient
+// action: a string describing the action ("DELETE" here)
+// log: a handler to the Log facility
+// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other)
+// options: a handler to the OperationOptions Map
+// uid: String for the unique id that specifies the object to delete
+
+log.info("Entering " + action + " Script");
+
+WebClient webClient = client;
+
+assert uid != null
+
+switch ( objectClass ) {
+case "__ACCOUNT__":
+ webClient.path("/users/" + uid);
+ webClient.delete();
+ break
+
+default:
+ break
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/a60e4bcb/fit/core-reference/src/test/resources/rest/SchemaScript.groovy
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/resources/rest/SchemaScript.groovy b/fit/core-reference/src/test/resources/rest/SchemaScript.groovy
new file mode 100644
index 0000000..ecf7080
--- /dev/null
+++ b/fit/core-reference/src/test/resources/rest/SchemaScript.groovy
@@ -0,0 +1,51 @@
+/*
+ * 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 org.identityconnectors.common.security.GuardedString
+import org.identityconnectors.framework.common.objects.AttributeInfo
+import org.identityconnectors.framework.common.objects.AttributeInfo.Flags
+import org.identityconnectors.framework.common.objects.AttributeInfoBuilder
+import org.identityconnectors.framework.common.objects.ObjectClassInfo
+import org.identityconnectors.framework.common.objects.ObjectClassInfoBuilder
+
+// Parameters:
+// The connector sends the following:
+// action: a string describing the action ("SCHEMA" here)
+// log: a handler to the Log facility
+// builder: SchemaBuilder instance for the connector
+//
+// The connector will make the final call to builder.build()
+// so the scipt just need to declare the different object types.
+
+log.info("Entering " + action + " Script");
+
+idAIB = new AttributeInfoBuilder("key", String.class);
+idAIB.setRequired(true);
+
+orgAttrsInfo = new HashSet<AttributeInfo>();
+orgAttrsInfo.add(idAIB.build());
+orgAttrsInfo.add(AttributeInfoBuilder.build("username", String.class));
+orgAttrsInfo.add(AttributeInfoBuilder.build("password", GuardedString.class));
+orgAttrsInfo.add(AttributeInfoBuilder.build("firstName", String.class));
+orgAttrsInfo.add(AttributeInfoBuilder.build("surname", String.class));
+orgAttrsInfo.add(AttributeInfoBuilder.build("email", String.class));
+
+ObjectClassInfo oci = new ObjectClassInfoBuilder().setType("__ACCOUNT__").addAllAttributeInfo(orgAttrsInfo).build();
+builder.defineObjectClass(oci);
+
+log.info(action + " script done");
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/syncope/blob/a60e4bcb/fit/core-reference/src/test/resources/rest/SearchScript.groovy
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/resources/rest/SearchScript.groovy b/fit/core-reference/src/test/resources/rest/SearchScript.groovy
new file mode 100644
index 0000000..c4fe900
--- /dev/null
+++ b/fit/core-reference/src/test/resources/rest/SearchScript.groovy
@@ -0,0 +1,100 @@
+/*
+ * 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.ArrayNode
+import com.fasterxml.jackson.databind.node.ObjectNode
+import javax.ws.rs.core.Response
+import org.apache.cxf.jaxrs.client.WebClient
+import org.identityconnectors.common.security.GuardedString
+
+// Parameters:
+// The connector sends the following:
+// client : CXF WebClient
+// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other)
+// action: a string describing the action ("SEARCH" here)
+// log: a handler to the Log facility
+// options: a handler to the OperationOptions Map
+// query: a handler to the Query Map
+//
+// The Query map describes the filter used (via FIQL's ConditionType):
+//
+// query = [ operation: "EQUALS", left: attribute, right: "value" ]
+// query = [ operation: "GREATER_THAN", left: attribute, right: "value" ]
+// query = [ operation: "GREATER_OR_EQUALS", left: attribute, right: "value" ]
+// query = [ operation: "LESS_THAN", left: attribute, right: "value" ]
+// query = [ operation: "LESS_OR_EQUALS", left: attribute, right: "value" ]
+// query = null : then we assume we fetch everything
+//
+// AND and OR filter just embed a left/right couple of queries.
+// query = [ operation: "AND", left: query1, right: query2 ]
+// query = [ operation: "OR", left: query1, right: query2 ]
+//
+// Returns: A list of Maps. Each map describing one row.
+// !!!! Each Map must contain a '__UID__' and '__NAME__' attribute.
+// This is required to build a ConnectorObject.
+
+def buildConnectorObject(node) {
+ return [
+ __UID__:node.get("key").textValue(),
+ __NAME__:node.get("key").textValue(),
+ username:node.get("username").textValue(),
+ password:node.has("password") && node.get("password").textValue() != null
+ ? new GuardedString(node.get("password").textValue().toCharArray())
+ : null,
+ firstName:node.get("firstName").textValue(),
+ surname:node.get("surname").textValue(),
+ email:node.get("email").textValue()
+ ];
+}
+
+log.info("Entering " + action + " Script");
+
+WebClient webClient = client;
+ObjectMapper mapper = new ObjectMapper();
+
+def result = []
+
+switch (objectClass) {
+case "__ACCOUNT__":
+ if (query == null || (!query.get("left").equals("__UID__") && !query.get("conditionType").equals("EQUALS"))) {
+ webClient.path("/users");
+ Response response = webClient.get();
+ ArrayNode node = mapper.readTree(response.getEntity());
+
+ for (i = 0; i < node.size(); i++) {
+ result.add(buildConnectorObject(node.get(i)));
+ }
+ } else {
+ webClient.path("/users/" + query.get("right"));
+ Response response = webClient.get();
+ if (response.getStatus() == 200) {
+ ObjectNode node = mapper.readTree(response.getEntity());
+ result.add(buildConnectorObject(node));
+ } else {
+ log.warn("Could not read object {0}", query.get("right"));
+ }
+ }
+
+ break
+
+default:
+ result;
+}
+
+return result;
http://git-wip-us.apache.org/repos/asf/syncope/blob/a60e4bcb/fit/core-reference/src/test/resources/rest/SyncScript.groovy
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/resources/rest/SyncScript.groovy b/fit/core-reference/src/test/resources/rest/SyncScript.groovy
new file mode 100644
index 0000000..a15636c
--- /dev/null
+++ b/fit/core-reference/src/test/resources/rest/SyncScript.groovy
@@ -0,0 +1,106 @@
+/*
+ * 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.ArrayNode
+import java.util.Date;
+import javax.ws.rs.core.Response
+import org.apache.cxf.jaxrs.client.WebClient
+import org.identityconnectors.common.security.GuardedString
+
+// Parameters:
+// The connector sends the following:
+// client : CXF WebClient
+// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other)
+// action: a string describing the action ("SYNC" or "GET_LATEST_SYNC_TOKEN" here)
+// log: a handler to the Log facility
+// options: a handler to the OperationOptions Map (null if action = "GET_LATEST_SYNC_TOKEN")
+// token: a handler to an Object representing the sync token (null if action = "GET_LATEST_SYNC_TOKEN")
+//
+//
+// Returns:
+// if action = "GET_LATEST_SYNC_TOKEN", it must return an object representing the last known
+// sync token for the corresponding ObjectClass
+//
+// if action = "SYNC":
+// A list of Maps . Each map describing one update:
+// Map should look like the following:
+//
+// [
+// "token": <Object> token object (could be Integer, Date, String) , [!! could be null]
+// "operation":<String> ("CREATE_OR_UPDATE"|"DELETE") will always default to CREATE_OR_DELETE ,
+// "uid":<String> uid (uid of the entry) ,
+// "previousUid":<String> prevuid (This is for rename ops) ,
+// "password":<String> password (optional... allows to pass clear text password if needed),
+// "attributes":Map<String,List> of attributes name/values
+// ]
+
+def buildConnectorObject(node) {
+ return [
+ __UID__:node.get("key").textValue(),
+ __NAME__:node.get("key").textValue(),
+ username:node.get("username").textValue(),
+ password:new GuardedString(node.get("password").textValue().toCharArray()),
+ firstName:node.get("firstName").textValue(),
+ surname:node.get("surname").textValue(),
+ email:node.get("email").textValue()
+ ];
+}
+
+log.info("Entering " + action + " Script");
+
+WebClient webClient = client;
+ObjectMapper mapper = new ObjectMapper();
+
+if (action.equalsIgnoreCase("GET_LATEST_SYNC_TOKEN")) {
+ switch (objectClass) {
+ case "__ACCOUNT__":
+ latestToken = new Date().getTime();
+ break;
+
+ default:
+ latestToken = null;
+ }
+
+ return latestToken;
+} else if (action.equalsIgnoreCase("SYNC")) {
+ def result = [];
+
+ switch (objectClass) {
+ case "__ACCOUNT__":
+ webClient.path("/users");
+ Response response = webClient.get();
+ ArrayNode node = mapper.readTree(response.getEntity());
+
+ for (i = 0; i < node.size(); i++) {
+ result.add([
+ operation:"CREATE_OR_UPDATE",
+ uid:node.get(i).get("key").textValue(),
+ token:new Date().getTime(),
+ attributes:buildConnectorObject(node.get(i))
+ ]);
+ }
+ break;
+ }
+
+ log.ok("Sync script: found " + result.size() + " events to sync");
+ return result;
+} else {
+ log.error("Sync script: action '" + action + "' is not implemented in this script");
+ return null;
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/a60e4bcb/fit/core-reference/src/test/resources/rest/TestScript.groovy
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/resources/rest/TestScript.groovy b/fit/core-reference/src/test/resources/rest/TestScript.groovy
new file mode 100644
index 0000000..c27ddee
--- /dev/null
+++ b/fit/core-reference/src/test/resources/rest/TestScript.groovy
@@ -0,0 +1,35 @@
+/*
+ * 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 org.apache.cxf.jaxrs.client.WebClient
+
+// Parameters:
+// The connector sends the following:
+// client : CXF WebClient
+// action: a string describing the action ("TEST" here)
+// log: a handler to the Log facility
+
+log.info("Entering " + action + " Script");
+
+WebClient webClient = client;
+ObjectMapper mapper = new ObjectMapper();
+
+ webClient.path("/users", false);
+ webClient.get();
+
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/syncope/blob/a60e4bcb/fit/core-reference/src/test/resources/rest/UpdateScript.groovy
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/resources/rest/UpdateScript.groovy b/fit/core-reference/src/test/resources/rest/UpdateScript.groovy
new file mode 100644
index 0000000..37371a7
--- /dev/null
+++ b/fit/core-reference/src/test/resources/rest/UpdateScript.groovy
@@ -0,0 +1,98 @@
+/*
+ * 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
+
+// Parameters:
+// The connector sends us the following:
+// client : CXF WebClient
+//
+// action: String correponding to the action (UPDATE/ADD_ATTRIBUTE_VALUES/REMOVE_ATTRIBUTE_VALUES)
+// - UPDATE : For each input attribute, replace all of the current values of that attribute
+// in the target object with the values of that attribute.
+// - ADD_ATTRIBUTE_VALUES: For each attribute that the input set contains, add to the current values
+// of that attribute in the target object all of the values of that attribute in the input set.
+// - REMOVE_ATTRIBUTE_VALUES: For each attribute that the input set contains, remove from the current values
+// of that attribute in the target object any value that matches one of the values of the attribute from the input set.
+
+// log: a handler to the Log facility
+//
+// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other)
+//
+// uid: a String representing the entry 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 (only for UPDATE)
+//
+// options: a handler to the OperationOptions Map
+
+log.info("Entering " + action + " Script");
+
+WebClient webClient = client;
+ObjectMapper mapper = new ObjectMapper();
+
+assert uid != null
+
+switch (action) {
+case "UPDATE":
+ switch (objectClass) {
+ case "__ACCOUNT__":
+ ObjectNode node = mapper.createObjectNode();
+ node.set("key", node.textNode(uid));
+ if (attributes.containsKey("__NAME__")) {
+ node.set("username", node.textNode(attributes.get("__NAME__").get(0)));
+ }
+ if (attributes.containsKey("username")) {
+ node.set("username", node.textNode(attributes.get("username").get(0)));
+ }
+ if (password != null) {
+ node.set("password", node.textNode(password));
+ }
+ if (attributes.containsKey("firstName")) {
+ node.set("firstName", node.textNode(attributes.get("firstName").get(0)));
+ }
+ if (attributes.containsKey("surname")) {
+ node.set("surname", node.textNode(attributes.get("surname").get(0)));
+ }
+ if (attributes.containsKey("email")) {
+ node.set("email", node.textNode(attributes.get("email").get(0)));
+ }
+
+ String payload = mapper.writeValueAsString(node);
+
+ webClient.path("/users/" + uid);
+ webClient.put(payload);
+
+ default:
+ break
+ }
+
+ return uid;
+ break
+
+case "ADD_ATTRIBUTE_VALUES":
+ break
+
+
+default:
+ break
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/syncope/blob/a60e4bcb/fit/enduser-reference/pom.xml
----------------------------------------------------------------------
diff --git a/fit/enduser-reference/pom.xml b/fit/enduser-reference/pom.xml
index 1db2aad..a350315 100644
--- a/fit/enduser-reference/pom.xml
+++ b/fit/enduser-reference/pom.xml
@@ -103,12 +103,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>
@@ -304,14 +298,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/a60e4bcb/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index df53d4b..e6f1852 100644
--- a/pom.xml
+++ b/pom.xml
@@ -351,6 +351,7 @@ under the License.
<connid.version>1.4.2.0</connid.version>
<connid.soap.version>1.4.1</connid.soap.version>
+ <connid.rest.version>1.0.1</connid.rest.version>
<connid.database.version>2.2.4</connid.database.version>
<connid.csvdir.version>0.8.5</connid.csvdir.version>
<connid.ldap.version>1.5.1</connid.ldap.version>
@@ -1348,13 +1349,6 @@ under the License.
<scope>test</scope>
</dependency>
<dependency>
- <groupId>net.tirasa.connid.bundles.soap</groupId>
- <artifactId>wssample</artifactId>
- <version>${connid.soap.version}</version>
- <type>war</type>
- <scope>test</scope>
- </dependency>
- <dependency>
<groupId>com.icegreen</groupId>
<artifactId>greenmail</artifactId>
<version>1.5.2</version>
@@ -1460,6 +1454,11 @@ under the License.
</artifactItem>
<artifactItem>
<groupId>net.tirasa.connid.bundles</groupId>
+ <artifactId>net.tirasa.connid.bundles.rest</artifactId>
+ <version>${connid.rest.version}</version>
+ </artifactItem>
+ <artifactItem>
+ <groupId>net.tirasa.connid.bundles</groupId>
<artifactId>net.tirasa.connid.bundles.csvdir</artifactId>
<version>${connid.csvdir.version}</version>
</artifactItem>
http://git-wip-us.apache.org/repos/asf/syncope/blob/a60e4bcb/src/main/asciidoc/getting-started/obtain.adoc
----------------------------------------------------------------------
diff --git a/src/main/asciidoc/getting-started/obtain.adoc b/src/main/asciidoc/getting-started/obtain.adoc
index 056d14b..f480a7b 100644
--- a/src/main/asciidoc/getting-started/obtain.adoc
+++ b/src/main/asciidoc/getting-started/obtain.adoc
@@ -451,9 +451,10 @@ You can configure any LDAP client (such as http://jxplorer.org/[JXplorer^], for
bind password: `secret`
| External resource: SOAP
-| An example SOAP server is available at http://localhost:9080/wssample/services +
- +
- You can check its internal data by visiting http://localhost:9080/wssample/exploredb.jsp
+| An example SOAP service is available at http://localhost:9080/syncope-fit-build-tools/cxf/soap
+
+| External resource: REST
+| An example REST service is available at http://localhost:9080/syncope-fit-build-tools/cxf/rest
| External resource: database
| http://www.h2database.com/[H2^] TCP database is available. +
http://git-wip-us.apache.org/repos/asf/syncope/blob/a60e4bcb/standalone/pom.xml
----------------------------------------------------------------------
diff --git a/standalone/pom.xml b/standalone/pom.xml
index cf3e4d1..e4817af 100644
--- a/standalone/pom.xml
+++ b/standalone/pom.xml
@@ -46,12 +46,6 @@ under the License.
<dependencies>
<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-build-tools</artifactId>
<version>${project.version}</version>
@@ -168,18 +162,15 @@ under the License.
<mkdir dir="${work.dir}/apache-tomcat-${tomcat.version}/${test.csvdir.path}" />
<copy file="../fit/core-reference/src/test/resources/test.csv" todir="${work.dir}/apache-tomcat-${tomcat.version}/${test.csvdir.path}" />
- <!-- ConnId's SOAP wssample (provides endpoint for SOAP resources) -->
- <copy file="${settings.localRepository}/net/tirasa/connid/bundles/soap/wssample/${connid.soap.version}/wssample-${connid.soap.version}.war" tofile="${work.dir}/apache-tomcat-${tomcat.version}/webapps/wssample.war" />
-
- <!-- Syncope build tools (provide H2 and Apache DS resources + ConnId connector server) -->
- <copy todir="${work.dir}/apache-tomcat-${tomcat.version}/webapps/syncope-build-tools">
+ <!-- Syncope build tools (provide H2, Apache DS and REST / SOAP resources + ConnId connector server) -->
+ <copy todir="${work.dir}/apache-tomcat-${tomcat.version}/webapps/syncope-fit-build-tools">
<fileset dir="../fit/build-tools/target/syncope-fit-build-tools-${project.version}" includes="**/*" />
</copy>
- <copy todir="${work.dir}/apache-tomcat-${tomcat.version}/webapps/syncope-build-tools/WEB-INF/lib">
+ <copy todir="${work.dir}/apache-tomcat-${tomcat.version}/webapps/syncope-fit-build-tools/WEB-INF/lib">
<fileset dir="../fit/core-reference/target/bundles/" includes="**/*" />
</copy>
- <zip destfile="${work.dir}/apache-tomcat-${tomcat.version}/webapps/syncope-build-tools.war" basedir="${work.dir}/apache-tomcat-${tomcat.version}/webapps/syncope-build-tools" />
- <delete dir="${work.dir}/apache-tomcat-${tomcat.version}/webapps/syncope-build-tools" />
+ <zip destfile="${work.dir}/apache-tomcat-${tomcat.version}/webapps/syncope-fit-build-tools.war" basedir="${work.dir}/apache-tomcat-${tomcat.version}/webapps/syncope-fit-build-tools" />
+ <delete dir="${work.dir}/apache-tomcat-${tomcat.version}/webapps/syncope-fit-build-tools" />
<!-- Tomcat shared libraries: H2, groovy, StAX2 API, Woodstox -->
<copy file="${settings.localRepository}/com/h2database/h2/${h2.version}/h2-${h2.version}.jar" todir="${work.dir}/apache-tomcat-${tomcat.version}/lib" />
@@ -265,6 +256,11 @@ under the License.
<targetPath>core/scriptedsql</targetPath>
<filtering>true</filtering>
</resource>
+ <resource>
+ <directory>../fit/core-reference/src/test/resources/rest</directory>
+ <targetPath>core/rest</targetPath>
+ <filtering>true</filtering>
+ </resource>
<resource>
<directory>../fit/console-reference/src/main/resources</directory>
[5/6] syncope git commit: [SYNCOPE-978] REST resource provided,
consolidated wssample into syncope-fit-build-tools
Posted by il...@apache.org.
[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� <il...@apache.org>
Authored: Thu Dec 1 09:27:28 2016 +0100
Committer: Francesco Chicchiricc� <il...@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("rest@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;
[4/6] syncope git commit: [SYNCOPE-978] REST resource provided,
consolidated wssample into syncope-fit-build-tools
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/core-reference/src/test/resources/rest/DeleteScript.groovy
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/resources/rest/DeleteScript.groovy b/fit/core-reference/src/test/resources/rest/DeleteScript.groovy
new file mode 100644
index 0000000..7cf805a
--- /dev/null
+++ b/fit/core-reference/src/test/resources/rest/DeleteScript.groovy
@@ -0,0 +1,44 @@
+/*
+ * 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 org.apache.cxf.jaxrs.client.WebClient
+
+// Parameters:
+// The connector sends the following:
+// client : CXF WebClient
+// action: a string describing the action ("DELETE" here)
+// log: a handler to the Log facility
+// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other)
+// options: a handler to the OperationOptions Map
+// uid: String for the unique id that specifies the object to delete
+
+log.info("Entering " + action + " Script");
+
+WebClient webClient = client;
+
+assert uid != null
+
+switch ( objectClass ) {
+case "__ACCOUNT__":
+ webClient.path("/users/" + uid);
+ webClient.delete();
+ break
+
+default:
+ break
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/core-reference/src/test/resources/rest/SchemaScript.groovy
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/resources/rest/SchemaScript.groovy b/fit/core-reference/src/test/resources/rest/SchemaScript.groovy
new file mode 100644
index 0000000..ecf7080
--- /dev/null
+++ b/fit/core-reference/src/test/resources/rest/SchemaScript.groovy
@@ -0,0 +1,51 @@
+/*
+ * 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 org.identityconnectors.common.security.GuardedString
+import org.identityconnectors.framework.common.objects.AttributeInfo
+import org.identityconnectors.framework.common.objects.AttributeInfo.Flags
+import org.identityconnectors.framework.common.objects.AttributeInfoBuilder
+import org.identityconnectors.framework.common.objects.ObjectClassInfo
+import org.identityconnectors.framework.common.objects.ObjectClassInfoBuilder
+
+// Parameters:
+// The connector sends the following:
+// action: a string describing the action ("SCHEMA" here)
+// log: a handler to the Log facility
+// builder: SchemaBuilder instance for the connector
+//
+// The connector will make the final call to builder.build()
+// so the scipt just need to declare the different object types.
+
+log.info("Entering " + action + " Script");
+
+idAIB = new AttributeInfoBuilder("key", String.class);
+idAIB.setRequired(true);
+
+orgAttrsInfo = new HashSet<AttributeInfo>();
+orgAttrsInfo.add(idAIB.build());
+orgAttrsInfo.add(AttributeInfoBuilder.build("username", String.class));
+orgAttrsInfo.add(AttributeInfoBuilder.build("password", GuardedString.class));
+orgAttrsInfo.add(AttributeInfoBuilder.build("firstName", String.class));
+orgAttrsInfo.add(AttributeInfoBuilder.build("surname", String.class));
+orgAttrsInfo.add(AttributeInfoBuilder.build("email", String.class));
+
+ObjectClassInfo oci = new ObjectClassInfoBuilder().setType("__ACCOUNT__").addAllAttributeInfo(orgAttrsInfo).build();
+builder.defineObjectClass(oci);
+
+log.info(action + " script done");
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/core-reference/src/test/resources/rest/SearchScript.groovy
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/resources/rest/SearchScript.groovy b/fit/core-reference/src/test/resources/rest/SearchScript.groovy
new file mode 100644
index 0000000..c4fe900
--- /dev/null
+++ b/fit/core-reference/src/test/resources/rest/SearchScript.groovy
@@ -0,0 +1,100 @@
+/*
+ * 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.ArrayNode
+import com.fasterxml.jackson.databind.node.ObjectNode
+import javax.ws.rs.core.Response
+import org.apache.cxf.jaxrs.client.WebClient
+import org.identityconnectors.common.security.GuardedString
+
+// Parameters:
+// The connector sends the following:
+// client : CXF WebClient
+// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other)
+// action: a string describing the action ("SEARCH" here)
+// log: a handler to the Log facility
+// options: a handler to the OperationOptions Map
+// query: a handler to the Query Map
+//
+// The Query map describes the filter used (via FIQL's ConditionType):
+//
+// query = [ operation: "EQUALS", left: attribute, right: "value" ]
+// query = [ operation: "GREATER_THAN", left: attribute, right: "value" ]
+// query = [ operation: "GREATER_OR_EQUALS", left: attribute, right: "value" ]
+// query = [ operation: "LESS_THAN", left: attribute, right: "value" ]
+// query = [ operation: "LESS_OR_EQUALS", left: attribute, right: "value" ]
+// query = null : then we assume we fetch everything
+//
+// AND and OR filter just embed a left/right couple of queries.
+// query = [ operation: "AND", left: query1, right: query2 ]
+// query = [ operation: "OR", left: query1, right: query2 ]
+//
+// Returns: A list of Maps. Each map describing one row.
+// !!!! Each Map must contain a '__UID__' and '__NAME__' attribute.
+// This is required to build a ConnectorObject.
+
+def buildConnectorObject(node) {
+ return [
+ __UID__:node.get("key").textValue(),
+ __NAME__:node.get("key").textValue(),
+ username:node.get("username").textValue(),
+ password:node.has("password") && node.get("password").textValue() != null
+ ? new GuardedString(node.get("password").textValue().toCharArray())
+ : null,
+ firstName:node.get("firstName").textValue(),
+ surname:node.get("surname").textValue(),
+ email:node.get("email").textValue()
+ ];
+}
+
+log.info("Entering " + action + " Script");
+
+WebClient webClient = client;
+ObjectMapper mapper = new ObjectMapper();
+
+def result = []
+
+switch (objectClass) {
+case "__ACCOUNT__":
+ if (query == null || (!query.get("left").equals("__UID__") && !query.get("conditionType").equals("EQUALS"))) {
+ webClient.path("/users");
+ Response response = webClient.get();
+ ArrayNode node = mapper.readTree(response.getEntity());
+
+ for (i = 0; i < node.size(); i++) {
+ result.add(buildConnectorObject(node.get(i)));
+ }
+ } else {
+ webClient.path("/users/" + query.get("right"));
+ Response response = webClient.get();
+ if (response.getStatus() == 200) {
+ ObjectNode node = mapper.readTree(response.getEntity());
+ result.add(buildConnectorObject(node));
+ } else {
+ log.warn("Could not read object {0}", query.get("right"));
+ }
+ }
+
+ break
+
+default:
+ result;
+}
+
+return result;
http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/core-reference/src/test/resources/rest/SyncScript.groovy
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/resources/rest/SyncScript.groovy b/fit/core-reference/src/test/resources/rest/SyncScript.groovy
new file mode 100644
index 0000000..a15636c
--- /dev/null
+++ b/fit/core-reference/src/test/resources/rest/SyncScript.groovy
@@ -0,0 +1,106 @@
+/*
+ * 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.ArrayNode
+import java.util.Date;
+import javax.ws.rs.core.Response
+import org.apache.cxf.jaxrs.client.WebClient
+import org.identityconnectors.common.security.GuardedString
+
+// Parameters:
+// The connector sends the following:
+// client : CXF WebClient
+// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other)
+// action: a string describing the action ("SYNC" or "GET_LATEST_SYNC_TOKEN" here)
+// log: a handler to the Log facility
+// options: a handler to the OperationOptions Map (null if action = "GET_LATEST_SYNC_TOKEN")
+// token: a handler to an Object representing the sync token (null if action = "GET_LATEST_SYNC_TOKEN")
+//
+//
+// Returns:
+// if action = "GET_LATEST_SYNC_TOKEN", it must return an object representing the last known
+// sync token for the corresponding ObjectClass
+//
+// if action = "SYNC":
+// A list of Maps . Each map describing one update:
+// Map should look like the following:
+//
+// [
+// "token": <Object> token object (could be Integer, Date, String) , [!! could be null]
+// "operation":<String> ("CREATE_OR_UPDATE"|"DELETE") will always default to CREATE_OR_DELETE ,
+// "uid":<String> uid (uid of the entry) ,
+// "previousUid":<String> prevuid (This is for rename ops) ,
+// "password":<String> password (optional... allows to pass clear text password if needed),
+// "attributes":Map<String,List> of attributes name/values
+// ]
+
+def buildConnectorObject(node) {
+ return [
+ __UID__:node.get("key").textValue(),
+ __NAME__:node.get("key").textValue(),
+ username:node.get("username").textValue(),
+ password:new GuardedString(node.get("password").textValue().toCharArray()),
+ firstName:node.get("firstName").textValue(),
+ surname:node.get("surname").textValue(),
+ email:node.get("email").textValue()
+ ];
+}
+
+log.info("Entering " + action + " Script");
+
+WebClient webClient = client;
+ObjectMapper mapper = new ObjectMapper();
+
+if (action.equalsIgnoreCase("GET_LATEST_SYNC_TOKEN")) {
+ switch (objectClass) {
+ case "__ACCOUNT__":
+ latestToken = new Date().getTime();
+ break;
+
+ default:
+ latestToken = null;
+ }
+
+ return latestToken;
+} else if (action.equalsIgnoreCase("SYNC")) {
+ def result = [];
+
+ switch (objectClass) {
+ case "__ACCOUNT__":
+ webClient.path("/users");
+ Response response = webClient.get();
+ ArrayNode node = mapper.readTree(response.getEntity());
+
+ for (i = 0; i < node.size(); i++) {
+ result.add([
+ operation:"CREATE_OR_UPDATE",
+ uid:node.get(i).get("key").textValue(),
+ token:new Date().getTime(),
+ attributes:buildConnectorObject(node.get(i))
+ ]);
+ }
+ break;
+ }
+
+ log.ok("Sync script: found " + result.size() + " events to sync");
+ return result;
+} else {
+ log.error("Sync script: action '" + action + "' is not implemented in this script");
+ return null;
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/core-reference/src/test/resources/rest/TestScript.groovy
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/resources/rest/TestScript.groovy b/fit/core-reference/src/test/resources/rest/TestScript.groovy
new file mode 100644
index 0000000..c27ddee
--- /dev/null
+++ b/fit/core-reference/src/test/resources/rest/TestScript.groovy
@@ -0,0 +1,35 @@
+/*
+ * 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 org.apache.cxf.jaxrs.client.WebClient
+
+// Parameters:
+// The connector sends the following:
+// client : CXF WebClient
+// action: a string describing the action ("TEST" here)
+// log: a handler to the Log facility
+
+log.info("Entering " + action + " Script");
+
+WebClient webClient = client;
+ObjectMapper mapper = new ObjectMapper();
+
+ webClient.path("/users", false);
+ webClient.get();
+
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/core-reference/src/test/resources/rest/UpdateScript.groovy
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/resources/rest/UpdateScript.groovy b/fit/core-reference/src/test/resources/rest/UpdateScript.groovy
new file mode 100644
index 0000000..37371a7
--- /dev/null
+++ b/fit/core-reference/src/test/resources/rest/UpdateScript.groovy
@@ -0,0 +1,98 @@
+/*
+ * 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
+
+// Parameters:
+// The connector sends us the following:
+// client : CXF WebClient
+//
+// action: String correponding to the action (UPDATE/ADD_ATTRIBUTE_VALUES/REMOVE_ATTRIBUTE_VALUES)
+// - UPDATE : For each input attribute, replace all of the current values of that attribute
+// in the target object with the values of that attribute.
+// - ADD_ATTRIBUTE_VALUES: For each attribute that the input set contains, add to the current values
+// of that attribute in the target object all of the values of that attribute in the input set.
+// - REMOVE_ATTRIBUTE_VALUES: For each attribute that the input set contains, remove from the current values
+// of that attribute in the target object any value that matches one of the values of the attribute from the input set.
+
+// log: a handler to the Log facility
+//
+// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other)
+//
+// uid: a String representing the entry 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 (only for UPDATE)
+//
+// options: a handler to the OperationOptions Map
+
+log.info("Entering " + action + " Script");
+
+WebClient webClient = client;
+ObjectMapper mapper = new ObjectMapper();
+
+assert uid != null
+
+switch (action) {
+case "UPDATE":
+ switch (objectClass) {
+ case "__ACCOUNT__":
+ ObjectNode node = mapper.createObjectNode();
+ node.set("key", node.textNode(uid));
+ if (attributes.containsKey("__NAME__")) {
+ node.set("username", node.textNode(attributes.get("__NAME__").get(0)));
+ }
+ if (attributes.containsKey("username")) {
+ node.set("username", node.textNode(attributes.get("username").get(0)));
+ }
+ if (password != null) {
+ node.set("password", node.textNode(password));
+ }
+ if (attributes.containsKey("firstName")) {
+ node.set("firstName", node.textNode(attributes.get("firstName").get(0)));
+ }
+ if (attributes.containsKey("surname")) {
+ node.set("surname", node.textNode(attributes.get("surname").get(0)));
+ }
+ if (attributes.containsKey("email")) {
+ node.set("email", node.textNode(attributes.get("email").get(0)));
+ }
+
+ String payload = mapper.writeValueAsString(node);
+
+ webClient.path("/users/" + uid);
+ webClient.put(payload);
+
+ default:
+ break
+ }
+
+ return uid;
+ break
+
+case "ADD_ATTRIBUTE_VALUES":
+ break
+
+
+default:
+ break
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/fit/enduser-reference/pom.xml
----------------------------------------------------------------------
diff --git a/fit/enduser-reference/pom.xml b/fit/enduser-reference/pom.xml
index 03d6eb3..9694885 100644
--- a/fit/enduser-reference/pom.xml
+++ b/fit/enduser-reference/pom.xml
@@ -103,12 +103,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>
@@ -304,14 +298,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/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 5c301ca..9c4a7fe 100644
--- a/pom.xml
+++ b/pom.xml
@@ -351,6 +351,7 @@ under the License.
<connid.version>1.4.2.0</connid.version>
<connid.soap.version>1.4.2-SNAPSHOT</connid.soap.version>
+ <connid.rest.version>1.0.1</connid.rest.version>
<connid.database.version>2.2.4</connid.database.version>
<connid.csvdir.version>0.8.5</connid.csvdir.version>
<connid.ldap.version>1.5.1</connid.ldap.version>
@@ -1343,13 +1344,6 @@ under the License.
<scope>test</scope>
</dependency>
<dependency>
- <groupId>net.tirasa.connid.bundles.soap</groupId>
- <artifactId>wssample</artifactId>
- <version>${connid.soap.version}</version>
- <type>war</type>
- <scope>test</scope>
- </dependency>
- <dependency>
<groupId>com.icegreen</groupId>
<artifactId>greenmail</artifactId>
<version>1.5.2</version>
@@ -1455,6 +1449,11 @@ under the License.
</artifactItem>
<artifactItem>
<groupId>net.tirasa.connid.bundles</groupId>
+ <artifactId>net.tirasa.connid.bundles.rest</artifactId>
+ <version>${connid.rest.version}</version>
+ </artifactItem>
+ <artifactItem>
+ <groupId>net.tirasa.connid.bundles</groupId>
<artifactId>net.tirasa.connid.bundles.csvdir</artifactId>
<version>${connid.csvdir.version}</version>
</artifactItem>
http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/src/main/asciidoc/getting-started/obtain.adoc
----------------------------------------------------------------------
diff --git a/src/main/asciidoc/getting-started/obtain.adoc b/src/main/asciidoc/getting-started/obtain.adoc
index a1c6559..08471de 100644
--- a/src/main/asciidoc/getting-started/obtain.adoc
+++ b/src/main/asciidoc/getting-started/obtain.adoc
@@ -450,9 +450,10 @@ You can configure any LDAP client (such as http://jxplorer.org/[JXplorer^], for
bind password: `secret`
| External resource: SOAP
-| An example SOAP server is available at http://localhost:9080/wssample/services +
- +
- You can check its internal data by visiting http://localhost:9080/wssample/exploredb.jsp
+| An example SOAP service is available at http://localhost:9080/syncope-fit-build-tools/cxf/soap
+
+| External resource: REST
+| An example REST service is available at http://localhost:9080/syncope-fit-build-tools/cxf/rest
| External resource: database
| http://www.h2database.com/[H2^] TCP database is available. +
http://git-wip-us.apache.org/repos/asf/syncope/blob/5af8e4a4/standalone/pom.xml
----------------------------------------------------------------------
diff --git a/standalone/pom.xml b/standalone/pom.xml
index eee4b8b..4a0adfd 100644
--- a/standalone/pom.xml
+++ b/standalone/pom.xml
@@ -46,12 +46,6 @@ under the License.
<dependencies>
<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-build-tools</artifactId>
<version>${project.version}</version>
@@ -168,18 +162,15 @@ under the License.
<mkdir dir="${work.dir}/apache-tomcat-${tomcat.version}/${test.csvdir.path}" />
<copy file="../fit/core-reference/src/test/resources/test.csv" todir="${work.dir}/apache-tomcat-${tomcat.version}/${test.csvdir.path}" />
- <!-- ConnId's SOAP wssample (provides endpoint for SOAP resources) -->
- <copy file="${settings.localRepository}/net/tirasa/connid/bundles/soap/wssample/${connid.soap.version}/wssample-${connid.soap.version}.war" tofile="${work.dir}/apache-tomcat-${tomcat.version}/webapps/wssample.war" />
-
- <!-- Syncope build tools (provide H2 and Apache DS resources + ConnId connector server) -->
- <copy todir="${work.dir}/apache-tomcat-${tomcat.version}/webapps/syncope-build-tools">
+ <!-- Syncope build tools (provide H2, Apache DS and REST / SOAP resources + ConnId connector server) -->
+ <copy todir="${work.dir}/apache-tomcat-${tomcat.version}/webapps/syncope-fit-build-tools">
<fileset dir="../fit/build-tools/target/syncope-fit-build-tools-${project.version}" includes="**/*" />
</copy>
- <copy todir="${work.dir}/apache-tomcat-${tomcat.version}/webapps/syncope-build-tools/WEB-INF/lib">
+ <copy todir="${work.dir}/apache-tomcat-${tomcat.version}/webapps/syncope-fit-build-tools/WEB-INF/lib">
<fileset dir="../fit/core-reference/target/bundles/" includes="**/*" />
</copy>
- <zip destfile="${work.dir}/apache-tomcat-${tomcat.version}/webapps/syncope-build-tools.war" basedir="${work.dir}/apache-tomcat-${tomcat.version}/webapps/syncope-build-tools" />
- <delete dir="${work.dir}/apache-tomcat-${tomcat.version}/webapps/syncope-build-tools" />
+ <zip destfile="${work.dir}/apache-tomcat-${tomcat.version}/webapps/syncope-fit-build-tools.war" basedir="${work.dir}/apache-tomcat-${tomcat.version}/webapps/syncope-fit-build-tools" />
+ <delete dir="${work.dir}/apache-tomcat-${tomcat.version}/webapps/syncope-fit-build-tools" />
<!-- Tomcat shared libraries: H2, groovy, StAX2 API, Woodstox -->
<copy file="${settings.localRepository}/com/h2database/h2/${h2.version}/h2-${h2.version}.jar" todir="${work.dir}/apache-tomcat-${tomcat.version}/lib" />
@@ -265,6 +256,11 @@ under the License.
<targetPath>core/scriptedsql</targetPath>
<filtering>true</filtering>
</resource>
+ <resource>
+ <directory>../fit/core-reference/src/test/resources/rest</directory>
+ <targetPath>core/rest</targetPath>
+ <filtering>true</filtering>
+ </resource>
<resource>
<directory>../fit/console-reference/src/main/resources</directory>
[6/6] syncope git commit: Avoid duplicate ldapGroups
Posted by il...@apache.org.
Avoid duplicate ldapGroups
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/9722c921
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/9722c921
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/9722c921
Branch: refs/heads/master
Commit: 9722c921827d034c63ed4a4ab42adbf76a1720fd
Parents: 5af8e4a
Author: Francesco Chicchiricc� <il...@apache.org>
Authored: Wed Nov 30 15:29:49 2016 +0100
Committer: Francesco Chicchiricc� <il...@apache.org>
Committed: Thu Dec 1 09:29:10 2016 +0100
----------------------------------------------------------------------
.../java/propagation/LDAPMembershipPropagationActions.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/9722c921/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
index 54be326..29390be 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
@@ -102,14 +102,14 @@ public class LDAPMembershipPropagationActions extends DefaultPropagationActions
Set<String> groups = new HashSet<>(groupConnObjectLinks);
Attribute ldapGroups = AttributeUtil.find(getGroupMembershipAttrName(), attributes);
-
if (ldapGroups != null) {
for (Object obj : ldapGroups.getValue()) {
groups.add(obj.toString());
}
+ attributes.remove(ldapGroups);
}
-
attributes.add(AttributeBuilder.build(getGroupMembershipAttrName(), groups));
+
task.setAttributes(attributes);
}
} else {
[3/6] syncope git commit: Avoid duplicate ldapGroups
Posted by il...@apache.org.
Avoid duplicate ldapGroups
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/f7505fa6
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/f7505fa6
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/f7505fa6
Branch: refs/heads/2_0_X
Commit: f7505fa6e672024e1bb1a603ff5eb6ab0d00b0a9
Parents: f9b03e8
Author: Francesco Chicchiricc� <il...@apache.org>
Authored: Wed Nov 30 15:29:49 2016 +0100
Committer: Francesco Chicchiricc� <il...@apache.org>
Committed: Thu Dec 1 09:28:58 2016 +0100
----------------------------------------------------------------------
.../java/propagation/LDAPMembershipPropagationActions.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/f7505fa6/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
index 54be326..29390be 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/propagation/LDAPMembershipPropagationActions.java
@@ -102,14 +102,14 @@ public class LDAPMembershipPropagationActions extends DefaultPropagationActions
Set<String> groups = new HashSet<>(groupConnObjectLinks);
Attribute ldapGroups = AttributeUtil.find(getGroupMembershipAttrName(), attributes);
-
if (ldapGroups != null) {
for (Object obj : ldapGroups.getValue()) {
groups.add(obj.toString());
}
+ attributes.remove(ldapGroups);
}
-
attributes.add(AttributeBuilder.build(getGroupMembershipAttrName(), groups));
+
task.setAttributes(attributes);
}
} else {
[2/6] syncope git commit: [SYNCOPE-978] REST resource provided,
consolidated wssample into syncope-fit-build-tools
Posted by il...@apache.org.
[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/a60e4bcb
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/a60e4bcb
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/a60e4bcb
Branch: refs/heads/2_0_X
Commit: a60e4bcb64253c532f541c74ed1d770b3d72a3e6
Parents: f7505fa
Author: Francesco Chicchiricc� <il...@apache.org>
Authored: Thu Dec 1 09:27:28 2016 +0100
Committer: Francesco Chicchiricc� <il...@apache.org>
Committed: Thu Dec 1 09:28:58 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/a60e4bcb/archetype/pom.xml
----------------------------------------------------------------------
diff --git a/archetype/pom.xml b/archetype/pom.xml
index ba70542..a3f7075 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/a60e4bcb/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 5913a03..eae0ac8 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/a60e4bcb/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 0c962d6..e5a5bed 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/a60e4bcb/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/a60e4bcb/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/a60e4bcb/fit/build-tools/pom.xml
----------------------------------------------------------------------
diff --git a/fit/build-tools/pom.xml b/fit/build-tools/pom.xml
index bb68ba2..70ac93f 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/a60e4bcb/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/a60e4bcb/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/a60e4bcb/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/a60e4bcb/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/a60e4bcb/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/a60e4bcb/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/a60e4bcb/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/a60e4bcb/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/a60e4bcb/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/a60e4bcb/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/a60e4bcb/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/a60e4bcb/fit/console-reference/pom.xml
----------------------------------------------------------------------
diff --git a/fit/console-reference/pom.xml b/fit/console-reference/pom.xml
index 057928e..6b5b335 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/a60e4bcb/fit/core-reference/pom.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/pom.xml b/fit/core-reference/pom.xml
index 8b11e04..9b2445e 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/a60e4bcb/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/a60e4bcb/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("rest@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/a60e4bcb/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/a60e4bcb/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;