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/11/15 14:09:08 UTC

[1/2] syncope git commit: [SYNCOPE-152] SCIM search via POST

Repository: syncope
Updated Branches:
  refs/heads/2_0_X 7a437c0f6 -> fa2ed7303
  refs/heads/master 5e83b3787 -> 07c7e777a


[SYNCOPE-152] SCIM search via POST


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/fa2ed730
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/fa2ed730
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/fa2ed730

Branch: refs/heads/2_0_X
Commit: fa2ed73036d6c75b2dca0aea0e764f0e68938d81
Parents: 7a437c0
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Wed Nov 15 15:08:14 2017 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Wed Nov 15 15:08:19 2017 +0100

----------------------------------------------------------------------
 .../syncope/core/logic/SCIMDataBinder.java      | 10 +-
 .../syncope/ext/scimv2/api/data/SCIMGroup.java  |  5 +-
 .../ext/scimv2/api/data/SCIMSearchRequest.java  | 96 ++++++++++++++++++++
 .../ext/scimv2/api/service/SearchService.java   | 17 +++-
 .../syncope/ext/scimv2/api/type/Resource.java   |  1 +
 .../ext/scimv2/cxf/service/AbstractService.java | 41 ++++++---
 .../scimv2/cxf/service/GroupServiceImpl.java    | 22 ++++-
 .../ext/scimv2/cxf/service/UserServiceImpl.java | 24 ++++-
 .../org/apache/syncope/fit/core/SCIMITCase.java | 20 ++++
 9 files changed, 208 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/fa2ed730/ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/SCIMDataBinder.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/SCIMDataBinder.java b/ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/SCIMDataBinder.java
