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

lahirujayathilake pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/airavata-custos.git


The following commit(s) were added to refs/heads/master by this push:
     new 72fdd0fd1 Added patch functionality for groups (#415)
72fdd0fd1 is described below

commit 72fdd0fd14d5a53cb5cf9b1015f5a2d4cd7208cb
Author: Ganning Xu <[email protected]>
AuthorDate: Fri Feb 28 13:28:26 2025 -0500

    Added patch functionality for groups (#415)
---
 .../api/group/GroupManagementController.java       | 75 ++++++++++++++++++++++
 .../service/management/GroupManagementService.java | 66 ++++++++++++++++---
 2 files changed, 132 insertions(+), 9 deletions(-)

diff --git 
a/api/src/main/java/org/apache/custos/api/group/GroupManagementController.java 
b/api/src/main/java/org/apache/custos/api/group/GroupManagementController.java
index b29f22334..a9ccd1ac1 100644
--- 
a/api/src/main/java/org/apache/custos/api/group/GroupManagementController.java
+++ 
b/api/src/main/java/org/apache/custos/api/group/GroupManagementController.java
@@ -52,6 +52,7 @@ import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.PatchMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestHeader;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -267,7 +268,81 @@ public class GroupManagementController {
 
         Group updatedGroup = groupManagementService.updateGroup(groupRequest);
         return ResponseEntity.ok(updatedGroup);
+    }
 
+    @PatchMapping("/groups/{groupId}")
+    @Operation(
+            summary = "Patch Group",
+            description = "Patches group with given ID. To remove all 
realm_roles or client_roles, pass in a list with \"custos-remove-all\" as the 
first list element. To remove all group attributes, pass in a list with 
\"custos-remove-all\" as the key of the first list element.",
+            requestBody = 
@io.swagger.v3.oas.annotations.parameters.RequestBody(
+                    required = true,
+                    content = @Content(
+                            schemaProperties = {
+                                    @SchemaProperty(
+                                            name = "name",
+                                            schema = @Schema(
+                                                    type = "string",
+                                                    description = "Group Name"
+                                            )
+                                    ),
+                                    @SchemaProperty(
+                                            name = "description",
+                                            schema = @Schema(
+                                                    type = "string",
+                                                    description = "Group 
Description"
+                                            )
+                                    ),
+                                    @SchemaProperty(
+                                            name = "attributes",
+                                            array = @ArraySchema(
+                                                    schema = 
@Schema(implementation = GroupAttribute.class),
+                                                    arraySchema = 
@Schema(description = "List of Group Attributes")
+                                            )
+                                    ),
+                                    @SchemaProperty(
+                                            name = "realm_roles",
+                                            array = @ArraySchema(
+                                                    schema = 
@Schema(implementation = String.class),
+                                                    arraySchema = 
@Schema(description = "List of Realm Roles")
+                                            )
+                                    ),
+                                    @SchemaProperty(
+                                            name = "client_roles",
+                                            array = @ArraySchema(
+                                                    schema = 
@Schema(implementation = String.class),
+                                                    arraySchema = 
@Schema(description = "List of Client Roles")
+                                            )
+                                    )
+                            }
+                    )
+            ),
+            parameters = {
+                    @Parameter(
+                            name = "client_id",
+                            in = ParameterIn.HEADER,
+                            description = "The client ID initiating the group 
update request",
+                            required = true,
+                            schema = @Schema(type = "string")
+                    ),
+                    @Parameter(
+                            name = "groupId",
+                            in = ParameterIn.PATH,
+                            description = "The ID of the group to update",
+                            required = true,
+                            schema = @Schema(type = "string")
+                    )
+            },
+            responses = {
+                    @ApiResponse(responseCode = "200", description = "Group 
updated successfully", content = @Content(schema = @Schema(implementation = 
Group.class))),
+                    @ApiResponse(responseCode = "401", description = 
"Unauthorized Request", content = @Content()),
+                    @ApiResponse(responseCode = "404", description = "When the 
associated Group cannot be found", content = @Content()),
+                    @ApiResponse(responseCode = "500", description = "Internal 
Server Error", content = @Content())
+            }
+    )
+    public ResponseEntity<Group> patchGroup(@PathVariable("groupId") String 
groupId, @RequestBody Group request, @RequestHeader HttpHeaders headers) {
+        AuthClaim authClaim = authorize(headers);
+        Group updatedGroup = groupManagementService.patchGroup(authClaim, 
groupId, request);
+        return ResponseEntity.ok(updatedGroup);
     }
 
     @DeleteMapping("/groups/{groupId}")
diff --git 
a/services/src/main/java/org/apache/custos/service/management/GroupManagementService.java
 
b/services/src/main/java/org/apache/custos/service/management/GroupManagementService.java
index 55c767b00..d3c22c250 100644
--- 
a/services/src/main/java/org/apache/custos/service/management/GroupManagementService.java
+++ 
b/services/src/main/java/org/apache/custos/service/management/GroupManagementService.java
@@ -19,6 +19,7 @@
 
 package org.apache.custos.service.management;
 
+import org.apache.custos.core.constants.Constants;
 import org.apache.custos.core.iam.api.GroupRepresentation;
 import org.apache.custos.core.iam.api.UserAttribute;
 import org.apache.custos.core.iam.api.UserRepresentation;
@@ -26,15 +27,8 @@ import org.apache.custos.core.iam.api.UserSearchMetadata;
 import org.apache.custos.core.iam.api.UserSearchRequest;
 import org.apache.custos.core.identity.api.AuthToken;
 import org.apache.custos.core.identity.api.GetUserManagementSATokenRequest;
-import org.apache.custos.core.user.profile.api.GetAllGroupsResponse;
-import org.apache.custos.core.user.profile.api.GetAllUserProfilesResponse;
-import org.apache.custos.core.user.profile.api.Group;
-import org.apache.custos.core.user.profile.api.GroupAttribute;
-import org.apache.custos.core.user.profile.api.GroupMembership;
-import org.apache.custos.core.user.profile.api.GroupToGroupMembership;
-import org.apache.custos.core.user.profile.api.UserGroupMembershipTypeRequest;
-import org.apache.custos.core.user.profile.api.UserProfile;
-import org.apache.custos.core.user.profile.api.UserProfileRequest;
+import org.apache.custos.core.user.profile.api.*;
+import org.apache.custos.service.auth.AuthClaim;
 import org.apache.custos.service.exceptions.InternalServerException;
 import org.apache.custos.service.iam.IamAdminService;
 import org.apache.custos.service.identity.IdentityService;
@@ -128,6 +122,60 @@ public class GroupManagementService {
         }
     }
 
+    public Group patchGroup(AuthClaim authClaim, String groupId, 
org.apache.custos.core.user.profile.api.Group groupChangeProperties) {
+        String REMOVE_ALL_TAG = "custos-remove-all"; // TODO: update 
ProtobufPropertiesModule.java for a cleaner solution
+
+        GroupRequest exGroupReq = GroupRequest.newBuilder()
+                .setTenantId(authClaim.getTenantId())
+                .setClientId(authClaim.getIamAuthId())
+                .setClientSec(authClaim.getIamAuthSecret())
+                .setPerformedBy(authClaim.getPerformedBy() != null ? 
authClaim.getPerformedBy() : Constants.SYSTEM)
+                
.setGroup(groupChangeProperties.toBuilder().setId(groupId).build())
+                .build();
+
+        Group exGroup = findGroup(exGroupReq);
+
+        Group.Builder mergedGroupBuilder = exGroup.toBuilder()
+                .setName(!groupChangeProperties.getName().isEmpty() ? 
groupChangeProperties.getName() : exGroup.getName())
+                
.setDescription(!groupChangeProperties.getDescription().isEmpty() ? 
groupChangeProperties.getDescription() : exGroup.getDescription());
+
+        List<String> clientRolesLst = 
groupChangeProperties.getClientRolesList();
+        if (!clientRolesLst.isEmpty()) {
+            mergedGroupBuilder.clearClientRoles();
+            if (!clientRolesLst.get(0).equals(REMOVE_ALL_TAG)) {
+                
mergedGroupBuilder.addAllClientRoles(groupChangeProperties.getClientRolesList());
+            }
+        }
+
+        List<String> realmRolesLst = groupChangeProperties.getRealmRolesList();
+        if (!realmRolesLst.isEmpty()) {
+            mergedGroupBuilder.clearRealmRoles();
+            if (!realmRolesLst.get(0).equals(REMOVE_ALL_TAG)) {
+                
mergedGroupBuilder.addAllRealmRoles(groupChangeProperties.getRealmRolesList());
+            }
+        }
+
+        List<GroupAttribute> groupAttributeList = 
groupChangeProperties.getAttributesList();
+        if (!groupAttributeList.isEmpty()) {
+            mergedGroupBuilder.clearAttributes();
+            if (!groupAttributeList.get(0).getKey().equals(REMOVE_ALL_TAG)) {
+                
mergedGroupBuilder.addAllAttributes(groupChangeProperties.getAttributesList());
+            }
+        }
+
+        Group mergedGroup = mergedGroupBuilder.build();
+
+        GroupRequest updateGroupRequest = GroupRequest.newBuilder()
+                .setTenantId(authClaim.getTenantId())
+                .setClientId(authClaim.getIamAuthId())
+                .setClientSec(authClaim.getIamAuthSecret())
+                .setPerformedBy(authClaim.getPerformedBy() != null ? 
authClaim.getPerformedBy() : Constants.SYSTEM)
+                .setGroup(mergedGroup.toBuilder().setId(groupId).build())
+                .build();
+
+        return updateGroup(updateGroupRequest);
+    }
+
     public org.apache.custos.core.user.profile.api.Status 
deleteGroup(org.apache.custos.core.user.profile.api.GroupRequest request) {
         try {
             LOGGER.debug("Request received to deleteGroup for group " + 
request.getGroup().getId() + " of tenant " + request.getTenantId());

Reply via email to