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;
}
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;
}
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);
}
}
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);
}
}
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();
}
Aggregations