Search in sources :

Example 16 with Patch

use of org.wso2.carbon.identity.api.server.idp.v1.model.Patch in project charon by wso2.

the class PatchOperationUtil method doPatchRemoveWithoutFilters.

/*
     * This is the patch remove operation when the path is specified without a filter in it.
     * @param parts
     * @param oldResource
     * @return
     * @throws BadRequestException
     * @throws CharonException
     */
private static AbstractSCIMObject doPatchRemoveWithoutFilters(String[] parts, AbstractSCIMObject oldResource) throws BadRequestException, CharonException {
    String[] attributeParts = getAttributeParts(parts[0]);
    if (attributeParts.length == 1) {
        Attribute attribute = oldResource.getAttribute(parts[0]);
        if (attribute != null) {
            if (attribute.getMutability().equals(SCIMDefinitions.Mutability.READ_ONLY) || attribute.getRequired().equals(true)) {
                throw new BadRequestException("Can not remove a required attribute or a read-only attribute", ResponseCodeConstants.MUTABILITY);
            } else {
                String attributeName = attribute.getName();
                oldResource.deleteAttribute(attributeName);
            }
        } else {
            throw new BadRequestException("No such attribute with the name : " + attributeParts[0] + " " + "in the current resource", ResponseCodeConstants.INVALID_PATH);
        }
    } else {
        Attribute attribute = oldResource.getAttribute(attributeParts[0]);
        if (attribute != null) {
            if (attribute.getMultiValued()) {
                // this is multivalued complex case
                List<Attribute> subValuesList = ((MultiValuedAttribute) attribute).getAttributeValues();
                if (subValuesList != null) {
                    for (Attribute subValue : subValuesList) {
                        Map<String, Attribute> subSubAttributeList = ((ComplexAttribute) subValue).getSubAttributesList();
                        // need to remove attributes while iterating through the list.
                        for (Iterator<Attribute> iterator = subSubAttributeList.values().iterator(); iterator.hasNext(); ) {
                            Attribute subSubAttribute = iterator.next();
                            if (subSubAttribute.getName().equals(attributeParts[1])) {
                                if (subSubAttribute.getMutability().equals(SCIMDefinitions.Mutability.READ_ONLY) || subSubAttribute.getRequired().equals(true)) {
                                    throw new BadRequestException("Can not remove a required attribute or a read-only attribute", ResponseCodeConstants.MUTABILITY);
                                } else {
                                    iterator.remove();
                                }
                            }
                        }
                    }
                }
            } else {
                Attribute subAttribute = attribute.getSubAttribute(attributeParts[1]);
                if (subAttribute != null) {
                    if (attributeParts.length == 3) {
                        if (subAttribute.getMultiValued()) {
                            List<Attribute> subSubValuesList = ((MultiValuedAttribute) subAttribute).getAttributeValues();
                            if (subSubValuesList != null) {
                                for (Attribute subSubValue : subSubValuesList) {
                                    Map<String, Attribute> subSubAttributeList = ((ComplexAttribute) subSubValue).getSubAttributesList();
                                    // need to remove attributes while iterating through the list.
                                    for (Iterator<Attribute> iterator = subSubAttributeList.values().iterator(); iterator.hasNext(); ) {
                                        Attribute subSubAttribute = iterator.next();
                                        if (subSubAttribute.getName().equals(attributeParts[2])) {
                                            if (subSubAttribute.getMutability().equals(SCIMDefinitions.Mutability.READ_ONLY) || subSubAttribute.getRequired().equals(true)) {
                                                throw new BadRequestException("Can not remove a required attribute or a read-only " + "attribute", ResponseCodeConstants.MUTABILITY);
                                            } else {
                                                iterator.remove();
                                            }
                                        }
                                    }
                                }
                            }
                        } else {
                            Attribute subSubAttribute = subAttribute.getSubAttribute(attributeParts[2]);
                            if (subSubAttribute.getMutability().equals(SCIMDefinitions.Mutability.READ_ONLY) || subSubAttribute.getRequired().equals(true)) {
                                throw new BadRequestException("Can not remove a required attribute or a read-only attribute", ResponseCodeConstants.MUTABILITY);
                            } else {
                                String subSubAttributeName = subSubAttribute.getName();
                                ((ComplexAttribute) subAttribute).removeSubAttribute(subSubAttributeName);
                            }
                        }
                    } else {
                        // this is complex attribute's sub attribute check
                        if (subAttribute.getMutability().equals(SCIMDefinitions.Mutability.READ_ONLY) || subAttribute.getRequired().equals(true)) {
                            throw new BadRequestException("Can not remove a required attribute or a read-only attribute", ResponseCodeConstants.MUTABILITY);
                        } else {
                            String subAttributeName = subAttribute.getName();
                            ((ComplexAttribute) attribute).removeSubAttribute(subAttributeName);
                        }
                    }
                } else {
                    throw new BadRequestException("No such sub attribute with the name : " + attributeParts[1] + " " + "in the attribute : " + attributeParts[0], ResponseCodeConstants.INVALID_PATH);
                }
            }
        } else {
            throw new BadRequestException("No such attribute with the name : " + attributeParts[0] + " " + "in the current resource", ResponseCodeConstants.INVALID_PATH);
        }
    }
    return oldResource;
}
Also used : MultiValuedAttribute(org.wso2.charon3.core.attributes.MultiValuedAttribute) SimpleAttribute(org.wso2.charon3.core.attributes.SimpleAttribute) ComplexAttribute(org.wso2.charon3.core.attributes.ComplexAttribute) Attribute(org.wso2.charon3.core.attributes.Attribute) ComplexAttribute(org.wso2.charon3.core.attributes.ComplexAttribute) BadRequestException(org.wso2.charon3.core.exceptions.BadRequestException) MultiValuedAttribute(org.wso2.charon3.core.attributes.MultiValuedAttribute)

