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 2017/10/27 15:21:41 UTC
[2/2] syncope git commit: [SYNCOPE-152] Initial implementation as
extension: user / group read and search (without filters, attributes or sort)
[SYNCOPE-152] Initial implementation as extension: user / group read and search (without filters, attributes or sort)
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/aa25af97
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/aa25af97
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/aa25af97
Branch: refs/heads/2_0_X
Commit: aa25af970cacaf6675f78d4dc65d4c02a5b9bd5b
Parents: 59ad56b
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Fri Oct 27 17:02:25 2017 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Fri Oct 27 17:02:25 2017 +0200
----------------------------------------------------------------------
.../apache/syncope/common/lib/to/UserTO.java | 10 +
ext/pom.xml | 1 +
ext/scimv2/pom.xml | 45 ++++
ext/scimv2/scim-rest-api/pom.xml | 70 ++++++
.../syncope/ext/scimv2/api/SCIMConstants.java | 32 +++
.../syncope/ext/scimv2/api/data/Display.java | 46 ++++
.../syncope/ext/scimv2/api/data/Group.java | 51 ++++
.../ext/scimv2/api/data/ListResponse.java | 74 ++++++
.../syncope/ext/scimv2/api/data/Member.java | 49 ++++
.../syncope/ext/scimv2/api/data/Meta.java | 80 +++++++
.../syncope/ext/scimv2/api/data/Reference.java | 39 +++
.../syncope/ext/scimv2/api/data/SCIMBean.java | 29 +++
.../syncope/ext/scimv2/api/data/SCIMGroup.java | 55 +++++
.../ext/scimv2/api/data/SCIMResource.java | 62 +++++
.../syncope/ext/scimv2/api/data/SCIMUser.java | 69 ++++++
.../ext/scimv2/api/service/GroupService.java | 64 +++++
.../ext/scimv2/api/service/RootService.java | 45 ++++
.../ext/scimv2/api/service/SCIMService.java | 41 ++++
.../ext/scimv2/api/service/UserService.java | 64 +++++
.../syncope/ext/scimv2/api/type/Function.java | 25 ++
.../ext/scimv2/api/type/ResourceType.java | 37 +++
.../syncope/ext/scimv2/api/type/SortOrder.java | 25 ++
ext/scimv2/scim-rest-cxf/pom.xml | 127 ++++++++++
.../ext/scimv2/cxf/JacksonSCIMJsonProvider.java | 51 ++++
.../scimv2/cxf/service/AbstractSCIMService.java | 235 +++++++++++++++++++
.../scimv2/cxf/service/GroupServiceImpl.java | 71 ++++++
.../ext/scimv2/cxf/service/RootServiceImpl.java | 41 ++++
.../ext/scimv2/cxf/service/UserServiceImpl.java | 70 ++++++
.../META-INF/cxf/org.apache.cxf.Logger | 1 +
.../main/resources/META-INF/web-fragment.xml | 70 ++++++
.../src/main/resources/restSCIMv2CXFContext.xml | 83 +++++++
fit/core-reference/pom.xml | 6 +
.../src/main/webapp/WEB-INF/web.xml | 2 +-
.../org/apache/syncope/fit/SCIMDetector.java | 55 +++++
.../apache/syncope/fit/core/SAML2ITCase.java | 9 +-
.../org/apache/syncope/fit/core/SCIMITCase.java | 96 ++++++++
fit/core-reference/src/test/resources/rebel.xml | 4 +
37 files changed, 1928 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/common/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java
index 061f06e..5efe6a5 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java
@@ -61,6 +61,8 @@ public class UserTO extends AnyTO implements GroupableRelatableTO {
private String securityAnswer;
+ private boolean suspended;
+
private boolean mustChangePassword;
private final List<RelationshipTO> relationships = new ArrayList<>();
@@ -186,6 +188,14 @@ public class UserTO extends AnyTO implements GroupableRelatableTO {
this.securityAnswer = securityAnswer;
}
+ public boolean isSuspended() {
+ return suspended;
+ }
+
+ public void setSuspended(final boolean suspended) {
+ this.suspended = suspended;
+ }
+
public boolean isMustChangePassword() {
return mustChangePassword;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/pom.xml
----------------------------------------------------------------------
diff --git a/ext/pom.xml b/ext/pom.xml
index 031757a..be5e3ce 100644
--- a/ext/pom.xml
+++ b/ext/pom.xml
@@ -92,6 +92,7 @@ under the License.
<module>camel</module>
<module>swagger-ui</module>
<module>saml2sp</module>
+ <module>scimv2</module>
</modules>
</project>
http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/pom.xml
----------------------------------------------------------------------
diff --git a/ext/scimv2/pom.xml b/ext/scimv2/pom.xml
new file mode 100644
index 0000000..ac554e3
--- /dev/null
+++ b/ext/scimv2/pom.xml
@@ -0,0 +1,45 @@
+<?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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.syncope</groupId>
+ <artifactId>syncope-ext</artifactId>
+ <version>2.0.7-SNAPSHOT</version>
+ </parent>
+
+ <name>Apache Syncope Ext: SCIMv2</name>
+ <description>Apache Syncope Ext: SCIMv2</description>
+ <groupId>org.apache.syncope.ext</groupId>
+ <artifactId>syncope-ext-scimv2</artifactId>
+ <packaging>pom</packaging>
+
+ <properties>
+ <rootpom.basedir>${basedir}/../..</rootpom.basedir>
+ </properties>
+
+ <modules>
+ <module>scim-rest-api</module>
+ <module>scim-rest-cxf</module>
+ </modules>
+
+</project>
http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/pom.xml
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/pom.xml b/ext/scimv2/scim-rest-api/pom.xml
new file mode 100644
index 0000000..0d0d1ae
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/pom.xml
@@ -0,0 +1,70 @@
+<?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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.syncope.ext</groupId>
+ <artifactId>syncope-ext-scimv2</artifactId>
+ <version>2.0.7-SNAPSHOT</version>
+ </parent>
+
+ <name>Apache Syncope Ext: SCIMv2 SCIM REST API</name>
+ <description>Apache Syncope Ext: SCIMv2 SCIM REST API</description>
+ <groupId>org.apache.syncope.ext.scimv2</groupId>
+ <artifactId>syncope-ext-scimv2-scim-rest-api</artifactId>
+ <packaging>jar</packaging>
+
+ <properties>
+ <rootpom.basedir>${basedir}/../../..</rootpom.basedir>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax.validation</groupId>
+ <artifactId>validation-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>javax.ws.rs-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-annotations</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-frontend-jaxrs</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+</project>
http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/SCIMConstants.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/SCIMConstants.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/SCIMConstants.java
new file mode 100644
index 0000000..979decd
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/SCIMConstants.java
@@ -0,0 +1,32 @@
+/*
+ * 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.ext.scimv2.api;
+
+import javax.ws.rs.core.MediaType;
+
+public final class SCIMConstants {
+
+ public static final String APPLICATION_SCIM_JSON = "application/scim+json";
+
+ public static final MediaType APPLICATION_SCIM_JSON_TYPE = new MediaType("application", "scim+json");
+
+ private SCIMConstants() {
+ // private constructor for static utility class
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Display.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Display.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Display.java
new file mode 100644
index 0000000..f79796c
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Display.java
@@ -0,0 +1,46 @@
+/*
+ * 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.ext.scimv2.api.data;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class Display extends SCIMBean {
+
+ private static final long serialVersionUID = 5337055958765320091L;
+
+ private final String value;
+
+ private final String display;
+
+ @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+ public Display(@JsonProperty("value") final String value, @JsonProperty("display") final String display) {
+ this.value = value;
+ this.display = display;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public String getDisplay() {
+ return display;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Group.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Group.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Group.java
new file mode 100644
index 0000000..f64b837
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Group.java
@@ -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.
+ */
+package org.apache.syncope.ext.scimv2.api.data;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.syncope.ext.scimv2.api.type.Function;
+
+@JsonPropertyOrder({ "value", "$ref", "display", "type" })
+public class Group extends Reference {
+
+ private static final long serialVersionUID = -7184515273837918246L;
+
+ @JsonIgnore
+ private final Function type;
+
+ @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+ public Group(
+ @JsonProperty("value") final String value,
+ @JsonProperty("$ref") final String ref,
+ @JsonProperty("display") final String display,
+ @JsonProperty("type") final Function type) {
+
+ super(value, ref, display);
+ this.type = type;
+ }
+
+ @JsonProperty
+ public String getType() {
+ return type == null ? null : type.name();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ListResponse.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ListResponse.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ListResponse.java
new file mode 100644
index 0000000..6983631
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ListResponse.java
@@ -0,0 +1,74 @@
+/*
+ * 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.ext.scimv2.api.data;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.apache.syncope.ext.scimv2.api.type.ResourceType;
+
+public class ListResponse<R extends SCIMResource> extends SCIMBean {
+
+ private static final long serialVersionUID = -776611610457583160L;
+
+ private final List<String> schemas = Arrays.asList(ResourceType.ListResponse.getSchema());
+
+ private final int totalResults;
+
+ @JsonProperty("Resources")
+ private final List<R> resources = new ArrayList<>();
+
+ private final int startIndex;
+
+ private final int itemsPerPage;
+
+ @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+ public ListResponse(
+ @JsonProperty("totalResults") final int totalResults,
+ @JsonProperty("startIndex") final int startIndex,
+ @JsonProperty("itemsPerPage") final int itemsPerPage) {
+
+ this.totalResults = totalResults;
+ this.startIndex = startIndex;
+ this.itemsPerPage = itemsPerPage;
+ }
+
+ public List<String> getSchemas() {
+ return schemas;
+ }
+
+ public int getTotalResults() {
+ return totalResults;
+ }
+
+ public List<R> getResources() {
+ return resources;
+ }
+
+ public int getStartIndex() {
+ return startIndex;
+ }
+
+ public int getItemsPerPage() {
+ return itemsPerPage;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Member.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Member.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Member.java
new file mode 100644
index 0000000..73c25eb
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Member.java
@@ -0,0 +1,49 @@
+/*
+ * 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.ext.scimv2.api.data;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.syncope.ext.scimv2.api.type.ResourceType;
+
+@JsonPropertyOrder({ "value", "$ref", "display", "type" })
+public class Member extends Reference {
+
+ private static final long serialVersionUID = 75245960461062907L;
+
+ @JsonIgnore
+ private final ResourceType type;
+
+ public Member(
+ @JsonProperty("value") final String value,
+ @JsonProperty("$ref") final String ref,
+ @JsonProperty("display") final String display,
+ @JsonProperty("type") final ResourceType type) {
+
+ super(value, ref, display);
+ this.type = type;
+ }
+
+ @JsonProperty
+ public String getType() {
+ return type == null ? null : type.name();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Meta.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Meta.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Meta.java
new file mode 100644
index 0000000..7ecb4af
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Meta.java
@@ -0,0 +1,80 @@
+/*
+ * 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.ext.scimv2.api.data;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.Date;
+import javax.ws.rs.core.EntityTag;
+import org.apache.syncope.ext.scimv2.api.type.ResourceType;
+
+public class Meta implements Serializable {
+
+ private static final long serialVersionUID = 8976451652101091915L;
+
+ private final ResourceType resourceType;
+
+ private final Date created;
+
+ private final Date lastModified;
+
+ @JsonIgnore
+ private final EntityTag version;
+
+ private final String location;
+
+ @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+ public Meta(
+ @JsonProperty("resourceType") final ResourceType resourceType,
+ @JsonProperty("created") final Date created,
+ @JsonProperty("lastModified") final Date lastModified,
+ @JsonProperty("version") final String version,
+ @JsonProperty("location") final String location) {
+
+ this.resourceType = resourceType;
+ this.created = created;
+ this.lastModified = lastModified;
+ this.version = new EntityTag(version);
+ this.location = location;
+ }
+
+ public ResourceType getResourceType() {
+ return resourceType;
+ }
+
+ public Date getCreated() {
+ return created;
+ }
+
+ public Date getLastModified() {
+ return lastModified;
+ }
+
+ @JsonProperty
+ public String getVersion() {
+ return version == null ? null : version.toString();
+ }
+
+ public String getLocation() {
+ return location;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Reference.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Reference.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Reference.java
new file mode 100644
index 0000000..d65f5e8
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Reference.java
@@ -0,0 +1,39 @@
+/*
+ * 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.ext.scimv2.api.data;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+abstract class Reference extends Display {
+
+ private static final long serialVersionUID = -6190164044699376089L;
+
+ @JsonProperty("$ref")
+ private final String ref;
+
+ Reference(final String value, final String display, final String ref) {
+ super(value, display);
+ this.ref = ref;
+ }
+
+ public String getRef() {
+ return ref;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMBean.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMBean.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMBean.java
new file mode 100644
index 0000000..95334cf
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMBean.java
@@ -0,0 +1,29 @@
+/*
+ * 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.ext.scimv2.api.data;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import java.io.Serializable;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+abstract class SCIMBean implements Serializable {
+
+ private static final long serialVersionUID = 7604407251038024743L;
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMGroup.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMGroup.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMGroup.java
new file mode 100644
index 0000000..0657476
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMGroup.java
@@ -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.
+ */
+package org.apache.syncope.ext.scimv2.api.data;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import java.util.ArrayList;
+import java.util.List;
+
+@JsonPropertyOrder({ "schemas", "id", "externalId", "displayName", "members", "meta" })
+public class SCIMGroup extends SCIMResource {
+
+ private static final long serialVersionUID = -2935466041674390279L;
+
+ private final String displayName;
+
+ private final List<Member> members = new ArrayList<>();
+
+ @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+ public SCIMGroup(
+ @JsonProperty("id") final String id,
+ @JsonProperty("schemas") final List<String> schemas,
+ @JsonProperty("meta") final Meta meta,
+ @JsonProperty("displayName") final String displayName) {
+
+ super(id, schemas, meta);
+ this.displayName = displayName;
+ }
+
+ public String getDisplayName() {
+ return displayName;
+ }
+
+ public List<Member> getMembers() {
+ return members;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMResource.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMResource.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMResource.java
new file mode 100644
index 0000000..fae74e1
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMResource.java
@@ -0,0 +1,62 @@
+/*
+ * 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.ext.scimv2.api.data;
+
+import java.util.Collections;
+import java.util.List;
+
+public abstract class SCIMResource extends SCIMBean {
+
+ private static final long serialVersionUID = -8465880682458920021L;
+
+ private final String id;
+
+ private String externalId;
+
+ private final List<String> schemas;
+
+ private final Meta meta;
+
+ public SCIMResource(final String id, final List<String> schemas, final Meta meta) {
+ this.id = id;
+ this.schemas = schemas == null ? Collections.<String>emptyList() : schemas;
+ this.meta = meta;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public List<String> getSchemas() {
+ return schemas;
+ }
+
+ public Meta getMeta() {
+ return meta;
+ }
+
+ public void setExternalId(final String externalId) {
+ this.externalId = externalId;
+ }
+
+ public String getExternalId() {
+ return externalId;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMUser.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMUser.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMUser.java
new file mode 100644
index 0000000..c76c0f0
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMUser.java
@@ -0,0 +1,69 @@
+/*
+ * 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.ext.scimv2.api.data;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import java.util.ArrayList;
+import java.util.List;
+
+@JsonPropertyOrder({ "schemas", "id", "externalId", "userName", "active", "groups", "roles", "meta" })
+public class SCIMUser extends SCIMResource {
+
+ private static final long serialVersionUID = -2935466041674390279L;
+
+ private final String userName;
+
+ private final boolean active;
+
+ private final List<Group> groups = new ArrayList<>();
+
+ private final List<Display> roles = new ArrayList<>();
+
+ @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+ public SCIMUser(
+ @JsonProperty("id") final String id,
+ @JsonProperty("schemas") final List<String> schemas,
+ @JsonProperty("meta") final Meta meta,
+ @JsonProperty("userName") final String userName,
+ @JsonProperty("active") final boolean active) {
+
+ super(id, schemas, meta);
+ this.userName = userName;
+ this.active = active;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public boolean isActive() {
+ return active;
+ }
+
+ public List<Group> getGroups() {
+ return groups;
+ }
+
+ public List<Display> getRoles() {
+ return roles;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/GroupService.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/GroupService.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/GroupService.java
new file mode 100644
index 0000000..c1bb82f
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/GroupService.java
@@ -0,0 +1,64 @@
+/*
+ * 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.ext.scimv2.api.service;
+
+import javax.validation.constraints.NotNull;
+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.core.Response;
+import org.apache.cxf.jaxrs.ext.PATCH;
+import org.apache.syncope.ext.scimv2.api.SCIMConstants;
+import org.apache.syncope.ext.scimv2.api.data.SCIMGroup;
+
+@Path("Groups")
+public interface GroupService extends SCIMService<SCIMGroup> {
+
+ @POST
+ @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
+ @Consumes({ SCIMConstants.APPLICATION_SCIM_JSON })
+ Response create();
+
+ @GET
+ @Path("{id}")
+ @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
+ SCIMGroup read(@NotNull @PathParam("id") String id);
+
+ @PUT
+ @Path("{id}")
+ @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
+ @Consumes({ SCIMConstants.APPLICATION_SCIM_JSON })
+ Response replace(@NotNull @PathParam("id") String id);
+
+ @DELETE
+ @Path("{id}")
+ @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
+ Response delete(@NotNull @PathParam("id") String id);
+
+ @PATCH
+ @Path("{id}")
+ @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
+ @Consumes({ SCIMConstants.APPLICATION_SCIM_JSON })
+ Response update(@NotNull @PathParam("id") String id);
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/RootService.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/RootService.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/RootService.java
new file mode 100644
index 0000000..8de7a0a
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/RootService.java
@@ -0,0 +1,45 @@
+/*
+ * 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.ext.scimv2.api.service;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.ext.scimv2.api.SCIMConstants;
+
+@Path("")
+public interface RootService extends SCIMService {
+
+ @GET
+ @Path("ServiceProviderConfigs")
+ @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
+ Response serviceProviderConfigs();
+
+ @GET
+ @Path("ResourceTypes")
+ @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
+ Response resourceTypes();
+
+ @GET
+ @Path("Schemas")
+ @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
+ Response schemas();
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/SCIMService.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/SCIMService.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/SCIMService.java
new file mode 100644
index 0000000..1b2fd3f
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/SCIMService.java
@@ -0,0 +1,41 @@
+/*
+ * 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.ext.scimv2.api.service;
+
+import java.util.List;
+import javax.ws.rs.GET;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import org.apache.syncope.ext.scimv2.api.SCIMConstants;
+import org.apache.syncope.ext.scimv2.api.data.ListResponse;
+import org.apache.syncope.ext.scimv2.api.data.SCIMResource;
+import org.apache.syncope.ext.scimv2.api.type.SortOrder;
+
+public interface SCIMService<R extends SCIMResource> {
+
+ @GET
+ @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
+ ListResponse<R> search(
+ @QueryParam("startIndex") Integer startIndex,
+ @QueryParam("count") Integer count,
+ @QueryParam("filter") String filter,
+ @QueryParam("sortBy") String sortBy,
+ @QueryParam("sortOrder") SortOrder sortOrder,
+ @QueryParam("attributes") List<String> attributes);
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/UserService.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/UserService.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/UserService.java
new file mode 100644
index 0000000..73518b5
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/UserService.java
@@ -0,0 +1,64 @@
+/*
+ * 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.ext.scimv2.api.service;
+
+import javax.validation.constraints.NotNull;
+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.core.Response;
+import org.apache.cxf.jaxrs.ext.PATCH;
+import org.apache.syncope.ext.scimv2.api.SCIMConstants;
+import org.apache.syncope.ext.scimv2.api.data.SCIMUser;
+
+@Path("Users")
+public interface UserService extends SCIMService<SCIMUser> {
+
+ @POST
+ @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
+ @Consumes({ SCIMConstants.APPLICATION_SCIM_JSON })
+ Response create();
+
+ @GET
+ @Path("{id}")
+ @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
+ SCIMUser read(@NotNull @PathParam("id") String id);
+
+ @PUT
+ @Path("{id}")
+ @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
+ @Consumes({ SCIMConstants.APPLICATION_SCIM_JSON })
+ Response replace(@NotNull @PathParam("id") String id);
+
+ @DELETE
+ @Path("{id}")
+ @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
+ Response delete(@NotNull @PathParam("id") String id);
+
+ @PATCH
+ @Path("{id}")
+ @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
+ @Consumes({ SCIMConstants.APPLICATION_SCIM_JSON })
+ Response update(@NotNull @PathParam("id") String id);
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/Function.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/Function.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/Function.java
new file mode 100644
index 0000000..49d4eef
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/Function.java
@@ -0,0 +1,25 @@
+/*
+ * 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.ext.scimv2.api.type;
+
+public enum Function {
+ direct,
+ indirect;
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/ResourceType.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/ResourceType.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/ResourceType.java
new file mode 100644
index 0000000..faf5ccc
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/ResourceType.java
@@ -0,0 +1,37 @@
+/*
+ * 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.ext.scimv2.api.type;
+
+public enum ResourceType {
+
+ User("urn:ietf:params:scim:schemas:core:2.0:User"),
+ Group("urn:ietf:params:scim:schemas:core:2.0:Group"),
+ ListResponse("urn:ietf:params:scim:api:messages:2.0:ListResponse");
+
+ private final String schema;
+
+ ResourceType(final String schema) {
+ this.schema = schema;
+ }
+
+ public String getSchema() {
+ return schema;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/SortOrder.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/SortOrder.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/SortOrder.java
new file mode 100644
index 0000000..6c7bf16
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/SortOrder.java
@@ -0,0 +1,25 @@
+/*
+ * 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.ext.scimv2.api.type;
+
+public enum SortOrder {
+ ascending,
+ descending;
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-cxf/pom.xml
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-cxf/pom.xml b/ext/scimv2/scim-rest-cxf/pom.xml
new file mode 100644
index 0000000..3db0ae6
--- /dev/null
+++ b/ext/scimv2/scim-rest-cxf/pom.xml
@@ -0,0 +1,127 @@
+<?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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.syncope.ext</groupId>
+ <artifactId>syncope-ext-scimv2</artifactId>
+ <version>2.0.7-SNAPSHOT</version>
+ </parent>
+
+ <name>Apache Syncope Ext: SCIMv2 SCIM REST CXF</name>
+ <description>Apache Syncope Ext: SCIMv2 SCIM REST CXF</description>
+ <groupId>org.apache.syncope.ext.scimv2</groupId>
+ <artifactId>syncope-ext-scimv2-scim-rest-cxf</artifactId>
+ <packaging>jar</packaging>
+
+ <properties>
+ <rootpom.basedir>${basedir}/../../..</rootpom.basedir>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-web</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.security</groupId>
+ <artifactId>spring-security-web</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.security</groupId>
+ <artifactId>spring-security-config</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.fasterxml.jackson.datatype</groupId>
+ <artifactId>jackson-datatype-joda</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.jaxrs</groupId>
+ <artifactId>jackson-jaxrs-json-provider</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.module</groupId>
+ <artifactId>jackson-module-afterburner</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>joda-time</groupId>
+ <artifactId>joda-time</artifactId>
+ </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>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-rs-client</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.syncope.core</groupId>
+ <artifactId>syncope-core-logic</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.syncope.ext.scimv2</groupId>
+ <artifactId>syncope-ext-scimv2-scim-rest-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ </plugin>
+ </plugins>
+
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ </build>
+</project>
http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/JacksonSCIMJsonProvider.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/JacksonSCIMJsonProvider.java b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/JacksonSCIMJsonProvider.java
new file mode 100644
index 0000000..28ca173
--- /dev/null
+++ b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/JacksonSCIMJsonProvider.java
@@ -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.
+ */
+package org.apache.syncope.ext.scimv2.cxf;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
+import java.text.SimpleDateFormat;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Produces;
+import javax.ws.rs.ext.Provider;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.ext.scimv2.api.SCIMConstants;
+
+@Provider
+@Consumes(SCIMConstants.APPLICATION_SCIM_JSON)
+@Produces(SCIMConstants.APPLICATION_SCIM_JSON)
+public class JacksonSCIMJsonProvider extends JacksonJsonProvider {
+
+ private static final ThreadLocal<SimpleDateFormat> DATE_FORMAT = new ThreadLocal<SimpleDateFormat>() {
+
+ @Override
+ protected SimpleDateFormat initialValue() {
+ SimpleDateFormat sdf = new SimpleDateFormat();
+ sdf.applyPattern(SyncopeConstants.DEFAULT_DATE_PATTERN);
+ return sdf;
+ }
+ };
+
+ public JacksonSCIMJsonProvider() {
+ super(new ObjectMapper(), BASIC_ANNOTATIONS);
+ _mapperConfig.getConfiguredMapper().disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
+ _mapperConfig.getConfiguredMapper().setDateFormat(DATE_FORMAT.get());
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/AbstractSCIMService.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/AbstractSCIMService.java b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/AbstractSCIMService.java
new file mode 100644
index 0000000..cee06eb
--- /dev/null
+++ b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/AbstractSCIMService.java
@@ -0,0 +1,235 @@
+/*
+ * 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.ext.scimv2.cxf.service;
+
+import java.util.Collections;
+import java.util.List;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.UriInfo;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.cxf.jaxrs.ext.MessageContext;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.core.logic.AbstractAnyLogic;
+import org.apache.syncope.core.logic.GroupLogic;
+import org.apache.syncope.core.logic.UserLogic;
+import org.apache.syncope.core.persistence.api.dao.AnyDAO;
+import org.apache.syncope.core.persistence.api.dao.search.MembershipCond;
+import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.apache.syncope.ext.scimv2.api.data.Display;
+import org.apache.syncope.ext.scimv2.api.data.Group;
+import org.apache.syncope.ext.scimv2.api.data.ListResponse;
+import org.apache.syncope.ext.scimv2.api.data.Member;
+import org.apache.syncope.ext.scimv2.api.data.Meta;
+import org.apache.syncope.ext.scimv2.api.data.SCIMGroup;
+import org.apache.syncope.ext.scimv2.api.data.SCIMResource;
+import org.apache.syncope.ext.scimv2.api.data.SCIMUser;
+import org.apache.syncope.ext.scimv2.api.service.SCIMService;
+import org.apache.syncope.ext.scimv2.api.type.Function;
+import org.apache.syncope.ext.scimv2.api.type.ResourceType;
+import org.apache.syncope.ext.scimv2.api.type.SortOrder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+abstract class AbstractSCIMService<R extends SCIMResource> implements SCIMService<R> {
+
+ protected static final Logger LOG = LoggerFactory.getLogger(AbstractSCIMService.class);
+
+ @Context
+ protected UriInfo uriInfo;
+
+ @Context
+ protected MessageContext messageContext;
+
+ private UserLogic userLogic;
+
+ private GroupLogic groupLogic;
+
+ protected UserLogic userLogic() {
+ synchronized (this) {
+ if (userLogic == null) {
+ userLogic = ApplicationContextProvider.getApplicationContext().getBean(UserLogic.class);
+ }
+ }
+ return userLogic;
+ }
+
+ protected GroupLogic groupLogic() {
+ synchronized (this) {
+ if (groupLogic == null) {
+ groupLogic = ApplicationContextProvider.getApplicationContext().getBean(GroupLogic.class);
+ }
+ }
+ return groupLogic;
+ }
+
+ protected AbstractAnyLogic<?, ?> anyLogic(final ResourceType type) {
+ switch (type) {
+ case User:
+ return userLogic();
+
+ case Group:
+ return groupLogic();
+
+ default:
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ protected SCIMUser toSCIMUser(final UserTO userTO, final String location) {
+ SCIMUser user = new SCIMUser(
+ userTO.getKey(),
+ Collections.singletonList(ResourceType.User.getSchema()),
+ new Meta(
+ ResourceType.User,
+ userTO.getCreationDate(),
+ userTO.getLastChangeDate(),
+ userTO.getETagValue(),
+ location),
+ userTO.getUsername(),
+ !userTO.isSuspended());
+
+ for (MembershipTO membership : userTO.getMemberships()) {
+ user.getGroups().add(new Group(
+ membership.getGroupKey(),
+ StringUtils.substringBefore(location, "/Users") + "/Groups/" + membership.getGroupKey(),
+ membership.getGroupName(),
+ Function.direct));
+ }
+ for (MembershipTO membership : userTO.getDynMemberships()) {
+ user.getGroups().add(new Group(
+ membership.getGroupKey(),
+ StringUtils.substringBefore(location, "/Users") + "/Groups/" + membership.getGroupKey(),
+ membership.getGroupName(),
+ Function.indirect));
+ }
+
+ for (String role : userTO.getRoles()) {
+ user.getRoles().add(new Display(role, null));
+ }
+
+ return user;
+ }
+
+ protected SCIMGroup toSCIMGroup(final GroupTO groupTO, final String location) {
+ SCIMGroup group = new SCIMGroup(
+ groupTO.getKey(),
+ Collections.singletonList(ResourceType.Group.getSchema()),
+ new Meta(
+ ResourceType.Group,
+ groupTO.getCreationDate(),
+ groupTO.getLastChangeDate(),
+ groupTO.getETagValue(),
+ location),
+ groupTO.getName());
+
+ MembershipCond membCond = new MembershipCond();
+ membCond.setGroup(groupTO.getKey());
+ SearchCond searchCond = SearchCond.getLeafCond(membCond);
+
+ int count = userLogic().
+ search(searchCond, 1, 1, Collections.<OrderByClause>emptyList(), SyncopeConstants.ROOT_REALM, false).
+ getLeft();
+
+ for (int page = 1; page <= (count / AnyDAO.DEFAULT_PAGE_SIZE) + 1; page++) {
+ List<UserTO> users = userLogic().search(
+ searchCond,
+ page,
+ AnyDAO.DEFAULT_PAGE_SIZE,
+ Collections.<OrderByClause>emptyList(),
+ SyncopeConstants.ROOT_REALM,
+ false).
+ getRight();
+ for (UserTO userTO : users) {
+ group.getMembers().add(new Member(
+ userTO.getKey(),
+ StringUtils.substringBefore(location, "/Groups") + "/Users/" + userTO.getKey(),
+ userTO.getUsername(),
+ ResourceType.User));
+ }
+ }
+
+ return group;
+ }
+
+ @SuppressWarnings("unchecked")
+ protected ListResponse<R> doSearch(
+ final ResourceType type,
+ final Integer startIndex,
+ final Integer count,
+ final String filter,
+ final String sortBy,
+ final SortOrder sortOrder,
+ final List<String> attributes) {
+
+ if (type == null) {
+ throw new UnsupportedOperationException();
+ }
+
+ int page = startIndex == null || startIndex <= 1 ? 1 : (startIndex / AnyDAO.DEFAULT_PAGE_SIZE) + 1;
+
+ Pair<Integer, ? extends List<? extends AnyTO>> result = anyLogic(type).search(
+ null,
+ page,
+ AnyDAO.DEFAULT_PAGE_SIZE,
+ Collections.<OrderByClause>emptyList(),
+ SyncopeConstants.ROOT_REALM,
+ false);
+
+ ListResponse<R> response = new ListResponse<>(
+ result.getLeft(), startIndex == null || startIndex <= 1 ? 1 : startIndex, AnyDAO.DEFAULT_PAGE_SIZE);
+
+ for (AnyTO anyTO : result.getRight()) {
+ SCIMResource resource = null;
+ if (anyTO instanceof UserTO) {
+ resource = toSCIMUser(
+ (UserTO) anyTO,
+ uriInfo.getAbsolutePathBuilder().path(anyTO.getKey()).build().toASCIIString());
+ } else if (anyTO instanceof GroupTO) {
+ resource = toSCIMGroup(
+ (GroupTO) anyTO,
+ uriInfo.getAbsolutePathBuilder().path(anyTO.getKey()).build().toASCIIString());
+ }
+
+ if (resource != null) {
+ response.getResources().add((R) resource);
+ }
+ }
+
+ return response;
+ }
+
+ @Override
+ public ListResponse<R> search(
+ final Integer startIndex,
+ final Integer count,
+ final String filter,
+ final String sortBy,
+ final SortOrder sortOrder,
+ final List<String> attributes) {
+
+ return doSearch(null, startIndex, count, filter, sortBy, sortOrder, attributes);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/GroupServiceImpl.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/GroupServiceImpl.java b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/GroupServiceImpl.java
new file mode 100644
index 0000000..151762a
--- /dev/null
+++ b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/GroupServiceImpl.java
@@ -0,0 +1,71 @@
+/*
+ * 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.ext.scimv2.cxf.service;
+
+import java.util.List;
+import java.util.UUID;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.ext.scimv2.api.data.ListResponse;
+import org.apache.syncope.ext.scimv2.api.data.SCIMGroup;
+import org.apache.syncope.ext.scimv2.api.service.GroupService;
+import org.apache.syncope.ext.scimv2.api.type.ResourceType;
+import org.apache.syncope.ext.scimv2.api.type.SortOrder;
+
+public class GroupServiceImpl extends AbstractSCIMService<SCIMGroup> implements GroupService {
+
+ @Override
+ public Response create() {
+ return Response.
+ created(uriInfo.getAbsolutePathBuilder().path(UUID.randomUUID().toString()).build()).
+ build();
+ }
+
+ @Override
+ public SCIMGroup read(final String id) {
+ return toSCIMGroup(groupLogic().read(id), uriInfo.getAbsolutePathBuilder().build().toASCIIString());
+ }
+
+ @Override
+ public Response replace(final String id) {
+ return Response.ok().build();
+ }
+
+ @Override
+ public Response delete(final String id) {
+ return Response.noContent().build();
+ }
+
+ @Override
+ public Response update(final String id) {
+ return Response.ok().build();
+ }
+
+ @Override
+ public ListResponse<SCIMGroup> search(
+ final Integer startIndex,
+ final Integer count,
+ final String filter,
+ final String sortBy,
+ final SortOrder sortOrder,
+ final List<String> attributes) {
+
+ return doSearch(ResourceType.Group, startIndex, count, filter, sortBy, sortOrder, attributes);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/RootServiceImpl.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/RootServiceImpl.java b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/RootServiceImpl.java
new file mode 100644
index 0000000..0172e7d
--- /dev/null
+++ b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/RootServiceImpl.java
@@ -0,0 +1,41 @@
+/*
+ * 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.ext.scimv2.cxf.service;
+
+import javax.ws.rs.core.Response;
+import org.apache.syncope.ext.scimv2.api.service.RootService;
+
+public class RootServiceImpl extends AbstractSCIMService implements RootService {
+
+ @Override
+ public Response serviceProviderConfigs() {
+ return Response.ok().build();
+ }
+
+ @Override
+ public Response resourceTypes() {
+ return Response.ok().build();
+ }
+
+ @Override
+ public Response schemas() {
+ return Response.ok().build();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/UserServiceImpl.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/UserServiceImpl.java b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/UserServiceImpl.java
new file mode 100644
index 0000000..6d51ca3
--- /dev/null
+++ b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/UserServiceImpl.java
@@ -0,0 +1,70 @@
+/*
+ * 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.ext.scimv2.cxf.service;
+
+import java.util.List;
+import java.util.UUID;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.ext.scimv2.api.data.ListResponse;
+import org.apache.syncope.ext.scimv2.api.data.SCIMUser;
+import org.apache.syncope.ext.scimv2.api.service.UserService;
+import org.apache.syncope.ext.scimv2.api.type.ResourceType;
+import org.apache.syncope.ext.scimv2.api.type.SortOrder;
+
+public class UserServiceImpl extends AbstractSCIMService<SCIMUser> implements UserService {
+
+ @Override
+ public Response create() {
+ return Response.
+ created(uriInfo.getAbsolutePathBuilder().path(UUID.randomUUID().toString()).build()).
+ build();
+ }
+
+ @Override
+ public SCIMUser read(final String id) {
+ return toSCIMUser(userLogic().read(id), uriInfo.getAbsolutePathBuilder().build().toASCIIString());
+ }
+
+ @Override
+ public Response replace(final String id) {
+ return Response.ok().build();
+ }
+
+ @Override
+ public Response delete(final String id) {
+ return Response.noContent().build();
+ }
+
+ @Override
+ public Response update(final String id) {
+ return Response.ok().build();
+ }
+
+ @Override
+ public ListResponse<SCIMUser> search(
+ final Integer startIndex,
+ final Integer count,
+ final String filter,
+ final String sortBy,
+ final SortOrder sortOrder,
+ final List<String> attributes) {
+
+ return doSearch(ResourceType.User, startIndex, count, filter, sortBy, sortOrder, attributes);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-cxf/src/main/resources/META-INF/cxf/org.apache.cxf.Logger
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-cxf/src/main/resources/META-INF/cxf/org.apache.cxf.Logger b/ext/scimv2/scim-rest-cxf/src/main/resources/META-INF/cxf/org.apache.cxf.Logger
new file mode 100644
index 0000000..6e7bd36
--- /dev/null
+++ b/ext/scimv2/scim-rest-cxf/src/main/resources/META-INF/cxf/org.apache.cxf.Logger
@@ -0,0 +1 @@
+org.apache.cxf.common.logging.Slf4jLogger
http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-cxf/src/main/resources/META-INF/web-fragment.xml
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-cxf/src/main/resources/META-INF/web-fragment.xml b/ext/scimv2/scim-rest-cxf/src/main/resources/META-INF/web-fragment.xml
new file mode 100644
index 0000000..5a021ae
--- /dev/null
+++ b/ext/scimv2/scim-rest-cxf/src/main/resources/META-INF/web-fragment.xml
@@ -0,0 +1,70 @@
+<?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.
+-->
+<web-fragment xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
+ http://xmlns.jcp.org/xml/ns/javaee/web-fragment_3_1.xsd"
+ id="${pom.artifactId}" version="3.1">
+
+ <listener>
+ <listener-class>org.apache.syncope.core.rest.cxf.ThreadLocalCleanupListener</listener-class>
+ </listener>
+
+ <servlet>
+ <servlet-name>SCIMv2CXFServlet</servlet-name>
+ <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
+ <init-param>
+ <param-name>config-location</param-name>
+ <param-value>classpath*:/restSCIMv2CXFContext.xml</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>SCIMv2CXFServlet</servlet-name>
+ <url-pattern>/scim/*</url-pattern>
+ </servlet-mapping>
+
+ <filter>
+ <filter-name>encodingFilter</filter-name>
+ <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
+ <init-param>
+ <param-name>encoding</param-name>
+ <param-value>UTF-8</param-value>
+ </init-param>
+ <init-param>
+ <param-name>forceEncoding</param-name>
+ <param-value>true</param-value>
+ </init-param>
+ </filter>
+ <filter>
+ <filter-name>springSecurityFilterChain</filter-name>
+ <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
+ </filter>
+
+ <filter-mapping>
+ <filter-name>encodingFilter</filter-name>
+ <url-pattern>/*</url-pattern>
+ </filter-mapping>
+ <filter-mapping>
+ <filter-name>springSecurityFilterChain</filter-name>
+ <url-pattern>/*</url-pattern>
+ </filter-mapping>
+
+</web-fragment>
http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/ext/scimv2/scim-rest-cxf/src/main/resources/restSCIMv2CXFContext.xml
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-cxf/src/main/resources/restSCIMv2CXFContext.xml b/ext/scimv2/scim-rest-cxf/src/main/resources/restSCIMv2CXFContext.xml
new file mode 100644
index 0000000..7293b26
--- /dev/null
+++ b/ext/scimv2/scim-rest-cxf/src/main/resources/restSCIMv2CXFContext.xml
@@ -0,0 +1,83 @@
+<?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: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/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.ext.scimv2.cxf.service"/>
+
+ <bean id="jsonProvider" class="org.apache.syncope.ext.scimv2.cxf.JacksonSCIMJsonProvider"/>
+
+ <bean id="validationProvider" class="org.apache.cxf.validation.BeanValidationProvider"/>
+ <bean id="validationInInterceptor" class="org.apache.cxf.jaxrs.validation.JAXRSBeanValidationInInterceptor">
+ <property name="provider" ref="validationProvider"/>
+ </bean>
+ <bean id="validationOutInterceptor" class="org.apache.cxf.jaxrs.validation.JAXRSBeanValidationOutInterceptor">
+ <property name="provider" ref="validationProvider"/>
+ </bean>
+
+ <bean id="gzipInInterceptor" class="org.apache.cxf.transport.common.gzip.GZIPInInterceptor"/>
+ <bean id="gzipOutInterceptor" class="org.apache.cxf.transport.common.gzip.GZIPOutInterceptor">
+ <property name="threshold" value="0"/>
+ <property name="force" value="true"/>
+ </bean>
+
+ <bean id="wadlGenerator" class="org.apache.cxf.jaxrs.model.wadl.WadlGenerator">
+ <property name="applicationTitle" value="Apache Syncope SCIMv2 ${syncope.version}"/>
+ <property name="namespacePrefix" value="syncope2"/>
+ <property name="incrementNamespacePrefix" value="false"/>
+ <property name="linkAnyMediaTypeToXmlSchema" value="true"/>
+ <property name="useJaxbContextForQnames" value="true"/>
+ <property name="addResourceAndMethodIds" value="true"/>
+ <property name="ignoreMessageWriters" value="true"/>
+ <property name="usePathParamsToCompareOperations" value="false"/>
+ </bean>
+
+ <jaxrs:server id="scimv2Container" address="/"
+ basePackages="org.apache.syncope.ext.scimv2.api.service, org.apache.syncope.ext.scimv2.cxf.service"
+ staticSubresourceResolution="true">
+ <jaxrs:properties>
+ <entry key="convert.wadl.resources.to.dom" value="false"/>
+ </jaxrs:properties>
+ <jaxrs:inInterceptors>
+ <ref bean="gzipInInterceptor"/>
+ <ref bean="validationInInterceptor"/>
+ </jaxrs:inInterceptors>
+ <jaxrs:outInterceptors>
+ <ref bean="gzipOutInterceptor"/>
+ <ref bean="validationOutInterceptor"/>
+ </jaxrs:outInterceptors>
+ <jaxrs:providers>
+ <ref bean="jsonProvider"/>
+ <ref bean="wadlGenerator"/>
+ </jaxrs:providers>
+ </jaxrs:server>
+
+</beans>
http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/fit/core-reference/pom.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/pom.xml b/fit/core-reference/pom.xml
index 7ea19b6..87348ff 100644
--- a/fit/core-reference/pom.xml
+++ b/fit/core-reference/pom.xml
@@ -1051,6 +1051,12 @@ under the License.
</dependency>
<dependency>
+ <groupId>org.apache.syncope.ext.scimv2</groupId>
+ <artifactId>syncope-ext-scimv2-scim-rest-cxf</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
<groupId>org.apache.syncope.ext</groupId>
<artifactId>syncope-ext-swagger-ui</artifactId>
<version>${project.version}</version>
http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/fit/core-reference/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/main/webapp/WEB-INF/web.xml b/fit/core-reference/src/main/webapp/WEB-INF/web.xml
index 49a82fe..ad39dab 100644
--- a/fit/core-reference/src/main/webapp/WEB-INF/web.xml
+++ b/fit/core-reference/src/main/webapp/WEB-INF/web.xml
@@ -46,4 +46,4 @@ under the License.
<auth-method>CLIENT-CERT</auth-method>
</login-config>
-</web-app>
\ No newline at end of file
+</web-app>
http://git-wip-us.apache.org/repos/asf/syncope/blob/aa25af97/fit/core-reference/src/test/java/org/apache/syncope/fit/SCIMDetector.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/SCIMDetector.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/SCIMDetector.java
new file mode 100644
index 0000000..d236c7f
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/SCIMDetector.java
@@ -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.
+ */
+package org.apache.syncope.fit;
+
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import javax.xml.bind.DatatypeConverter;
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.syncope.ext.scimv2.api.SCIMConstants;
+import org.apache.syncope.fit.core.SCIMITCase;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SCIMDetector {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SCIMDetector.class);
+
+ private static Boolean ENABLED;
+
+ public static boolean isSCIMAvailable() {
+ synchronized (LOG) {
+ if (ENABLED == null) {
+ try {
+ Response response = WebClient.create(SCIMITCase.SCIM_ADDRESS).path("ServiceProviderConfigs").
+ accept(SCIMConstants.APPLICATION_SCIM_JSON_TYPE).
+ header(HttpHeaders.AUTHORIZATION,
+ "Basic " + DatatypeConverter.printBase64Binary(
+ (AbstractITCase.ADMIN_UNAME + ":" + AbstractITCase.ADMIN_PWD).getBytes())).
+ get();
+ ENABLED = response.getStatus() == 200;
+ } catch (Exception e) {
+ // ignore
+ ENABLED = false;
+ }
+ }
+ }
+ return ENABLED;
+ }
+}