Search in sources :

Example 16 with SCIMException

use of io.jans.scim.model.exception.SCIMException in project jans by JanssenProject.

the class ResourceValidator method validateCanonicalizedAttributes.

/**
 * Inspects the resource passed in the constructor and for every attribute annotated with a non-empty collection of
 * {@link Attribute#canonicalValues() canonical values}, it checks whether the attribute value matches any of the
 * canonical values supplied.
 * <p>This method should be called after a successful call to {@link #validateRequiredAttributes()}.</p>
 * @throws SCIMException When a validation does not pass (there is no match for any of the attributes inspected)
 */
public void validateCanonicalizedAttributes() throws SCIMException {
    Map<String, List<Method>> map = IntrospectUtil.canonicalCoreAttrs.get(resourceClass);
    for (String attributePath : map.keySet()) {
        Attribute attrAnnot = IntrospectUtil.getFieldAnnotation(attributePath, resourceClass, Attribute.class);
        List<String> canonicalVals = Arrays.asList(attrAnnot.canonicalValues());
        log.debug("Validating values of canonical attribute '{}'", attributePath);
        for (Object val : IntrospectUtil.getAttributeValues(resource, map.get(attributePath))) {
            if (!canonicalVals.contains(val.toString())) {
                log.error("Error validating canonical attribute '{}', wrong value supplied: '{}'", attributePath, val.toString());
                throw new SCIMException(String.format(ATTR_VALIDATION_FAILED, attributePath));
            }
        }
    }
}
Also used : SCIMException(io.jans.scim.model.exception.SCIMException) Attribute(io.jans.scim.model.scim2.annotations.Attribute)

Example 17 with SCIMException

use of io.jans.scim.model.exception.SCIMException in project jans by JanssenProject.

the class ResourceValidator method validateExtendedAttributes.

/**
 * Inspects the resource passed in the constructor and for every extended attribute (see {@link BaseScimResource#getCustomAttributes()},
 * the attribute's value is checked to see if it complies with the data type it is supposed to belong to. This
 * information is obtained from the list of <code>Extension</code>s passed in the constructor (every {@link ExtensionField}
 * has an associated {@link ExtensionField#getType() type}.
 * <p>When an attribute is {@link ExtensionField#isMultiValued() multi-valued}, every single item inside the collection
 * is validated.</p>
 * @throws SCIMException When any of the validations do not pass or an attribute seems not to be part of a known schema.
 */
