All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.captaingoldfish.scim.sdk.server.patch.msazure.MsAzurePatchRemoveRebuilder Maven / Gradle / Ivy

// Generated by delombok at Thu Nov 02 20:38:53 CET 2023
package de.captaingoldfish.scim.sdk.server.patch.msazure;

import java.util.List;
import java.util.Optional;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import de.captaingoldfish.scim.sdk.common.constants.enums.PatchOp;
import de.captaingoldfish.scim.sdk.common.utils.JsonHelper;


/**
 * This class is a workaround handler in order to handle the broken patch requests of Microsoft Azure. Azure
 * sends illegal patch-remove requests that look as follows:
 *
 * 
 * PATCH /scim/Groups/2752513
 * {
 *     "schemas": [
 *         "urn:ietf:params:scim:api:messages:2.0:PatchOp"
 *     ],
 *     "Operations": [
 *         {
 *             "op": "Remove",
 *             "path": "members",
 *             "value": [
 *                 {
 *                     "value": "2392066"
 *                 }
 *             ]
 *         }
 *     ]
 * }
 * 
* * the value in the request must not be present. Instead the request should look like this: * *
 * PATCH /scim/Groups/2752513
 * {
 *     "schemas": [
 *         "urn:ietf:params:scim:api:messages:2.0:PatchOp"
 *     ],
 *     "Operations": [
 *         {
 *             "op": "Remove",
 *             "path": "members[value eq \"2392066\"]"
 *         }
 *     ]
 * }
 * 
* * This class will try its best to fix the bad request and turn it into a valid request * * @author Pascal Knueppel * @since 07.06.2021 */ public final class MsAzurePatchRemoveRebuilder { @java.lang.SuppressWarnings("all") private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(MsAzurePatchRemoveRebuilder.class); /** * the patch operation that is currently executed */ private final PatchOp patchOp; /** * the path of the patch operation */ private final String path; /** * the values of the patch operation. This attribute should actually be empty */ private final List values; /** * tries to build a valid path operation from the illegal Azure request. If a new path is created it will also * clear the {@link #values} list in order to bypass the validation successfully * * @return the original path if the request not illegal or the path could not be fixed or a new fixed path */ public String fixPath() { // just a security check to make sure that the if-block that prevents this class to be executed in case of ADD // and REPLACE should disappear if (!PatchOp.REMOVE.equals(patchOp)) { log.trace("[MS Azure workaround] only handling \'REMOVE\' requests"); return path; } // nothing must be done patch request can be handled normally since no illegal value operand is present if (values.isEmpty()) { log.trace("[MS Azure workaround] workaround not executed for values-list is empty"); return path; } StringBuilder newPath = new StringBuilder(path).append('['); for ( int i = 0 ; i < values.size() ; i++ ) { // if several values are present in the request we will concatenate them with 'or' if (i > 0) { newPath.append(" or "); } String value = values.get(i); if (!JsonHelper.isValidJson(value)) { // do nothing anymore this will cause the request to normally abort at the specific validation point log.trace("[MS Azure workaround] attribute in \'value\' operand is not valid json: {}", value); return path; } JsonNode jsonNode = JsonHelper.readJsonDocument(value); final boolean isNodeAnObject = Optional.ofNullable(jsonNode).map(JsonNode::isObject).orElse(false); if (!isNodeAnObject) { // do nothing anymore this will cause the request to normally abort at the specific validation point log.trace("[MS Azure workaround] attribute in \'value\' operand is not an object: {}", value); return path; } ObjectNode objectNode = (ObjectNode)jsonNode; // we will only support the case when one attribute is present per object if (objectNode.size() != 1) { // do nothing anymore this will cause the request to normally abort at the specific validation point log.trace("[MS Azure workaround] workaround not executed for \'value\' operand object has more than one " + "attributes: {}", objectNode.toPrettyString()); return path; } final String fieldName = objectNode.fieldNames().next(); final JsonNode valueNode = objectNode.get(fieldName); if (valueNode.isObject() || valueNode.isArray()) { // do nothing anymore this will cause the request to normally abort at the specific validation point // for simplicity we will only support simple values in such a case log.trace("[MS Azure workaround] workaround not executed for attribute in value \'operand\' is not a simple type: {}", valueNode.toPrettyString()); return path; } newPath.append(fieldName).append(" eq \"").append(valueNode.textValue()).append("\""); } // removes all value references from the PatchTargetHandler to bypass the request validation values.clear(); return newPath.append(']').toString(); } @java.lang.SuppressWarnings("all") public MsAzurePatchRemoveRebuilder(final PatchOp patchOp, final String path, final List values) { this.patchOp = patchOp; this.path = path; this.values = values; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy