Search in sources :

Example 1 with UserPatch

use of org.apache.syncope.common.lib.patch.UserPatch in project syncope by apache.

the class UserSelfUpdateResource method newResourceResponse.

@Override
protected ResourceResponse newResourceResponse(final IResource.Attributes attributes) {
    ResourceResponse response = new AbstractResource.ResourceResponse();
    response.setContentType(MediaType.TEXT_PLAIN);
    try {
        HttpServletRequest request = (HttpServletRequest) attributes.getRequest().getContainerRequest();
        if (!xsrfCheck(request)) {
            LOG.error("XSRF TOKEN does not match");
            response.setError(Response.Status.BAD_REQUEST.getStatusCode(), "XSRF TOKEN does not match");
            return response;
        }
        if (!captchaCheck(request.getHeader("captcha"), request.getSession().getAttribute(SyncopeEnduserConstants.CAPTCHA_SESSION_KEY))) {
            throw new IllegalArgumentException("Entered captcha is not matching");
        }
        UserTO userTO = MAPPER.readValue(request.getReader().readLine(), UserTO.class);
        Map<String, CustomAttributesInfo> customForm = SyncopeEnduserApplication.get().getCustomForm();
        // check if request is compliant with customization form rules
        if (UserRequestValidator.compliant(userTO, customForm, false)) {
            // 1. membership attributes management
            Set<AttrTO> membAttrs = new HashSet<>();
            userTO.getPlainAttrs().stream().filter(attr -> (attr.getSchema().contains(SyncopeEnduserConstants.MEMBERSHIP_ATTR_SEPARATOR))).forEachOrdered((attr) -> {
                String[] simpleAttrs = attr.getSchema().split(SyncopeEnduserConstants.MEMBERSHIP_ATTR_SEPARATOR);
                MembershipTO membership = userTO.getMemberships().stream().filter(item -> simpleAttrs[0].equals(item.getGroupName())).findFirst().orElse(null);
                if (membership == null) {
                    membership = new MembershipTO.Builder().group(null, simpleAttrs[0]).build();
                    userTO.getMemberships().add(membership);
                }
                AttrTO clone = SerializationUtils.clone(attr);
                clone.setSchema(simpleAttrs[1]);
                membership.getPlainAttrs().add(clone);
                membAttrs.add(attr);
            });
            userTO.getPlainAttrs().removeAll(membAttrs);
            // 2. millis -> Date conversion for PLAIN attributes of USER and its MEMBERSHIPS
            SyncopeEnduserSession.get().getDatePlainSchemas().stream().map(plainSchema -> {
                millisToDate(userTO.getPlainAttrs(), plainSchema);
                return plainSchema;
            }).forEachOrdered(plainSchema -> {
                userTO.getMemberships().forEach(membership -> {
                    millisToDate(membership.getPlainAttrs(), plainSchema);
                });
            });
            membAttrs.clear();
            userTO.getDerAttrs().stream().filter(attr -> (attr.getSchema().contains(SyncopeEnduserConstants.MEMBERSHIP_ATTR_SEPARATOR))).forEachOrdered(attr -> {
                String[] simpleAttrs = attr.getSchema().split(SyncopeEnduserConstants.MEMBERSHIP_ATTR_SEPARATOR);
                MembershipTO membership = userTO.getMemberships().stream().filter(item -> simpleAttrs[0].equals(item.getGroupName())).findFirst().orElse(null);
                if (membership == null) {
                    membership = new MembershipTO.Builder().group(null, simpleAttrs[0]).build();
                    userTO.getMemberships().add(membership);
                }
                AttrTO clone = SerializationUtils.clone(attr);
                clone.setSchema(simpleAttrs[1]);
                membership.getDerAttrs().add(clone);
                membAttrs.add(attr);
            });
            userTO.getDerAttrs().removeAll(membAttrs);
            membAttrs.clear();
            userTO.getVirAttrs().stream().filter(attr -> (attr.getSchema().contains(SyncopeEnduserConstants.MEMBERSHIP_ATTR_SEPARATOR))).forEachOrdered((attr) -> {
                String[] simpleAttrs = attr.getSchema().split(SyncopeEnduserConstants.MEMBERSHIP_ATTR_SEPARATOR);
                MembershipTO membership = userTO.getMemberships().stream().filter(item -> simpleAttrs[0].equals(item.getGroupName())).findFirst().orElse(null);
                if (membership == null) {
                    membership = new MembershipTO.Builder().group(null, simpleAttrs[0]).build();
                    userTO.getMemberships().add(membership);
                }
                AttrTO clone = SerializationUtils.clone(attr);
                clone.setSchema(simpleAttrs[1]);
                membership.getVirAttrs().add(clone);
                membAttrs.add(attr);
            });
            userTO.getVirAttrs().removeAll(membAttrs);
            // get old user object from session
            UserTO selfTO = SyncopeEnduserSession.get().getSelfTO();
            // align "userTO" and "selfTO" objects
            if (customForm != null && !customForm.isEmpty()) {
                completeUserObject(userTO, selfTO);
            }
            // create diff patch
            UserPatch userPatch = AnyOperations.diff(userTO, selfTO, false);
            // update user by patch
            Response res = SyncopeEnduserSession.get().getService(userTO.getETagValue(), UserSelfService.class).update(userPatch);
            buildResponse(response, res.getStatus(), res.getStatusInfo().getFamily().equals(Response.Status.Family.SUCCESSFUL) ? "User [" + userTO.getUsername() + "] successfully updated" : "ErrorMessage{{ " + res.getStatusInfo().getReasonPhrase() + " }}");
        } else {
            LOG.warn("Incoming update request [{}] is not compliant with form customization rules." + " Update NOT allowed", userTO.getUsername());
            buildResponse(response, Response.Status.OK.getStatusCode(), "User: " + userTO.getUsername() + " successfully created");
        }
    } catch (final Exception e) {
        LOG.error("Error while updating user", e);
        response.setError(Response.Status.BAD_REQUEST.getStatusCode(), new StringBuilder().append("ErrorMessage{{ ").append(e.getMessage()).append(" }}").toString());
    }
    return response;
}
Also used : AttrTO(org.apache.syncope.common.lib.to.AttrTO) EntityTOUtils(org.apache.syncope.common.lib.EntityTOUtils) Set(java.util.Set) AbstractResource(org.apache.wicket.request.resource.AbstractResource) SerializationUtils(org.apache.commons.lang3.SerializationUtils) UserPatch(org.apache.syncope.common.lib.patch.UserPatch) UserSelfService(org.apache.syncope.common.rest.api.service.UserSelfService) HashSet(java.util.HashSet) HttpServletRequest(javax.servlet.http.HttpServletRequest) MediaType(javax.ws.rs.core.MediaType) SyncopeEnduserConstants(org.apache.syncope.client.enduser.SyncopeEnduserConstants) SyncopeEnduserSession(org.apache.syncope.client.enduser.SyncopeEnduserSession) IResource(org.apache.wicket.request.resource.IResource) Response(javax.ws.rs.core.Response) UserRequestValidator(org.apache.syncope.client.enduser.util.UserRequestValidator) Map(java.util.Map) Optional(java.util.Optional) SyncopeEnduserApplication(org.apache.syncope.client.enduser.SyncopeEnduserApplication) CustomAttributesInfo(org.apache.syncope.client.enduser.model.CustomAttributesInfo) Resource(org.apache.syncope.client.enduser.annotations.Resource) UserTO(org.apache.syncope.common.lib.to.UserTO) MembershipTO(org.apache.syncope.common.lib.to.MembershipTO) AnyOperations(org.apache.syncope.common.lib.AnyOperations) UserSelfService(org.apache.syncope.common.rest.api.service.UserSelfService) AttrTO(org.apache.syncope.common.lib.to.AttrTO) UserPatch(org.apache.syncope.common.lib.patch.UserPatch) HttpServletRequest(javax.servlet.http.HttpServletRequest) Response(javax.ws.rs.core.Response) UserTO(org.apache.syncope.common.lib.to.UserTO) MembershipTO(org.apache.syncope.common.lib.to.MembershipTO) CustomAttributesInfo(org.apache.syncope.client.enduser.model.CustomAttributesInfo) HashSet(java.util.HashSet)

