Search in sources :

Example 21 with CharonException

use of org.wso2.charon.core.exceptions.CharonException in project charon by wso2.

the class AbstractValidator method checkIfReadOnlyAndImmutableSubAttributesModified.

/*
     * check for read only and immutable sub attributes which has been modified on update request
     *
     * @param newAttributeList
     * @param oldAttributeList
     * @param attributeSchema
     * @throws BadRequestException
     * @throws CharonException
     */
private static void checkIfReadOnlyAndImmutableSubAttributesModified(Map<String, Attribute> newAttributeList, Map<String, Attribute> oldAttributeList, AttributeSchema attributeSchema) throws BadRequestException, CharonException {
    // check for sub attributes.
    AbstractAttribute newAttribute = (AbstractAttribute) newAttributeList.get(attributeSchema.getName());
    AbstractAttribute oldAttribute = (AbstractAttribute) oldAttributeList.get(attributeSchema.getName());
    List<AttributeSchema> subAttributeSchemaList = attributeSchema.getSubAttributeSchemas();
    if (subAttributeSchemaList != null) {
        if (SCIMResourceSchemaManager.getInstance().getExtensionName() != null) {
            if (attributeSchema.getName().equals(SCIMResourceSchemaManager.getInstance().getExtensionName())) {
                checkIfReadOnlyAndImmutableExtensionAttributesModified(subAttributeSchemaList, newAttribute, oldAttribute);
            }
        }
        if (newAttribute != null && oldAttribute != null) {
            if (attributeSchema.getMultiValued()) {
                // this is complex multivalued case
                List<Attribute> newSubValuesList = ((MultiValuedAttribute) newAttribute).getAttributeValues();
                List<Attribute> oldSubValuesList = ((MultiValuedAttribute) oldAttribute).getAttributeValues();
                // if size aren't equal, they do not preserver immutable quality
                if (newSubValuesList.size() != oldSubValuesList.size() && attributeSchema.getMutability().equals(SCIMDefinitions.Mutability.IMMUTABLE)) {
                    throw new BadRequestException(ResponseCodeConstants.MUTABILITY);
                }
                // no need to check sub attributes of sub values separately for equality, stop at the sub value level
                for (Attribute subValue : newSubValuesList) {
                    if (!isListContains((((ComplexAttribute) subValue).getName()), oldSubValuesList) && attributeSchema.getMutability().equals(SCIMDefinitions.Mutability.IMMUTABLE)) {
                        throw new BadRequestException(ResponseCodeConstants.MUTABILITY);
                    }
                }
            } else {
                // A complex attribute itself can not be immutable if it's sub variables are not immutable
                checkForReadOnlyAndImmutableInComplexAttributes(newAttribute, oldAttribute, subAttributeSchemaList);
            }
        } else if (newAttribute == null && oldAttribute != null) {
            if (attributeSchema.getMultiValued()) {
                List<Attribute> oldSubValuesList = ((MultiValuedAttribute) oldAttribute).getAttributeValues();
                Attribute clonedMultiValuedAttribute = (Attribute) CopyUtil.deepCopy(oldAttribute);
                clonedMultiValuedAttribute.deleteSubAttributes();
                for (Attribute subValue : oldSubValuesList) {
                    Attribute clonedSubValue = (Attribute) CopyUtil.deepCopy(subValue);
                    clonedSubValue.deleteSubAttributes();
                    for (AttributeSchema subAttributeSchema : subAttributeSchemaList) {
                        if (subAttributeSchema.getMutability().equals(SCIMDefinitions.Mutability.READ_ONLY) || subAttributeSchema.getMutability().equals(SCIMDefinitions.Mutability.IMMUTABLE)) {
                            if (((ComplexAttribute) subValue).isSubAttributeExist(subAttributeSchema.getName())) {
                                Attribute clonedSubValuesAttribute = (Attribute) CopyUtil.deepCopy(((ComplexAttribute) subValue).getSubAttribute(subAttributeSchema.getName()));
                                ((ComplexAttribute) clonedSubValue).setSubAttribute(clonedSubValuesAttribute);
                            }
                        }
                    }
                    ((MultiValuedAttribute) (clonedMultiValuedAttribute)).setAttributeValue(clonedSubValue);
                }
            } else {
                Map<String, Attribute> oldSubAttributeList = ((ComplexAttribute) (oldAttribute)).getSubAttributesList();
                Attribute clonedAttribute = (Attribute) CopyUtil.deepCopy(oldAttribute);
                clonedAttribute.deleteSubAttributes();
                for (AttributeSchema subAttributeSchema : subAttributeSchemaList) {
                    if (subAttributeSchema.getMutability().equals(SCIMDefinitions.Mutability.READ_ONLY) || subAttributeSchema.getMutability().equals(SCIMDefinitions.Mutability.IMMUTABLE)) {
                        if (oldSubAttributeList.containsKey(subAttributeSchema.getName())) {
                            ((ComplexAttribute) (clonedAttribute)).setSubAttribute((Attribute) CopyUtil.deepCopy(oldSubAttributeList.get(subAttributeSchema.getName())));
                        }
                    }
                }
                newAttributeList.put(clonedAttribute.getName(), clonedAttribute);
            }
        } else if (newAttribute != null && oldAttribute == null) {
            if (attributeSchema.getMultiValued()) {
                if (attributeSchema.getMultiValued()) {
                    List<Attribute> newSubValuesList = ((MultiValuedAttribute) newAttribute).getAttributeValues();
                    for (Attribute subValue : newSubValuesList) {
                        for (AttributeSchema subAttributeSchema : subAttributeSchemaList) {
                            if (subAttributeSchema.getMutability().equals(SCIMDefinitions.Mutability.READ_ONLY)) {
                                ((ComplexAttribute) (subValue)).removeSubAttribute(subAttributeSchema.getName());
                            }
                        }
                    }
                }
            } else {
                // this is complex attribute case
                Map<String, Attribute> newSubAttributeList = ((ComplexAttribute) (newAttribute)).getSubAttributesList();
                for (AttributeSchema subAttributeSchema : subAttributeSchemaList) {
                    if (subAttributeSchema.getMutability().equals(SCIMDefinitions.Mutability.READ_ONLY)) {
                        if (newSubAttributeList.containsKey(subAttributeSchema.getName())) {
                            String error = "Read only attribute: " + subAttributeSchema.getName() + " is set from consumer in the SCIM Object. Removing it.";
                            logger.debug(error);
                            ((ComplexAttribute) newAttribute).removeSubAttribute(subAttributeSchema.getName());
                        }
                    }
                }
            }
        }
    }
}
Also used : MultiValuedAttribute(org.wso2.charon3.core.attributes.MultiValuedAttribute) ComplexAttribute(org.wso2.charon3.core.attributes.ComplexAttribute) AbstractAttribute(org.wso2.charon3.core.attributes.AbstractAttribute) Attribute(org.wso2.charon3.core.attributes.Attribute) SimpleAttribute(org.wso2.charon3.core.attributes.SimpleAttribute) ComplexAttribute(org.wso2.charon3.core.attributes.ComplexAttribute) AbstractAttribute(org.wso2.charon3.core.attributes.AbstractAttribute) BadRequestException(org.wso2.charon3.core.exceptions.BadRequestException) ArrayList(java.util.ArrayList) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map) MultiValuedAttribute(org.wso2.charon3.core.attributes.MultiValuedAttribute)

