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