Example 2 with UserPatch

use of org.apache.syncope.common.lib.patch.UserPatch in project syncope by apache.

the class AnyOperations method patch.

public static UserTO patch(final UserTO userTO, final UserPatch userPatch) {
    UserTO result = SerializationUtils.clone(userTO);
    patch(userTO, userPatch, result);
    // 1. password
    if (userPatch.getPassword() != null) {
        result.setPassword(userPatch.getPassword().getValue());
    }
    // 2. username
    if (userPatch.getUsername() != null) {
        result.setUsername(userPatch.getUsername().getValue());
    }
    // 3. relationships
    userPatch.getRelationships().forEach(relPatch -> {
        if (relPatch.getRelationshipTO() == null) {
            LOG.warn("Invalid {} specified: {}", RelationshipPatch.class.getName(), relPatch);
        } else {
            result.getRelationships().remove(relPatch.getRelationshipTO());
            if (relPatch.getOperation() == PatchOperation.ADD_REPLACE) {
                result.getRelationships().add(relPatch.getRelationshipTO());
            }
        }
    });
    // 4. memberships
    userPatch.getMemberships().forEach(membPatch -> {
        if (membPatch.getGroup() == null) {
            LOG.warn("Invalid {} specified: {}", MembershipPatch.class.getName(), membPatch);
        } else {
            Optional<MembershipTO> memb = result.getMemberships().stream().filter(membership -> membPatch.getGroup().equals(membership.getGroupKey())).findFirst();
            if (memb.isPresent()) {
                result.getMemberships().remove(memb.get());
            }
            if (membPatch.getOperation() == PatchOperation.ADD_REPLACE) {
                MembershipTO newMembershipTO = new MembershipTO.Builder().group(membPatch.getGroup()).build();
                // 3. plain attributes
                newMembershipTO.getPlainAttrs().addAll(membPatch.getPlainAttrs());
                // 4. virtual attributes
                newMembershipTO.getVirAttrs().addAll(membPatch.getVirAttrs());
                result.getMemberships().add(newMembershipTO);
            }
        }
    });
    // 5. roles
    for (StringPatchItem rolePatch : userPatch.getRoles()) {
        switch(rolePatch.getOperation()) {
            case ADD_REPLACE:
                result.getRoles().add(rolePatch.getValue());
                break;
            case DELETE:
            default:
                result.getRoles().remove(rolePatch.getValue());
        }
    }
    return result;
}
Also used : StringPatchItem(org.apache.syncope.common.lib.patch.StringPatchItem) AttrTO(org.apache.syncope.common.lib.to.AttrTO) AnyObjectPatch(org.apache.syncope.common.lib.patch.AnyObjectPatch) LoggerFactory(org.slf4j.LoggerFactory) AnyTO(org.apache.syncope.common.lib.to.AnyTO) HashMap(java.util.HashMap) SerializationUtils(org.apache.commons.lang3.SerializationUtils) BooleanReplacePatchItem(org.apache.syncope.common.lib.patch.BooleanReplacePatchItem) UserPatch(org.apache.syncope.common.lib.patch.UserPatch) RelationshipPatch(org.apache.syncope.common.lib.patch.RelationshipPatch) StringUtils(org.apache.commons.lang3.StringUtils) GroupPatch(org.apache.syncope.common.lib.patch.GroupPatch) MembershipPatch(org.apache.syncope.common.lib.patch.MembershipPatch) Pair(org.apache.commons.lang3.tuple.Pair) Map(java.util.Map) AbstractReplacePatchItem(org.apache.syncope.common.lib.patch.AbstractReplacePatchItem) MembershipTO(org.apache.syncope.common.lib.to.MembershipTO) AnyPatch(org.apache.syncope.common.lib.patch.AnyPatch) Logger(org.slf4j.Logger) Collection(java.util.Collection) Set(java.util.Set) GroupTO(org.apache.syncope.common.lib.to.GroupTO) AttrPatch(org.apache.syncope.common.lib.patch.AttrPatch) PasswordPatch(org.apache.syncope.common.lib.patch.PasswordPatch) RelationshipTO(org.apache.syncope.common.lib.to.RelationshipTO) PatchOperation(org.apache.syncope.common.lib.types.PatchOperation) Optional(java.util.Optional) StringReplacePatchItem(org.apache.syncope.common.lib.patch.StringReplacePatchItem) UserTO(org.apache.syncope.common.lib.to.UserTO) AnyObjectTO(org.apache.syncope.common.lib.to.AnyObjectTO) MembershipPatch(org.apache.syncope.common.lib.patch.MembershipPatch) UserTO(org.apache.syncope.common.lib.to.UserTO) MembershipTO(org.apache.syncope.common.lib.to.MembershipTO) StringPatchItem(org.apache.syncope.common.lib.patch.StringPatchItem) RelationshipPatch(org.apache.syncope.common.lib.patch.RelationshipPatch)

