This is an automated email from the ASF dual-hosted git repository.

ilgrosso pushed a commit to branch 3_0_X
in repository https://gitbox.apache.org/repos/asf/syncope.git


The following commit(s) were added to refs/heads/3_0_X by this push:
     new 60ab1885a6 [SYNCOPE-1880] accept Prefer header with return-no-content 
value with SCIM Patch to return 204 (No Content) (#1077)
60ab1885a6 is described below

commit 60ab1885a642e4357e48a9872d71f32f38247724
Author: Samuel Garofalo <[email protected]>
AuthorDate: Tue May 13 12:29:09 2025 +0200

    [SYNCOPE-1880] accept Prefer header with return-no-content value with SCIM 
Patch to return 204 (No Content) (#1077)
---
 .../scimv2/cxf/service/AbstractSCIMService.java    | 35 +++++++++++++++++++++-
 .../scimv2/cxf/service/SCIMGroupServiceImpl.java   | 20 +++++++++----
 .../ext/scimv2/cxf/service/SCIMServiceImpl.java    |  5 ++++
 .../scimv2/cxf/service/SCIMUserServiceImpl.java    | 20 +++++++++----
 .../org/apache/syncope/fit/core/SCIMITCase.java    | 28 +++++++++++++++--
 5 files changed, 93 insertions(+), 15 deletions(-)

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
index 61b8f7cbfa..da3038c1b6 100644
--- 
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
@@ -32,6 +32,8 @@ 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.UserTO;
+import org.apache.syncope.common.rest.api.Preference;
+import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.core.logic.AbstractAnyLogic;
 import org.apache.syncope.core.logic.GroupLogic;
 import org.apache.syncope.core.logic.SCIMDataBinder;
@@ -124,12 +126,33 @@ abstract class AbstractSCIMService<R extends 
SCIMResource> {
                 build();
     }
 
-    protected Response updateResponse(final String key, final SCIMResource 
resource) {
+    protected Response updateResponse(final String key, final SCIMResource 
resource, final boolean patch) {
+        if (patch) {
+            Response.ResponseBuilder builder;
+            switch (getPreference()) {
+                case RETURN_NO_CONTENT:
+                    builder = Response.noContent();
+                    break;
+
+                case RETURN_CONTENT:
+                case NONE:
+                default:
+                    builder = 
Response.ok(uriInfo.getAbsolutePathBuilder().path(key).build()).entity(getResource(key));
+                    break;
+            }
+            if (getPreference() == Preference.RETURN_CONTENT || 
getPreference() == Preference.RETURN_NO_CONTENT) {
+                builder.header(RESTHeaders.PREFERENCE_APPLIED, 
getPreference().toString());
+            }
+
+            return builder.build();
+        }
         return Response.ok(uriInfo.getAbsolutePathBuilder().path(key).build()).
                 entity(resource).
                 build();
     }
 
+    protected abstract SCIMResource getResource(String key);
+
     protected ResponseBuilder checkETag(final Resource resource, final String 
key) {
         OffsetDateTime lastChange = anyDAO(resource).findLastChange(key);
         if (lastChange == null) {
@@ -223,4 +246,14 @@ abstract class AbstractSCIMService<R extends SCIMResource> 
{
 
         return response;
     }
+
+    /**
+     * Reads {@code Prefer} header from request and parses into a {@code 
Preference} instance.
+     *
+     * @return a {@code Preference} instance matching the passed {@code 
Prefer} header,
+     * or {@code Preference.NONE} if missing.
+     */
+    protected Preference getPreference() {
+        return 
Preference.fromString(messageContext.getHttpServletRequest().getHeader(RESTHeaders.PREFER));
+    }
 }
diff --git 
a/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/SCIMGroupServiceImpl.java
 
b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/SCIMGroupServiceImpl.java
index d6818b8786..04e1777742 100644
--- 
a/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/SCIMGroupServiceImpl.java
+++ 
b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/SCIMGroupServiceImpl.java
@@ -53,6 +53,7 @@ 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.SCIMGroup;
 import org.apache.syncope.ext.scimv2.api.data.SCIMPatchOp;
+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.service.SCIMGroupService;
 import org.apache.syncope.ext.scimv2.api.type.ErrorType;
@@ -166,11 +167,8 @@ public class SCIMGroupServiceImpl extends 
AbstractSCIMService<SCIMGroup> impleme
 
         return updateResponse(
                 id,
-                binder.toSCIMGroup(
-                        groupLogic.read(id),
-                        
uriInfo.getAbsolutePathBuilder().path(id).build().toASCIIString(),
-                        List.of(),
-                        List.of()));
+                null,
+                true);
     }
 
     @Override
@@ -212,7 +210,17 @@ public class SCIMGroupServiceImpl extends 
AbstractSCIMService<SCIMGroup> impleme
                         result.getEntity(),
                         
uriInfo.getAbsolutePathBuilder().path(result.getEntity().getKey()).build().toASCIIString(),
                         List.of(),
-                        List.of()));
+                        List.of()),
+                false);
+    }
+
+    @Override
+    protected SCIMResource getResource(final String key) {
+        return binder.toSCIMGroup(
+                groupLogic.read(key),
+                
uriInfo.getAbsolutePathBuilder().path(key).build().toASCIIString(),
+                List.of(),
+                List.of());
     }
 
     @Override