Example 22 with CharonException

use of org.wso2.charon.core.exceptions.CharonException in project charon by wso2.

the class AbstractValidator method validateSCIMObjectForRequiredSubAttributes.

/*
     * Validate SCIMObject for required sub attributes given the object and the corresponding schema.
     *
     * @param attribute
     * @param attributeSchema
     * @param scimObject
     * @throws CharonException
     * @throws BadRequestException
     */
private static void validateSCIMObjectForRequiredSubAttributes(AbstractAttribute attribute, AttributeSchema attributeSchema, AbstractSCIMObject scimObject) throws CharonException, BadRequestException {
    if (attribute != null) {
        List<AttributeSchema> subAttributesSchemaList = ((AttributeSchema) attributeSchema).getSubAttributeSchemas();
        if (subAttributesSchemaList != null) {
            for (AttributeSchema subAttributeSchema : subAttributesSchemaList) {
                if (subAttributeSchema.getRequired()) {
                    if (attribute instanceof ComplexAttribute) {
                        if (attribute.getSubAttribute(subAttributeSchema.getName()) == null) {
                            String error = "Required sub attribute: " + subAttributeSchema.getName() + " is missing in the SCIM Attribute: " + attribute.getName();
                            throw new BadRequestException(error, ResponseCodeConstants.INVALID_VALUE);
                        } else if (attribute.getSubAttribute(subAttributeSchema.getName()) instanceof SimpleAttribute) {
                            // If the attributes updated with "", that check is happening here.
                            if (StringUtils.isEmpty(((SimpleAttribute) attribute.getSubAttribute(subAttributeSchema.getName())).getValue().toString())) {
                                String error = "Required sub attribute: " + subAttributeSchema.getName() + " is missing in the SCIM Attribute: " + attribute.getName();
                                throw new BadRequestException(error, ResponseCodeConstants.INVALID_VALUE);
                            }
                        }
                    } else if (attribute instanceof MultiValuedAttribute) {
                        List<Attribute> values = ((MultiValuedAttribute) attribute).getAttributeValues();
                        for (Attribute value : values) {
                            if (value instanceof ComplexAttribute) {
                                if (value.getSubAttribute(subAttributeSchema.getName()) == null) {
                                    String error = "Required sub attribute: " + subAttributeSchema.getName() + ", is missing in the SCIM Attribute: " + attribute.getName();
                                    throw new BadRequestException(error, ResponseCodeConstants.INVALID_VALUE);
                                }
                            }
                        }
                    }
                }
                // Check for canonical attributes in groups.
                validateCanonicalAttributesInScimObject(attribute, subAttributeSchema, scimObject);
                // Following is only applicable for extension schema validation.
                AbstractAttribute subAttribute = null;
                if (attribute instanceof ComplexAttribute) {
                    subAttribute = (AbstractAttribute) ((ComplexAttribute) attribute).getSubAttribute(subAttributeSchema.getName());
                } else if (attribute instanceof MultiValuedAttribute) {
                    List<Attribute> subAttributeList = ((MultiValuedAttribute) attribute).getAttributeValues();
                    for (Attribute subAttrbte : subAttributeList) {
                        if (subAttrbte.getName().equals(subAttributeSchema.getName())) {
                            subAttribute = (AbstractAttribute) subAttrbte;
                        }
                    }
                }
                List<AttributeSchema> subSubAttributesSchemaList = subAttributeSchema.getSubAttributeSchemas();
                if (subSubAttributesSchemaList != null) {
                    validateSCIMObjectForRequiredSubAttributes(subAttribute, subAttributeSchema, scimObject);
                }
            }
        }
    }
}
Also used : MultiValuedAttribute(org.wso2.charon3.core.attributes.MultiValuedAttribute) ComplexAttribute(org.wso2.charon3.core.attributes.ComplexAttribute) AbstractAttribute(org.wso2.charon3.core.attributes.AbstractAttribute) Attribute(org.wso2.charon3.core.attributes.Attribute) SimpleAttribute(org.wso2.charon3.core.attributes.SimpleAttribute) SimpleAttribute(org.wso2.charon3.core.attributes.SimpleAttribute) ComplexAttribute(org.wso2.charon3.core.attributes.ComplexAttribute) BadRequestException(org.wso2.charon3.core.exceptions.BadRequestException) AbstractAttribute(org.wso2.charon3.core.attributes.AbstractAttribute) ArrayList(java.util.ArrayList) List(java.util.List) MultiValuedAttribute(org.wso2.charon3.core.attributes.MultiValuedAttribute)