Example 3 with UserPatch

use of org.apache.syncope.common.lib.patch.UserPatch in project syncope by apache.

the class AnyOperations method diff.

/**
 * Calculate modifications needed by first in order to be equal to second.
 *
 * @param updated updated UserTO
 * @param original original UserTO
 * @param incremental perform incremental diff (without removing existing info)
 * @return UserPatch containing differences
 */
public static UserPatch diff(final UserTO updated, final UserTO original, final boolean incremental) {
    UserPatch result = new UserPatch();
    diff(updated, original, result, incremental);
    // 1. password
    if (updated.getPassword() != null && (original.getPassword() == null || !original.getPassword().equals(updated.getPassword()))) {
        result.setPassword(new PasswordPatch.Builder().value(updated.getPassword()).resources(updated.getResources()).build());
    }
    // 2. username
    result.setUsername(replacePatchItem(updated.getUsername(), original.getUsername(), new StringReplacePatchItem()));
    // 3. security question / answer
    if (updated.getSecurityQuestion() == null) {
        result.setSecurityQuestion(null);
        result.setSecurityAnswer(null);
    } else if (!updated.getSecurityQuestion().equals(original.getSecurityQuestion()) || StringUtils.isNotBlank(updated.getSecurityAnswer())) {
        result.setSecurityQuestion(new StringReplacePatchItem.Builder().value(updated.getSecurityQuestion()).build());
        result.setSecurityAnswer(new StringReplacePatchItem.Builder().value(updated.getSecurityAnswer()).build());
    }
    result.setMustChangePassword(replacePatchItem(updated.isMustChangePassword(), original.isMustChangePassword(), new BooleanReplacePatchItem()));
    // 4. roles
    if (!incremental) {
        original.getRoles().stream().filter(role -> !updated.getRoles().contains(role)).forEach(toRemove -> {
            result.getRoles().add(new StringPatchItem.Builder().operation(PatchOperation.DELETE).value(toRemove).build());
        });
    }
    updated.getRoles().stream().filter(role -> !original.getRoles().contains(role)).forEach(toAdd -> {
        result.getRoles().add(new StringPatchItem.Builder().operation(PatchOperation.ADD_REPLACE).value(toAdd).build());
    });
    // 5. relationships
    Map<Pair<String, String>, RelationshipTO> updatedRels = EntityTOUtils.buildRelationshipMap(updated.getRelationships());
    Map<Pair<String, String>, RelationshipTO> originalRels = EntityTOUtils.buildRelationshipMap(original.getRelationships());
    updatedRels.entrySet().stream().filter(entry -> (!originalRels.containsKey(entry.getKey()))).forEachOrdered(entry -> {
        result.getRelationships().add(new RelationshipPatch.Builder().operation(PatchOperation.ADD_REPLACE).relationshipTO(entry.getValue()).build());
    });
    if (!incremental) {
        originalRels.keySet().stream().filter(relationship -> !updatedRels.containsKey(relationship)).forEach(key -> {
            result.getRelationships().add(new RelationshipPatch.Builder().operation(PatchOperation.DELETE).relationshipTO(originalRels.get(key)).build());
        });
    }
    // 6. memberships
    Map<String, MembershipTO> updatedMembs = EntityTOUtils.buildMembershipMap(updated.getMemberships());
    Map<String, MembershipTO> originalMembs = EntityTOUtils.buildMembershipMap(original.getMemberships());
    updatedMembs.entrySet().stream().map(entry -> {
        MembershipPatch membershipPatch = new MembershipPatch.Builder().operation(PatchOperation.ADD_REPLACE).group(entry.getValue().getGroupKey()).build();
        MembershipTO omemb;
        if (originalMembs.containsKey(entry.getKey())) {
            // get the original membership
            omemb = originalMembs.get(entry.getKey());
        } else {
            // create an empty one to generate the patch
            omemb = new MembershipTO.Builder().group(entry.getKey()).build();
        }
        diff(entry.getValue(), omemb, membershipPatch, incremental);
        return membershipPatch;
    }).forEachOrdered(membershipPatch -> {
        result.getMemberships().add(membershipPatch);
    });
    if (!incremental) {
        originalMembs.keySet().stream().filter(membership -> !updatedMembs.containsKey(membership)).forEach(key -> {
            result.getMemberships().add(new MembershipPatch.Builder().operation(PatchOperation.DELETE).group(originalMembs.get(key).getGroupKey()).build());
        });
    }
    return result;
}
Also used : StringPatchItem(org.apache.syncope.common.lib.patch.StringPatchItem) AttrTO(org.apache.syncope.common.lib.to.AttrTO) AnyObjectPatch(org.apache.syncope.common.lib.patch.AnyObjectPatch) LoggerFactory(org.slf4j.LoggerFactory) AnyTO(org.apache.syncope.common.lib.to.AnyTO) HashMap(java.util.HashMap) SerializationUtils(org.apache.commons.lang3.SerializationUtils) BooleanReplacePatchItem(org.apache.syncope.common.lib.patch.BooleanReplacePatchItem) UserPatch(org.apache.syncope.common.lib.patch.UserPatch) RelationshipPatch(org.apache.syncope.common.lib.patch.RelationshipPatch) StringUtils(org.apache.commons.lang3.StringUtils) GroupPatch(org.apache.syncope.common.lib.patch.GroupPatch) MembershipPatch(org.apache.syncope.common.lib.patch.MembershipPatch) Pair(org.apache.commons.lang3.tuple.Pair) Map(java.util.Map) AbstractReplacePatchItem(org.apache.syncope.common.lib.patch.AbstractReplacePatchItem) MembershipTO(org.apache.syncope.common.lib.to.MembershipTO) AnyPatch(org.apache.syncope.common.lib.patch.AnyPatch) Logger(org.slf4j.Logger) Collection(java.util.Collection) Set(java.util.Set) GroupTO(org.apache.syncope.common.lib.to.GroupTO) AttrPatch(org.apache.syncope.common.lib.patch.AttrPatch) PasswordPatch(org.apache.syncope.common.lib.patch.PasswordPatch) RelationshipTO(org.apache.syncope.common.lib.to.RelationshipTO) PatchOperation(org.apache.syncope.common.lib.types.PatchOperation) Optional(java.util.Optional) StringReplacePatchItem(org.apache.syncope.common.lib.patch.StringReplacePatchItem) UserTO(org.apache.syncope.common.lib.to.UserTO) AnyObjectTO(org.apache.syncope.common.lib.to.AnyObjectTO) MembershipPatch(org.apache.syncope.common.lib.patch.MembershipPatch) StringReplacePatchItem(org.apache.syncope.common.lib.patch.StringReplacePatchItem) RelationshipTO(org.apache.syncope.common.lib.to.RelationshipTO) MembershipTO(org.apache.syncope.common.lib.to.MembershipTO) BooleanReplacePatchItem(org.apache.syncope.common.lib.patch.BooleanReplacePatchItem) UserPatch(org.apache.syncope.common.lib.patch.UserPatch) Pair(org.apache.commons.lang3.tuple.Pair)

