Return-Path: X-Original-To: apmail-syncope-commits-archive@www.apache.org Delivered-To: apmail-syncope-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 3C6A410C01 for ; Wed, 6 Nov 2013 15:58:07 +0000 (UTC) Received: (qmail 35711 invoked by uid 500); 6 Nov 2013 15:58:04 -0000 Delivered-To: apmail-syncope-commits-archive@syncope.apache.org Received: (qmail 35520 invoked by uid 500); 6 Nov 2013 15:58:00 -0000 Mailing-List: contact commits-help@syncope.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@syncope.apache.org Delivered-To: mailing list commits@syncope.apache.org Received: (qmail 35506 invoked by uid 99); 6 Nov 2013 15:57:58 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 06 Nov 2013 15:57:58 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 06 Nov 2013 15:57:54 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 5CB592388B4E; Wed, 6 Nov 2013 15:57:34 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1539376 [3/4] - in /syncope/trunk: client/src/main/java/org/apache/syncope/client/ common/src/main/java/org/apache/syncope/common/report/ common/src/main/java/org/apache/syncope/common/services/ common/src/main/java/org/apache/syncope/comm... Date: Wed, 06 Nov 2013 15:57:30 -0000 To: commits@syncope.apache.org From: ilgrosso@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20131106155734.5CB592388B4E@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/WorkflowAdapter.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/WorkflowAdapter.java?rev=1539376&r1=1539375&r2=1539376&view=diff ============================================================================== --- syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/WorkflowAdapter.java (original) +++ syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/WorkflowAdapter.java Wed Nov 6 15:57:28 2013 @@ -19,7 +19,7 @@ package org.apache.syncope.core.workflow; import java.util.List; -import java.util.Map; +import org.apache.syncope.common.mod.AbstractAttributableMod; import org.apache.syncope.common.to.WorkflowDefinitionTO; import org.apache.syncope.common.to.WorkflowFormTO; import org.apache.syncope.core.persistence.dao.NotFoundException; @@ -108,6 +108,6 @@ public interface WorkflowAdapter { * @throws NotFoundException not found exception * @throws WorkflowException workflow exception */ - WorkflowResult> submitForm(WorkflowFormTO form, String username) + WorkflowResult submitForm(WorkflowFormTO form, String username) throws NotFoundException, WorkflowException; } Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/WorkflowUserSuspender.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/WorkflowUserSuspender.java?rev=1539376&r1=1539375&r2=1539376&view=diff ============================================================================== --- syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/WorkflowUserSuspender.java (original) +++ syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/WorkflowUserSuspender.java Wed Nov 6 15:57:28 2013 @@ -21,13 +21,12 @@ package org.apache.syncope.core.workflow import java.util.AbstractMap.SimpleEntry; import java.util.List; import java.util.Map; -import org.apache.syncope.common.to.UserTO; +import org.apache.syncope.common.mod.UserMod; import org.apache.syncope.core.persistence.beans.PropagationTask; import org.apache.syncope.core.persistence.beans.user.SyncopeUser; import org.apache.syncope.core.policy.UserSuspender; import org.apache.syncope.core.propagation.PropagationTaskExecutor; import org.apache.syncope.core.propagation.impl.PropagationManager; -import org.apache.syncope.core.rest.data.UserDataBinder; import org.apache.syncope.core.workflow.user.UserWorkflowAdapter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -48,9 +47,6 @@ public class WorkflowUserSuspender imple @Autowired private PropagationTaskExecutor taskExecutor; - @Autowired - private UserDataBinder userDataBinder; - @Override public void suspend(final SyncopeUser user, final boolean suspend) { try { @@ -64,10 +60,13 @@ public class WorkflowUserSuspender imple // propagate suspension if and only if it is required by policy if (suspend) { + UserMod userMod = new UserMod(); + userMod.setId(updated.getResult()); + final List tasks = propagationManager.getUserUpdateTaskIds( - new WorkflowResult>( - new SimpleEntry(updated.getResult(), Boolean.FALSE), - updated.getPropByRes(), updated.getPerformedTasks())); + new WorkflowResult>( + new SimpleEntry(userMod, Boolean.FALSE), + updated.getPropByRes(), updated.getPerformedTasks())); taskExecutor.execute(tasks); } Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/role/NoOpRoleWorkflowAdapter.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/role/NoOpRoleWorkflowAdapter.java?rev=1539376&r1=1539375&r2=1539376&view=diff ============================================================================== --- syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/role/NoOpRoleWorkflowAdapter.java (original) +++ syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/role/NoOpRoleWorkflowAdapter.java Wed Nov 6 15:57:28 2013 @@ -21,7 +21,6 @@ package org.apache.syncope.core.workflow import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.Map; import org.apache.syncope.common.mod.RoleMod; import org.apache.syncope.common.to.RoleTO; @@ -39,10 +38,10 @@ import org.springframework.transaction.a /** * Simple implementation basically not involving any workflow engine. */ -@Transactional(rollbackFor = {Throwable.class}) +@Transactional(rollbackFor = { Throwable.class }) public class NoOpRoleWorkflowAdapter extends AbstractRoleWorkflowAdapter { - private static final List TASKS = Arrays.asList(new String[] {"create", "update", "delete"}); + private static final List TASKS = Arrays.asList(new String[] { "create", "update", "delete" }); @Override public WorkflowResult create(final RoleTO roleTO) @@ -129,9 +128,10 @@ public class NoOpRoleWorkflowAdapter ext } @Override - public WorkflowResult> submitForm(final WorkflowFormTO form, final String username) + public WorkflowResult submitForm(final WorkflowFormTO form, final String username) throws NotFoundException, WorkflowException { throw new WorkflowException(new UnsupportedOperationException("Not supported.")); } + } Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/AbstractUserWorkflowAdapter.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/AbstractUserWorkflowAdapter.java?rev=1539376&r1=1539375&r2=1539376&view=diff ============================================================================== --- syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/AbstractUserWorkflowAdapter.java (original) +++ syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/AbstractUserWorkflowAdapter.java Wed Nov 6 15:57:28 2013 @@ -29,10 +29,12 @@ import org.apache.syncope.core.rest.data import org.apache.syncope.core.workflow.WorkflowException; import org.apache.syncope.core.workflow.WorkflowInstanceLoader; import org.apache.syncope.core.workflow.WorkflowResult; +import org.identityconnectors.common.security.EncryptorFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.crypto.codec.Base64; import org.springframework.transaction.annotation.Transactional; -@Transactional(rollbackFor = {Throwable.class}) +@Transactional(rollbackFor = { Throwable.class }) public abstract class AbstractUserWorkflowAdapter implements UserWorkflowAdapter { @Autowired @@ -41,6 +43,19 @@ public abstract class AbstractUserWorkfl @Autowired protected UserDAO userDAO; + public static String encrypt(final String clear) { + byte[] encryptedBytes = EncryptorFactory.getInstance().getDefaultEncryptor().encrypt(clear.getBytes()); + + return new String(Base64.encode(encryptedBytes)); + } + + public static String decrypt(final String crypted) { + byte[] decryptedBytes = + EncryptorFactory.getInstance().getDefaultEncryptor().decrypt(Base64.decode(crypted.getBytes())); + + return new String(decryptedBytes); + } + @Override public Class getLoaderClass() { return null; @@ -62,11 +77,11 @@ public abstract class AbstractUserWorkfl return doActivate(dataBinder.getUserFromId(userId), token); } - protected abstract WorkflowResult> doUpdate(SyncopeUser user, UserMod userMod) + protected abstract WorkflowResult> doUpdate(SyncopeUser user, UserMod userMod) throws WorkflowException; @Override - public WorkflowResult> update(final UserMod userMod) + public WorkflowResult> update(final UserMod userMod) throws UnauthorizedRoleException, WorkflowException { return doUpdate(dataBinder.getUserFromId(userMod.getId()), userMod); Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/NoOpUserWorkflowAdapter.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/NoOpUserWorkflowAdapter.java?rev=1539376&r1=1539375&r2=1539376&view=diff ============================================================================== --- syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/NoOpUserWorkflowAdapter.java (original) +++ syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/NoOpUserWorkflowAdapter.java Wed Nov 6 15:57:28 2013 @@ -40,11 +40,11 @@ import org.springframework.transaction.a /** * Simple implementation basically not involving any workflow engine. */ -@Transactional(rollbackFor = {Throwable.class}) +@Transactional(rollbackFor = { Throwable.class }) public class NoOpUserWorkflowAdapter extends AbstractUserWorkflowAdapter { private static final List TASKS = - Arrays.asList(new String[] {"create", "activate", "update", "suspend", "reactivate", "delete"}); + Arrays.asList(new String[] { "create", "activate", "update", "suspend", "reactivate", "delete" }); public static final String ENABLED = "enabled"; @@ -107,15 +107,16 @@ public class NoOpUserWorkflowAdapter ext } @Override - protected WorkflowResult> doUpdate(final SyncopeUser user, final UserMod userMod) + protected WorkflowResult> doUpdate(final SyncopeUser user, final UserMod userMod) throws WorkflowException { PropagationByResource propByRes = dataBinder.update(user, userMod); SyncopeUser updated = userDAO.save(user); - return new WorkflowResult>( - new AbstractMap.SimpleEntry(updated.getId(), !user.isSuspended()), propByRes, "update"); + userMod.setId(updated.getId()); + return new WorkflowResult>( + new AbstractMap.SimpleEntry(userMod, !user.isSuspended()), propByRes, "update"); } @Override @@ -198,7 +199,7 @@ public class NoOpUserWorkflowAdapter ext } @Override - public WorkflowResult> submitForm(final WorkflowFormTO form, final String username) + public WorkflowResult submitForm(final WorkflowFormTO form, final String username) throws NotFoundException, WorkflowException { throw new WorkflowException(new UnsupportedOperationException("Not supported.")); Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/UserWorkflowAdapter.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/UserWorkflowAdapter.java?rev=1539376&r1=1539375&r2=1539376&view=diff ============================================================================== --- syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/UserWorkflowAdapter.java (original) +++ syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/UserWorkflowAdapter.java Wed Nov 6 15:57:28 2013 @@ -97,7 +97,7 @@ public interface UserWorkflowAdapter ext * @throws UnauthorizedRoleException authorization exception * @throws WorkflowException workflow exception */ - WorkflowResult> update(UserMod userMod) + WorkflowResult> update(UserMod userMod) throws UnauthorizedRoleException, WorkflowException; /** Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/ActivitiUserWorkflowAdapter.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/ActivitiUserWorkflowAdapter.java?rev=1539376&r1=1539375&r2=1539376&view=diff ============================================================================== --- syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/ActivitiUserWorkflowAdapter.java (original) +++ syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/ActivitiUserWorkflowAdapter.java Wed Nov 6 15:57:28 2013 @@ -67,19 +67,20 @@ import org.apache.syncope.common.to.Work import org.apache.syncope.common.types.ResourceOperation; import org.apache.syncope.common.types.WorkflowFormPropertyType; import org.apache.syncope.common.util.BeanUtils; +import org.apache.syncope.common.validation.SyncopeClientException; import org.apache.syncope.core.persistence.beans.user.SyncopeUser; import org.apache.syncope.core.persistence.dao.NotFoundException; +import org.apache.syncope.core.persistence.validation.attrvalue.ParsingValidationException; import org.apache.syncope.core.propagation.PropagationByResource; import org.apache.syncope.core.rest.controller.UnauthorizedRoleException; +import org.apache.syncope.core.util.EntitlementUtil; import org.apache.syncope.core.workflow.WorkflowException; import org.apache.syncope.core.workflow.WorkflowInstanceLoader; import org.apache.syncope.core.workflow.WorkflowResult; import org.apache.syncope.core.workflow.user.AbstractUserWorkflowAdapter; -import org.identityconnectors.common.security.EncryptorFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.crypto.codec.Base64; import org.springframework.transaction.annotation.Transactional; import org.w3c.dom.Document; import org.w3c.dom.NodeList; @@ -94,7 +95,7 @@ public class ActivitiUserWorkflowAdapter */ private static final Logger LOG = LoggerFactory.getLogger(ActivitiUserWorkflowAdapter.class); - private static final String[] PROPERTY_IGNORE_PROPS = {"type"}; + private static final String[] PROPERTY_IGNORE_PROPS = { "type" }; public static final String WF_PROCESS_ID = "userWorkflow"; @@ -102,6 +103,8 @@ public class ActivitiUserWorkflowAdapter public static final String SYNCOPE_USER = "syncopeUser"; + public static final String WF_EXECUTOR = "wfExecutor"; + public static final String USER_TO = "userTO"; public static final String ENABLED = "enabled"; @@ -145,6 +148,18 @@ public class ActivitiUserWorkflowAdapter return ActivitiWorkflowLoader.class; } + private void throwException(final ActivitiException e, final String defaultMessage) { + if (e.getCause() != null) { + if (e.getCause().getCause() instanceof SyncopeClientException) { + throw (SyncopeClientException) e.getCause().getCause(); + } else if (e.getCause().getCause() instanceof ParsingValidationException) { + throw (ParsingValidationException) e.getCause().getCause(); + } + } + + throw new WorkflowException(defaultMessage, e); + } + private void updateStatus(final SyncopeUser user) { List tasks = taskService.createTaskQuery().processInstanceId(user.getWorkflowId()).list(); if (tasks.isEmpty() || tasks.size() > 1) { @@ -185,17 +200,25 @@ public class ActivitiUserWorkflowAdapter return result; } - private String encrypt(final String clear) { - byte[] encryptedBytes = EncryptorFactory.getInstance().getDefaultEncryptor().encrypt(clear.getBytes()); - - return new String(Base64.encode(encryptedBytes)); - } + /** + * Saves resources to be propagated and password for later - after form submission - propagation. + */ + private void saveForFormSubmit(final SyncopeUser user, final String password, + final PropagationByResource propByRes) { - private String decrypt(final String crypted) { - byte[] decryptedBytes = - EncryptorFactory.getInstance().getDefaultEncryptor().decrypt(Base64.decode(crypted.getBytes())); + String formTaskId = getFormTask(user); + if (formTaskId != null) { + // SYNCOPE-238: This is needed to simplify the task query in this.getForms() + taskService.setVariableLocal(formTaskId, TASK_IS_FORM, Boolean.TRUE); + runtimeService.setVariable(user.getWorkflowId(), PROP_BY_RESOURCE, propByRes); + if (propByRes != null) { + propByRes.clear(); + } - return new String(decryptedBytes); + if (StringUtils.isNotBlank(password)) { + runtimeService.setVariable(user.getWorkflowId(), ENCRYPTED_PWD, encrypt(password)); + } + } } @Override @@ -211,20 +234,22 @@ public class ActivitiUserWorkflowAdapter throws WorkflowException { final Map variables = new HashMap(); + variables.put(WF_EXECUTOR, EntitlementUtil.getAuthenticatedUsername()); variables.put(USER_TO, userTO); variables.put(ENABLED, enabled); - final ProcessInstance processInstance; + ProcessInstance processInstance = null; try { processInstance = runtimeService.startProcessInstanceByKey(WF_PROCESS_ID, variables); } catch (ActivitiException e) { - throw new WorkflowException("While starting " + WF_PROCESS_ID + " instance", e); + throwException(e, "While starting " + WF_PROCESS_ID + " instance"); } - SyncopeUser user = (SyncopeUser) runtimeService.getVariable(processInstance.getProcessInstanceId(), - SYNCOPE_USER); + SyncopeUser user = (SyncopeUser) runtimeService.getVariable( + processInstance.getProcessInstanceId(), SYNCOPE_USER); - Boolean updatedEnabled = (Boolean) runtimeService.getVariable(processInstance.getProcessInstanceId(), ENABLED); + Boolean updatedEnabled = (Boolean) runtimeService.getVariable( + processInstance.getProcessInstanceId(), ENABLED); if (updatedEnabled != null) { user.setSuspended(!updatedEnabled); } @@ -237,28 +262,16 @@ public class ActivitiUserWorkflowAdapter updateStatus(user); user = userDAO.save(user); - Boolean propagateEnable = (Boolean) runtimeService.getVariable(processInstance.getProcessInstanceId(), - PROPAGATE_ENABLE); + Boolean propagateEnable = (Boolean) runtimeService.getVariable( + processInstance.getProcessInstanceId(), PROPAGATE_ENABLE); if (propagateEnable == null) { propagateEnable = enabled; } - // save resources to be propagated and password for later - after form submission - propagation PropagationByResource propByRes = new PropagationByResource(); propByRes.set(ResourceOperation.CREATE, user.getResourceNames()); - String formTaskId = getFormTask(user); - if (formTaskId != null) { - // SYNCOPE-238: This is needed to simplify the task query in this.getForms() - taskService.setVariableLocal(formTaskId, TASK_IS_FORM, Boolean.TRUE); - runtimeService.setVariable(processInstance.getProcessInstanceId(), PROP_BY_RESOURCE, propByRes); - propByRes = null; - - if (StringUtils.isNotBlank(userTO.getPassword())) { - runtimeService.setVariable( - processInstance.getProcessInstanceId(), ENCRYPTED_PWD, encrypt(userTO.getPassword())); - } - } + saveForFormSubmit(user, userTO.getPassword(), propByRes); return new WorkflowResult>( new SimpleEntry(user.getId(), propagateEnable), propByRes, getPerformedTasks(user)); @@ -270,9 +283,14 @@ public class ActivitiUserWorkflowAdapter Set preTasks = getPerformedTasks(user); final Map variables = new HashMap(); - variables.put(SYNCOPE_USER, user); + variables.put(WF_EXECUTOR, EntitlementUtil.getAuthenticatedUsername()); variables.put(TASK, task); + // using BeanUtils to access all user's properties and trigger lazy loading - we are about to + // serialize a SyncopeUser instance for availability within workflow tasks, and this breaks transactions + BeanUtils.copyProperties(user, new SyncopeUser()); + variables.put(SYNCOPE_USER, user); + if (moreVariables != null && !moreVariables.isEmpty()) { variables.putAll(moreVariables); } @@ -286,7 +304,7 @@ public class ActivitiUserWorkflowAdapter try { taskService.complete(tasks.get(0).getId(), variables); } catch (ActivitiException e) { - throw new WorkflowException("While completing task '" + tasks.get(0).getName() + "' for " + user, e); + throwException(e, "While completing task '" + tasks.get(0).getName() + "' for " + user); } } else { LOG.warn("Expected a single task, found {}", tasks.size()); @@ -302,43 +320,36 @@ public class ActivitiUserWorkflowAdapter protected WorkflowResult doActivate(final SyncopeUser user, final String token) throws WorkflowException { - Set performedTasks = doExecuteTask(user, "activate", Collections.singletonMap(TOKEN, (Object) token)); + Set tasks = doExecuteTask(user, "activate", Collections.singletonMap(TOKEN, (Object) token)); + updateStatus(user); SyncopeUser updated = userDAO.save(user); - return new WorkflowResult(updated.getId(), null, performedTasks); + return new WorkflowResult(updated.getId(), null, tasks); } @Override - protected WorkflowResult> doUpdate(final SyncopeUser user, final UserMod userMod) + protected WorkflowResult> doUpdate(final SyncopeUser user, final UserMod userMod) throws WorkflowException { - Set task = doExecuteTask(user, "update", Collections.singletonMap(USER_MOD, (Object) userMod)); + Set tasks = doExecuteTask(user, "update", Collections.singletonMap(USER_MOD, (Object) userMod)); updateStatus(user); SyncopeUser updated = userDAO.save(user); - PropagationByResource propByRes = (PropagationByResource) runtimeService.getVariable(user.getWorkflowId(), - PROP_BY_RESOURCE); + PropagationByResource propByRes = (PropagationByResource) runtimeService.getVariable( + user.getWorkflowId(), PROP_BY_RESOURCE); - // save resources to be propagated and password for later - after form submission - propagation - String formTaskId = getFormTask(user); - if (formTaskId != null) { - // SYNCOPE-238: This is needed to simplify the task query in this.getForms() - taskService.setVariableLocal(formTaskId, TASK_IS_FORM, Boolean.TRUE); - if (StringUtils.isNotBlank(userMod.getPassword())) { - runtimeService.setVariable(user.getWorkflowId(), ENCRYPTED_PWD, encrypt(userMod.getPassword())); - } - } + saveForFormSubmit(updated, userMod.getPassword(), propByRes); Boolean propagateEnable = (Boolean) runtimeService.getVariable(user.getWorkflowId(), PROPAGATE_ENABLE); - return new WorkflowResult>(new SimpleEntry( - updated.getId(), propagateEnable), propByRes, task); + return new WorkflowResult>( + new SimpleEntry(userMod, propagateEnable), propByRes, tasks); } @Override - @Transactional(rollbackFor = {Throwable.class}) + @Transactional(rollbackFor = { Throwable.class }) protected WorkflowResult doSuspend(final SyncopeUser user) throws WorkflowException { @@ -366,12 +377,25 @@ public class ActivitiUserWorkflowAdapter throws WorkflowException { doExecuteTask(user, "delete", null); - userDAO.delete(user); - if (!historyService.createHistoricProcessInstanceQuery(). - processInstanceId(user.getWorkflowId()).list().isEmpty()) { + PropagationByResource propByRes = new PropagationByResource(); + propByRes.set(ResourceOperation.DELETE, user.getResourceNames()); + + saveForFormSubmit(user, null, propByRes); + + if (runtimeService.createProcessInstanceQuery(). + processInstanceId(user.getWorkflowId()).active().list().isEmpty()) { + + userDAO.delete(user.getId()); + + if (!historyService.createHistoricProcessInstanceQuery(). + processInstanceId(user.getWorkflowId()).list().isEmpty()) { - historyService.deleteHistoricProcessInstance(user.getWorkflowId()); + historyService.deleteHistoricProcessInstance(user.getWorkflowId()); + } + } else { + updateStatus(user); + userDAO.save(user); } } @@ -522,7 +546,8 @@ public class ActivitiUserWorkflowAdapter } } - final WorkflowFormTO formTO = getHFormTO(task.getProcessInstanceId(), task.getId(), task.getFormKey(), props); + final WorkflowFormTO formTO = getHistoricFormTO( + task.getProcessInstanceId(), task.getId(), task.getFormKey(), props); BeanUtils.copyProperties(task, formTO); final HistoricActivityInstance historicActivityInstance = historyService.createHistoricActivityInstanceQuery(). @@ -536,8 +561,7 @@ public class ActivitiUserWorkflowAdapter return formTO; } - @SuppressWarnings("unchecked") - private WorkflowFormTO getHFormTO( + private WorkflowFormTO getHistoricFormTO( final String processInstanceId, final String taskId, final String formKey, @@ -717,7 +741,7 @@ public class ActivitiUserWorkflowAdapter } @Override - public WorkflowResult> submitForm(final WorkflowFormTO form, final String username) + public WorkflowResult submitForm(final WorkflowFormTO form, final String username) throws WorkflowException { Map.Entry checked = checkTask(form.getTaskId(), username); @@ -736,7 +760,7 @@ public class ActivitiUserWorkflowAdapter try { formService.submitTaskFormData(form.getTaskId(), form.getPropertiesForSubmit()); } catch (ActivitiException e) { - throw new WorkflowException("While submitting form for task " + form.getTaskId(), e); + throwException(e, "While submitting form for task " + form.getTaskId()); } Set postTasks = getPerformedTasks(user); @@ -750,14 +774,20 @@ public class ActivitiUserWorkflowAdapter PropagationByResource propByRes = (PropagationByResource) runtimeService.getVariable(user.getWorkflowId(), PROP_BY_RESOURCE); - // fetch - if available - the encrpted password + // fetch - if available - the encrypted password String clearPassword = null; String encryptedPwd = (String) runtimeService.getVariable(user.getWorkflowId(), ENCRYPTED_PWD); if (StringUtils.isNotBlank(encryptedPwd)) { clearPassword = decrypt(encryptedPwd); } - return new WorkflowResult>(new SimpleEntry(updated.getId(), - clearPassword), propByRes, postTasks); + UserMod userMod = (UserMod) runtimeService.getVariable(user.getWorkflowId(), USER_MOD); + if (userMod == null) { + userMod = new UserMod(); + userMod.setId(updated.getId()); + userMod.setPassword(clearPassword); + } + + return new WorkflowResult(userMod, propByRes, postTasks); } } Copied: syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/AbstractActivitiServiceTask.java (from r1538533, syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/AbstractActivitiDelegate.java) URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/AbstractActivitiServiceTask.java?p2=syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/AbstractActivitiServiceTask.java&p1=syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/AbstractActivitiDelegate.java&r1=1538533&r2=1539376&rev=1539376&view=diff ============================================================================== --- syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/AbstractActivitiDelegate.java (original) +++ syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/AbstractActivitiServiceTask.java Wed Nov 6 15:57:28 2013 @@ -18,44 +18,31 @@ */ package org.apache.syncope.core.workflow.user.activiti.task; -import org.activiti.engine.TaskService; -import org.activiti.engine.delegate.DelegateExecution; -import org.activiti.engine.delegate.JavaDelegate; -import org.apache.syncope.core.persistence.dao.ConfDAO; -import org.apache.syncope.core.rest.data.UserDataBinder; -import org.apache.syncope.core.util.ApplicationContextProvider; +import org.activiti.engine.RuntimeService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; /** - * Abstract base class for Activiti's JavaDelegate implementations in Syncope. + * Abstract base class for Activiti's service tasks in Syncope, with Spring support. */ -public abstract class AbstractActivitiDelegate implements JavaDelegate { +@Component +public abstract class AbstractActivitiServiceTask { /** * Logger. */ - protected static final Logger LOG = LoggerFactory.getLogger(AbstractActivitiDelegate.class); + protected static final Logger LOG = LoggerFactory.getLogger(AbstractActivitiServiceTask.class); - protected static final ConfigurableApplicationContext CONTEXT = ApplicationContextProvider.getApplicationContext(); + @Autowired + protected RuntimeService runtimeService; - protected TaskService taskService; - - protected UserDataBinder dataBinder; - - protected ConfDAO confDAO; - - @Override - public final void execute(final DelegateExecution execution) throws Exception { - - taskService = CONTEXT.getBean(TaskService.class); - - dataBinder = CONTEXT.getBean(UserDataBinder.class); - confDAO = CONTEXT.getBean(ConfDAO.class); - - doExecute(execution); + @Transactional(rollbackFor = { Throwable.class }) + public void execute(final String executionId) { + doExecute(executionId); } - protected abstract void doExecute(DelegateExecution execution) throws Exception; + protected abstract void doExecute(final String executionId); } Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/AutoActivate.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/AutoActivate.java?rev=1539376&r1=1539375&r2=1539376&view=diff ============================================================================== --- syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/AutoActivate.java (original) +++ syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/AutoActivate.java Wed Nov 6 15:57:28 2013 @@ -18,13 +18,14 @@ */ package org.apache.syncope.core.workflow.user.activiti.task; -import org.activiti.engine.delegate.DelegateExecution; import org.apache.syncope.core.workflow.user.activiti.ActivitiUserWorkflowAdapter; +import org.springframework.stereotype.Component; -public class AutoActivate extends AbstractActivitiDelegate { +@Component +public class AutoActivate extends AbstractActivitiServiceTask { @Override - protected void doExecute(final DelegateExecution execution) throws Exception { - execution.setVariable(ActivitiUserWorkflowAdapter.PROPAGATE_ENABLE, Boolean.TRUE); + protected void doExecute(final String executionId) { + runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.PROPAGATE_ENABLE, Boolean.TRUE); } } Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/Create.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/Create.java?rev=1539376&r1=1539375&r2=1539376&view=diff ============================================================================== --- syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/Create.java (original) +++ syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/Create.java Wed Nov 6 15:57:28 2013 @@ -18,24 +18,29 @@ */ package org.apache.syncope.core.workflow.user.activiti.task; -import org.activiti.engine.delegate.DelegateExecution; import org.apache.syncope.common.to.UserTO; import org.apache.syncope.core.persistence.beans.user.SyncopeUser; +import org.apache.syncope.core.rest.data.UserDataBinder; import org.apache.syncope.core.workflow.user.activiti.ActivitiUserWorkflowAdapter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; -public class Create extends AbstractActivitiDelegate { +@Component +public class Create extends AbstractActivitiServiceTask { - @Override - protected void doExecute(final DelegateExecution execution) throws Exception { + @Autowired + private UserDataBinder dataBinder; - UserTO userTO = (UserTO) execution.getVariable(ActivitiUserWorkflowAdapter.USER_TO); + @Override + protected void doExecute(final String executionId) { + UserTO userTO = (UserTO) runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.USER_TO); // create and set workflow id SyncopeUser user = new SyncopeUser(); dataBinder.create(user, userTO); - user.setWorkflowId(execution.getProcessInstanceId()); + user.setWorkflowId(executionId); // report SyncopeUser as result - execution.setVariable(ActivitiUserWorkflowAdapter.SYNCOPE_USER, user); + runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.SYNCOPE_USER, user); } } Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/Delete.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/Delete.java?rev=1539376&r1=1539375&r2=1539376&view=diff ============================================================================== --- syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/Delete.java (original) +++ syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/Delete.java Wed Nov 6 15:57:28 2013 @@ -18,23 +18,24 @@ */ package org.apache.syncope.core.workflow.user.activiti.task; -import org.activiti.engine.delegate.DelegateExecution; import org.apache.syncope.core.persistence.beans.user.SyncopeUser; import org.apache.syncope.core.workflow.user.activiti.ActivitiUserWorkflowAdapter; +import org.springframework.stereotype.Component; -public class Delete extends AbstractActivitiDelegate { +@Component +public class Delete extends AbstractActivitiServiceTask { @Override - protected void doExecute(final DelegateExecution execution) throws Exception { + protected void doExecute(final String executionId) { + SyncopeUser user = + (SyncopeUser) runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.SYNCOPE_USER); - SyncopeUser user = (SyncopeUser) execution.getVariable(ActivitiUserWorkflowAdapter.SYNCOPE_USER); - - // TODO: do something with SyncopeUser... + // Do something with SyncopeUser... if (user != null) { user.checkToken(""); } // remove SyncopeUser variable - execution.removeVariable(ActivitiUserWorkflowAdapter.SYNCOPE_USER); + runtimeService.removeVariable(executionId, ActivitiUserWorkflowAdapter.SYNCOPE_USER); } } Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/GenerateToken.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/GenerateToken.java?rev=1539376&r1=1539375&r2=1539376&view=diff ============================================================================== --- syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/GenerateToken.java (original) +++ syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/GenerateToken.java Wed Nov 6 15:57:28 2013 @@ -18,20 +18,27 @@ */ package org.apache.syncope.core.workflow.user.activiti.task; -import org.activiti.engine.delegate.DelegateExecution; import org.apache.syncope.core.persistence.beans.user.SyncopeUser; +import org.apache.syncope.core.persistence.dao.ConfDAO; import org.apache.syncope.core.workflow.user.activiti.ActivitiUserWorkflowAdapter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; -public class GenerateToken extends AbstractActivitiDelegate { +@Component +public class GenerateToken extends AbstractActivitiServiceTask { + + @Autowired + private ConfDAO confDAO; @Override - protected void doExecute(final DelegateExecution execution) throws Exception { - SyncopeUser user = (SyncopeUser) execution.getVariable(ActivitiUserWorkflowAdapter.SYNCOPE_USER); + protected void doExecute(final String executionId) { + SyncopeUser user = + (SyncopeUser) runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.SYNCOPE_USER); user.generateToken( Integer.parseInt(confDAO.find("token.length", "256").getValue()), Integer.parseInt(confDAO.find("token.expireTime", "60").getValue())); - execution.setVariable(ActivitiUserWorkflowAdapter.SYNCOPE_USER, user); + runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.SYNCOPE_USER, user); } } Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/Reactivate.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/Reactivate.java?rev=1539376&r1=1539375&r2=1539376&view=diff ============================================================================== --- syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/Reactivate.java (original) +++ syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/Reactivate.java Wed Nov 6 15:57:28 2013 @@ -18,11 +18,12 @@ */ package org.apache.syncope.core.workflow.user.activiti.task; -import org.activiti.engine.delegate.DelegateExecution; +import org.springframework.stereotype.Component; -public class Reactivate extends AbstractActivitiDelegate { +@Component +public class Reactivate extends AbstractActivitiServiceTask { @Override - protected void doExecute(final DelegateExecution execution) throws Exception { + protected void doExecute(final String executionId) { } } Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/Suspend.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/Suspend.java?rev=1539376&r1=1539375&r2=1539376&view=diff ============================================================================== --- syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/Suspend.java (original) +++ syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/Suspend.java Wed Nov 6 15:57:28 2013 @@ -18,11 +18,12 @@ */ package org.apache.syncope.core.workflow.user.activiti.task; -import org.activiti.engine.delegate.DelegateExecution; +import org.springframework.stereotype.Component; -public class Suspend extends AbstractActivitiDelegate { +@Component +public class Suspend extends AbstractActivitiServiceTask { @Override - protected void doExecute(final DelegateExecution execution) throws Exception { + protected void doExecute(final String executionId) { } } Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/Update.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/Update.java?rev=1539376&r1=1539375&r2=1539376&view=diff ============================================================================== --- syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/Update.java (original) +++ syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/Update.java Wed Nov 6 15:57:28 2013 @@ -18,24 +18,38 @@ */ package org.apache.syncope.core.workflow.user.activiti.task; -import org.activiti.engine.delegate.DelegateExecution; +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; +import org.apache.syncope.core.rest.data.UserDataBinder; import org.apache.syncope.core.workflow.user.activiti.ActivitiUserWorkflowAdapter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; -public class Update extends AbstractActivitiDelegate { +@Component +public class Update extends AbstractActivitiServiceTask { + + @Autowired + private UserDataBinder dataBinder; @Override - protected void doExecute(final DelegateExecution execution) throws Exception { - SyncopeUser user = (SyncopeUser) execution.getVariable(ActivitiUserWorkflowAdapter.SYNCOPE_USER); - UserMod userMod = (UserMod) execution.getVariable(ActivitiUserWorkflowAdapter.USER_MOD); + protected void doExecute(final String executionId) { + SyncopeUser user = + (SyncopeUser) runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.SYNCOPE_USER); + UserMod userMod = + (UserMod) runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.USER_MOD); + // 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, userMod); + PropagationByResource propByRes = dataBinder.update(user, actualMod); // report updated user and propagation by resource as result - execution.setVariable(ActivitiUserWorkflowAdapter.SYNCOPE_USER, user); - execution.setVariable(ActivitiUserWorkflowAdapter.PROP_BY_RESOURCE, propByRes); + runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.SYNCOPE_USER, user); + runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.PROP_BY_RESOURCE, propByRes); } } Modified: syncope/trunk/core/src/main/resources/content.xml URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/resources/content.xml?rev=1539376&r1=1539375&r2=1539376&view=diff ============================================================================== --- syncope/trunk/core/src/main/resources/content.xml (original) +++ syncope/trunk/core/src/main/resources/content.xml Wed Nov 6 15:57:28 2013 @@ -28,7 +28,7 @@ under the License. - + @@ -88,11 +88,6 @@ under the License. - - - - - Modified: syncope/trunk/core/src/main/resources/restContext.xml URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/resources/restContext.xml?rev=1539376&r1=1539375&r2=1539376&view=diff ============================================================================== --- syncope/trunk/core/src/main/resources/restContext.xml (original) +++ syncope/trunk/core/src/main/resources/restContext.xml Wed Nov 6 15:57:28 2013 @@ -97,8 +97,8 @@ under the License. - + Modified: syncope/trunk/core/src/main/resources/securityContext.xml URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/resources/securityContext.xml?rev=1539376&r1=1539375&r2=1539376&view=diff ============================================================================== --- syncope/trunk/core/src/main/resources/securityContext.xml (original) +++ syncope/trunk/core/src/main/resources/securityContext.xml Wed Nov 6 15:57:28 2013 @@ -42,6 +42,7 @@ under the License. + Modified: syncope/trunk/core/src/main/resources/userWorkflow.bpmn20.xml URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/resources/userWorkflow.bpmn20.xml?rev=1539376&r1=1539375&r2=1539376&view=diff ============================================================================== --- syncope/trunk/core/src/main/resources/userWorkflow.bpmn20.xml (original) +++ syncope/trunk/core/src/main/resources/userWorkflow.bpmn20.xml Wed Nov 6 15:57:28 2013 @@ -35,18 +35,17 @@ under the License. - + + + ${wfExecutor == 'anonymous' || syncopeUser.getRoleIds().contains(9)} + ${!syncopeUser.getRoleIds().contains(9)} - - ${syncopeUser.getRoleIds().contains(9)} - @@ -73,7 +72,7 @@ under the License. - ${enabled==null} + ${enabled == null} ${enabled} @@ -83,12 +82,12 @@ under the License. + activiti:expression="#{autoActivate.execute(execution.processInstanceId)}"/> + activiti:expression="#{generateToken.execute(execution.processInstanceId)}"/> @@ -117,6 +116,15 @@ under the License. + + + ${wfExecutor == syncopeUser.getUsername() and task == 'update' + and (!userMod.getMembershipsToAdd().isEmpty() or !userMod.getMembershipsToRemove().isEmpty())} + + + + ${wfExecutor == syncopeUser.getUsername() and task == 'delete'} + ${task == 'update'} @@ -127,15 +135,39 @@ under the License. ${task == 'delete'} + + + + + + + + + + + + + ${approve} + + + ${!approve} + + + + + + + + - + - + @@ -153,7 +185,7 @@ under the License. + activiti:expression="#{reactivate.execute(execution.processInstanceId)}"/> @@ -180,9 +212,34 @@ under the License. ${empty task} + + + + + + + + + + + + + ${approve} + + + ${!approve} + + + + + + + + - + Modified: syncope/trunk/core/src/main/resources/workflowContext.xml URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/resources/workflowContext.xml?rev=1539376&r1=1539375&r2=1539376&view=diff ============================================================================== --- syncope/trunk/core/src/main/resources/workflowContext.xml (original) +++ syncope/trunk/core/src/main/resources/workflowContext.xml Wed Nov 6 15:57:28 2013 @@ -19,8 +19,11 @@ under the License. --> + http://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/context + http://www.springframework.org/schema/context/spring-context.xsd"> @@ -69,6 +72,8 @@ under the License. + + Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/EntitlementTest.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/EntitlementTest.java?rev=1539376&r1=1539375&r2=1539376&view=diff ============================================================================== --- syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/EntitlementTest.java (original) +++ syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/EntitlementTest.java Wed Nov 6 15:57:28 2013 @@ -41,7 +41,7 @@ public class EntitlementTest extends Abs @Test public void findAll() { List list = entitlementDAO.findAll(); - assertEquals("did not get expected number of entitlements ", 89, list.size()); + assertEquals("did not get expected number of entitlements ", 84, list.size()); } @Test Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/relationships/RoleTest.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/relationships/RoleTest.java?rev=1539376&r1=1539375&r2=1539376&view=diff ============================================================================== --- syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/relationships/RoleTest.java (original) +++ syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/relationships/RoleTest.java Wed Nov 6 15:57:28 2013 @@ -103,7 +103,7 @@ public class RoleTest extends AbstractDA assertNotNull(child2); assertEquals(role, child2.getParent()); - List ownedRoles = roleDAO.findOwned(user); + List ownedRoles = roleDAO.findOwnedByUser(user.getId()); assertFalse(ownedRoles.isEmpty()); assertEquals(2, ownedRoles.size()); assertTrue(ownedRoles.contains(role)); Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/AbstractTest.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/AbstractTest.java?rev=1539376&r1=1539375&r2=1539376&view=diff ============================================================================== --- syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/AbstractTest.java (original) +++ syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/AbstractTest.java Wed Nov 6 15:57:28 2013 @@ -46,7 +46,7 @@ import org.apache.syncope.common.service import org.apache.syncope.common.services.RoleService; import org.apache.syncope.common.services.SchemaService; import org.apache.syncope.common.services.TaskService; -import org.apache.syncope.common.services.UserRequestService; +import org.apache.syncope.common.services.UserSelfService; import org.apache.syncope.common.services.UserService; import org.apache.syncope.common.services.UserWorkflowService; import org.apache.syncope.common.services.WorkflowService; @@ -87,6 +87,12 @@ public abstract class AbstractTest { protected static final SyncopeClientFactoryBean clientFactory = new SyncopeClientFactoryBean().setAddress(ADDRESS); + protected static final String RESOURCE_NAME_LDAP = "resource-ldap"; + + protected static final String RESOURCE_NAME_TESTDB = "resource-testdb"; + + protected static final String RESOURCE_NAME_CSV = "resource-csv"; + protected static String ANONYMOUS_UNAME; protected static String ANONYMOUS_KEY; @@ -95,6 +101,8 @@ public abstract class AbstractTest { protected static UserService userService; + protected static UserSelfService userSelfService; + protected static UserWorkflowService userWorkflowService; protected static RoleService roleService; @@ -119,8 +127,6 @@ public abstract class AbstractTest { protected static SchemaService schemaService; - protected static UserRequestService userRequestService; - protected static PolicyService policyService; @Autowired @@ -157,6 +163,7 @@ public abstract class AbstractTest { adminClient = clientFactory.create(ADMIN_UNAME, ADMIN_PWD); userService = adminClient.getService(UserService.class); + userSelfService = adminClient.getService(UserSelfService.class); userWorkflowService = adminClient.getService(UserWorkflowService.class); roleService = adminClient.getService(RoleService.class); resourceService = adminClient.getService(ResourceService.class); @@ -170,7 +177,6 @@ public abstract class AbstractTest { workflowService = adminClient.getService(WorkflowService.class); notificationService = adminClient.getService(NotificationService.class); schemaService = adminClient.getService(SchemaService.class); - userRequestService = adminClient.getService(UserRequestService.class); } protected static String getUUIDString() { Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/AuthenticationTestITCase.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/AuthenticationTestITCase.java?rev=1539376&r1=1539375&r2=1539376&view=diff ============================================================================== --- syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/AuthenticationTestITCase.java (original) +++ syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/AuthenticationTestITCase.java Wed Nov 6 15:57:28 2013 @@ -57,6 +57,22 @@ import org.junit.runners.MethodSorters; @FixMethodOrder(MethodSorters.JVM) public class AuthenticationTestITCase extends AbstractTest { + private int getFailedLogins(UserService testUserService, long userId) { + UserTO readUserTO = testUserService.read(userId); + assertNotNull(readUserTO); + assertNotNull(readUserTO.getFailedLogins()); + return readUserTO.getFailedLogins(); + } + + private void assertReadFails(UserService userService, long id) { + try { + userService.read(id); + fail("access should not work"); + } catch (Exception e) { + assertNotNull(e); + } + } + @Test public void testAdminEntitlements() { // 1. as anonymous, read all available entitlements @@ -260,8 +276,8 @@ public class AuthenticationTestITCase ex long userId = userTO.getId(); assertNotNull(userTO); - UserService userService2 = clientFactory.create(userTO.getUsername(), "password123").getService( - UserService.class); + UserService userService2 = clientFactory.create(userTO.getUsername(), "password123"). + getService(UserService.class); assertEquals(0, getFailedLogins(userService2, userId)); // authentications failed ... @@ -274,11 +290,9 @@ public class AuthenticationTestITCase ex assertEquals(3, getFailedLogins(userService, userId)); // last authentication before suspension - userService3 = clientFactory.create(userTO.getUsername(), "wrongpwd1").getService(UserService.class); assertReadFails(userService3, userId); userTO = userService.read(userTO.getId()); - assertNotNull(userTO); assertNotNull(userTO.getFailedLogins()); assertEquals(Integer.valueOf(3), userTO.getFailedLogins()); @@ -342,20 +356,4 @@ public class AuthenticationTestITCase ex role1User = response.readEntity(UserTO.class); assertNotNull(role1User); } - - private int getFailedLogins(UserService testUserService, long userId) { - UserTO readUserTO = testUserService.read(userId); - assertNotNull(readUserTO); - assertNotNull(readUserTO.getFailedLogins()); - return readUserTO.getFailedLogins(); - } - - private void assertReadFails(UserService userService, long id) { - try { - userService.read(id); - fail("access should not work"); - } catch (Exception e) { - assertNotNull(e); - } - } } Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/ResourceTestITCase.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/ResourceTestITCase.java?rev=1539376&r1=1539375&r2=1539376&view=diff ============================================================================== --- syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/ResourceTestITCase.java (original) +++ syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/ResourceTestITCase.java Wed Nov 6 15:57:28 2013 @@ -532,7 +532,7 @@ public class ResourceTestITCase extends @Test public void anonymous() { - ResourceService unauthenticated = clientFactory.create(null, null).getService(ResourceService.class); + ResourceService unauthenticated = clientFactory.createAnonymous().getService(ResourceService.class); try { unauthenticated.list(); fail(); Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/RoleTestITCase.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/RoleTestITCase.java?rev=1539376&r1=1539375&r2=1539376&view=diff ============================================================================== --- syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/RoleTestITCase.java (original) +++ syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/RoleTestITCase.java Wed Nov 6 15:57:28 2013 @@ -503,7 +503,7 @@ public class RoleTestITCase extends Abst @Test public void anonymous() { - RoleService unauthenticated = clientFactory.create(null, null).getService(RoleService.class); + RoleService unauthenticated = clientFactory.createAnonymous().getService(RoleService.class); try { unauthenticated.list(); fail(); Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/SchemaTestITCase.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/SchemaTestITCase.java?rev=1539376&r1=1539375&r2=1539376&view=diff ============================================================================== --- syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/SchemaTestITCase.java (original) +++ syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/SchemaTestITCase.java Wed Nov 6 15:57:28 2013 @@ -284,7 +284,7 @@ public class SchemaTestITCase extends Ab @Test public void anonymous() { - SchemaService unauthenticated = clientFactory.create(null, null).getService(SchemaService.class); + SchemaService unauthenticated = clientFactory.createAnonymous().getService(SchemaService.class); try { unauthenticated.list(AttributableType.USER, SchemaType.VIRTUAL); fail(); Added: syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/UserSelfTestITCase.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/UserSelfTestITCase.java?rev=1539376&view=auto ============================================================================== --- syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/UserSelfTestITCase.java (added) +++ syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/UserSelfTestITCase.java Wed Nov 6 15:57:28 2013 @@ -0,0 +1,222 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.rest; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.security.AccessControlException; +import java.util.Map; +import org.apache.syncope.client.SyncopeClient; +import org.apache.syncope.common.mod.AttributeMod; +import org.apache.syncope.common.mod.MembershipMod; +import org.apache.syncope.common.mod.StatusMod; +import org.apache.syncope.common.mod.UserMod; +import org.apache.syncope.common.services.UserSelfService; +import org.apache.syncope.common.services.UserService; +import org.apache.syncope.common.to.MembershipTO; +import org.apache.syncope.common.to.UserTO; +import org.apache.syncope.common.to.WorkflowFormPropertyTO; +import org.apache.syncope.common.to.WorkflowFormTO; +import org.apache.syncope.common.types.AttributableType; +import org.apache.syncope.common.types.ClientExceptionType; +import org.apache.syncope.common.validation.SyncopeClientException; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +@FixMethodOrder(MethodSorters.JVM) +public class UserSelfTestITCase extends AbstractTest { + + @Test + public void selfRegistrationAllowed() { + assertTrue(clientFactory.createAnonymous().isSelfRegistrationAllowed()); + } + + @Test + public void create() { + // 1. self-registration as admin: failure + try { + userSelfService.create(UserTestITCase.getUniqueSampleTO("anonymous@syncope.apache.org")); + fail(); + } catch (AccessControlException e) { + assertNotNull(e); + } + + // 2. self-registration as anonymous: works + SyncopeClient anonClient = clientFactory.createAnonymous(); + UserTO self = anonClient.getService(UserSelfService.class). + create(UserTestITCase.getUniqueSampleTO("anonymous@syncope.apache.org")). + readEntity(UserTO.class); + assertNotNull(self); + assertEquals("createApproval", self.getStatus()); + } + + @Test + public void createAndApprove() { + // self-create user with membership: goes 'createApproval' with resources and membership but no propagation + UserTO userTO = UserTestITCase.getUniqueSampleTO("anonymous@syncope.apache.org"); + MembershipTO membership = new MembershipTO(); + membership.setRoleId(3L); + userTO.getMemberships().add(membership); + userTO.getResources().add(RESOURCE_NAME_TESTDB); + + SyncopeClient anonClient = clientFactory.createAnonymous(); + userTO = anonClient.getService(UserSelfService.class). + create(userTO). + readEntity(UserTO.class); + assertNotNull(userTO); + assertEquals("createApproval", userTO.getStatus()); + assertFalse(userTO.getMemberships().isEmpty()); + assertFalse(userTO.getResources().isEmpty()); + + try { + resourceService.getConnectorObject(RESOURCE_NAME_TESTDB, AttributableType.USER, userTO.getId()); + fail(); + } catch (SyncopeClientException e) { + assertEquals(ClientExceptionType.NotFound, e.getType()); + } + + // now approve and verify that propagation has happened + WorkflowFormTO form = userWorkflowService.getFormForUser(userTO.getId()); + form = userWorkflowService.claimForm(form.getTaskId()); + Map props = form.getPropertyMap(); + props.get("approve").setValue(Boolean.TRUE.toString()); + form.setProperties(props.values()); + userTO = userWorkflowService.submitForm(form); + assertNotNull(userTO); + assertEquals("active", userTO.getStatus()); + assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_TESTDB, AttributableType.USER, userTO.getId())); + } + + @Test + public void read() { + UserService userService2 = clientFactory.create("rossini", ADMIN_PWD).getService(UserService.class); + + try { + userService2.read(1L); + fail(); + } catch (AccessControlException e) { + assertNotNull(e); + } + + UserSelfService userSelfService2 = clientFactory.create("rossini", ADMIN_PWD).getService(UserSelfService.class); + UserTO userTO = userSelfService2.read(); + assertEquals("rossini", userTO.getUsername()); + } + + @Test + public void updateWithoutApproval() { + // 1. create user as admin + UserTO created = createUser(UserTestITCase.getUniqueSampleTO("anonymous@syncope.apache.org")); + assertNotNull(created); + assertFalse(created.getUsername().endsWith("XX")); + + // 2. self-update (username) - works + UserMod userMod = new UserMod(); + userMod.setUsername(created.getUsername() + "XX"); + + SyncopeClient authClient = clientFactory.create(created.getUsername(), "password123"); + UserTO updated = authClient.getService(UserSelfService.class).update(created.getId(), userMod). + readEntity(UserTO.class); + assertNotNull(updated); + assertEquals("active", updated.getStatus()); + assertTrue(updated.getUsername().endsWith("XX")); + } + + @Test + public void updateWitApproval() { + // 1. create user as admin + UserTO created = createUser(UserTestITCase.getUniqueSampleTO("anonymous@syncope.apache.org")); + assertNotNull(created); + assertFalse(created.getUsername().endsWith("XX")); + + // 2. self-update (username + memberships + resource) - works but needs approval + MembershipMod membershipMod = new MembershipMod(); + membershipMod.setRole(7L); + AttributeMod testAttributeMod = new AttributeMod(); + testAttributeMod.setSchema("testAttribute"); + testAttributeMod.getValuesToBeAdded().add("a value"); + membershipMod.getAttrsToUpdate().add(testAttributeMod); + + UserMod userMod = new UserMod(); + userMod.setUsername(created.getUsername() + "XX"); + userMod.getMembershipsToAdd().add(membershipMod); + userMod.getResourcesToAdd().add(RESOURCE_NAME_TESTDB); + userMod.setPassword("newPassword123"); + StatusMod statusMod = new StatusMod(); + statusMod.setOnSyncope(false); + statusMod.getResourceNames().add(RESOURCE_NAME_TESTDB); + userMod.setPwdPropRequest(statusMod); + + SyncopeClient authClient = clientFactory.create(created.getUsername(), "password123"); + UserTO updated = authClient.getService(UserSelfService.class).update(created.getId(), userMod). + readEntity(UserTO.class); + assertNotNull(updated); + assertEquals("updateApproval", updated.getStatus()); + assertFalse(updated.getUsername().endsWith("XX")); + assertTrue(updated.getMemberships().isEmpty()); + + // no propagation happened + assertTrue(updated.getResources().isEmpty()); + try { + resourceService.getConnectorObject(RESOURCE_NAME_TESTDB, AttributableType.USER, updated.getId()); + fail(); + } catch (SyncopeClientException e) { + assertEquals(ClientExceptionType.NotFound, e.getType()); + } + + // 3. approve self-update as admin + WorkflowFormTO form = userWorkflowService.getFormForUser(updated.getId()); + form = userWorkflowService.claimForm(form.getTaskId()); + Map props = form.getPropertyMap(); + props.get("approve").setValue(Boolean.TRUE.toString()); + form.setProperties(props.values()); + updated = userWorkflowService.submitForm(form); + assertNotNull(updated); + assertEquals("active", updated.getStatus()); + assertTrue(updated.getUsername().endsWith("XX")); + assertEquals(1, updated.getMemberships().size()); + + // check that propagation also happened + assertTrue(updated.getResources().contains(RESOURCE_NAME_TESTDB)); + assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_TESTDB, AttributableType.USER, updated.getId())); + } + + @Test + public void delete() { + UserTO created = createUser(UserTestITCase.getUniqueSampleTO("anonymous@syncope.apache.org")); + assertNotNull(created); + + SyncopeClient authClient = clientFactory.create(created.getUsername(), "password123"); + UserTO deleted = authClient.getService(UserSelfService.class).delete().readEntity(UserTO.class); + assertNotNull(deleted); + assertEquals("deleteApproval", deleted.getStatus()); + } + + @Test + public void issueSYNCOPE373() { + UserTO userTO = userSelfService.read(); + assertEquals(ADMIN_UNAME, userTO.getUsername()); + } + +} Propchange: syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/UserSelfTestITCase.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/UserSelfTestITCase.java ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision HeadURL Propchange: syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/UserSelfTestITCase.java ------------------------------------------------------------------------------ svn:mime-type = text/plain