Example 17 with Patch

use of org.wso2.carbon.identity.api.server.idp.v1.model.Patch in project charon by wso2.

the class PatchOperationUtil method doPatchReplace.

/*
     * This is the main patch replace method.
     * @param operation
     * @param decoder
     * @param oldResource
     * @param copyOfOldResource
     * @param schema
     * @return
     * @throws CharonException
     * @throws NotImplementedException
     * @throws BadRequestException
     * @throws JSONException
     * @throws InternalErrorException
     */
public static AbstractSCIMObject doPatchReplace(PatchOperation operation, JSONDecoder decoder, AbstractSCIMObject oldResource, AbstractSCIMObject copyOfOldResource, SCIMResourceTypeSchema schema) throws CharonException, NotImplementedException, BadRequestException, InternalErrorException {
    if (operation.getPath() != null) {
        String path = operation.getPath();
        // split the path to extract the filter if present.
        String[] parts = path.split("[\\[\\]]");
        if (operation.getPath().contains("[")) {
            try {
                doPatchReplaceOnPathWithFilters(oldResource, schema, decoder, operation, parts);
            } catch (JSONException e) {
                throw new BadRequestException(ResponseCodeConstants.INVALID_SYNTAX);
            }
        } else {
            doPatchReplaceOnPathWithoutFilters(oldResource, schema, decoder, operation, parts);
        }
    } else {
        doPatchReplaceOnResource(oldResource, copyOfOldResource, schema, decoder, operation);
    }
    // validate the updated object
    AbstractSCIMObject validatedResource = ServerSideValidator.validateUpdatedSCIMObject(copyOfOldResource, oldResource, schema, true);
    return validatedResource;
}
Also used : AbstractSCIMObject(org.wso2.charon3.core.objects.AbstractSCIMObject) JSONException(org.json.JSONException) BadRequestException(org.wso2.charon3.core.exceptions.BadRequestException)

Example 18 with Patch

use of org.wso2.carbon.identity.api.server.idp.v1.model.Patch in project charon by wso2.

the class GroupResourceManager method updateWithPatchForAddRemoveOperations.

/**
 * Updates the group based on the operations defined in the patchRequest. The updated group information is sent
 * back in the response.
 *
 * @param existingGroupId   SCIM2 ID of the existing group.
 * @param opList            List of patch operations.
 * @param userManager       SCIM UserManager that handles the persistence layer.
 * @param attributes        Attributes to return in the response.
 * @param excludeAttributes Attributes to exclude in the response.
 * @return SCIM Response.
 */