Example 4 with UserPatch

use of org.apache.syncope.common.lib.patch.UserPatch in project syncope by apache.

the class FlowableUserWorkflowAdapter method doConfirmPasswordReset.

@Override
protected WorkflowResult<Pair<UserPatch, Boolean>> doConfirmPasswordReset(final User user, final String token, final String password) {
    Map<String, Object> variables = new HashMap<>(4);
    variables.put(TOKEN, token);
    variables.put(PASSWORD, password);
    variables.put(USER_TO, dataBinder.getUserTO(user, true));
    variables.put(EVENT, "confirmPasswordReset");
    Set<String> tasks = doExecuteTask(user, "confirmPasswordReset", variables);
    userDAO.save(user);
    PropagationByResource propByRes = engine.getRuntimeService().getVariable(user.getWorkflowId(), PROP_BY_RESOURCE, PropagationByResource.class);
    UserPatch updatedPatch = engine.getRuntimeService().getVariable(user.getWorkflowId(), USER_PATCH, UserPatch.class);
    Boolean propagateEnable = engine.getRuntimeService().getVariable(user.getWorkflowId(), PROPAGATE_ENABLE, Boolean.class);
    return new WorkflowResult<>(Pair.of(updatedPatch, propagateEnable), propByRes, tasks);
}
Also used : WorkflowResult(org.apache.syncope.core.provisioning.api.WorkflowResult) HashMap(java.util.HashMap) PropagationByResource(org.apache.syncope.core.provisioning.api.PropagationByResource) UserPatch(org.apache.syncope.common.lib.patch.UserPatch)

