Repository: syncope Updated Branches: refs/heads/master e98d2b252 -> 36ad4ace0
[SYNCOPE-710] Reworking password propagation request and virtual attributes management Project: http://git-wip-us.apache.org/repos/asf/syncope/repo Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/2524280e Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/2524280e Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/2524280e Branch: refs/heads/master Commit: 2524280ebeaff46bc351f4692fb4f966148bc87e Parents: 91cb526 Author: Francesco Chicchiriccò <[email protected]> Authored: Wed Oct 14 17:39:02 2015 +0200 Committer: Francesco Chicchiriccò <[email protected]> Committed: Wed Oct 14 17:39:02 2015 +0200 ---------------------------------------------------------------------- .../propagation/impl/PropagationManager.java | 47 ++-------- .../core/rest/controller/UserController.java | 93 +++++++++----------- .../syncope/core/rest/data/UserDataBinder.java | 15 ++-- .../user/AbstractUserWorkflowAdapter.java | 9 +- .../workflow/user/NoOpUserWorkflowAdapter.java | 28 +++--- .../core/workflow/user/UserWorkflowAdapter.java | 3 +- .../activiti/ActivitiUserWorkflowAdapter.java | 18 +++- .../user/activiti/task/PasswordReset.java | 25 +++++- .../workflow/user/activiti/task/Update.java | 13 +-- .../syncope/core/rest/UserTestITCase.java | 40 +++++++++ .../syncope/core/rest/VirAttrTestITCase.java | 9 +- 11 files changed, 167 insertions(+), 133 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/syncope/blob/2524280e/core/src/main/java/org/apache/syncope/core/propagation/impl/PropagationManager.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/syncope/core/propagation/impl/PropagationManager.java b/core/src/main/java/org/apache/syncope/core/propagation/impl/PropagationManager.java index eddbbb4..166017a 100644 --- a/core/src/main/java/org/apache/syncope/core/propagation/impl/PropagationManager.java +++ b/core/src/main/java/org/apache/syncope/core/propagation/impl/PropagationManager.java @@ -248,31 +248,6 @@ public class PropagationManager { } /** - * Performs update on each resource associated to the user excluding the specified into 'resourceNames' parameter. - * - * @param user to be propagated - * @param enable whether user must be enabled or not - * @param noPropResourceNames external resource names not to be considered for propagation - * @return list of propagation tasks - * @throws NotFoundException if user is not found - */ - public List<PropagationTask> getUserUpdateTaskIds(final SyncopeUser user, final Boolean enable, - final Set<String> noPropResourceNames) - throws NotFoundException { - - return getUpdateTaskIds( - user, // SyncopeUser to be updated on external resources - null, // no password - false, - enable, // status to be propagated - Collections.<String>emptySet(), // no virtual attributes to be managed - Collections.<AttributeMod>emptySet(), // no virtual attributes to be managed - null, // no propagation by resources - noPropResourceNames, - Collections.<MembershipMod>emptySet()); - } - - /** * Performs update on each resource associated to the user. * * @param wfResult user to be propagated (and info associated), as per result from workflow @@ -388,8 +363,12 @@ public class PropagationManager { PropagationByResource localPropByRes = binder.fillVirtual(subject, vAttrsToBeRemoved == null ? Collections.<String>emptySet() : vAttrsToBeRemoved, vAttrsToBeUpdated == null - ? Collections.<AttributeMod>emptySet() - : vAttrsToBeUpdated, AttributableUtil.getInstance(subject)); + ? Collections.<AttributeMod>emptySet() + : vAttrsToBeUpdated, AttributableUtil.getInstance(subject)); + localPropByRes.merge(propByRes); + if (noPropResourceNames != null) { + localPropByRes.removeAll(noPropResourceNames); + } // SYNCOPE-458 fill membership virtual attributes if (subject instanceof SyncopeUser) { @@ -402,23 +381,13 @@ public class PropagationManager { ? Collections.<String>emptySet() : membershipMod.getVirAttrsToRemove(), membershipMod.getVirAttrsToUpdate() == null ? Collections.<AttributeMod>emptySet() - : membershipMod.getVirAttrsToUpdate(), AttributableUtil.getInstance( - AttributableType.MEMBERSHIP)); + : membershipMod.getVirAttrsToUpdate(), AttributableUtil.getInstance( + AttributableType.MEMBERSHIP)); } } } } - if (propByRes == null || propByRes.isEmpty()) { - localPropByRes.addAll(ResourceOperation.UPDATE, subject.getResourceNames()); - } else { - localPropByRes.merge(propByRes); - } - - if (noPropResourceNames != null) { - localPropByRes.removeAll(noPropResourceNames); - } - Map<String, AttributeMod> vAttrsToBeUpdatedMap = null; if (vAttrsToBeUpdated != null) { vAttrsToBeUpdatedMap = new HashMap<String, AttributeMod>(); http://git-wip-us.apache.org/repos/asf/syncope/blob/2524280e/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java b/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java index 68843a7..93a6859 100644 --- a/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java +++ b/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java @@ -20,7 +20,6 @@ package org.apache.syncope.core.rest.controller; import java.lang.reflect.Method; import java.security.AccessControlException; -import java.util.AbstractMap; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -41,6 +40,7 @@ import org.apache.syncope.common.types.ClientExceptionType; import org.apache.syncope.common.SyncopeClientException; import org.apache.syncope.common.mod.AttributeMod; import org.apache.syncope.common.mod.MembershipMod; +import org.apache.syncope.common.types.ResourceOperation; import org.apache.syncope.common.types.SubjectType; import org.apache.syncope.core.persistence.beans.PropagationTask; import org.apache.syncope.core.persistence.beans.role.SyncopeRole; @@ -258,54 +258,44 @@ public class UserController extends AbstractSubjectController<UserTO, UserMod> { UserMod actual = attrTransformer.transform(userMod); LOG.debug("Transformed: {}", actual); - // SYNCOPE-501: check if there are memberships to be removed with virtual attributes assigned - boolean removeMemberships = false; + PropagationByResource propByResVirAttr = new PropagationByResource(); for (Long membershipId : actual.getMembershipsToRemove()) { - if (!binder.fillMembershipVirtual( + propByResVirAttr.merge(binder.fillMembershipVirtual( null, null, membershipId, Collections.<String>emptySet(), Collections.<AttributeMod>emptySet(), - true).isEmpty()) { - - removeMemberships = true; - } + true)); } // Actual operations: workflow, propagation, notification WorkflowResult<Map.Entry<UserMod, Boolean>> updated = uwfAdapter.update(actual); - List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds(updated); - if (tasks.isEmpty()) { - // SYNCOPE-459: take care of user virtual attributes ... - PropagationByResource propByResVirAttr = binder.fillVirtual( + // SYNCOPE-459: take care of user virtual attributes ... + propByResVirAttr.merge(binder.fillVirtual( + updated.getResult().getKey().getId(), + actual.getVirAttrsToRemove(), + actual.getVirAttrsToUpdate())); + for (MembershipMod membershipMod : actual.getMembershipsToAdd()) { + propByResVirAttr.merge(binder.fillMembershipVirtual( updated.getResult().getKey().getId(), - actual.getVirAttrsToRemove(), - actual.getVirAttrsToUpdate()); - // SYNCOPE-501: update only virtual attributes (if any of them changed), password propagation is - // not required, take care also of membership virtual attributes - boolean addOrUpdateMemberships = false; - for (MembershipMod membershipMod : actual.getMembershipsToAdd()) { - if (!binder.fillMembershipVirtual( - updated.getResult().getKey().getId(), - membershipMod.getRole(), - null, - membershipMod.getVirAttrsToRemove(), - membershipMod.getVirAttrsToUpdate(), - false).isEmpty()) { - - addOrUpdateMemberships = true; - } - } - tasks.addAll(!propByResVirAttr.isEmpty() || addOrUpdateMemberships || removeMemberships - ? propagationManager.getUserUpdateTaskIds(updated, false, null) - : Collections.<PropagationTask>emptyList()); + membershipMod.getRole(), + null, + membershipMod.getVirAttrsToRemove(), + membershipMod.getVirAttrsToUpdate(), + false)); + } + if (updated.getPropByRes() == null) { + updated.setPropByRes(propByResVirAttr); + } else { + updated.getPropByRes().merge(propByResVirAttr); } + List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds(updated); + PropagationReporter propagationReporter = ApplicationContextProvider.getApplicationContext(). getBean(PropagationReporter.class); - if (!tasks.isEmpty()) { try { taskExecutor.execute(tasks, propagationReporter); @@ -347,19 +337,22 @@ public class UserController extends AbstractSubjectController<UserTO, UserMod> { public UserTO status(final StatusMod statusMod) { SyncopeUser user = binder.getUserFromId(statusMod.getId()); - WorkflowResult<Long> updated; if (statusMod.isOnSyncope()) { - updated = setStatusOnWfAdapter(user, statusMod); - } else { - updated = new WorkflowResult<Long>(user.getId(), null, statusMod.getType().name().toLowerCase()); + setStatusOnWfAdapter(user, statusMod); } - // Resources to exclude from propagation - Set<String> resourcesToBeExcluded = new HashSet<String>(user.getResourceNames()); - resourcesToBeExcluded.removeAll(statusMod.getResourceNames()); - - List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds( - user, statusMod.getType() != StatusMod.ModType.SUSPEND, resourcesToBeExcluded); + PropagationByResource propByRes = new PropagationByResource(); + propByRes.addAll(ResourceOperation.UPDATE, statusMod.getResourceNames()); + List<PropagationTask> tasks = propagationManager.getUpdateTaskIds( + user, // SyncopeUser to be updated on external resources + null, // no password + false, + statusMod.getType() != StatusMod.ModType.SUSPEND, // status to be propagated + Collections.<String>emptySet(), // no virtual attributes to be managed + Collections.<AttributeMod>emptySet(), // no virtual attributes to be managed + propByRes, + null, + Collections.<MembershipMod>emptySet()); PropagationReporter propReporter = ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class); try { @@ -369,7 +362,7 @@ public class UserController extends AbstractSubjectController<UserTO, UserMod> { propReporter.onPrimaryResourceFailure(tasks); } - final UserTO savedTO = binder.getUserTO(updated.getResult()); + final UserTO savedTO = binder.getUserTO(user.getId()); savedTO.getPropagationStatusTOs().addAll(propReporter.getStatuses()); return savedTO; } @@ -403,16 +396,10 @@ public class UserController extends AbstractSubjectController<UserTO, UserMod> { throw new NotFoundException("User with token " + token); } - uwfAdapter.confirmPasswordReset(user.getId(), token, password); + WorkflowResult<Map.Entry<UserMod, Boolean>> updated = + uwfAdapter.confirmPasswordReset(user.getId(), token, password); - UserMod userMod = new UserMod(); - userMod.setId(user.getId()); - userMod.setPassword(password); - - List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds( - new WorkflowResult<Map.Entry<UserMod, Boolean>>( - new AbstractMap.SimpleEntry<UserMod, Boolean>(userMod, null), null, "confirmPasswordReset"), - true, null); + List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds(updated); PropagationReporter propReporter = ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class); try { http://git-wip-us.apache.org/repos/asf/syncope/blob/2524280e/core/src/main/java/org/apache/syncope/core/rest/data/UserDataBinder.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/syncope/core/rest/data/UserDataBinder.java b/core/src/main/java/org/apache/syncope/core/rest/data/UserDataBinder.java index fcd67c2..89752aa 100644 --- a/core/src/main/java/org/apache/syncope/core/rest/data/UserDataBinder.java +++ b/core/src/main/java/org/apache/syncope/core/rest/data/UserDataBinder.java @@ -272,16 +272,21 @@ public class UserDataBinder extends AbstractAttributableDataBinder { // password if (StringUtils.isNotBlank(userMod.getPassword())) { - setPassword(user, userMod.getPassword(), scce); - user.setChangePwdDate(new Date()); - propByRes.addAll(ResourceOperation.UPDATE, currentResources); + if (userMod.getPwdPropRequest() == null || userMod.getPwdPropRequest().isOnSyncope()) { + setPassword(user, userMod.getPassword(), scce); + user.setChangePwdDate(new Date()); + } + if (userMod.getPwdPropRequest() == null) { + propByRes.addAll(ResourceOperation.UPDATE, currentResources); + } else { + propByRes.addAll(ResourceOperation.UPDATE, userMod.getPwdPropRequest().getResourceNames()); + } } // username if (userMod.getUsername() != null && !userMod.getUsername().equals(user.getUsername())) { - propByRes.addAll(ResourceOperation.UPDATE, currentResources); - user.setUsername(userMod.getUsername()); + propByRes.addAll(ResourceOperation.UPDATE, currentResources); } // security question / answer: http://git-wip-us.apache.org/repos/asf/syncope/blob/2524280e/core/src/main/java/org/apache/syncope/core/workflow/user/AbstractUserWorkflowAdapter.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/syncope/core/workflow/user/AbstractUserWorkflowAdapter.java b/core/src/main/java/org/apache/syncope/core/workflow/user/AbstractUserWorkflowAdapter.java index 9425f17..b3e1b0b 100644 --- a/core/src/main/java/org/apache/syncope/core/workflow/user/AbstractUserWorkflowAdapter.java +++ b/core/src/main/java/org/apache/syncope/core/workflow/user/AbstractUserWorkflowAdapter.java @@ -126,14 +126,15 @@ public abstract class AbstractUserWorkflowAdapter implements UserWorkflowAdapter doRequestPasswordReset(dataBinder.getUserFromId(userId)); } - protected abstract void doConfirmPasswordReset(SyncopeUser user, String token, String password) - throws WorkflowException; + protected abstract WorkflowResult<Map.Entry<UserMod, Boolean>> doConfirmPasswordReset( + SyncopeUser user, String token, String password) throws WorkflowException; @Override - public void confirmPasswordReset(final Long userId, final String token, final String password) + public WorkflowResult<Map.Entry<UserMod, Boolean>> confirmPasswordReset( + final Long userId, final String token, final String password) throws UnauthorizedRoleException, WorkflowException { - doConfirmPasswordReset(dataBinder.getUserFromId(userId), token, password); + return doConfirmPasswordReset(dataBinder.getUserFromId(userId), token, password); } protected abstract void doDelete(SyncopeUser user) throws WorkflowException; http://git-wip-us.apache.org/repos/asf/syncope/blob/2524280e/core/src/main/java/org/apache/syncope/core/workflow/user/NoOpUserWorkflowAdapter.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/syncope/core/workflow/user/NoOpUserWorkflowAdapter.java b/core/src/main/java/org/apache/syncope/core/workflow/user/NoOpUserWorkflowAdapter.java index 1ffc4c7..83924e4 100644 --- a/core/src/main/java/org/apache/syncope/core/workflow/user/NoOpUserWorkflowAdapter.java +++ b/core/src/main/java/org/apache/syncope/core/workflow/user/NoOpUserWorkflowAdapter.java @@ -24,7 +24,7 @@ import java.util.AbstractMap.SimpleEntry; import java.util.Collections; import java.util.List; import java.util.Map; -import org.apache.commons.lang3.SerializationUtils; +import org.apache.syncope.common.mod.StatusMod; import org.apache.syncope.common.mod.UserMod; import org.apache.syncope.common.to.UserTO; import org.apache.syncope.common.to.WorkflowFormTO; @@ -115,13 +115,7 @@ public class NoOpUserWorkflowAdapter extends AbstractUserWorkflowAdapter { protected WorkflowResult<Map.Entry<UserMod, Boolean>> doUpdate(final SyncopeUser user, final UserMod userMod) throws WorkflowException { - // update password internally only if required - UserMod actualMod = SerializationUtils.clone(userMod); - if (actualMod.getPwdPropRequest() != null && !actualMod.getPwdPropRequest().isOnSyncope()) { - actualMod.setPassword(null); - } - // update SyncopeUser - PropagationByResource propByRes = dataBinder.update(user, actualMod); + PropagationByResource propByRes = dataBinder.update(user, userMod); SyncopeUser updated = userDAO.save(user); @@ -155,16 +149,26 @@ public class NoOpUserWorkflowAdapter extends AbstractUserWorkflowAdapter { } @Override - protected void doConfirmPasswordReset(final SyncopeUser user, final String token, final String password) - throws WorkflowException { + protected WorkflowResult<Map.Entry<UserMod, Boolean>> doConfirmPasswordReset( + final SyncopeUser user, final String token, final String password) throws WorkflowException { if (!user.checkToken(token)) { throw new WorkflowException(new IllegalArgumentException("Wrong token: " + token + " for " + user)); } user.removeToken(); - user.setPassword(password, user.getCipherAlgorithm()); - userDAO.save(user); + + UserMod userMod = new UserMod(); + userMod.setId(user.getId()); + userMod.setPassword(password); + StatusMod pwdPropRequest = new StatusMod(); + + pwdPropRequest.setId(user.getId()); + pwdPropRequest.setOnSyncope(true); + pwdPropRequest.getResourceNames().addAll(user.getResourceNames()); + userMod.setPwdPropRequest(pwdPropRequest); + + return doUpdate(user, userMod); } @Override http://git-wip-us.apache.org/repos/asf/syncope/blob/2524280e/core/src/main/java/org/apache/syncope/core/workflow/user/UserWorkflowAdapter.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/syncope/core/workflow/user/UserWorkflowAdapter.java b/core/src/main/java/org/apache/syncope/core/workflow/user/UserWorkflowAdapter.java index c2844db..955e8fc 100644 --- a/core/src/main/java/org/apache/syncope/core/workflow/user/UserWorkflowAdapter.java +++ b/core/src/main/java/org/apache/syncope/core/workflow/user/UserWorkflowAdapter.java @@ -151,8 +151,9 @@ public interface UserWorkflowAdapter extends WorkflowAdapter { * @param password new password value * @throws UnauthorizedRoleException authorization exception * @throws WorkflowException workflow exception + * @return user just updated and propagations to be performed */ - void confirmPasswordReset(Long userId, String token, String password) + WorkflowResult<Map.Entry<UserMod, Boolean>> confirmPasswordReset(Long userId, String token, String password) throws UnauthorizedRoleException, WorkflowException; /** http://git-wip-us.apache.org/repos/asf/syncope/blob/2524280e/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/ActivitiUserWorkflowAdapter.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/ActivitiUserWorkflowAdapter.java b/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/ActivitiUserWorkflowAdapter.java index f974267..08a1d91 100644 --- a/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/ActivitiUserWorkflowAdapter.java +++ b/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/ActivitiUserWorkflowAdapter.java @@ -401,8 +401,8 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter { } @Override - protected void doConfirmPasswordReset(final SyncopeUser user, final String token, final String password) - throws WorkflowException { + protected WorkflowResult<Map.Entry<UserMod, Boolean>> doConfirmPasswordReset( + final SyncopeUser user, final String token, final String password) throws WorkflowException { Map<String, Object> variables = new HashMap<String, Object>(4); variables.put(TOKEN, token); @@ -410,8 +410,20 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter { variables.put(USER_TO, userDataBinder.getUserTO(user, true)); variables.put(EVENT, "confirmPasswordReset"); - doExecuteTask(user, "confirmPasswordReset", variables); + Set<String> tasks = doExecuteTask(user, "confirmPasswordReset", variables); + userDAO.save(user); + + PropagationByResource propByRes = + runtimeService.getVariable(user.getWorkflowId(), PROP_BY_RESOURCE, PropagationByResource.class); + UserMod userMod = + runtimeService.getVariable(user.getWorkflowId(), USER_MOD, UserMod.class); + + Boolean propagateEnable = runtimeService.getVariable(user.getWorkflowId(), PROPAGATE_ENABLE, Boolean.class); + + return new WorkflowResult<Map.Entry<UserMod, Boolean>>( + new SimpleEntry<UserMod, Boolean>(userMod, propagateEnable), propByRes, tasks); + } @Override http://git-wip-us.apache.org/repos/asf/syncope/blob/2524280e/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/PasswordReset.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/PasswordReset.java b/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/PasswordReset.java index e9d59a3..0e9e982 100644 --- a/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/PasswordReset.java +++ b/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/PasswordReset.java @@ -18,14 +18,22 @@ */ package org.apache.syncope.core.workflow.user.activiti.task; +import org.apache.syncope.common.mod.StatusMod; +import org.apache.syncope.common.mod.UserMod; import org.apache.syncope.core.persistence.beans.user.SyncopeUser; +import org.apache.syncope.core.propagation.PropagationByResource; +import org.apache.syncope.core.rest.data.UserDataBinder; import org.apache.syncope.core.workflow.WorkflowException; import org.apache.syncope.core.workflow.user.activiti.ActivitiUserWorkflowAdapter; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class PasswordReset extends AbstractActivitiServiceTask { + @Autowired + private UserDataBinder dataBinder; + @Override protected void doExecute(final String executionId) { SyncopeUser user = @@ -38,8 +46,23 @@ public class PasswordReset extends AbstractActivitiServiceTask { } user.removeToken(); - user.setPassword(password, user.getCipherAlgorithm()); + + UserMod userMod = new UserMod(); + userMod.setId(user.getId()); + userMod.setPassword(password); + + StatusMod pwdPropRequest = new StatusMod(); + pwdPropRequest.setId(user.getId()); + pwdPropRequest.setOnSyncope(true); + pwdPropRequest.getResourceNames().addAll(user.getResourceNames()); + userMod.setPwdPropRequest(pwdPropRequest); + + PropagationByResource propByRes = dataBinder.update(user, userMod); + + // report updated user and propagation by resource as result runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.SYNCOPE_USER, user); + runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.USER_MOD, userMod); + runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.PROP_BY_RESOURCE, propByRes); } } http://git-wip-us.apache.org/repos/asf/syncope/blob/2524280e/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/Update.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/Update.java b/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/Update.java index e110df9..f366119 100644 --- a/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/Update.java +++ b/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/Update.java @@ -18,7 +18,6 @@ */ package org.apache.syncope.core.workflow.user.activiti.task; -import org.apache.commons.lang3.SerializationUtils; import org.apache.syncope.common.mod.UserMod; import org.apache.syncope.core.persistence.beans.user.SyncopeUser; import org.apache.syncope.core.propagation.PropagationByResource; @@ -40,19 +39,11 @@ public class Update extends AbstractActivitiServiceTask { UserMod userMod = runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.USER_MOD, UserMod.class); - // update password internally only if required - UserMod updatedMod = SerializationUtils.clone(userMod); - String updatedPwd = updatedMod.getPassword(); - if (updatedMod.getPwdPropRequest() != null && !updatedMod.getPwdPropRequest().isOnSyncope()) { - updatedMod.setPassword(null); - } - // update SyncopeUser - PropagationByResource propByRes = dataBinder.update(user, updatedMod); - updatedMod.setPassword(updatedPwd); + PropagationByResource propByRes = dataBinder.update(user, userMod); // report updated user and propagation by resource as result runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.SYNCOPE_USER, user); - runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.USER_MOD, updatedMod); + runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.USER_MOD, userMod); runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.PROP_BY_RESOURCE, propByRes); } } http://git-wip-us.apache.org/repos/asf/syncope/blob/2524280e/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java b/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java index 269f0a8..3c9b0f2 100644 --- a/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java +++ b/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java @@ -2584,4 +2584,44 @@ public class UserTestITCase extends AbstractTest { configurationService.set(pwdCipherAlgo.getSchema(), pwdCipherAlgo); } } + + @Test + public void issueSYNCOPE710() { + // 1. create roles for indirect resource assignment + RoleTO ldapRole = RoleTestITCase.buildBasicRoleTO("syncope710.ldap"); + ldapRole.getResources().add(RESOURCE_NAME_LDAP); + ldapRole = createRole(ldapRole); + + RoleTO dbRole = RoleTestITCase.buildBasicRoleTO("syncope710.db"); + dbRole.getResources().add(RESOURCE_NAME_TESTDB); + dbRole = createRole(dbRole); + + // 2. create user with memberships for the roles created above + UserTO userTO = getUniqueSampleTO("[email protected]"); + userTO.getResources().clear(); + userTO.getMemberships().clear(); + MembershipTO memb = new MembershipTO(); + memb.setRoleId(ldapRole.getId()); + userTO.getMemberships().add(memb); + memb = new MembershipTO(); + memb.setRoleId(dbRole.getId()); + userTO.getMemberships().add(memb); + + userTO = createUser(userTO); + assertEquals(2, userTO.getPropagationStatusTOs().size()); + + // 3. request to propagate passwod only to db + StatusMod pwdPropRequest = new StatusMod(); + pwdPropRequest.setOnSyncope(false); + pwdPropRequest.getResourceNames().add(RESOURCE_NAME_TESTDB); + + UserMod userMod = new UserMod(); + userMod.setId(userTO.getId()); + userMod.setPassword("newpassword123"); + userMod.setPwdPropRequest(pwdPropRequest); + + userTO = updateUser(userMod); + assertEquals(1, userTO.getPropagationStatusTOs().size()); + assertEquals(RESOURCE_NAME_TESTDB, userTO.getPropagationStatusTOs().get(0).getResource()); + } } http://git-wip-us.apache.org/repos/asf/syncope/blob/2524280e/core/src/test/java/org/apache/syncope/core/rest/VirAttrTestITCase.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/syncope/core/rest/VirAttrTestITCase.java b/core/src/test/java/org/apache/syncope/core/rest/VirAttrTestITCase.java index e065998..e7cae5b 100644 --- a/core/src/test/java/org/apache/syncope/core/rest/VirAttrTestITCase.java +++ b/core/src/test/java/org/apache/syncope/core/rest/VirAttrTestITCase.java @@ -297,7 +297,7 @@ public class VirAttrTestITCase extends AbstractTest { assertTrue(found); // create a new user - UserTO userTO = UserTestITCase.getUniqueSampleTO("[email protected]"); + UserTO userTO = UserTestITCase.getUniqueSampleTO("[email protected]"); userTO.getResources().clear(); userTO.getMemberships().clear(); userTO.getDerAttrs().clear(); @@ -332,7 +332,7 @@ public class VirAttrTestITCase extends AbstractTest { toBeUpdated = updateUser(userMod); assertNotNull(toBeUpdated); - assertEquals("[email protected]", toBeUpdated.getVirAttrs().get(0).getValues().get(0)); + assertTrue(toBeUpdated.getVirAttrs().get(0).getValues().contains("[email protected]")); // check if propagates correctly with assertEquals on size of tasks list assertEquals(2, toBeUpdated.getPropagationStatusTOs().size()); } finally { @@ -640,8 +640,9 @@ public class VirAttrTestITCase extends AbstractTest { assertNotNull(userTO); // 3. check again after update if membership has virtual attribute populated with new value assertNotNull(userTO.getMemberships().get(0).getVirAttrMap().get("mvirtualdata")); - assertEquals("[email protected]", userTO.getMemberships().get(0).getVirAttrMap().get( - "mvirtualdata").getValues().get(0)); + assertEquals( + "[email protected]", + userTO.getMemberships().get(0).getVirAttrMap().get("mvirtualdata").getValues().get(0)); // ---------------------------------------- // force cache expiring without any modification