public SCIMResponse updateWithPatchForAddRemoveOperations(String existingGroupId, List<PatchOperation> opList, UserManager userManager, String attributes, String excludeAttributes) {
    try {
        Map<String, List<PatchOperation>> patchOperations = new HashMap<>();
        patchOperations.put(SCIMConstants.OperationalConstants.ADD, new ArrayList<>());
        patchOperations.put(SCIMConstants.OperationalConstants.REMOVE, new ArrayList<>());
        patchOperations.put(SCIMConstants.OperationalConstants.REPLACE, new ArrayList<>());
        for (PatchOperation patchOperation : opList) {
            switch(patchOperation.getOperation()) {
                case SCIMConstants.OperationalConstants.ADD:
                    patchOperations.get(SCIMConstants.OperationalConstants.ADD).add(patchOperation);
                    break;
                case SCIMConstants.OperationalConstants.REMOVE:
                    patchOperations.get(SCIMConstants.OperationalConstants.REMOVE).add(patchOperation);
                    break;
                case SCIMConstants.OperationalConstants.REPLACE:
                    patchOperations.get(SCIMConstants.OperationalConstants.REPLACE).add(patchOperation);
                    break;
                default:
                    throw new BadRequestException("Unknown operation: " + patchOperation.getOperation(), ResponseCodeConstants.INVALID_SYNTAX);
            }
        }
        SCIMResourceTypeSchema schema = SCIMResourceSchemaManager.getInstance().getGroupResourceSchema();
        String groupName = getGroupName(userManager, existingGroupId);
        processGroupPatchOperations(patchOperations, schema);
        // Get the URIs of required attributes which must be given a value.
        Map<String, Boolean> requiredAttributes = ResourceManagerUtil.getOnlyRequiredAttributesURIs((SCIMResourceTypeSchema) CopyUtil.deepCopy(schema), attributes, excludeAttributes);
        Group updatedGroup = userManager.patchGroup(existingGroupId, groupName, patchOperations, requiredAttributes);
        if (updatedGroup != null) {
            // Create a deep copy of the group object since we are going to change it.
            Group copyOfUpdatedGroup = (Group) CopyUtil.deepCopy(updatedGroup);
            ServerSideValidator.validateReturnedAttributes(copyOfUpdatedGroup, attributes, excludeAttributes);
            // Encode the updated group object and add id attribute to Location header.
            String encodedGroup = getEncoder().encodeSCIMObject(copyOfUpdatedGroup);
            Map<String, String> httpHeaders = new HashMap<>();
            httpHeaders.put(SCIMConstants.LOCATION_HEADER, getResourceEndpointURL(SCIMConstants.GROUP_ENDPOINT) + "/" + updatedGroup.getId());
            httpHeaders.put(SCIMConstants.CONTENT_TYPE_HEADER, SCIMConstants.APPLICATION_JSON);
            return new SCIMResponse(ResponseCodeConstants.CODE_OK, encodedGroup, httpHeaders);
        } else {
            String error = "Updated group resource is null.";
            throw new CharonException(error);
        }
    } catch (NotFoundException | BadRequestException | NotImplementedException | CharonException e) {
        return AbstractResourceManager.encodeSCIMException(e);
    } catch (RuntimeException e) {
        CharonException e1 = new CharonException("Error in performing the patch operation on group resource.", e);
        return AbstractResourceManager.encodeSCIMException(e1);
    }
}
Also used : Group(org.wso2.charon3.core.objects.Group) HashMap(java.util.HashMap) NotImplementedException(org.wso2.charon3.core.exceptions.NotImplementedException) NotFoundException(org.wso2.charon3.core.exceptions.NotFoundException) PatchOperation(org.wso2.charon3.core.utils.codeutils.PatchOperation) BadRequestException(org.wso2.charon3.core.exceptions.BadRequestException) ArrayList(java.util.ArrayList) List(java.util.List) SCIMResourceTypeSchema(org.wso2.charon3.core.schema.SCIMResourceTypeSchema) CharonException(org.wso2.charon3.core.exceptions.CharonException) SCIMResponse(org.wso2.charon3.core.protocol.SCIMResponse)

Example 19 with Patch

use of org.wso2.carbon.identity.api.server.idp.v1.model.Patch in project charon by wso2.

the class GroupResourceManager method updateWithPATCH.

/**
 * Updates the group based on the operations defined in the patchRequest. The updated group information is not
 * sent back in the response.
 *
 * @param existingGroupId SCIM2 ID of the existing group
 * @param patchRequest    SCIM2 patch request
 * @param userManager     SCIM UserManager that handles the persistence layer.
 * @return
 */