Example 23 with CharonException

use of org.wso2.charon.core.exceptions.CharonException in project charon by wso2.

the class AbstractValidator method setDisplayNameInComplexMultiValuedAttributes.

/*
     * This method is basically for adding display sub attribute to multivalued attributes
     * which has 'display' as a sub attribute in the respective attribute schema
     *
     * @param scimObject
     * @param resourceSchema
     * @throws CharonException
     * @throws BadRequestException
     */
protected static void setDisplayNameInComplexMultiValuedAttributes(AbstractSCIMObject scimObject, SCIMResourceTypeSchema resourceSchema) throws CharonException, BadRequestException {
    Map<String, Attribute> attributeList = scimObject.getAttributeList();
    ArrayList<AttributeSchema> attributeSchemaList = resourceSchema.getAttributesList();
    for (AttributeSchema attributeSchema : attributeSchemaList) {
        if (attributeSchema.getMultiValued() && attributeSchema.getType().equals(SCIMDefinitions.DataType.COMPLEX)) {
            if (attributeSchema.getSubAttributeSchema(SCIMConstants.CommonSchemaConstants.DISPLAY) != null) {
                if (attributeList.containsKey(attributeSchema.getName())) {
                    Attribute multiValuedAttribute = attributeList.get(attributeSchema.getName());
                    setDisplayNameInComplexMultiValuedSubAttributes(multiValuedAttribute, attributeSchema);
                }
            }
        } else if (attributeSchema.getType().equals(SCIMDefinitions.DataType.COMPLEX)) {
            // this is only valid for extension schema
            List<AttributeSchema> subAttributeSchemaList = attributeSchema.getSubAttributeSchemas();
            for (AttributeSchema subAttributeSchema : subAttributeSchemaList) {
                if (subAttributeSchema.getMultiValued() && subAttributeSchema.getType().equals(SCIMDefinitions.DataType.COMPLEX)) {
                    if (subAttributeSchema.getSubAttributeSchema(SCIMConstants.CommonSchemaConstants.DISPLAY) != null) {
                        Attribute extensionAttribute = attributeList.get(attributeSchema.getName());
                        if (extensionAttribute != null) {
                            if ((((ComplexAttribute) extensionAttribute).getSubAttribute(subAttributeSchema.getName())) != null) {
                                Attribute multiValuedAttribute = (attributeList.get(attributeSchema.getName())).getSubAttribute(subAttributeSchema.getName());
                                setDisplayNameInComplexMultiValuedSubAttributes(multiValuedAttribute, subAttributeSchema);
                            }
                        }
                    }
                }
            }
        }
    }
}
Also used : MultiValuedAttribute(org.wso2.charon3.core.attributes.MultiValuedAttribute) ComplexAttribute(org.wso2.charon3.core.attributes.ComplexAttribute) AbstractAttribute(org.wso2.charon3.core.attributes.AbstractAttribute) Attribute(org.wso2.charon3.core.attributes.Attribute) SimpleAttribute(org.wso2.charon3.core.attributes.SimpleAttribute) ArrayList(java.util.ArrayList) List(java.util.List)

