Search in sources :

Example 6 with GroupResource

use of io.jans.scim.model.scim2.group.GroupResource in project jans by JanssenProject.

the class GroupWebService method patchGroup.

@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/groups.write" })
@RefAdjusted
public Response patchGroup(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. patchGroup");
        response = inspectPatchRequest(request, GroupResource.class);
        if (response != null)
            return response;
        GluuGroup gluuGroup = groupService.getGroupByInum(id);
        if (gluuGroup == null)
            return notFoundResponse(id, groupResourceType);
        response = externalConstraintsService.applyEntityCheck(gluuGroup, request, httpHeaders, uriInfo, HttpMethod.PATCH, groupResourceType);
        if (response != null)
            return response;
        boolean skipValidation = isMembersValidationSkipped();
        boolean displayExcluded = isDisplayExcluded(skipValidation, attrsList, excludedAttrsList);
        GroupResource group = new GroupResource();
        // Fill group instance with all info from gluuGroup
        scim2GroupService.transferAttributesToGroupResource(gluuGroup, group, !skipValidation, endpointUrl, usersUrl);
        GroupResource original = (GroupResource) ScimResourceUtil.clone(group);
        Predicate<String> p = skipValidation ? selectionFilterSkipPredicate : (filter -> false);
        // Apply patches one by one in sequence
        for (PatchOperation po : request.getOperations()) {
            group = (GroupResource) scim2PatchService.applyPatchOperation(group, po, p);
        }
        log.debug("patchGroup. Revising final resource representation still passes validations");
        // Throws exception if final representation does not pass overall validation
        executeValidation(group);
        checkDisplayNameExistence(group.getDisplayName(), id);
        // Update timestamp
        group.getMeta().setLastModified(DateUtil.millisToISOString(System.currentTimeMillis()));
        if (!displayExcluded) {
            scim2GroupService.restoreMembersDisplay(original, group);
        }
        // Replaces the information found in gluuGroup with the contents of group
        scim2GroupService.replaceGroupInfo(gluuGroup, group, skipValidation, !displayExcluded, endpointUrl, usersUrl);
        String json = resourceSerializer.serialize(group, attrsList, excludedAttrsList);
        response = Response.ok(new URI(group.getMeta().getLocation())).entity(json).build();
    } catch (DuplicateEntryException e) {
        log.error(e.getMessage());
        response = getErrorResponse(Response.Status.CONFLICT, ErrorScimType.UNIQUENESS, e.getMessage());
    } 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 patchGroup method", e);
        response = getErrorResponse(Response.Status.INTERNAL_SERVER_ERROR, "Unexpected error: " + e.getMessage());
    }
    return response;
}
Also used : StringUtils(org.apache.commons.lang.StringUtils) Produces(javax.ws.rs.Produces) QUERY_PARAM_FILTER(io.jans.scim.model.scim2.Constants.QUERY_PARAM_FILTER) URISyntaxException(java.net.URISyntaxException) Path(javax.ws.rs.Path) QUERY_PARAM_SORT_ORDER(io.jans.scim.model.scim2.Constants.QUERY_PARAM_SORT_ORDER) BaseScimResource(io.jans.scim.model.scim2.BaseScimResource) MediaType(javax.ws.rs.core.MediaType) SCIMException(io.jans.scim.model.exception.SCIMException) QueryParam(javax.ws.rs.QueryParam) Consumes(javax.ws.rs.Consumes) DefaultValue(javax.ws.rs.DefaultValue) HeaderParam(javax.ws.rs.HeaderParam) GluuGroup(io.jans.scim.model.GluuGroup) PatchOperation(io.jans.scim.model.scim2.patch.PatchOperation) URI(java.net.URI) DELETE(javax.ws.rs.DELETE) SortOrder(io.jans.orm.model.SortOrder) Predicate(java.util.function.Predicate) PatchRequest(io.jans.scim.model.scim2.patch.PatchRequest) QUERY_PARAM_EXCLUDED_ATTRS(io.jans.scim.model.scim2.Constants.QUERY_PARAM_EXCLUDED_ATTRS) GroupResource(io.jans.scim.model.scim2.group.GroupResource) List(java.util.List) Response(javax.ws.rs.core.Response) ErrorScimType(io.jans.scim.model.scim2.ErrorScimType) Scim2PatchService(io.jans.scim.service.scim2.Scim2PatchService) PostConstruct(javax.annotation.PostConstruct) QUERY_PARAM_START_INDEX(io.jans.scim.model.scim2.Constants.QUERY_PARAM_START_INDEX) QUERY_PARAM_SORT_BY(io.jans.scim.model.scim2.Constants.QUERY_PARAM_SORT_BY) GroupService(io.jans.scim.service.GroupService) PathParam(javax.ws.rs.PathParam) QUERY_PARAM_COUNT(io.jans.scim.model.scim2.Constants.QUERY_PARAM_COUNT) GET(javax.ws.rs.GET) QUERY_PARAM_ATTRIBUTES(io.jans.scim.model.scim2.Constants.QUERY_PARAM_ATTRIBUTES) DuplicateEntryException(io.jans.orm.exception.operation.DuplicateEntryException) DateUtil(io.jans.scim.model.scim2.util.DateUtil) HttpMethod(javax.ws.rs.HttpMethod) ScimResourceUtil(io.jans.scim.model.scim2.util.ScimResourceUtil) Inject(javax.inject.Inject) Named(javax.inject.Named) POST(javax.ws.rs.POST) ProtectedApi(io.jans.scim.service.filter.ProtectedApi) UTF8_CHARSET_FRAGMENT(io.jans.scim.model.scim2.Constants.UTF8_CHARSET_FRAGMENT) RefAdjusted(io.jans.scim.service.scim2.interceptor.RefAdjusted) GROUP_OVERHEAD_BYPASS_PARAM(io.jans.scim.model.scim2.Constants.GROUP_OVERHEAD_BYPASS_PARAM) InvalidAttributeValueException(javax.management.InvalidAttributeValueException) SearchRequest(io.jans.scim.model.scim2.SearchRequest) PagedResult(io.jans.orm.model.PagedResult) MEDIA_TYPE_SCIM_JSON(io.jans.scim.model.scim2.Constants.MEDIA_TYPE_SCIM_JSON) Scim2GroupService(io.jans.scim.service.scim2.Scim2GroupService) PUT(javax.ws.rs.PUT) GluuGroup(io.jans.scim.model.GluuGroup) URI(java.net.URI) InvalidAttributeValueException(javax.management.InvalidAttributeValueException) 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) Response(javax.ws.rs.core.Response) SCIMException(io.jans.scim.model.exception.SCIMException) PatchOperation(io.jans.scim.model.scim2.patch.PatchOperation) DuplicateEntryException(io.jans.orm.exception.operation.DuplicateEntryException) 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)