@Override
public SCIMResponse updateWithPATCH(String existingGroupId, String patchRequest, UserManager userManager) {
    try {
        if (userManager == null) {
            String error = "Provided user manager handler is null.";
            throw new InternalErrorException(error);
        }
        SCIMResourceTypeSchema schema = SCIMResourceSchemaManager.getInstance().getGroupResourceSchema();
        Map<String, Boolean> requestAttributes = ResourceManagerUtil.getAllAttributeURIs(schema);
        Group oldGroup = userManager.getGroup(existingGroupId, requestAttributes);
        if (oldGroup == null) {
            throw new NotFoundException("No group with the id : " + existingGroupId + " exists in the user store.");
        }
        // Make a copy of original group. This will be used to restore to the original condition if failure occurs.
        Group originalGroup = (Group) CopyUtil.deepCopy(oldGroup);
        Group patchedGroup = doPatchGroup(oldGroup, schema, patchRequest);
        userManager.updateGroup(originalGroup, patchedGroup);
        // Build the 204 response.
        Map<String, String> httpHeaders = new HashMap<>();
        httpHeaders.put(SCIMConstants.CONTENT_TYPE_HEADER, SCIMConstants.APPLICATION_JSON);
        return new SCIMResponse(ResponseCodeConstants.CODE_NO_CONTENT, null, httpHeaders);
    } catch (NotFoundException | BadRequestException | NotImplementedException | CharonException | InternalErrorException e) {
        return AbstractResourceManager.encodeSCIMException(e);
    } catch (RuntimeException e) {
        CharonException ex = new CharonException("Error in performing the patch operation on group resource.", e);
        return AbstractResourceManager.encodeSCIMException(ex);
    }
}
Also used : Group(org.wso2.charon3.core.objects.Group) HashMap(java.util.HashMap) NotImplementedException(org.wso2.charon3.core.exceptions.NotImplementedException) NotFoundException(org.wso2.charon3.core.exceptions.NotFoundException) InternalErrorException(org.wso2.charon3.core.exceptions.InternalErrorException) BadRequestException(org.wso2.charon3.core.exceptions.BadRequestException) SCIMResourceTypeSchema(org.wso2.charon3.core.schema.SCIMResourceTypeSchema) CharonException(org.wso2.charon3.core.exceptions.CharonException) SCIMResponse(org.wso2.charon3.core.protocol.SCIMResponse)

Example 20 with Patch

use of org.wso2.carbon.identity.api.server.idp.v1.model.Patch in project product-mi-tooling by wso2.

the class GroupsApi method updateLogLevelByNodeId.

@PATCH
@Path("/{group-id}/log-configs/nodes/{node-id}")
@Consumes({ "application/json" })
@Produces({ "application/json" })
@Operation(summary = "Update log level by nodeId", description = "", tags = { "logConfigs" })
@ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Logger update status", content = @Content(schema = @Schema(implementation = SuccessStatus.class))), @ApiResponse(responseCode = "200", description = "Unexpected error", content = @Content(schema = @Schema(implementation = Error.class))) })
public Response updateLogLevelByNodeId(@PathParam("group-id") @Parameter(description = "Group ID of the node") String groupId, @PathParam("node-id") @Parameter(description = "NodeId") String nodeId, @Valid LogConfigUpdateRequest request) throws ManagementApiException {
    LogConfigDelegate logConfigDelegate = new LogConfigDelegate();
    Ack ack = logConfigDelegate.updateLogLevelByNodeId(groupId, nodeId, request);
    return Response.ok().entity(ack).build();
}
Also used : LogConfigDelegate(org.wso2.ei.dashboard.micro.integrator.delegates.LogConfigDelegate) Ack(org.wso2.ei.dashboard.core.rest.model.Ack) Operation(io.swagger.v3.oas.annotations.Operation) ApiResponses(io.swagger.v3.oas.annotations.responses.ApiResponses)

Aggregations

BadRequestException (org.wso2.charon3.core.exceptions.BadRequestException)19 ArrayList (java.util.ArrayList)11 HashMap (java.util.HashMap)11 Test (org.testng.annotations.Test)11 JSONArray (org.json.JSONArray)9 JSONObject (org.json.JSONObject)9 Attribute (org.wso2.charon3.core.attributes.Attribute)9 ComplexAttribute (org.wso2.charon3.core.attributes.ComplexAttribute)9 MultiValuedAttribute (org.wso2.charon3.core.attributes.MultiValuedAttribute)9 SimpleAttribute (org.wso2.charon3.core.attributes.SimpleAttribute)9 CharonException (org.wso2.charon3.core.exceptions.CharonException)9 SCIMResponse (org.wso2.charon3.core.protocol.SCIMResponse)8 List (java.util.List)7 NotImplementedException (org.wso2.charon3.core.exceptions.NotImplementedException)7 LinkedHashMap (java.util.LinkedHashMap)6 Map (java.util.Map)6 JSONException (org.json.JSONException)6 APIManagementException (org.wso2.carbon.apimgt.api.APIManagementException)6 AttributeSchema (org.wso2.charon3.core.schema.AttributeSchema)6 ExtractableResponse (io.restassured.response.ExtractableResponse)5