Search in sources :

Example 26 with BaseScimResource

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;
}
Also used : Extension(io.jans.scim.model.scim2.extensions.Extension)

Example 27 with BaseScimResource

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());
}
Also used : ExtensionField(io.jans.scim.model.scim2.extensions.ExtensionField) Field(java.lang.reflect.Field) Attribute(io.jans.scim.model.scim2.annotations.Attribute) InvalidAttributeValueException(javax.management.InvalidAttributeValueException)

Example 28 with BaseScimResource

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);
    }
}
Also used : BaseScimResource(io.jans.scim.model.scim2.BaseScimResource) JsonNode(com.fasterxml.jackson.databind.JsonNode) IOException(java.io.IOException) IOException(java.io.IOException)

Example 29 with BaseScimResource

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);
}
Also used : Meta(io.jans.scim.model.scim2.Meta)

Example 30 with BaseScimResource

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;
}
Also used : PatchOperationType(io.jans.scim.model.scim2.patch.PatchOperationType) Attribute(io.jans.scim.model.scim2.annotations.Attribute) HashMap(java.util.HashMap) Extension(io.jans.scim.model.scim2.extensions.Extension) SCIMException(io.jans.scim.model.exception.SCIMException) BaseScimResource(io.jans.scim.model.scim2.BaseScimResource) NullType(javax.lang.model.type.NullType) HashMap(java.util.HashMap) Map(java.util.Map) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper)

Aggregations

BaseScimResource (io.jans.scim.model.scim2.BaseScimResource)12 Extension (io.jans.scim.model.scim2.extensions.Extension)12 ArrayList (java.util.ArrayList)12 InvalidAttributeValueException (javax.management.InvalidAttributeValueException)12 Response (javax.ws.rs.core.Response)11 SCIMException (io.jans.scim.model.exception.SCIMException)10 BaseScimResource (org.gluu.oxtrust.model.scim2.BaseScimResource)9 URI (java.net.URI)8 ExtensionField (io.jans.scim.model.scim2.extensions.ExtensionField)7 ListResponse (io.jans.scim.model.scim2.ListResponse)6 URISyntaxException (java.net.URISyntaxException)6 ListViewResponse (org.gluu.persist.model.ListViewResponse)6 SearchRequest (io.jans.scim.model.scim2.SearchRequest)5 UserResource (io.jans.scim.model.scim2.user.UserResource)5 PagedResult (io.jans.orm.model.PagedResult)4 Filter (io.jans.orm.search.filter.Filter)4 Attribute (io.jans.scim.model.scim2.annotations.Attribute)4 DefaultValue (javax.ws.rs.DefaultValue)4 GET (javax.ws.rs.GET)4 HeaderParam (javax.ws.rs.HeaderParam)4