Example 7 with GroupResource

use of io.jans.scim.model.scim2.group.GroupResource in project jans by JanssenProject.

the class GroupWebService method updateGroup.

/**
 * This implementation differs from spec in the following aspects:
 * - Passing a null value for an attribute, does not modify the attribute in the destination, however passing an
 * empty array for a multivalued attribute does clear the attribute. Thus, to clear single-valued attribute, PATCH
 * operation should be used
 */
@Path("{id}")
@PUT
@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/groups.write" })
@RefAdjusted
public Response updateGroup(GroupResource group, @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. updateGroup");
        // empty externalId, no place to store it in LDAP
        group.setExternalId(null);
        // Check if the ids match in case the group coming has one
        if (group.getId() != null && !group.getId().equals(id))
            throw new SCIMException("Parameter id does not match with id attribute of Group");
        GluuGroup gluuGroup = groupService.getGroupByInum(id);
        if (gluuGroup == null)
            return notFoundResponse(id, groupResourceType);
        response = externalConstraintsService.applyEntityCheck(gluuGroup, group, httpHeaders, uriInfo, HttpMethod.PUT, groupResourceType);
        if (response != null)
            return response;
        executeValidation(group, true);
        if (StringUtils.isNotEmpty(group.getDisplayName())) {
            checkDisplayNameExistence(group.getDisplayName(), id);
        }
        boolean skipValidation = isMembersValidationSkipped();
        boolean displayExcluded = isDisplayExcluded(skipValidation, attrsList, excludedAttrsList);
        GroupResource updatedResource = scim2GroupService.updateGroup(gluuGroup, group, skipValidation, !displayExcluded, endpointUrl, usersUrl);
        String json = resourceSerializer.serialize(updatedResource, attrsList, excludedAttrsList);
        response = Response.ok(new URI(updatedResource.getMeta().getLocation())).entity(json).build();
    } catch (DuplicateEntryException e) {
        log.error(e.getMessage());
        response = getErrorResponse(Response.Status.CONFLICT, ErrorScimType.UNIQUENESS, e.getMessage());
    } catch (SCIMException e) {
        log.error("Validation check at updateGroup returned: {}", e.getMessage());
        response = getErrorResponse(Response.Status.BAD_REQUEST, ErrorScimType.INVALID_VALUE, e.getMessage());
    } catch (InvalidAttributeValueException e) {
        log.error(e.getMessage());
        response = getErrorResponse(Response.Status.BAD_REQUEST, ErrorScimType.MUTABILITY, e.getMessage());
    } catch (Exception e) {
        log.error("Failure at updateGroup 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) DuplicateEntryException(io.jans.orm.exception.operation.DuplicateEntryException) GluuGroup(io.jans.scim.model.GluuGroup) URI(java.net.URI) InvalidAttributeValueException(javax.management.InvalidAttributeValueException) 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) 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) PUT(javax.ws.rs.PUT)

Example 8 with GroupResource

use of io.jans.scim.model.scim2.group.GroupResource in project jans by JanssenProject.

the class GroupWebService method getGroupById.

@Path("{id}")
@GET
@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/groups.read" })
@RefAdjusted
public Response getGroupById(@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. getGroupById");
        GluuGroup gluuGroup = groupService.getGroupByInum(id);
        if (gluuGroup == null)
            return notFoundResponse(id, groupResourceType);
        response = externalConstraintsService.applyEntityCheck(gluuGroup, null, httpHeaders, uriInfo, HttpMethod.GET, groupResourceType);
        if (response != null)
            return response;
        boolean displayExcluded = isDisplayExcluded(false, attrsList, excludedAttrsList);
        GroupResource group = scim2GroupService.buildGroupResource(gluuGroup, !displayExcluded, endpointUrl, usersUrl);
        String json = resourceSerializer.serialize(group, attrsList, excludedAttrsList);
        response = Response.ok(new URI(group.getMeta().getLocation())).entity(json).build();
    } catch (Exception e) {
        log.error("Failure at getGroupById method", e);
        response = getErrorResponse(Response.Status.INTERNAL_SERVER_ERROR, "Unexpected error: " + e.getMessage());
    }
    return response;
}
Also used : Response(javax.ws.rs.core.Response) GluuGroup(io.jans.scim.model.GluuGroup) 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) Path(javax.ws.rs.Path) DefaultValue(javax.ws.rs.DefaultValue) HeaderParam(javax.ws.rs.HeaderParam) RefAdjusted(io.jans.scim.service.scim2.interceptor.RefAdjusted) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET) ProtectedApi(io.jans.scim.service.filter.ProtectedApi)