Example 24 with CharonException

use of org.wso2.charon.core.exceptions.CharonException in project charon by wso2.

the class AbstractValidator method validatePatchOperationEffectForRequiredSubAttributes.

/**
 * Validation the patch operation effect on sub attributes of a scim attribute.
 *
 * @param oldAttribute    Old scim attribute.
 * @param newAttribute    Updated scim attribute.
 * @param attributeSchema Attribute schema of the attribute.
 * @param scimObject      Scim object.
 * @throws CharonException     When error occurred during the validation.
 * @throws BadRequestException When error occurred due to the client issues.
 */
private static void validatePatchOperationEffectForRequiredSubAttributes(AbstractAttribute oldAttribute, AbstractAttribute newAttribute, AttributeSchema attributeSchema, AbstractSCIMObject scimObject) throws CharonException, BadRequestException {
    if (newAttribute == null || attributeSchema == null || oldAttribute == null) {
        return;
    }
    List<AttributeSchema> subAttributesSchemaList = attributeSchema.getSubAttributeSchemas();
    if (subAttributesSchemaList == null) {
        return;
    }
    for (AttributeSchema subAttributeSchema : subAttributesSchemaList) {
        // Nothing to validate id the attribute schema has required=false.
        if (!subAttributeSchema.getRequired()) {
            continue;
        }
        if (newAttribute instanceof ComplexAttribute) {
            // If the sub attribute contained in the old attribute but not in the new attribute.
            if (newAttribute.getSubAttribute(subAttributeSchema.getName()) == null && oldAttribute.getSubAttribute(subAttributeSchema.getName()) != null) {
                String error = "Required sub attribute: " + subAttributeSchema.getName() + " is missing in the SCIM Attribute: " + newAttribute.getName();
                throw new BadRequestException(error, ResponseCodeConstants.INVALID_VALUE);
            } else if (newAttribute.getSubAttribute(subAttributeSchema.getName()) instanceof SimpleAttribute) {
                // If the attributes updated with "", that check is happening here.
                if (StringUtils.isEmpty(((SimpleAttribute) newAttribute.getSubAttribute(subAttributeSchema.getName())).getValue().toString())) {
                    String error = "Required sub attribute: " + subAttributeSchema.getName() + " is missing in the SCIM Attribute: " + newAttribute.getName();
                    throw new BadRequestException(error, ResponseCodeConstants.INVALID_VALUE);
                }
            }
        } else if (newAttribute instanceof MultiValuedAttribute) {
            List<Attribute> newValues = ((MultiValuedAttribute) newAttribute).getAttributeValues();
            for (Attribute value : newValues) {
                if (value instanceof ComplexAttribute) {
                    if (value.getSubAttribute(subAttributeSchema.getName()) == null) {
                        String error = "Required sub attribute: " + subAttributeSchema.getName() + ", is missing in the SCIM Attribute: " + newAttribute.getName();
                        throw new BadRequestException(error, ResponseCodeConstants.INVALID_VALUE);
                    }
                }
            }
        }
        // Check for canonical attributes in groups.
        validateCanonicalAttributesInScimObject(newAttribute, subAttributeSchema, scimObject);
        /*
            Following is only applicable for extension schema validation.
            Extension schema also considered as complex Attribute.
            Therefore, The Complex Attributes inside the extension will validate here.
             */
        AbstractAttribute newSubAttribute = null;
        AbstractAttribute oldSubAttribute = null;
        if (newAttribute instanceof ComplexAttribute) {
            newSubAttribute = (AbstractAttribute) (newAttribute).getSubAttribute(subAttributeSchema.getName());
            oldSubAttribute = (AbstractAttribute) (oldAttribute).getSubAttribute(subAttributeSchema.getName());
        } else if (newAttribute instanceof MultiValuedAttribute) {
            List<Attribute> subAttributeList = ((MultiValuedAttribute) newAttribute).getAttributeValues();
            for (Attribute subAttrbte : subAttributeList) {
                if (subAttrbte.getName().equals(subAttributeSchema.getName())) {
                    newSubAttribute = (AbstractAttribute) subAttrbte;
                }
            }
        }
        List<AttributeSchema> subSubAttributesSchemaList = subAttributeSchema.getSubAttributeSchemas();
        if (subSubAttributesSchemaList != null) {
            validatePatchOperationEffectForRequiredSubAttributes(oldSubAttribute, newSubAttribute, subAttributeSchema, scimObject);
        }
    }
}
Also used : MultiValuedAttribute(org.wso2.charon3.core.attributes.MultiValuedAttribute) ComplexAttribute(org.wso2.charon3.core.attributes.ComplexAttribute) AbstractAttribute(org.wso2.charon3.core.attributes.AbstractAttribute) Attribute(org.wso2.charon3.core.attributes.Attribute) SimpleAttribute(org.wso2.charon3.core.attributes.SimpleAttribute) SimpleAttribute(org.wso2.charon3.core.attributes.SimpleAttribute) ComplexAttribute(org.wso2.charon3.core.attributes.ComplexAttribute) BadRequestException(org.wso2.charon3.core.exceptions.BadRequestException) AbstractAttribute(org.wso2.charon3.core.attributes.AbstractAttribute) ArrayList(java.util.ArrayList) List(java.util.List) MultiValuedAttribute(org.wso2.charon3.core.attributes.MultiValuedAttribute)

