use of io.jans.scim.model.scim2.BaseScimResource in project jans by JanssenProject.
the class ExtensionService method extensionOfAttribute.
public Extension extensionOfAttribute(Class<? extends BaseScimResource> cls, String attribute) {
List<Extension> extensions = getResourceExtensions(cls);
Extension belong = null;
try {
for (Extension ext : extensions) {
if (attribute.startsWith(ext.getUrn() + ":")) {
attribute = attribute.substring(ext.getUrn().length() + 1);
for (String fieldName : ext.getFields().keySet()) if (attribute.equals(fieldName)) {
belong = ext;
break;
}
}
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return belong;
}
use of io.jans.scim.model.scim2.BaseScimResource in project jans by JanssenProject.
the class ScimResourceUtil method deleteFromResource.
/**
* Returns a SCIM resource with the same data found in <code>origin</code> object, except for the attribute referenced
* by <code>path</code> being removed from the output. In other words, this method nullifies an attribute.
* @param origin The resource having the the original data
* @param path An attribute path (in dot notation). Examples could be: <code>displayName, emails.type, addresses,
* meta.lastModified</code>.
* @param extensions A list of <code>Extension</code>s associated to <code>origin</code> Object
* @return The resulting object: data in origin without the attribute referenced by <code>path</code>
* @throws InvalidAttributeValueException If there is an attempt to remove an attribute annotated as {@link Attribute#isRequired()
* required} or {@link io.jans.scim.model.scim2.AttributeDefinition.Mutability#READ_ONLY read-only}
*/
public static BaseScimResource deleteFromResource(BaseScimResource origin, String path, List<Extension> extensions) throws InvalidAttributeValueException {
Field f = IntrospectUtil.findFieldFromPath(origin.getClass(), path);
if (f != null) {
Attribute attrAnnot = f.getAnnotation(Attribute.class);
if (attrAnnot != null && (attrAnnot.mutability().equals(READ_ONLY) || attrAnnot.isRequired()))
throw new InvalidAttributeValueException("Cannot remove read-only or required attribute " + path);
}
Map<String, Object> map = mapper.convertValue(origin, new TypeReference<Map<String, Object>>() {
});
traversalClass tclass = new traversalClass(origin.getClass());
if (// Extensions stuff
f == null)
deleteCustomAttribute(map, path, extensions);
else
tclass.traverseDelete(map, path);
return mapper.convertValue(map, origin.getClass());
}
use of io.jans.scim.model.scim2.BaseScimResource in project jans by JanssenProject.
the class ListResponseJsonSerializer method serialize.
@Override
public void serialize(ListResponse listResponse, JsonGenerator jGen, SerializerProvider provider) throws IOException {
try {
jGen.writeStartObject();
jGen.writeArrayFieldStart("schemas");
for (String schema : listResponse.getSchemas()) jGen.writeString(schema);
jGen.writeEndArray();
jGen.writeNumberField("totalResults", listResponse.getTotalResults());
if (!skipResults) {
if (listResponse.getItemsPerPage() > 0) {
// these two bits are "REQUIRED when partial results are returned due to pagination." (section 3.4.2 RFC 7644)
jGen.writeNumberField("startIndex", listResponse.getStartIndex());
jGen.writeNumberField("itemsPerPage", listResponse.getItemsPerPage());
}
// Section 3.4.2 RFC 7644: Resources [...] REQUIRED if "totalResults" is non-zero
if (listResponse.getTotalResults() > 0) {
jGen.writeArrayFieldStart("Resources");
if (listResponse.getResources().size() > 0) {
for (BaseScimResource resource : listResponse.getResources()) {
JsonNode jsonResource = mapper.readTree(resourceSerializer.serialize(resource, attributes, excludeAttributes));
jGen.writeTree(jsonResource);
}
} else if (jsonResources != null) {
for (JsonNode node : jsonResources) {
jGen.writeTree(node);
}
}
jGen.writeEndArray();
}
}
jGen.writeEndObject();
} catch (Exception e) {
throw new IOException(e);
}
}
use of io.jans.scim.model.scim2.BaseScimResource in project jans by JanssenProject.
the class BaseScimWebService method assignMetaInformation.
protected void assignMetaInformation(BaseScimResource resource) {
// Generate some meta information (this replaces the info client passed in the request)
String val = DateUtil.millisToISOString(System.currentTimeMillis());
Meta meta = new Meta();
meta.setResourceType(ScimResourceUtil.getType(resource.getClass()));
meta.setCreated(val);
meta.setLastModified(val);
// For version attritute: Service provider support for this attribute is optional and subject to the service provider's support for versioning
// For location attribute: this will be set after current user creation in LDAP
resource.setMeta(meta);
}
use of io.jans.scim.model.scim2.BaseScimResource in project jans by JanssenProject.
the class Scim2PatchService method applyPatchOperation.
public BaseScimResource applyPatchOperation(BaseScimResource resource, PatchOperation operation, Predicate<String> selectionFilterSkipPredicate) throws Exception {
BaseScimResource result = null;
Map<String, Object> genericMap = null;
PatchOperationType opType = operation.getType();
Class<? extends BaseScimResource> clazz = resource.getClass();
String path = operation.getPath();
log.debug("applyPatchOperation of type {}", opType);
// Determine if operation is with value filter
if (StringUtils.isNotEmpty(path) && !operation.getType().equals(PatchOperationType.ADD)) {
Pair<Boolean, String> pair = validateBracketedPath(path);
if (pair.getFirst()) {
String valSelFilter = pair.getSecond();
if (valSelFilter == null) {
throw new SCIMException("Unexpected syntax in value selection filter");
} else {
int i = path.indexOf("[");
String attribute = path.substring(0, i);
i = path.lastIndexOf("].");
String subAttribute = i == -1 ? "" : path.substring(i + 2);
// Abort earlier
if (selectionFilterSkipPredicate.test(valSelFilter)) {
log.info("Patch operation will be skipped");
return resource;
} else {
return applyPatchOperationWithValueFilter(resource, operation, valSelFilter, attribute, subAttribute);
}
}
}
}
if (!opType.equals(PatchOperationType.REMOVE)) {
Object value = operation.getValue();
List<String> extensionUrns = extService.getUrnsOfExtensions(clazz);
if (value instanceof Map) {
genericMap = IntrospectUtil.strObjMap(value);
} else {
// It's an atomic value or an array
if (StringUtils.isEmpty(path)) {
throw new SCIMException("Value(s) supplied for resource not parseable");
}
// Create a simple map and trim the last part of path
String[] subPaths = ScimResourceUtil.splitPath(path, extensionUrns);
genericMap = Collections.singletonMap(subPaths[subPaths.length - 1], value);
if (subPaths.length == 1) {
path = "";
} else {
path = path.substring(0, path.lastIndexOf("."));
}
}
if (StringUtils.isNotEmpty(path)) {
// Visit backwards creating a composite map
String[] subPaths = ScimResourceUtil.splitPath(path, extensionUrns);
for (int i = subPaths.length - 1; i >= 0; i--) {
// Create a string consisting of all subpaths until the i-th
StringBuilder sb = new StringBuilder();
for (int j = 0; j <= i; j++) {
sb.append(subPaths[j]).append(".");
}
Attribute annot = IntrospectUtil.getFieldAnnotation(sb.substring(0, sb.length() - 1), clazz, Attribute.class);
boolean multivalued = !(annot == null || annot.multiValueClass().equals(NullType.class));
Map<String, Object> genericBiggerMap = new HashMap<>();
genericBiggerMap.put(subPaths[i], multivalued ? Collections.singletonList(genericMap) : genericMap);
genericMap = genericBiggerMap;
}
}
log.debug("applyPatchOperation. Generating a ScimResource from generic map: {}", genericMap.toString());
}
// Try parse genericMap as an instance of the resource
ObjectMapper mapper = new ObjectMapper();
BaseScimResource alter = opType.equals(PatchOperationType.REMOVE) ? resource : mapper.convertValue(genericMap, clazz);
List<Extension> extensions = extService.getResourceExtensions(clazz);
switch(operation.getType()) {
case REPLACE:
result = ScimResourceUtil.transferToResourceReplace(alter, resource, extensions);
break;
case ADD:
result = ScimResourceUtil.transferToResourceAdd(alter, resource, extensions);
break;
case REMOVE:
result = ScimResourceUtil.deleteFromResource(alter, operation.getPath(), extensions);
break;
}
return result;
}
Aggregations