Example 5 with UserPatch

use of org.apache.syncope.common.lib.patch.UserPatch in project syncope by apache.

the class Update method doExecute.

@Override
protected void doExecute(final String executionId) {
    User user = engine.getRuntimeService().getVariable(executionId, FlowableUserWorkflowAdapter.USER, User.class);
    UserPatch userPatch = engine.getRuntimeService().getVariable(executionId, FlowableUserWorkflowAdapter.USER_PATCH, UserPatch.class);
    user = userDAO.save(user);
    UserTO original = dataBinder.getUserTO(user, true);
    PropagationByResource propByRes = dataBinder.update(user, userPatch);
    PasswordPatch password = userPatch.getPassword();
    Set<AttrTO> virAttrs = userPatch.getVirAttrs();
    UserTO updated = dataBinder.getUserTO(user.getKey());
    userPatch = AnyOperations.diff(updated, original, false);
    userPatch.setPassword(password);
    userPatch.getVirAttrs().clear();
    userPatch.getVirAttrs().addAll(virAttrs);
    // report updated user and propagation by resource as result
    engine.getRuntimeService().setVariable(executionId, FlowableUserWorkflowAdapter.USER, user);
    engine.getRuntimeService().setVariable(executionId, FlowableUserWorkflowAdapter.USER_TO, updated);
    engine.getRuntimeService().setVariable(executionId, FlowableUserWorkflowAdapter.USER_PATCH, userPatch);
    engine.getRuntimeService().setVariable(executionId, FlowableUserWorkflowAdapter.PROP_BY_RESOURCE, propByRes);
}
Also used : User(org.apache.syncope.core.persistence.api.entity.user.User) PasswordPatch(org.apache.syncope.common.lib.patch.PasswordPatch) UserTO(org.apache.syncope.common.lib.to.UserTO) AttrTO(org.apache.syncope.common.lib.to.AttrTO) PropagationByResource(org.apache.syncope.core.provisioning.api.PropagationByResource) UserPatch(org.apache.syncope.common.lib.patch.UserPatch)