index e3b3140..3dd3615 100644
--- a/ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/SCIMDataBinder.java
+++ b/ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/SCIMDataBinder.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.core.logic;
 
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -101,9 +102,15 @@ public class SCIMDataBinder {
     public SCIMUser toSCIMUser(final UserTO userTO, final String location) {
         SCIMConf conf = confManager.get();
 
+        List<String> schemas = new ArrayList<>();
+        schemas.add(Resource.User.schema());
+        if (conf.getEnterpriseUserConf() != null) {
+            schemas.add(Resource.EnterpriseUser.schema());
+        }
+
         SCIMUser user = new SCIMUser(
                 userTO.getKey(),
-                Collections.singletonList(Resource.User.schema()),
+                schemas,
                 new Meta(
                         Resource.User,
                         userTO.getCreationDate(),
@@ -356,7 +363,6 @@ public class SCIMDataBinder {
     public SCIMGroup toSCIMGroup(final GroupTO groupTO, final String location) {
         SCIMGroup group = new SCIMGroup(
                 groupTO.getKey(),
-                Collections.singletonList(Resource.Group.schema()),
                 new Meta(
                         Resource.Group,
                         groupTO.getCreationDate(),

http://git-wip-us.apache.org/repos/asf/syncope/blob/fa2ed730/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
index 0657476..7bafd4b 100644
--- 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
@@ -22,7 +22,9 @@ 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.Collections;
 import java.util.List;
+import org.apache.syncope.ext.scimv2.api.type.Resource;
 
 @JsonPropertyOrder({ "schemas", "id", "externalId", "displayName", "members", "meta" })
 public class SCIMGroup extends SCIMResource {
@@ -36,11 +38,10 @@ public class SCIMGroup extends SCIMResource {
     @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);
+        super(id, Collections.singletonList(Resource.Group.schema()), meta);
         this.displayName = displayName;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/fa2ed730/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMSearchRequest.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMSearchRequest.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMSearchRequest.java
new file mode 100644
index 0000000..570ee3a
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMSearchRequest.java
@@ -0,0 +1,96 @@
+/*
+ * 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.Resource;
+import org.apache.syncope.ext.scimv2.api.type.SortOrder;
+
+public class SCIMSearchRequest extends SCIMBean {
+
+    private static final long serialVersionUID = 5759362928661983543L;
+
+    private final List<String> schemas = Arrays.asList(Resource.SearchRequest.schema());
+
+    private final List<String> attributes = new ArrayList<>();
+
+    private final List<String> excludedAttributes = new ArrayList<>();
+
+    private final String filter;
+
+    private final String sortBy;
+
+    private final SortOrder sortOrder;
+
+    private final Integer startIndex;
+
+    private final Integer count;
+
+    @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+    public SCIMSearchRequest(
+            @JsonProperty("filter") final String filter,
+            @JsonProperty("sortBy") final String sortBy,
+            @JsonProperty("sortOrder") final SortOrder sortOrder,
+            @JsonProperty("startIndex") final Integer startIndex,
+            @JsonProperty("count") final Integer count) {
+
+        this.filter = filter;
+        this.sortBy = sortBy;
+        this.sortOrder = sortOrder;
+        this.startIndex = startIndex;
+        this.count = count;
+    }
+
+    public List<String> getSchemas() {
+        return schemas;
+    }
+
+    public List<String> getAttributes() {
+        return attributes;
+    }
+
+    public List<String> getExcludedAttributes() {
+        return excludedAttributes;
+    }
+
+    public String getFilter() {
+        return filter;
+    }
+
+    public String getSortBy() {
+        return sortBy;
+    }
+
+    public SortOrder getSortOrder() {
+        return sortOrder;
+    }
+
+    public Integer getStartIndex() {
+        return startIndex;
+    }
+
+    public Integer getCount() {
+        return count;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/fa2ed730/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/SearchService.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/SearchService.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/SearchService.java
index fcd4789..d6cbaf5 100644
--- a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/SearchService.java
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/SearchService.java
@@ -19,12 +19,16 @@
 package org.apache.syncope.ext.scimv2.api.service;
 
 import java.util.List;
+import javax.ws.rs.Consumes;
 import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
 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.data.SCIMSearchRequest;
 import org.apache.syncope.ext.scimv2.api.type.SortOrder;
 
 public interface SearchService<R extends SCIMResource> {
@@ -32,10 +36,17 @@ public interface SearchService<R extends SCIMResource> {
     @GET
     @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
     ListResponse<R> search(
-            @QueryParam("startIndex") Integer startIndex,
-            @QueryParam("count") Integer count,
+            @QueryParam("attributes") List<String> attributes,
+            @QueryParam("excludedAttributes") List<String> excludedAttributes,
             @QueryParam("filter") String filter,
             @QueryParam("sortBy") String sortBy,
             @QueryParam("sortOrder") SortOrder sortOrder,
-            @QueryParam("attributes") List<String> attributes);
+            @QueryParam("startIndex") Integer startIndex,
+            @QueryParam("count") Integer count);
+
+    @POST
+    @Path(".search")
+    @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
+    @Consumes({ SCIMConstants.APPLICATION_SCIM_JSON })
+    ListResponse<R> search(SCIMSearchRequest request);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/fa2ed730/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/Resource.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/Resource.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/Resource.java
index 8fb2bde..7800b68 100644
--- a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/Resource.java
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/Resource.java
@@ -26,6 +26,7 @@ public enum Resource {
     User("urn:ietf:params:scim:schemas:core:2.0:User"),
     EnterpriseUser("urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"),
     Group("urn:ietf:params:scim:schemas:core:2.0:Group"),
+    SearchRequest("urn:ietf:params:scim:api:messages:2.0:SearchRequest"),
     ListResponse("urn:ietf:params:scim:api:messages:2.0:ListResponse"),
     Error("urn:ietf:params:scim:api:messages:2.0:Error");
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/fa2ed730/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/AbstractService.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/AbstractService.java b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/AbstractService.java
index 5eeca49..4274041 100644
--- a/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/AbstractService.java
+++ b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/AbstractService.java
@@ -39,6 +39,7 @@ import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.spring.ApplicationContextProvider;
 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.data.SCIMSearchRequest;
 import org.apache.syncope.ext.scimv2.api.type.Resource;
 import org.apache.syncope.ext.scimv2.api.type.SortOrder;
 import org.slf4j.Logger;
@@ -104,27 +105,26 @@ abstract class AbstractService<R extends SCIMResource> implements SearchService<
     @SuppressWarnings("unchecked")
     protected ListResponse<R> doSearch(
             final Resource type,
-            final Integer startIndex,
-            final Integer count,
-            final String filter,
-            final String sortBy,
-            final SortOrder sortOrder,
-            final List<String> attributes) {
+            final SCIMSearchRequest request) {
 
         if (type == null) {
             throw new UnsupportedOperationException();
         }
 
+        int startIndex = request.getStartIndex() == null || request.getStartIndex() <= 1
+                ? 1
+                : (request.getStartIndex() / AnyDAO.DEFAULT_PAGE_SIZE) + 1;
+
         Pair<Integer, ? extends List<? extends AnyTO>> result = anyLogic(type).search(
-                StringUtils.isBlank(filter) ? null : SearchCondConverter.convert(filter),
-                startIndex == null || startIndex <= 1 ? 1 : (startIndex / AnyDAO.DEFAULT_PAGE_SIZE) + 1,
+                StringUtils.isBlank(request.getFilter()) ? null : SearchCondConverter.convert(request.getFilter()),
+                startIndex,
                 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);
+                result.getLeft(), startIndex == 1 ? 1 : startIndex - 1, AnyDAO.DEFAULT_PAGE_SIZE);
 
         for (AnyTO anyTO : result.getRight()) {
             SCIMResource resource = null;
@@ -148,13 +148,28 @@ abstract class AbstractService<R extends SCIMResource> implements SearchService<
 
     @Override
     public ListResponse<R> search(
-            final Integer startIndex,
-            final Integer count,
+            final List<String> attributes,
+            final List<String> excludedAttributes,
             final String filter,
             final String sortBy,
             final SortOrder sortOrder,
-            final List<String> attributes) {
+            final Integer startIndex,
+            final Integer count) {
 
-        return doSearch(null, startIndex, count, filter, sortBy, sortOrder, attributes);
+        SCIMSearchRequest request = new SCIMSearchRequest(filter, sortBy, sortOrder, startIndex, count);
+        if (attributes != null) {
+            request.getAttributes().addAll(attributes);
+        }
+        if (excludedAttributes != null) {
+            request.getExcludedAttributes().addAll(excludedAttributes);
+        }
+
+        return doSearch(null, request);
     }
+
+    @Override
+    public ListResponse<R> search(final SCIMSearchRequest request) {
+        return doSearch(null, request);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/fa2ed730/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
index d03b57c..fdc47aa 100644
--- 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
@@ -23,6 +23,7 @@ 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.data.SCIMSearchRequest;
 import org.apache.syncope.ext.scimv2.api.service.GroupService;
 import org.apache.syncope.ext.scimv2.api.type.Resource;
 import org.apache.syncope.ext.scimv2.api.type.SortOrder;
@@ -58,14 +59,27 @@ public class GroupServiceImpl extends AbstractService<SCIMGroup> implements Grou
 
     @Override
     public ListResponse<SCIMGroup> search(
-            final Integer startIndex,
-            final Integer count,
+            final List<String> attributes,
+            final List<String> excludedAttributes,
             final String filter,
             final String sortBy,
             final SortOrder sortOrder,
-            final List<String> attributes) {
+            final Integer startIndex,
+            final Integer count) {
+
+        SCIMSearchRequest request = new SCIMSearchRequest(filter, sortBy, sortOrder, startIndex, count);
+        if (attributes != null) {
+            request.getAttributes().addAll(attributes);
+        }
+        if (excludedAttributes != null) {
+            request.getExcludedAttributes().addAll(excludedAttributes);
+        }
 
-        return doSearch(Resource.Group, startIndex, count, filter, sortBy, sortOrder, attributes);
+        return doSearch(Resource.Group, request);
     }
 
+    @Override
+    public ListResponse<SCIMGroup> search(final SCIMSearchRequest request) {
+        return doSearch(Resource.Group, request);
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/fa2ed730/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
index 67b9b47..0f98362 100644
--- 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
@@ -22,6 +22,7 @@ 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.SCIMSearchRequest;
 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.Resource;
@@ -58,13 +59,28 @@ public class UserServiceImpl extends AbstractService<SCIMUser> implements UserSe
 
     @Override
     public ListResponse<SCIMUser> search(
-            final Integer startIndex,
-            final Integer count,
+            final List<String> attributes,
+            final List<String> excludedAttributes,
             final String filter,
             final String sortBy,
             final SortOrder sortOrder,
-            final List<String> attributes) {
+            final Integer startIndex,
+            final Integer count) {
 
-        return doSearch(Resource.User, startIndex, count, filter, sortBy, sortOrder, attributes);
+        SCIMSearchRequest request = new SCIMSearchRequest(filter, sortBy, sortOrder, startIndex, count);
+        if (attributes != null) {
+            request.getAttributes().addAll(attributes);
+        }
+        if (excludedAttributes != null) {
+            request.getExcludedAttributes().addAll(excludedAttributes);
+        }
+
+        return doSearch(Resource.User, request);
     }
+
+    @Override
+    public ListResponse<SCIMUser> search(final SCIMSearchRequest request) {
+        return doSearch(Resource.User, request);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/fa2ed730/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SCIMITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SCIMITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SCIMITCase.java
index cabe7f8..ca15f05 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SCIMITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SCIMITCase.java
@@ -71,6 +71,7 @@ public class SCIMITCase extends AbstractITCase {
     private WebClient webClient() {
         return WebClient.create(SCIM_ADDRESS, Arrays.asList(new JacksonSCIMJsonProvider())).
                 accept(SCIMConstants.APPLICATION_SCIM_JSON_TYPE).
+                type(SCIMConstants.APPLICATION_SCIM_JSON_TYPE).
                 header(HttpHeaders.AUTHORIZATION, "Bearer " + adminClient.getJWT());
     }
 
@@ -225,6 +226,25 @@ public class SCIMITCase extends AbstractITCase {
         SCIMGroup additional = groups.getResources().get(0);
         assertEquals("additional", additional.getDisplayName());
 
+        // eq via POST
+        String request = "{"
+                + "     \"schemas\": [\"urn:ietf:params:scim:api:messages:2.0:SearchRequest\"],"
+                + "     \"filter\": \"displayName eq \\\"additional\\\"\""
+                + "   }";
+        response = webClient().path("Groups").path("/.search").post(request);
+        assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
+        assertEquals(
+                SCIMConstants.APPLICATION_SCIM_JSON,
+                StringUtils.substringBefore(response.getHeaderString(HttpHeaders.CONTENT_TYPE), ";"));
+
+        groups = response.readEntity(new GenericType<ListResponse<SCIMGroup>>() {
+        });
+        assertNotNull(groups);
+        assertEquals(1, groups.getTotalResults());
+
+        additional = groups.getResources().get(0);
+        assertEquals("additional", additional.getDisplayName());
+
         // gt
         UserTO newUser = userService.create(UserITCase.getUniqueSampleTO("scimsearch@syncope.apache.org")).readEntity(
                 new GenericType<ProvisioningResult<UserTO>>() {


[2/2] syncope git commit: [SYNCOPE-152] SCIM search via POST

Posted by il...@apache.org.
[SYNCOPE-152] SCIM search via POST


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/07c7e777
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/07c7e777
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/07c7e777

Branch: refs/heads/master
Commit: 07c7e777a25c58c1b97a73e3e945e27402c1d82f
Parents: 5e83b37
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Wed Nov 15 15:08:14 2017 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Wed Nov 15 15:08:58 2017 +0100

----------------------------------------------------------------------
 .../syncope/core/logic/SCIMDataBinder.java      | 10 +-
 .../syncope/ext/scimv2/api/data/SCIMGroup.java  |  5 +-
 .../ext/scimv2/api/data/SCIMSearchRequest.java  | 96 ++++++++++++++++++++
 .../ext/scimv2/api/service/SearchService.java   | 17 +++-
 .../syncope/ext/scimv2/api/type/Resource.java   |  1 +
 .../ext/scimv2/cxf/service/AbstractService.java | 41 ++++++---
 .../scimv2/cxf/service/GroupServiceImpl.java    | 22 ++++-
 .../ext/scimv2/cxf/service/UserServiceImpl.java | 24 ++++-
 .../org/apache/syncope/fit/core/SCIMITCase.java | 20 ++++
 9 files changed, 208 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/07c7e777/ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/SCIMDataBinder.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/SCIMDataBinder.java b/ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/SCIMDataBinder.java
index d15d30b..e46c4c8 100644
--- a/ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/SCIMDataBinder.java
+++ b/ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/SCIMDataBinder.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.core.logic;
 
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -98,9 +99,15 @@ public class SCIMDataBinder {
     public SCIMUser toSCIMUser(final UserTO userTO, final String location) {
         SCIMConf conf = confManager.get();
 
+        List<String> schemas = new ArrayList<>();
+        schemas.add(Resource.User.schema());
+        if (conf.getEnterpriseUserConf() != null) {
+            schemas.add(Resource.EnterpriseUser.schema());
+        }
+
         SCIMUser user = new SCIMUser(
                 userTO.getKey(),
-                Collections.singletonList(Resource.User.schema()),
+                schemas,
                 new Meta(
                         Resource.User,
                         userTO.getCreationDate(),
@@ -353,7 +360,6 @@ public class SCIMDataBinder {
     public SCIMGroup toSCIMGroup(final GroupTO groupTO, final String location) {
         SCIMGroup group = new SCIMGroup(
                 groupTO.getKey(),
-                Collections.singletonList(Resource.Group.schema()),
                 new Meta(
                         Resource.Group,
                         groupTO.getCreationDate(),

http://git-wip-us.apache.org/repos/asf/syncope/blob/07c7e777/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
index 0657476..7bafd4b 100644
--- 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
@@ -22,7 +22,9 @@ 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.Collections;
 import java.util.List;
+import org.apache.syncope.ext.scimv2.api.type.Resource;
 
 @JsonPropertyOrder({ "schemas", "id", "externalId", "displayName", "members", "meta" })
 public class SCIMGroup extends SCIMResource {
@@ -36,11 +38,10 @@ public class SCIMGroup extends SCIMResource {
     @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);
+        super(id, Collections.singletonList(Resource.Group.schema()), meta);
         this.displayName = displayName;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/07c7e777/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMSearchRequest.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMSearchRequest.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMSearchRequest.java
new file mode 100644
index 0000000..570ee3a
--- /dev/null
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SCIMSearchRequest.java
@@ -0,0 +1,96 @@
+/*
+ * 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.Resource;
+import org.apache.syncope.ext.scimv2.api.type.SortOrder;
+
+public class SCIMSearchRequest extends SCIMBean {
+
+    private static final long serialVersionUID = 5759362928661983543L;
+
+    private final List<String> schemas = Arrays.asList(Resource.SearchRequest.schema());
+
+    private final List<String> attributes = new ArrayList<>();
+
+    private final List<String> excludedAttributes = new ArrayList<>();
+
+    private final String filter;
+
+    private final String sortBy;
+
+    private final SortOrder sortOrder;
+
+    private final Integer startIndex;
+
+    private final Integer count;
+
+    @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
+    public SCIMSearchRequest(
+            @JsonProperty("filter") final String filter,
+            @JsonProperty("sortBy") final String sortBy,
+            @JsonProperty("sortOrder") final SortOrder sortOrder,
+            @JsonProperty("startIndex") final Integer startIndex,
+            @JsonProperty("count") final Integer count) {
+
+        this.filter = filter;
+        this.sortBy = sortBy;
+        this.sortOrder = sortOrder;
+        this.startIndex = startIndex;
+        this.count = count;
+    }
+
+    public List<String> getSchemas() {
+        return schemas;
+    }
+
+    public List<String> getAttributes() {
+        return attributes;
+    }
+
+    public List<String> getExcludedAttributes() {
+        return excludedAttributes;
+    }
+
+    public String getFilter() {
+        return filter;
+    }
+
+    public String getSortBy() {
+        return sortBy;
+    }
+
+    public SortOrder getSortOrder() {
+        return sortOrder;
+    }
+
+    public Integer getStartIndex() {
+        return startIndex;
+    }
+
+    public Integer getCount() {
+        return count;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/07c7e777/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/SearchService.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/SearchService.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/SearchService.java
index fcd4789..d6cbaf5 100644
--- a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/SearchService.java
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/SearchService.java
@@ -19,12 +19,16 @@
 package org.apache.syncope.ext.scimv2.api.service;
 
 import java.util.List;
+import javax.ws.rs.Consumes;
 import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
 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.data.SCIMSearchRequest;
 import org.apache.syncope.ext.scimv2.api.type.SortOrder;
 
 public interface SearchService<R extends SCIMResource> {
@@ -32,10 +36,17 @@ public interface SearchService<R extends SCIMResource> {
     @GET
     @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
     ListResponse<R> search(
-            @QueryParam("startIndex") Integer startIndex,
-            @QueryParam("count") Integer count,
+            @QueryParam("attributes") List<String> attributes,
+            @QueryParam("excludedAttributes") List<String> excludedAttributes,
             @QueryParam("filter") String filter,
             @QueryParam("sortBy") String sortBy,
             @QueryParam("sortOrder") SortOrder sortOrder,
-            @QueryParam("attributes") List<String> attributes);
+            @QueryParam("startIndex") Integer startIndex,
+            @QueryParam("count") Integer count);
+
+    @POST
+    @Path(".search")
+    @Produces({ SCIMConstants.APPLICATION_SCIM_JSON })
+    @Consumes({ SCIMConstants.APPLICATION_SCIM_JSON })
+    ListResponse<R> search(SCIMSearchRequest request);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/07c7e777/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/Resource.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/Resource.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/Resource.java
index 8fb2bde..7800b68 100644
--- a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/Resource.java
+++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/Resource.java
@@ -26,6 +26,7 @@ public enum Resource {
     User("urn:ietf:params:scim:schemas:core:2.0:User"),
     EnterpriseUser("urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"),
     Group("urn:ietf:params:scim:schemas:core:2.0:Group"),
+    SearchRequest("urn:ietf:params:scim:api:messages:2.0:SearchRequest"),
     ListResponse("urn:ietf:params:scim:api:messages:2.0:ListResponse"),
     Error("urn:ietf:params:scim:api:messages:2.0:Error");
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/07c7e777/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/AbstractService.java
----------------------------------------------------------------------
diff --git a/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/AbstractService.java b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/AbstractService.java
index 6f61e4c..ac34111 100644
--- a/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/AbstractService.java
+++ b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/AbstractService.java
@@ -39,6 +39,7 @@ import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.spring.ApplicationContextProvider;
 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.data.SCIMSearchRequest;
 import org.apache.syncope.ext.scimv2.api.type.Resource;
 import org.apache.syncope.ext.scimv2.api.type.SortOrder;
 import org.slf4j.Logger;
@@ -104,27 +105,26 @@ abstract class AbstractService<R extends SCIMResource> implements SearchService<
     @SuppressWarnings("unchecked")
     protected ListResponse<R> doSearch(
             final Resource type,
-            final Integer startIndex,
-            final Integer count,
-            final String filter,
-            final String sortBy,
-            final SortOrder sortOrder,
-            final List<String> attributes) {
+            final SCIMSearchRequest request) {
 
         if (type == null) {
             throw new UnsupportedOperationException();
         }
 
+        int startIndex = request.getStartIndex() == null || request.getStartIndex() <= 1
+                ? 1
+                : (request.getStartIndex() / AnyDAO.DEFAULT_PAGE_SIZE) + 1;
+
         Pair<Integer, ? extends List<? extends AnyTO>> result = anyLogic(type).search(
-                StringUtils.isBlank(filter) ? null : SearchCondConverter.convert(filter),
-                startIndex == null || startIndex <= 1 ? 1 : (startIndex / AnyDAO.DEFAULT_PAGE_SIZE) + 1,
+                StringUtils.isBlank(request.getFilter()) ? null : SearchCondConverter.convert(request.getFilter()),
+                startIndex,
                 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);
+                result.getLeft(), startIndex == 1 ? 1 : startIndex - 1, AnyDAO.DEFAULT_PAGE_SIZE);
 
         result.getRight().forEach(anyTO -> {
             SCIMResource resource = null;
@@ -148,13 +148,28 @@ abstract class AbstractService<R extends SCIMResource> implements SearchService<
 
     @Override
     public ListResponse<R> search(
-            final Integer startIndex,
-            final Integer count,
+            final List<String> attributes,
+            final List<String> excludedAttributes,
             final String filter,
             final String sortBy,
             final SortOrder sortOrder,
-            final List<String> attributes) {
+            final Integer startIndex,
+            final Integer count) {
 
-        return doSearch(null, startIndex, count, filter, sortBy, sortOrder, attributes);
+        SCIMSearchRequest request = new SCIMSearchRequest(filter, sortBy, sortOrder, startIndex, count);
+        if (attributes != null) {
+            request.getAttributes().addAll(attributes);
+        }
+        if (excludedAttributes != null) {
+            request.getExcludedAttributes().addAll(excludedAttributes);
+        }
+
+        return doSearch(null, request);
     }
+
+    @Override
+    public ListResponse<R> search(final SCIMSearchRequest request) {
+        return doSearch(null, request);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/07c7e777/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
index d03b57c..fdc47aa 100644
--- 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
@@ -23,6 +23,7 @@ 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.data.SCIMSearchRequest;
 import org.apache.syncope.ext.scimv2.api.service.GroupService;
 import org.apache.syncope.ext.scimv2.api.type.Resource;
 import org.apache.syncope.ext.scimv2.api.type.SortOrder;
@@ -58,14 +59,27 @@ public class GroupServiceImpl extends AbstractService<SCIMGroup> implements Grou
 
     @Override
     public ListResponse<SCIMGroup> search(
-            final Integer startIndex,
-            final Integer count,
+            final List<String> attributes,
+            final List<String> excludedAttributes,
             final String filter,
             final String sortBy,
             final SortOrder sortOrder,
-            final List<String> attributes) {
+            final Integer startIndex,
+            final Integer count) {
+
+        SCIMSearchRequest request = new SCIMSearchRequest(filter, sortBy, sortOrder, startIndex, count);
+        if (attributes != null) {
+            request.getAttributes().addAll(attributes);
+        }
+        if (excludedAttributes != null) {
+            request.getExcludedAttributes().addAll(excludedAttributes);
+        }
 
-        return doSearch(Resource.Group, startIndex, count, filter, sortBy, sortOrder, attributes);
+        return doSearch(Resource.Group, request);
     }
 
+    @Override
+    public ListResponse<SCIMGroup> search(final SCIMSearchRequest request) {
+        return doSearch(Resource.Group, request);
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/07c7e777/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
index 67b9b47..0f98362 100644
--- 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
@@ -22,6 +22,7 @@ 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.SCIMSearchRequest;
 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.Resource;
@@ -58,13 +59,28 @@ public class UserServiceImpl extends AbstractService<SCIMUser> implements UserSe
 
     @Override
     public ListResponse<SCIMUser> search(
-            final Integer startIndex,
-            final Integer count,
+            final List<String> attributes,
+            final List<String> excludedAttributes,
             final String filter,
             final String sortBy,
             final SortOrder sortOrder,
-            final List<String> attributes) {
+            final Integer startIndex,
+            final Integer count) {
 
-        return doSearch(Resource.User, startIndex, count, filter, sortBy, sortOrder, attributes);
+        SCIMSearchRequest request = new SCIMSearchRequest(filter, sortBy, sortOrder, startIndex, count);
+        if (attributes != null) {
+            request.getAttributes().addAll(attributes);
+        }
+        if (excludedAttributes != null) {
+            request.getExcludedAttributes().addAll(excludedAttributes);
+        }
+
+        return doSearch(Resource.User, request);
     }
+
+    @Override
+    public ListResponse<SCIMUser> search(final SCIMSearchRequest request) {
+        return doSearch(Resource.User, request);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/07c7e777/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SCIMITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SCIMITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SCIMITCase.java
index cc582b5..068ebfa 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SCIMITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SCIMITCase.java
@@ -71,6 +71,7 @@ public class SCIMITCase extends AbstractITCase {
     private WebClient webClient() {
         return WebClient.create(SCIM_ADDRESS, Arrays.asList(new JacksonSCIMJsonProvider())).
                 accept(SCIMConstants.APPLICATION_SCIM_JSON_TYPE).
+                type(SCIMConstants.APPLICATION_SCIM_JSON_TYPE).
                 header(HttpHeaders.AUTHORIZATION, "Bearer " + adminClient.getJWT());
     }
 
@@ -225,6 +226,25 @@ public class SCIMITCase extends AbstractITCase {
         SCIMGroup additional = groups.getResources().get(0);
         assertEquals("additional", additional.getDisplayName());
 
+        // eq via POST
+        String request = "{"
+                + "     \"schemas\": [\"urn:ietf:params:scim:api:messages:2.0:SearchRequest\"],"
+                + "     \"filter\": \"displayName eq \\\"additional\\\"\""
+                + "   }";
+        response = webClient().path("Groups").path("/.search").post(request);
+        assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
+        assertEquals(
+                SCIMConstants.APPLICATION_SCIM_JSON,
+                StringUtils.substringBefore(response.getHeaderString(HttpHeaders.CONTENT_TYPE), ";"));
+
+        groups = response.readEntity(new GenericType<ListResponse<SCIMGroup>>() {
+        });
+        assertNotNull(groups);
+        assertEquals(1, groups.getTotalResults());
+
+        additional = groups.getResources().get(0);
+        assertEquals("additional", additional.getDisplayName());
+
         // gt
         UserTO newUser = userService.create(UserITCase.getUniqueSampleTO("scimsearch@syncope.apache.org")).readEntity(
                 new GenericType<ProvisioningResult<UserTO>>() {