Example 9 with GroupResource

use of io.jans.scim.model.scim2.group.GroupResource in project jans by JanssenProject.

the class Scim2GroupService method restoreMembersDisplay.

/**
 * Takes two GroupResource objects and attempts to fill the members' display names
 * in the second object when missing based on the data existing in the first object.
 * In practice the first object represents an already stored group while the
 * second is the result of modifications applied upon the first. In the course
 * of modifications some display names may have removed. This method tries to
 * recover some of this lost data
 * @param trusted Object containing valid group data
 * @param altered Modified object
 */
public void restoreMembersDisplay(GroupResource trusted, GroupResource altered) {
    int aSize = membersCount(altered);
    int tSize = membersCount(trusted);
    if (aSize > 0 && tSize > 0) {
        Map<String, String> map = trusted.getMembers().stream().filter(m -> m.getDisplay() != null).collect(Collectors.toMap(Member::getValue, Member::getDisplay));
        for (Member member : altered.getMembers()) {
            String inum = member.getValue();
            if (member.getDisplay() == null) {
                member.setDisplay(map.get(inum));
            }
        }
    }
}
Also used : GroupService(io.jans.scim.service.GroupService) Arrays(java.util.Arrays) Filter(io.jans.orm.search.filter.Filter) Meta(io.jans.scim.model.scim2.Meta) DateUtil(io.jans.scim.model.scim2.util.DateUtil) GluuStatus(io.jans.model.GluuStatus) ArrayList(java.util.ArrayList) ScimResourceUtil(io.jans.scim.model.scim2.util.ScimResourceUtil) HashSet(java.util.HashSet) Inject(javax.inject.Inject) BaseScimResource(io.jans.scim.model.scim2.BaseScimResource) PersonService(io.jans.scim.service.PersonService) Map(java.util.Map) GluuGroup(io.jans.scim.model.GluuGroup) Status(javax.ws.rs.core.Response.Status) SortOrder(io.jans.orm.model.SortOrder) Member(io.jans.scim.model.scim2.group.Member) Logger(org.slf4j.Logger) UserResource(io.jans.scim.model.scim2.user.UserResource) OrganizationService(io.jans.scim.service.OrganizationService) Set(java.util.Set) ScimFilterParserService(io.jans.scim.service.antlr.scimFilter.ScimFilterParserService) Collectors(java.util.stream.Collectors) PersistenceEntryManager(io.jans.orm.PersistenceEntryManager) Serializable(java.io.Serializable) GroupResource(io.jans.scim.model.scim2.group.GroupResource) List(java.util.List) Stream(java.util.stream.Stream) ExternalScimService(io.jans.scim.service.external.ExternalScimService) PagedResult(io.jans.orm.model.PagedResult) Optional(java.util.Optional) WebApplicationException(javax.ws.rs.WebApplicationException) ApplicationScoped(javax.enterprise.context.ApplicationScoped) GluuCustomPerson(io.jans.scim.model.GluuCustomPerson) Collections(java.util.Collections) Member(io.jans.scim.model.scim2.group.Member)