Example 25 with CharonException

use of org.wso2.charon.core.exceptions.CharonException in project charon by wso2.

the class AbstractValidator method validatePatchOperationEffectForRequiredAttributes.

/**
 * Validate whether scim object updates due to one patch operation, violate the required attributes conditions.
 *
 * @param oldObject      Scim object before update.
 * @param newObject      Scim object after update.
 * @param resourceSchema Schema for the scim resource.
 * @throws BadRequestException When error occurred due to client issue.
 * @throws CharonException     When error occurred due to validation failure.
 */
public static void validatePatchOperationEffectForRequiredAttributes(AbstractSCIMObject oldObject, AbstractSCIMObject newObject, ResourceTypeSchema resourceSchema) throws BadRequestException, CharonException {
    // Get attributes from schema.
    List<AttributeSchema> attributeSchemaList = resourceSchema.getAttributesList();
    // Get attribute list from old scim object.
    Map<String, Attribute> oldAttributeList = oldObject.getAttributeList();
    // Get attribute list from new scim object.
    Map<String, Attribute> newAttributeList = newObject.getAttributeList();
    for (AttributeSchema attributeSchema : attributeSchemaList) {
        // Check for required attributes.
        if (attributeSchema.getRequired()) {
            /*
                If the attribute is not present in the updated object but included in the old object,
                it means the operation has removed the required attribute.
                 */
            if (!newAttributeList.containsKey(attributeSchema.getName()) && oldAttributeList.containsKey(attributeSchema.getName())) {
                String error = "Required attribute " + attributeSchema.getName() + " is missing in the SCIM " + "Object.";
                throw new BadRequestException(error, ResponseCodeConstants.INVALID_VALUE);
            }
        }
        // Check for required sub attributes.
        AbstractAttribute newAttribute = (AbstractAttribute) newAttributeList.get(attributeSchema.getName());
        AbstractAttribute oldAttribute = (AbstractAttribute) oldAttributeList.get(attributeSchema.getName());
        validatePatchOperationEffectForRequiredSubAttributes(oldAttribute, newAttribute, attributeSchema, newObject);
    }
}
Also used : MultiValuedAttribute(org.wso2.charon3.core.attributes.MultiValuedAttribute) ComplexAttribute(org.wso2.charon3.core.attributes.ComplexAttribute) AbstractAttribute(org.wso2.charon3.core.attributes.AbstractAttribute) Attribute(org.wso2.charon3.core.attributes.Attribute) SimpleAttribute(org.wso2.charon3.core.attributes.SimpleAttribute) BadRequestException(org.wso2.charon3.core.exceptions.BadRequestException) AbstractAttribute(org.wso2.charon3.core.attributes.AbstractAttribute)