Aggregations

UserPatch (org.apache.syncope.common.lib.patch.UserPatch)102 UserTO (org.apache.syncope.common.lib.to.UserTO)73 Test (org.junit.jupiter.api.Test)59 PasswordPatch (org.apache.syncope.common.lib.patch.PasswordPatch)37 SyncopeClientException (org.apache.syncope.common.lib.SyncopeClientException)18 AttrTO (org.apache.syncope.common.lib.to.AttrTO)17 MembershipTO (org.apache.syncope.common.lib.to.MembershipTO)17 Response (javax.ws.rs.core.Response)16 Map (java.util.Map)12 StringReplacePatchItem (org.apache.syncope.common.lib.patch.StringReplacePatchItem)12 ConnObjectTO (org.apache.syncope.common.lib.to.ConnObjectTO)11 GroupTO (org.apache.syncope.common.lib.to.GroupTO)11 PropagationByResource (org.apache.syncope.core.provisioning.api.PropagationByResource)11 WorkflowResult (org.apache.syncope.core.provisioning.api.WorkflowResult)11 JdbcTemplate (org.springframework.jdbc.core.JdbcTemplate)11 GenericType (javax.ws.rs.core.GenericType)10 Pair (org.apache.commons.lang3.tuple.Pair)10 PatchOperation (org.apache.syncope.common.lib.types.PatchOperation)10 List (java.util.List)9 AttrPatch (org.apache.syncope.common.lib.patch.AttrPatch)9