public void validateExtendedAttributes() throws SCIMException {
    // Note: throughout this method, we always ignore presence of nulls
    // Gets all extended attributes (see the @JsonAnySetter annotation in BaseScimResource)
    Map<String, Object> extendedAttributes = resource.getCustomAttributes();
    // Iterate over every extension of the resource object (in practice it will be just one at most)
    for (String schema : extendedAttributes.keySet()) {
        // Validate if the schema referenced in the extended attributes is contained in the valid set of extension
        Extension extension = null;
        for (Extension ext : extensions) if (ext.getUrn().equals(schema)) {
            extension = ext;
            break;
        }
        if (extension != null) {
            log.debug("validateExtendedAttributes. Revising attributes under schema {}", schema);
            try {
                // Obtains a generic map consisting of all name/value(s) pairs associated to this schema
                Map<String, Object> attrsMap = IntrospectUtil.strObjMap(extendedAttributes.get(schema));
                for (String attr : attrsMap.keySet()) {
                    Object value = attrsMap.get(attr);
                    if (value != null) {
                        /*
                             Gets the class associated to the value of current attribute. For extended attributes, we
                             should only see coming: String, Integer, Double, boolean, and Collection.
                             Different things will be rejected
                             */
                        Class cls = value.getClass();
                        boolean isCollection = IntrospectUtil.isCollection(cls);
                        // If the attribute coming is unknown, NPE will be thrown and we are covered
                        log.debug("validateExtendedAttributes. Got value(s) for attribute '{}'", attr);
                        // Check if the multivalued custom attribute is consistent with the nature of the value itself
                        if (isCollection == extension.getFields().get(attr).isMultiValued()) {
                            if (isCollection) {
                                for (Object elem : (Collection) value) if (elem != null)
                                    validateDataTypeExtendedAttr(extension, attr, elem);
                            } else
                                validateDataTypeExtendedAttr(extension, attr, value);
                        } else
                            throw new SCIMException(ERROR_PARSING_EXTENDED);
                    }
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                throw new SCIMException(ERROR_PARSING_EXTENDED);
            }
        } else
            throw new SCIMException(String.format(UNKNOWN_EXTENSION, schema));
    }
}
Also used : Extension(io.jans.scim.model.scim2.extensions.Extension) SCIMException(io.jans.scim.model.exception.SCIMException) SCIMException(io.jans.scim.model.exception.SCIMException)

Example 18 with SCIMException

use of io.jans.scim.model.exception.SCIMException in project jans by JanssenProject.

the class FidoDeviceWebService method doSearchDevices.

private Response doSearchDevices(String userId, String filter, Integer startIndex, Integer count, String sortBy, String sortOrder, String attrsList, String excludedAttrsList, String method) {
    Response response;
    try {
        SearchRequest searchReq = new SearchRequest();
        response = prepareSearchRequest(searchReq.getSchemas(), filter, sortBy, sortOrder, startIndex, count, attrsList, excludedAttrsList, searchReq);
        if (response != null)
            return response;
        response = externalConstraintsService.applySearchCheck(searchReq, httpHeaders, uriInfo, method, fidoResourceType);
        if (response != null)
            return response;
        response = validateExistenceOfUser(userId);
        if (response != null)
            return response;
        PagedResult<BaseScimResource> resources = searchDevices(userId, searchReq.getFilter(), translateSortByAttribute(FidoDeviceResource.class, searchReq.getSortBy()), SortOrder.getByValue(searchReq.getSortOrder()), searchReq.getStartIndex(), searchReq.getCount());
        String json = getListResponseSerialized(resources.getTotalEntriesCount(), searchReq.getStartIndex(), resources.getEntries(), searchReq.getAttributesStr(), searchReq.getExcludedAttributesStr(), searchReq.getCount() == 0);
        response = Response.ok(json).location(new URI(endpointUrl)).build();
    } catch (SCIMException e) {
        log.error(e.getMessage(), e);
        response = getErrorResponse(Response.Status.BAD_REQUEST, ErrorScimType.INVALID_FILTER, e.getMessage());
    } catch (Exception e) {
        log.error("Failure at searchDevices method", e);
        response = getErrorResponse(Response.Status.INTERNAL_SERVER_ERROR, "Unexpected error: " + e.getMessage());
    }
    return response;
}
Also used : Response(javax.ws.rs.core.Response) SearchRequest(io.jans.scim.model.scim2.SearchRequest) SCIMException(io.jans.scim.model.exception.SCIMException) FidoDeviceResource(io.jans.scim.model.scim2.fido.FidoDeviceResource) BaseScimResource(io.jans.scim.model.scim2.BaseScimResource) URI(java.net.URI) URISyntaxException(java.net.URISyntaxException) SCIMException(io.jans.scim.model.exception.SCIMException) InvalidAttributeValueException(javax.management.InvalidAttributeValueException)

Example 19 with SCIMException

use of io.jans.scim.model.exception.SCIMException in project jans by JanssenProject.

the class GroupWebService method doSearchGroups.

private Response doSearchGroups(String filter, Integer startIndex, Integer count, String sortBy, String sortOrder, String attrsList, String excludedAttrsList, String method, boolean fillMembersDisplay) {
    Response response;
    try {
        SearchRequest searchReq = new SearchRequest();
        response = prepareSearchRequest(searchReq.getSchemas(), filter, sortBy, sortOrder, startIndex, count, attrsList, excludedAttrsList, searchReq);
        if (response != null)
            return response;
        response = externalConstraintsService.applySearchCheck(searchReq, httpHeaders, uriInfo, method, groupResourceType);
        if (response != null)
            return response;
        PagedResult<BaseScimResource> resources = scim2GroupService.searchGroups(searchReq.getFilter(), translateSortByAttribute(GroupResource.class, searchReq.getSortBy()), SortOrder.getByValue(searchReq.getSortOrder()), searchReq.getStartIndex(), searchReq.getCount(), endpointUrl, usersUrl, getMaxCount(), fillMembersDisplay);
        String json = getListResponseSerialized(resources.getTotalEntriesCount(), searchReq.getStartIndex(), resources.getEntries(), searchReq.getAttributesStr(), searchReq.getExcludedAttributesStr(), searchReq.getCount() == 0);
        response = Response.ok(json).location(new URI(endpointUrl)).build();
    } catch (SCIMException e) {
        log.error(e.getMessage(), e);
        response = getErrorResponse(Response.Status.BAD_REQUEST, ErrorScimType.INVALID_FILTER, e.getMessage());
    } catch (Exception e) {
        log.error("Failure at searchGroups method", e);
        response = getErrorResponse(Response.Status.INTERNAL_SERVER_ERROR, "Unexpected error: " + e.getMessage());
    }
    return response;
}
Also used : Response(javax.ws.rs.core.Response) SearchRequest(io.jans.scim.model.scim2.SearchRequest) SCIMException(io.jans.scim.model.exception.SCIMException) BaseScimResource(io.jans.scim.model.scim2.BaseScimResource) URI(java.net.URI) GroupResource(io.jans.scim.model.scim2.group.GroupResource) URISyntaxException(java.net.URISyntaxException) SCIMException(io.jans.scim.model.exception.SCIMException) DuplicateEntryException(io.jans.orm.exception.operation.DuplicateEntryException) InvalidAttributeValueException(javax.management.InvalidAttributeValueException)

Example 20 with SCIMException

use of io.jans.scim.model.exception.SCIMException in project jans by JanssenProject.

the class UserWebService method patchUser.

@Path("{id}")
@PATCH
@Consumes({ MEDIA_TYPE_SCIM_JSON, MediaType.APPLICATION_JSON })
@Produces({ MEDIA_TYPE_SCIM_JSON + UTF8_CHARSET_FRAGMENT, MediaType.APPLICATION_JSON + UTF8_CHARSET_FRAGMENT })
@HeaderParam("Accept")
@DefaultValue(MEDIA_TYPE_SCIM_JSON)
@ProtectedApi(scopes = { "https://jans.io/scim/users.write" })
@RefAdjusted
public Response patchUser(PatchRequest request, @PathParam("id") String id, @QueryParam(QUERY_PARAM_ATTRIBUTES) String attrsList, @QueryParam(QUERY_PARAM_EXCLUDED_ATTRS) String excludedAttrsList) {
    Response response;
    try {
        log.debug("Executing web service method. patchUser");
        response = inspectPatchRequest(request, UserResource.class);
        if (response != null)
            return response;
        ScimCustomPerson person = userPersistenceHelper.getPersonByInum(id);
        if (person == null)
            return notFoundResponse(id, userResourceType);
        response = externalConstraintsService.applyEntityCheck(person, request, httpHeaders, uriInfo, HttpMethod.PATCH, userResourceType);
        if (response != null)
            return response;
        UserResource user = new UserResource();
        // Fill user instance with all info from person
        scim2UserService.transferAttributesToUserResource(person, user, endpointUrl);
        // Apply patches one by one in sequence
        for (PatchOperation po : request.getOperations()) {
            // Handle special case: https://github.com/GluuFederation/oxTrust/issues/800
            if (po.getType().equals(REMOVE) && po.getPath().equals("pairwiseIdentifiers")) {
                // If this block weren't here, the implementation will throw error because read-only attribute cannot be altered
                person.setPpid(null);
                user.setPairwiseIdentifiers(null);
                scim2UserService.removePPIDsBranch(person.getDn());
            } else {
                user = (UserResource) scim2PatchService.applyPatchOperation(user, po);
            }
        }
        // Throws exception if final representation does not pass overall validation
        log.debug("patchUser. Revising final resource representation still passes validations");
        executeValidation(user);
        ScimResourceUtil.adjustPrimarySubAttributes(user);
        // Update timestamp
        user.getMeta().setLastModified(DateUtil.millisToISOString(System.currentTimeMillis()));
        // Replaces the information found in person with the contents of user
        scim2UserService.replacePersonInfo(person, user, endpointUrl);
        String json = resourceSerializer.serialize(user, attrsList, excludedAttrsList);
        response = Response.ok(new URI(user.getMeta().getLocation())).entity(json).build();
    } catch (InvalidAttributeValueException e) {
        log.error(e.getMessage(), e);
        response = getErrorResponse(Response.Status.BAD_REQUEST, ErrorScimType.MUTABILITY, e.getMessage());
    } catch (SCIMException e) {
        response = getErrorResponse(Response.Status.BAD_REQUEST, ErrorScimType.INVALID_SYNTAX, e.getMessage());
    } catch (Exception e) {
        log.error("Failure at patchUser method", e);
        response = getErrorResponse(Response.Status.INTERNAL_SERVER_ERROR, "Unexpected error: " + e.getMessage());
    }
    return response;
}
Also used : Response(javax.ws.rs.core.Response) SCIMException(io.jans.scim.model.exception.SCIMException) ScimCustomPerson(io.jans.scim.model.scim.ScimCustomPerson) UserResource(io.jans.scim.model.scim2.user.UserResource) PatchOperation(io.jans.scim.model.scim2.patch.PatchOperation) URI(java.net.URI) InvalidAttributeValueException(javax.management.InvalidAttributeValueException) URISyntaxException(java.net.URISyntaxException) SCIMException(io.jans.scim.model.exception.SCIMException) DuplicateEntryException(io.jans.orm.exception.operation.DuplicateEntryException) InvalidAttributeValueException(javax.management.InvalidAttributeValueException) Path(javax.ws.rs.Path) DefaultValue(javax.ws.rs.DefaultValue) HeaderParam(javax.ws.rs.HeaderParam) RefAdjusted(io.jans.scim.service.scim2.interceptor.RefAdjusted) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces) ProtectedApi(io.jans.scim.service.filter.ProtectedApi) PATCH(io.jans.scim.ws.rs.scim2.PATCH)