diff --git 
a/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/SCIMServiceImpl.java
 
b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/SCIMServiceImpl.java
index 693c09cfc1..2d124aaae5 100644
--- 
a/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/SCIMServiceImpl.java
+++ 
b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/SCIMServiceImpl.java
@@ -73,4 +73,9 @@ public class SCIMServiceImpl extends 
AbstractSCIMService<SCIMResource> implement
     public Response schema(final String schema) {
         return Response.ok(scimLogic.schema(schema)).build();
     }
+
+    @Override
+    protected SCIMResource getResource(final String key) {
+        return null;
+    }
 }
diff --git 
a/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/SCIMUserServiceImpl.java
 
b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/SCIMUserServiceImpl.java
index 69d51b4164..e5e9ec9d38 100644
--- 
a/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/SCIMUserServiceImpl.java
+++ 
b/ext/scimv2/scim-rest-cxf/src/main/java/org/apache/syncope/ext/scimv2/cxf/service/SCIMUserServiceImpl.java
@@ -40,6 +40,7 @@ import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.ext.scimv2.api.BadRequestException;
 import org.apache.syncope.ext.scimv2.api.data.ListResponse;
 import org.apache.syncope.ext.scimv2.api.data.SCIMPatchOp;
+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.data.SCIMUser;
 import org.apache.syncope.ext.scimv2.api.service.SCIMUserService;
@@ -102,11 +103,8 @@ public class SCIMUserServiceImpl extends 
AbstractSCIMService<SCIMUser> implement
 
         return updateResponse(
                 id,
-                binder.toSCIMUser(
-                        userLogic.read(id),
-                        
uriInfo.getAbsolutePathBuilder().path(id).build().toASCIIString(),
-                        List.of(),
-                        List.of()));
+                null,
+                true);
     }
 
     @Override
@@ -144,7 +142,17 @@ public class SCIMUserServiceImpl extends 
AbstractSCIMService<SCIMUser> implement
                         result.getEntity(),
                         
uriInfo.getAbsolutePathBuilder().path(result.getEntity().getKey()).build().toASCIIString(),
                         List.of(),
-                        List.of()));
+                        List.of()),
+                false);
+    }
+
+    @Override
+    protected SCIMResource getResource(final String key) {
+        return binder.toSCIMUser(
+                userLogic.read(key),
+                
uriInfo.getAbsolutePathBuilder().path(key).build().toASCIIString(),
+                List.of(),
+                List.of());
     }
 
     @Override
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 192ce565cf..0beb6162b1 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
@@ -61,6 +61,8 @@ import org.apache.syncope.common.lib.to.GroupTO;
 import org.apache.syncope.common.lib.to.ProvisioningResult;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.PatchOperation;
+import org.apache.syncope.common.rest.api.Preference;
+import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.ext.scimv2.api.SCIMConstants;
 import org.apache.syncope.ext.scimv2.api.data.Group;
 import org.apache.syncope.ext.scimv2.api.data.ListResponse;
@@ -694,8 +696,11 @@ public class SCIMITCase extends AbstractITCase {
                         + "\"value\":\"Password123!\""
                         + "}]"
                         + "}";
-        response = 
webClient().path("Users").path(user.getId()).invoke(HttpMethod.PATCH, body);
-        assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
+        response = webClient().path("Users").path(user.getId())
+                .header(RESTHeaders.PREFER, Preference.RETURN_NO_CONTENT)
+                .invoke(HttpMethod.PATCH, body);
+        assertEquals(Response.Status.NO_CONTENT.getStatusCode(), 
response.getStatus());
+        assertFalse(response.hasEntity());
     }
 
     @Test
@@ -862,6 +867,25 @@ public class SCIMITCase extends AbstractITCase {
 
         group = response.readEntity(SCIMGroup.class);
         assertTrue(group.getMembers().isEmpty());
+
+        // 4. add member
+        body =
+                "{"
+                + 
"\"schemas\":[\"urn:ietf:params:scim:api:messages:2.0:PatchOp\"],"
+                + "\"Operations\":["
+                + "{"
+                + "\"op\":\"Add\","
+                + "\"path\":\"members\","
+                + "\"value\":[{"
+                + "\"value\":\"b3cbc78d-32e6-4bd4-92e0-bbe07566a2ee\"}]"
+                + "}"
+                + "]"
+                + "}";
+        response = webClient().path("Groups").path(group.getId())
+                .header(RESTHeaders.PREFER, Preference.RETURN_NO_CONTENT)
+                .invoke(HttpMethod.PATCH, body);
+        assertEquals(Response.Status.NO_CONTENT.getStatusCode(), 
response.getStatus());
+        assertFalse(response.hasEntity());
     }
 
     @Test

Reply via email to