From 4aa1bb50e2876a6652dd47bfed1093b28c89e532 Mon Sep 17 00:00:00 2001 From: ChanikaRuchini Date: Tue, 5 Dec 2023 15:19:16 +0530 Subject: [PATCH] Support attributes and excludeAttributes query params for List roles v2 endpoint --- .../core/extensions/RoleV2Manager.java | 19 ++++++---- .../protocol/endpoints/ResourceManager.java | 16 ++++---- .../endpoints/RoleResourceV2Manager.java | 38 +++++++++++++++---- .../core/schema/SCIMSchemaDefinitions.java | 8 ++-- .../core/utils/ResourceManagerUtil.java | 12 +++++- 5 files changed, 65 insertions(+), 28 deletions(-) diff --git a/modules/charon-core/src/main/java/org/wso2/charon3/core/extensions/RoleV2Manager.java b/modules/charon-core/src/main/java/org/wso2/charon3/core/extensions/RoleV2Manager.java index ad2cb40c6..3d20fb274 100644 --- a/modules/charon-core/src/main/java/org/wso2/charon3/core/extensions/RoleV2Manager.java +++ b/modules/charon-core/src/main/java/org/wso2/charon3/core/extensions/RoleV2Manager.java @@ -79,17 +79,19 @@ RoleV2 getRole(String id, Map requiredAttributes) /** * List roles with Get. * - * @param node Node - * @param startIndex Start Index - * @param count Count - * @param sortBy Sort by - * @param sortOrder Sort order + * @param node Node + * @param startIndex Start Index + * @param count Count + * @param sortBy Sort by + * @param sortOrder Sort order + * @param requiredAttributes Required attributes * @return List of roles. * @throws CharonException CharonException. * @throws NotImplementedException NotImplementedException. * @throws BadRequestException BadRequestException. */ - RolesV2GetResponse listRolesWithGET(Node node, Integer startIndex, Integer count, String sortBy, String sortOrder) + RolesV2GetResponse listRolesWithGET(Node node, Integer startIndex, Integer count, String sortBy, String sortOrder, + List requiredAttributes) throws CharonException, NotImplementedException, BadRequestException; /** @@ -110,13 +112,14 @@ RoleV2 updateRole(RoleV2 oldRole, RoleV2 newRole) /** * List roles with Post. * - * @param searchRequest Search request. + * @param searchRequest Search request. + * @param requiredAttributes Required attributes. * @return List of roles. * @throws NotImplementedException NotImplementedException. * @throws BadRequestException BadRequestException. * @throws CharonException CharonException. */ - RolesV2GetResponse listRolesWithPost(SearchRequest searchRequest) + RolesV2GetResponse listRolesWithPost(SearchRequest searchRequest, List requiredAttributes) throws NotImplementedException, BadRequestException, CharonException; /** diff --git a/modules/charon-core/src/main/java/org/wso2/charon3/core/protocol/endpoints/ResourceManager.java b/modules/charon-core/src/main/java/org/wso2/charon3/core/protocol/endpoints/ResourceManager.java index c476e1742..4c6d45566 100644 --- a/modules/charon-core/src/main/java/org/wso2/charon3/core/protocol/endpoints/ResourceManager.java +++ b/modules/charon-core/src/main/java/org/wso2/charon3/core/protocol/endpoints/ResourceManager.java @@ -295,16 +295,18 @@ default SCIMResponse deleteRole(String id, RoleV2Manager roleManager) { /** * GET method to list roles in roleV2 model. * - * @param roleManager RoleV2 manager. - * @param filter Filter to be executed. - * @param startIndex Starting index value of the filter. - * @param count Number of required results. - * @param sortBy SortBy. - * @param sortOrder Sorting order. + * @param roleManager RoleV2 manager. + * @param filter Filter to be executed. + * @param startIndex Starting index value of the filter. + * @param count Number of required results. + * @param sortBy SortBy. + * @param sortOrder Sorting order. + * @param attributes Requested attributes. + * @param excludeAttributes Requested exclude attributes. * @return SCIMResponse. */ default SCIMResponse listWithGETRole(RoleV2Manager roleManager, String filter, Integer startIndex, Integer count, - String sortBy, String sortOrder) { + String sortBy, String sortOrder, String attributes, String excludeAttributes) { return new SCIMResponse(ResponseCodeConstants.CODE_NOT_IMPLEMENTED, ResponseCodeConstants.DESC_NOT_IMPLEMENTED, Collections.emptyMap()); diff --git a/modules/charon-core/src/main/java/org/wso2/charon3/core/protocol/endpoints/RoleResourceV2Manager.java b/modules/charon-core/src/main/java/org/wso2/charon3/core/protocol/endpoints/RoleResourceV2Manager.java index 458113435..1813ac24a 100644 --- a/modules/charon-core/src/main/java/org/wso2/charon3/core/protocol/endpoints/RoleResourceV2Manager.java +++ b/modules/charon-core/src/main/java/org/wso2/charon3/core/protocol/endpoints/RoleResourceV2Manager.java @@ -46,6 +46,7 @@ import org.wso2.charon3.core.objects.plainobjects.RolesV2GetResponse; import org.wso2.charon3.core.protocol.ResponseCodeConstants; import org.wso2.charon3.core.protocol.SCIMResponse; +import org.wso2.charon3.core.schema.AttributeSchema; import org.wso2.charon3.core.schema.SCIMConstants; import org.wso2.charon3.core.schema.SCIMResourceSchemaManager; import org.wso2.charon3.core.schema.SCIMResourceTypeSchema; @@ -157,7 +158,8 @@ public SCIMResponse deleteRole(String id, RoleV2Manager roleManager) { @Override public SCIMResponse listWithGETRole(RoleV2Manager roleManager, String filter, Integer startIndexInt, - Integer countInt, String sortBy, String sortOrder) { + Integer countInt, String sortBy, String sortOrder, String attributes, + String excludeAttributes) { try { if (roleManager == null) { @@ -171,10 +173,12 @@ public SCIMResponse listWithGETRole(RoleV2Manager roleManager, String filter, In // Build node for filtering. Node rootNode = buildNode(filter, schema); JSONEncoder encoder = getEncoder(); - + // Get the list of required attributes which must be given a value + List requestedAttributes = getRequestedAttributes( + (SCIMResourceTypeSchema) CopyUtil.deepCopy(schema), attributes, excludeAttributes); RolesV2GetResponse rolesResponse = roleManager.listRolesWithGET(rootNode, startIndex, count, sortBy, - sortOrder); - return processRoleList(rolesResponse, encoder, startIndex); + sortOrder, requestedAttributes); + return processRoleList(rolesResponse, encoder, startIndex, attributes, excludeAttributes); } catch (CharonException | InternalErrorException | BadRequestException | NotImplementedException e) { return encodeSCIMException(e); } catch (IOException e) { @@ -184,6 +188,18 @@ public SCIMResponse listWithGETRole(RoleV2Manager roleManager, String filter, In } } + private List getRequestedAttributes(SCIMResourceTypeSchema schema, String requestedAttributes, + String requestedExcludingAttributes) throws CharonException { + + ArrayList requestedAttributeSchemas = ResourceManagerUtil.getOnlyRequiredAttributes( + (SCIMResourceTypeSchema) CopyUtil.deepCopy(schema), requestedAttributes, requestedExcludingAttributes); + List requestedAttributesList = new ArrayList<>(); + for (AttributeSchema attributeSchema : requestedAttributeSchemas) { + requestedAttributesList.add(attributeSchema.getName()); + } + return requestedAttributesList; + } + @Override public SCIMResponse listWithPOSTRole(String searchRequest, RoleV2Manager roleManager) { @@ -222,8 +238,13 @@ public SCIMResponse listWithPOSTRole(String searchRequest, RoleV2Manager roleMan if (searchRequestObject.getSortOder() == null && searchRequestObject.getSortBy() != null) { searchRequestObject.setSortOder(SCIMConstants.OperationalConstants.ASCENDING); } + String attributes = searchRequestObject.getAttributesAsString(); + String excludeAttributes = searchRequestObject.getExcludedAttributesAsString(); + + List requestedAttributes = getRequestedAttributes( + (SCIMResourceTypeSchema) CopyUtil.deepCopy(schema), attributes, excludeAttributes); - RolesV2GetResponse rolesResponse = roleManager.listRolesWithPost(searchRequestObject); + RolesV2GetResponse rolesResponse = roleManager.listRolesWithPost(searchRequestObject, requestedAttributes); for (RoleV2 role : rolesResponse.getRoles()) { ServerSideValidator.validateRetrievedSCIMObjectInList(role, schema, @@ -415,7 +436,8 @@ private Node buildNode(String filter, SCIMResourceTypeSchema schema) throws BadR * @throws CharonException CharonException. * @throws BadRequestException BadRequestException. */ - private SCIMResponse processRoleList(RolesV2GetResponse rolesResponse, JSONEncoder encoder, int startIndex) + private SCIMResponse processRoleList(RolesV2GetResponse rolesResponse, JSONEncoder encoder, int startIndex, + String attributes, String excludeAttributes) throws CharonException, BadRequestException { if (rolesResponse == null) { @@ -425,8 +447,8 @@ private SCIMResponse processRoleList(RolesV2GetResponse rolesResponse, JSONEncod rolesResponse.setRoles(Collections.emptyList()); } for (RoleV2 role : rolesResponse.getRoles()) { - ServerSideValidator.validateSCIMObjectForRequiredAttributes(role, - SCIMSchemaDefinitions.SCIM_ROLE_V2_SCHEMA); + ServerSideValidator.validateRetrievedSCIMObject(role, SCIMSchemaDefinitions.SCIM_ROLE_V2_SCHEMA, + attributes, excludeAttributes); } // Create a listed resource object out of the returned groups list. ListedResource listedResource = createListedResource(rolesResponse, startIndex); diff --git a/modules/charon-core/src/main/java/org/wso2/charon3/core/schema/SCIMSchemaDefinitions.java b/modules/charon-core/src/main/java/org/wso2/charon3/core/schema/SCIMSchemaDefinitions.java index b82e05e55..586486019 100644 --- a/modules/charon-core/src/main/java/org/wso2/charon3/core/schema/SCIMSchemaDefinitions.java +++ b/modules/charon-core/src/main/java/org/wso2/charon3/core/schema/SCIMSchemaDefinitions.java @@ -1120,7 +1120,7 @@ public static class SCIMRoleSchemaDefinition { SCIMAttributeSchema.createSCIMAttributeSchema(SCIMConstants.RoleSchemaConstants.AUDIENCE_VALUE_URI, SCIMConstants.RoleSchemaConstants.VALUE, SCIMDefinitions.DataType.STRING, false, SCIMConstants.RoleSchemaConstants.AUDIENCE_VALUE_DESC, false, false, - SCIMDefinitions.Mutability.IMMUTABLE, SCIMDefinitions.Returned.DEFAULT, + SCIMDefinitions.Mutability.IMMUTABLE, SCIMDefinitions.Returned.ALWAYS, SCIMDefinitions.Uniqueness.NONE, null, null, null); // A human-readable name of role's audience. @@ -1128,7 +1128,7 @@ public static class SCIMRoleSchemaDefinition { SCIMAttributeSchema.createSCIMAttributeSchema(SCIMConstants.RoleSchemaConstants.AUDIENCE_DISPLAY_URI, SCIMConstants.RoleSchemaConstants.DISPLAY, SCIMDefinitions.DataType.STRING, false, SCIMConstants.RoleSchemaConstants.AUDIENCE_DISPLAY_DESC, false, false, - SCIMDefinitions.Mutability.IMMUTABLE, SCIMDefinitions.Returned.DEFAULT, + SCIMDefinitions.Mutability.IMMUTABLE, SCIMDefinitions.Returned.ALWAYS, SCIMDefinitions.Uniqueness.NONE, null, null, null); // Type of the role's audience (eg: application, organization). @@ -1136,7 +1136,7 @@ public static class SCIMRoleSchemaDefinition { SCIMAttributeSchema.createSCIMAttributeSchema(SCIMConstants.RoleSchemaConstants.AUDIENCE_TYPE_URI, SCIMConstants.RoleSchemaConstants.TYPE, SCIMDefinitions.DataType.STRING, false, SCIMConstants.RoleSchemaConstants.AUDIENCE_TYPE_DESC, false, false, - SCIMDefinitions.Mutability.IMMUTABLE, SCIMDefinitions.Returned.DEFAULT, + SCIMDefinitions.Mutability.IMMUTABLE, SCIMDefinitions.Returned.ALWAYS, SCIMDefinitions.Uniqueness.NONE, new ArrayList<>( Arrays.asList(SCIMConstants.RoleSchemaConstants.APPLICATION, SCIMConstants.RoleSchemaConstants.ORGANIZATION)), null, null); @@ -1157,7 +1157,7 @@ public static class SCIMRoleSchemaDefinition { SCIMAttributeSchema.createSCIMAttributeSchema(SCIMConstants.RoleSchemaConstants.AUDIENCE_URI, SCIMConstants.RoleSchemaConstants.AUDIENCE, SCIMDefinitions.DataType.COMPLEX, false, SCIMConstants.RoleSchemaConstants.AUDIENCE_DESC, false, false, - SCIMDefinitions.Mutability.READ_WRITE, SCIMDefinitions.Returned.DEFAULT, + SCIMDefinitions.Mutability.READ_WRITE, SCIMDefinitions.Returned.ALWAYS, SCIMDefinitions.Uniqueness.NONE, null, null, new ArrayList<>(Arrays.asList(AUDIENCE_VALUE, AUDIENCE_DISPLAY, AUDIENCE_TYPE))); diff --git a/modules/charon-core/src/main/java/org/wso2/charon3/core/utils/ResourceManagerUtil.java b/modules/charon-core/src/main/java/org/wso2/charon3/core/utils/ResourceManagerUtil.java index e09c2402d..e02b97949 100644 --- a/modules/charon-core/src/main/java/org/wso2/charon3/core/utils/ResourceManagerUtil.java +++ b/modules/charon-core/src/main/java/org/wso2/charon3/core/utils/ResourceManagerUtil.java @@ -48,6 +48,16 @@ public static Map getOnlyRequiredAttributesURIs(SCIMResourceTyp String requestedExcludingAttributes) throws CharonException { + ArrayList attributeSchemaArrayList = + getOnlyRequiredAttributes(schema, requestedAttributes, requestedExcludingAttributes); + return convertSchemasToURIs(attributeSchemaArrayList); + } + + public static ArrayList getOnlyRequiredAttributes(SCIMResourceTypeSchema schema, + String requestedAttributes, + String requestedExcludingAttributes) + throws CharonException { + ArrayList attributeSchemaArrayList = (ArrayList) CopyUtil.deepCopy(schema.getAttributesList()); @@ -105,7 +115,7 @@ public static Map getOnlyRequiredAttributesURIs(SCIMResourceTyp requestedAttributes, requestedExcludingAttributes, requestedAttributesList, requestedExcludingAttributesList); } - return convertSchemasToURIs(attributeSchemaArrayList); + return attributeSchemaArrayList; } /*