Aggregations

SCIMException (io.jans.scim.model.exception.SCIMException)21 InvalidAttributeValueException (javax.management.InvalidAttributeValueException)13 URI (java.net.URI)12 URISyntaxException (java.net.URISyntaxException)12 Response (javax.ws.rs.core.Response)12 DuplicateEntryException (io.jans.orm.exception.operation.DuplicateEntryException)8 ProtectedApi (io.jans.scim.service.filter.ProtectedApi)8 RefAdjusted (io.jans.scim.service.scim2.interceptor.RefAdjusted)8 Consumes (javax.ws.rs.Consumes)8 DefaultValue (javax.ws.rs.DefaultValue)8 HeaderParam (javax.ws.rs.HeaderParam)8 Produces (javax.ws.rs.Produces)8 Path (javax.ws.rs.Path)6 BaseScimResource (io.jans.scim.model.scim2.BaseScimResource)5 PUT (javax.ws.rs.PUT)5 SearchRequest (io.jans.scim.model.scim2.SearchRequest)4 GluuGroup (io.jans.scim.model.GluuGroup)3 ScimCustomPerson (io.jans.scim.model.scim.ScimCustomPerson)3 Attribute (io.jans.scim.model.scim2.annotations.Attribute)3 Extension (io.jans.scim.model.scim2.extensions.Extension)3