Aggregations

CharonException (org.wso2.charon3.core.exceptions.CharonException)153 SCIMResponse (org.wso2.charon3.core.protocol.SCIMResponse)137 SCIMResourceTypeSchema (org.wso2.charon3.core.schema.SCIMResourceTypeSchema)120 User (org.wso2.charon3.core.objects.User)114 BadRequestException (org.wso2.charon3.core.exceptions.BadRequestException)109 Test (org.testng.annotations.Test)106 JSONObject (org.json.JSONObject)88 SimpleAttribute (org.wso2.charon3.core.attributes.SimpleAttribute)80 ComplexAttribute (org.wso2.charon3.core.attributes.ComplexAttribute)73 MultiValuedAttribute (org.wso2.charon3.core.attributes.MultiValuedAttribute)63 JSONDecoder (org.wso2.charon3.core.encoder.JSONDecoder)59 HashMap (java.util.HashMap)55 Group (org.wso2.charon3.core.objects.Group)55 AbstractSCIMObject (org.wso2.charon3.core.objects.AbstractSCIMObject)52 DataProvider (org.testng.annotations.DataProvider)51 InternalErrorException (org.wso2.charon3.core.exceptions.InternalErrorException)49 Attribute (org.wso2.charon3.core.attributes.Attribute)46 NotFoundException (org.wso2.charon3.core.exceptions.NotFoundException)46 NotImplementedException (org.wso2.charon3.core.exceptions.NotImplementedException)42 ArrayList (java.util.ArrayList)37