Example 10 with GroupResource

use of io.jans.scim.model.scim2.group.GroupResource in project jans by JanssenProject.

the class Scim2GroupService method transferAttributesToGroup.

private void transferAttributesToGroup(GroupResource res, GluuGroup group, boolean skipMembersValidation, boolean fillMembersDisplay, String usersUrl) {
    // externalId (so jansExtId) not part of LDAP schema
    group.setAttribute("jansMetaCreated", res.getMeta().getCreated());
    group.setAttribute("jansMetaLastMod", res.getMeta().getLastModified());
    // When creating group, location will be set again when having an inum
    group.setAttribute("jansMetaLocation", res.getMeta().getLocation());
    group.setDisplayName(res.getDisplayName());
    group.setStatus(GluuStatus.ACTIVE);
    group.setOrganization(organizationService.getDnForOrganization());
    Set<Member> members = res.getMembers();
    if (members != null && members.size() > 0) {
        Set<String> groupMembers = group.getMembers().stream().map(userPersistenceHelper::getUserInumFromDN).collect(Collectors.toCollection(HashSet::new));
        List<String> listMembers = new ArrayList<>();
        List<Member> invalidMembers = new ArrayList<>();
        // Add the members, and complement the $refs and users' display names in res
        for (Member member : members) {
            GluuCustomPerson person;
            // it's not null as it is required in GroupResource
            String inum = member.getValue();
            // we make database lookups
            if (!skipMembersValidation && !groupMembers.contains(inum)) {
                person = personService.getPersonByInum(inum);
                if (person != null && fillMembersDisplay) {
                    member.setDisplay(person.getDisplayName());
                }
            } else {
                person = new GluuCustomPerson();
                person.setDn(personService.getDnForPerson(inum));
            }
            if (person == null) {
                log.info("Member identified by {} does not exist. Ignored", inum);
                invalidMembers.add(member);
            } else {
                member.setRef(usersUrl + "/" + inum);
                member.setType(ScimResourceUtil.getType(UserResource.class));
                if (skipMembersValidation) {
                    // In overhead bypass mode, display names must not be returned
                    member.setDisplay(null);
                }
                listMembers.add(person.getDn());
            }
        }
        group.setMembers(listMembers);
        members.removeAll(invalidMembers);
        if (members.isEmpty()) {
            res.setMembers(null);
        }
    } else {
        group.setMembers(new ArrayList<>());
    }
}
Also used : GluuCustomPerson(io.jans.scim.model.GluuCustomPerson) ArrayList(java.util.ArrayList) UserResource(io.jans.scim.model.scim2.user.UserResource) Member(io.jans.scim.model.scim2.group.Member)

Aggregations

GroupResource (io.jans.scim.model.scim2.group.GroupResource)13 Response (javax.ws.rs.core.Response)13 URI (java.net.URI)6 InvalidAttributeValueException (javax.management.InvalidAttributeValueException)6 DefaultValue (javax.ws.rs.DefaultValue)6 HeaderParam (javax.ws.rs.HeaderParam)6 Path (javax.ws.rs.Path)6 Produces (javax.ws.rs.Produces)6 GroupResource (org.gluu.oxtrust.model.scim2.group.GroupResource)6 GluuGroup (io.jans.scim.model.GluuGroup)5 Member (io.jans.scim.model.scim2.group.Member)5 UserResource (io.jans.scim.model.scim2.user.UserResource)5 BaseScimResource (io.jans.scim.model.scim2.BaseScimResource)4 ArrayList (java.util.ArrayList)4 Consumes (javax.ws.rs.Consumes)4 WebApplicationException (javax.ws.rs.WebApplicationException)4 GluuGroup (org.gluu.oxtrust.model.GluuGroup)4 ListViewResponse (org.gluu.persist.model.ListViewResponse)4 ApiOperation (com.wordnik.swagger.annotations.ApiOperation)3 DuplicateEntryException (io.jans.orm.exception.operation.DuplicateEntryException)3