syncope-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From skylar...@apache.org
Subject [syncope] branch 2_0_X updated: [SYNCOPE-1394] Added unclaim capability for user requests
Date Thu, 29 Nov 2018 15:15:41 GMT
This is an automated email from the ASF dual-hosted git repository.

skylark17 pushed a commit to branch 2_0_X
in repository https://gitbox.apache.org/repos/asf/syncope.git


The following commit(s) were added to refs/heads/2_0_X by this push:
     new 13fd705  [SYNCOPE-1394] Added unclaim capability for user requests
13fd705 is described below

commit 13fd70567ce4552b20e4d108bdd91bcb9adfaac6
Author: skylark17 <matteo.alessandroni@tirasa.net>
AuthorDate: Thu Nov 29 16:15:22 2018 +0100

    [SYNCOPE-1394] Added unclaim capability for user requests
---
 .../console/approvals/ApprovalDirectoryPanel.java  |  36 +++++-
 .../console/rest/UserWorkflowRestClient.java       |   4 +
 .../wicket/markup/html/form/ActionLink.java        |   1 +
 .../client/console/pages/Approvals.properties      |   5 +-
 .../client/console/pages/Approvals_it.properties   |   3 +-
 .../client/console/pages/Approvals_ja.properties   |   3 +-
 .../console/pages/Approvals_pt_BR.properties       |   3 +-
 .../client/console/pages/Approvals_ru.properties   |   5 +-
 .../wicket/markup/html/form/ActionPanel.properties |   4 +
 .../console/widgets/ApprovalsWidget.properties     |   2 +-
 .../console/widgets/ApprovalsWidget_it.properties  |   2 +-
 .../console/widgets/ApprovalsWidget_ja.properties  |   2 +-
 .../widgets/ApprovalsWidget_pt_BR.properties       |   2 +-
 .../console/widgets/ApprovalsWidget_ru.properties  |   2 +-
 .../syncope/common/lib/to/WorkflowFormTO.java      |  10 +-
 .../common/lib/types/StandardEntitlement.java      |   2 +
 .../rest/api/service/UserWorkflowService.java      |  14 ++-
 .../syncope/core/logic/UserWorkflowLogic.java      |   6 +-
 .../rest/cxf/service/UserWorkflowServiceImpl.java  |   5 +
 .../activiti/ActivitiUserWorkflowAdapter.java      |  42 ++++++-
 .../syncope/core/workflow/api/WorkflowAdapter.java |   8 ++
 .../flowable/FlowableUserWorkflowAdapter.java      |  42 ++++++-
 .../java/DefaultAnyObjectWorkflowAdapter.java      |   5 +
 .../workflow/java/DefaultGroupWorkflowAdapter.java |   5 +
 .../workflow/java/DefaultUserWorkflowAdapter.java  |   5 +
 .../apache/syncope/fit/core/UserSelfITCase.java    |  55 ++++++++-
 .../syncope/fit/core/UserWorkflowITCase.java       | 123 ++++++++++++++++++++-
 27 files changed, 360 insertions(+), 36 deletions(-)

diff --git a/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDirectoryPanel.java
b/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDirectoryPanel.java
index 7722202..d272ba8 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDirectoryPanel.java
@@ -126,7 +126,7 @@ public class ApprovalDirectoryPanel
         columns.add(new DatePropertyColumn<WorkflowFormTO>(
                 new ResourceModel("dueDate"), "dueDate", "dueDate"));
         columns.add(new PropertyColumn<WorkflowFormTO, String>(
-                new ResourceModel("owner"), "owner", "owner"));
+                new ResourceModel("assignee"), "assignee", "assignee"));
 
         return columns;
     }
@@ -146,10 +146,32 @@ public class ApprovalDirectoryPanel
                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
                 target.add(container);
             }
+
         }, ActionLink.ActionType.CLAIM, StandardEntitlement.WORKFLOW_FORM_CLAIM);
 
         panel.add(new ActionLink<WorkflowFormTO>() {
 
+            private static final long serialVersionUID = -8250444429732720947L;
+
+            @Override
+            public void onClick(final AjaxRequestTarget target, final WorkflowFormTO ignore)
{
+                unclaimForm(model.getObject().getTaskId());
+                SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
+                ApprovalDirectoryPanel.this.getTogglePanel().close(target);
+                target.add(container);
+                ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
+            }
+
+            @Override
+            protected boolean statusCondition(final WorkflowFormTO modelObject) {
+                return SyncopeConsoleSession.get().getSelfTO().getUsername().
+                        equals(model.getObject().getAssignee());
+            }
+
+        }, ActionLink.ActionType.UNCLAIM, StandardEntitlement.WORKFLOW_FORM_UNCLAIM);
+
+        panel.add(new ActionLink<WorkflowFormTO>() {
+
             private static final long serialVersionUID = -3722207913631435501L;
 
             @Override
@@ -182,7 +204,7 @@ public class ApprovalDirectoryPanel
             @Override
             protected boolean statusCondition(final WorkflowFormTO modelObject) {
                 return SyncopeConsoleSession.get().getSelfTO().getUsername().
-                        equals(model.getObject().getOwner());
+                        equals(model.getObject().getAssignee());
             }
 
         }, ActionLink.ActionType.MANAGE_APPROVAL, StandardEntitlement.WORKFLOW_FORM_READ);
@@ -234,7 +256,7 @@ public class ApprovalDirectoryPanel
             @Override
             protected boolean statusCondition(final WorkflowFormTO modelObject) {
                 return SyncopeConsoleSession.get().getSelfTO().getUsername().
-                        equals(model.getObject().getOwner());
+                        equals(model.getObject().getAssignee());
             }
 
         }, ActionLink.ActionType.EDIT_APPROVAL, StandardEntitlement.WORKFLOW_FORM_SUBMIT);
@@ -302,6 +324,14 @@ public class ApprovalDirectoryPanel
         }
     }
 
+    private void unclaimForm(final String taskId) {
+        try {
+            restClient.unclaimForm(taskId);
+        } catch (SyncopeClientException scee) {
+            SyncopeConsoleSession.get().error(getString(Constants.ERROR) + ": " + scee.getMessage());
+        }
+    }
+
     private class ApprovalUserWizardBuilder extends UserWizardBuilder {
 
         private static final long serialVersionUID = 1854981134836384069L;
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/UserWorkflowRestClient.java
b/client/console/src/main/java/org/apache/syncope/client/console/rest/UserWorkflowRestClient.java
index 8ccf057..6dda0bc 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/UserWorkflowRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/UserWorkflowRestClient.java
@@ -49,6 +49,10 @@ public class UserWorkflowRestClient extends BaseRestClient {
         return getService(UserWorkflowService.class).claimForm(taskKey);
     }
 
+    public WorkflowFormTO unclaimForm(final String taskKey) {
+        return getService(UserWorkflowService.class).unclaimForm(taskKey);
+    }
+
     public void submitForm(final WorkflowFormTO form) {
         getService(UserWorkflowService.class).submitForm(form);
     }
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java
b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java
index d8e8f77..8d6cb60 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java
@@ -68,6 +68,7 @@ public abstract class ActionLink<T extends Serializable> implements
Serializable
         REQUEST_PASSWORD_RESET("update"),
         DRYRUN("execute"),
         CLAIM("claim"),
+        UNCLAIM("unclaim"),
         SELECT("read"),
         CLOSE("read"),
         EXPORT("read"),
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Approvals.properties
b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Approvals.properties
index 1ea8063..4ccf481 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Approvals.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Approvals.properties
@@ -19,8 +19,9 @@ key=Key
 description=Description
 createTime=Create Time
 dueDate=Due Date
-owner=Owner
+assignee=Assignee
 claim=Claim
+unclaim=Unclaim
 manage=Manage
 approvals=Approvals
 delete=Delete
@@ -28,7 +29,7 @@ type=Type
 username=Username
 new_user=New User
 creationDate = Creation Date
-claimDate = Claim Dare
+claimDate = Claim Date
 approval.edit=Approval Edit
 approval.manage=Approval Manage
 any.edit=Edit ${anyTO.type} ${anyTO.username}
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_it.properties
b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_it.properties
index 7e12ce5..37e0406 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_it.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_it.properties
@@ -19,8 +19,9 @@ key=Chiave
 description=Descrizione
 createTime=Data di creazione
 dueDate=Scadenza
-owner=Esecutore
+assignee=Esecutore
 claim=Richiedi
+unclaim=Annulla richiesta
 manage=Gestisci
 approvals=Approvazioni
 delete=Rimuovi
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_ja.properties
b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_ja.properties
index b2ff626..ae74807 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_ja.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_ja.properties
@@ -19,8 +19,9 @@ key=\u30ad\u30fc
 description=\u8aac\u660e
 createTime=\u4f5c\u6210\u6642\u523b
 dueDate=\u671f\u9650
-owner=\u30aa\u30fc\u30ca\u30fc
+assignee=\u30aa\u30fc\u30ca\u30fc
 claim=\u7533\u8acb
+unclaim=\u7533\u3057\u7acb\u3066\u3092\u53d6\u308a\u6d88\u3059
 manage=\u7ba1\u7406
 approvals=\u627f\u8a8d
 delete=\u524a\u9664
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_pt_BR.properties
b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_pt_BR.properties
index e5ff74c..aa878f3 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_pt_BR.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_pt_BR.properties
@@ -19,8 +19,9 @@ key=Chave
 description=Descri\u00e7\u00e3o
 createTime=Tempo de Cria\u00e7\u00e3o
 dueDate=Data acordada
-owner=Propriet\u00e1rio
+assignee=Propriet\u00e1rio
 claim=Requerimento
+unclaim=Cancelar requerimento
 manage=Ger\u00eancia
 approvals=Aprova\u00e7\u00f5es
 delete=Excluir
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_ru.properties
b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_ru.properties
index 6f4fb58..18d3476 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_ru.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/pages/Approvals_ru.properties
@@ -25,10 +25,11 @@ description=\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435
 createTime=\u0414\u0430\u0442\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f
 # dueDate=\u00d0\u00a1\u00d1\u0080\u00d0\u00be\u00d0\u00ba
 dueDate=\u0421\u0440\u043e\u043a
-# owner=\u00d0\u0092\u00d0\u00bb\u00d0\u00b0\u00d0\u00b4\u00d0\u00b5\u00d0\u00bb\u00d0\u00b5\u00d1\u0086
-owner=\u0412\u043b\u0430\u0434\u0435\u043b\u0435\u0446
+# assignee=\u00d0\u0092\u00d0\u00bb\u00d0\u00b0\u00d0\u00b4\u00d0\u00b5\u00d0\u00bb\u00d0\u00b5\u00d1\u0086
+assignee=\u0412\u043b\u0430\u0434\u0435\u043b\u0435\u0446
 # claim=\u00d0\u0092\u00d1\u008b\u00d0\u00bf\u00d0\u00be\u00d0\u00bb\u00d0\u00bd\u00d0\u00b8\u00d1\u0082\u00d1\u008c
\u00d1\u0081\u00d0\u00be\u00d0\u00b3\u00d0\u00bb\u00d0\u00b0\u00d1\u0081\u00d0\u00be\u00d0\u00b2\u00d0\u00b0\u00d0\u00bd\u00d0\u00b8\u00d0\u00b5
 claim=\u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0441\u043e\u0433\u043b\u0430\u0441\u043e\u0432\u0430\u043d\u0438\u0435
+unclaim=\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441
 # manage=\u00d0\u00a3\u00d0\u00bf\u00d1\u0080\u00d0\u00b0\u00d0\u00b2\u00d0\u00bb\u00d0\u00b5\u00d0\u00bd\u00d0\u00b8\u00d0\u00b5
 manage=\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435
 # approvals=\u00d0\u0097\u00d0\u00b0\u00d1\u008f\u00d0\u00b2\u00d0\u00ba\u00d0\u00b8
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionPanel.properties
b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionPanel.properties
index 1086b88..819ed50 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionPanel.properties
@@ -142,6 +142,10 @@ claim.class=fa fa-ticket
 claim.title=claim
 claim.alt=claim icon
 
+unclaim.class=fa fa-undo
+unclaim.title=unclaim
+unclaim.alt=unclaim icon
+
 select.class=glyphicon glyphicon-ok
 select.title=select
 select.alt=select icon
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ApprovalsWidget.properties
b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ApprovalsWidget.properties
index dd5b98f..47f6b8c 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ApprovalsWidget.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ApprovalsWidget.properties
@@ -16,6 +16,6 @@
 # under the License.
 alerts.view.all=View all approvals
 duedate=Due date
-owner=Owner
+assignee=Assignee
 createApproval=Create Approval
 summary=${number} pending approval(s)
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ApprovalsWidget_it.properties
b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ApprovalsWidget_it.properties
index 7b2287e..63bbe4b 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ApprovalsWidget_it.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ApprovalsWidget_it.properties
@@ -16,6 +16,6 @@
 # under the License.
 alerts.view.all=Tutte le approvazioni
 duedate=Scadenza
-owner=Assegnato
+assignee=Assegnato
 createApproval=Approvazione Creazione
 summary=${number} approvazioni pendenti
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ApprovalsWidget_ja.properties
b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ApprovalsWidget_ja.properties
index a6089eb..385d98b 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ApprovalsWidget_ja.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ApprovalsWidget_ja.properties
@@ -16,6 +16,6 @@
 # under the License.
 alerts.view.all=\u3059\u3079\u3066\u306e\u627f\u8a8d\u3092\u8868\u793a
 duedate=\u671f\u9650
-owner=\u30aa\u30fc\u30ca\u30fc
+assignee=\u30aa\u30fc\u30ca\u30fc
 createApproval=\u627f\u8a8d\u3092\u4f5c\u6210
 summary=${number} \u4fdd\u7559\u306e\u627f\u8a8d
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ApprovalsWidget_pt_BR.properties
b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ApprovalsWidget_pt_BR.properties
index c24f3d8..6b708e9 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ApprovalsWidget_pt_BR.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ApprovalsWidget_pt_BR.properties
@@ -16,6 +16,6 @@
 # under the License.
 alerts.view.all=View all Approvals
 duedate=Due date
-owner=Owner
+assignee=Assignee
 createApproval=Create Approval
 summary=${number} pending approval(s)
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ApprovalsWidget_ru.properties
b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ApprovalsWidget_ru.properties
index 10281ff..ac3734f 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ApprovalsWidget_ru.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/widgets/ApprovalsWidget_ru.properties
@@ -17,6 +17,6 @@
 #
 alerts.view.all=\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432\u0441\u0435
\u0437\u0430\u044f\u0432\u043a\u0438
 duedate=\u0421\u0440\u043e\u043a
-owner=\u0412\u043b\u0430\u0434\u0435\u043b\u0435\u0446
+assignee=\u0412\u043b\u0430\u0434\u0435\u043b\u0435\u0446
 createApproval=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0437\u0430\u044f\u0432\u043a\u0443
 summary=\u041e\u0436\u0438\u0434\u0430\u044e\u0442 \u0441\u043e\u0433\u043b\u0430\u0441\u043e\u0432\u0430\u043d\u0438\u044f:
${number}
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/WorkflowFormTO.java
b/common/lib/src/main/java/org/apache/syncope/common/lib/to/WorkflowFormTO.java
index 0e80be6..f2bafb3 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/WorkflowFormTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/WorkflowFormTO.java
@@ -48,7 +48,7 @@ public class WorkflowFormTO extends AbstractBaseBean {
 
     private Date dueDate;
 
-    private String owner;
+    private String assignee;
 
     private UserTO userTO;
 
@@ -110,12 +110,12 @@ public class WorkflowFormTO extends AbstractBaseBean {
         }
     }
 
-    public String getOwner() {
-        return owner;
+    public String getAssignee() {
+        return assignee;
     }
 
-    public void setOwner(final String owner) {
-        this.owner = owner;
+    public void setAssignee(final String assignee) {
+        this.assignee = assignee;
     }
 
     public UserTO getUserTO() {
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/StandardEntitlement.java
b/common/lib/src/main/java/org/apache/syncope/common/lib/types/StandardEntitlement.java
index 99c66d7..70c03fe 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/StandardEntitlement.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/StandardEntitlement.java
@@ -208,6 +208,8 @@ public final class StandardEntitlement {
 
     public static final String WORKFLOW_FORM_CLAIM = "WORKFLOW_FORM_CLAIM";
 
+    public static final String WORKFLOW_FORM_UNCLAIM = "WORKFLOW_FORM_UNCLAIM";
+
     public static final String WORKFLOW_FORM_SUBMIT = "WORKFLOW_FORM_SUBMIT";
 
     public static final String MAIL_TEMPLATE_LIST = "MAIL_TEMPLATE_LIST";
diff --git a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserWorkflowService.java
b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserWorkflowService.java
index d89f250..47cd160 100644
--- a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserWorkflowService.java
+++ b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserWorkflowService.java
@@ -41,7 +41,8 @@ import org.apache.syncope.common.rest.api.beans.WorkflowFormQuery;
  * REST operations related to user workflow.
  */
 @Api(tags = "UserWorkflow", authorizations = {
-    @Authorization(value = "BasicAuthentication"),
+    @Authorization(value = "BasicAuthentication")
+    ,
     @Authorization(value = "Bearer") })
 @Path("userworkflow")
 public interface UserWorkflowService extends JAXRSService {
@@ -80,6 +81,17 @@ public interface UserWorkflowService extends JAXRSService {
     WorkflowFormTO claimForm(@NotNull @PathParam("taskId") String taskId);
 
     /**
+     * Unclaims the form for the given task id.
+     *
+     * @param taskId workflow task id
+     * @return the workflow form for the given task id
+     */
+    @POST
+    @Path("forms/{taskId}/unclaim")
+    @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, MediaType.APPLICATION_XML
})
+    WorkflowFormTO unclaimForm(@NotNull @PathParam("taskId") String taskId);
+
+    /**
      * Submits a workflow form.
      *
      * @param form workflow form.
diff --git a/core/logic/src/main/java/org/apache/syncope/core/logic/UserWorkflowLogic.java
b/core/logic/src/main/java/org/apache/syncope/core/logic/UserWorkflowLogic.java
index dabf93b..4fb0c64 100644
--- a/core/logic/src/main/java/org/apache/syncope/core/logic/UserWorkflowLogic.java
+++ b/core/logic/src/main/java/org/apache/syncope/core/logic/UserWorkflowLogic.java
@@ -60,11 +60,15 @@ public class UserWorkflowLogic extends AbstractTransactionalLogic<WorkflowFormTO
     private UserDAO userDAO;
 
     @PreAuthorize("hasRole('" + StandardEntitlement.WORKFLOW_FORM_CLAIM + "')")
-
     public WorkflowFormTO claimForm(final String taskId) {
         return uwfAdapter.claimForm(taskId);
     }
 
+    @PreAuthorize("hasRole('" + StandardEntitlement.WORKFLOW_FORM_UNCLAIM + "')")
+    public WorkflowFormTO unclaimForm(final String taskId) {
+        return uwfAdapter.unclaimForm(taskId);
+    }
+
     @PreAuthorize("hasRole('" + StandardEntitlement.USER_UPDATE + "')")
     public UserTO executeWorkflowTask(final UserTO userTO, final String taskId) {
         WorkflowResult<String> updated = uwfAdapter.execute(userTO, taskId);
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserWorkflowServiceImpl.java
b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserWorkflowServiceImpl.java
index 7a25cb8..643baf3 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserWorkflowServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/UserWorkflowServiceImpl.java
@@ -42,6 +42,11 @@ public class UserWorkflowServiceImpl extends AbstractServiceImpl implements
User
     }
 
     @Override
+    public WorkflowFormTO unclaimForm(final String taskId) {
+        return logic.unclaimForm(taskId);
+    }
+
+    @Override
     public UserTO executeTask(final String taskId, final UserTO userTO) {
         return logic.executeWorkflowTask(userTO, taskId);
     }
diff --git a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
index a1c63a7..f85fdf6 100644
--- a/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
+++ b/core/workflow-activiti/src/main/java/org/apache/syncope/core/workflow/activiti/ActivitiUserWorkflowAdapter.java
@@ -52,9 +52,13 @@ import org.activiti.engine.repository.Deployment;
 import org.activiti.engine.repository.Model;
 import org.activiti.engine.repository.ProcessDefinition;
 import org.activiti.engine.runtime.ProcessInstance;
+import org.activiti.engine.task.IdentityLink;
+import org.activiti.engine.task.IdentityLinkType;
 import org.activiti.engine.task.Task;
 import org.activiti.engine.task.TaskQuery;
 import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
 import org.apache.commons.collections4.Transformer;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -767,9 +771,25 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter
{
             }
         }
 
+        boolean hasAssignees = IterableUtils.matchesAny(engine.getTaskService().getIdentityLinksForTask(taskId),
+                new Predicate<IdentityLink>() {
+
+            @Override
+            public boolean evaluate(final IdentityLink identityLink) {
+                return IdentityLinkType.ASSIGNEE.equals(identityLink.getType());
+            }
+        });
+        if (hasAssignees) {
+            try {
+                engine.getTaskService().unclaim(taskId);
+            } catch (ActivitiException e) {
+                throw new WorkflowException("While unclaiming task " + taskId, e);
+            }
+        }
+
         Task task;
         try {
-            engine.getTaskService().setOwner(taskId, authUser);
+            engine.getTaskService().claim(taskId, authUser);
             task = engine.getTaskService().createTaskQuery().taskId(taskId).singleResult();
         } catch (ActivitiException e) {
             throw new WorkflowException("While reading task " + taskId, e);
@@ -778,6 +798,22 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter
{
         return getFormTO(task, checked.getValue());
     }
 
+    @Override
+    public WorkflowFormTO unclaimForm(final String taskId) {
+        String authUser = AuthContextUtils.getUsername();
+        Pair<Task, TaskFormData> checked = checkTask(taskId, authUser);
+
+        Task task;
+        try {
+            engine.getTaskService().unclaim(taskId);
+            task = engine.getTaskService().createTaskQuery().taskId(taskId).singleResult();
+        } catch (ActivitiException e) {
+            throw new WorkflowException("While unclaiming task " + taskId, e);
+        }
+
+        return getFormTO(task, checked.getValue());
+    }
+
     private Map<String, String> getPropertiesForSubmit(final WorkflowFormTO form) {
         Map<String, String> props = new HashMap<>();
         for (WorkflowFormPropertyTO prop : form.getProperties()) {
@@ -794,9 +830,9 @@ public class ActivitiUserWorkflowAdapter extends AbstractUserWorkflowAdapter
{
         String authUser = AuthContextUtils.getUsername();
         Pair<Task, TaskFormData> checked = checkTask(form.getTaskId(), authUser);
 
-        if (!checked.getKey().getOwner().equals(authUser)) {
+        if (!checked.getKey().getAssignee().equals(authUser)) {
             throw new WorkflowException(new IllegalArgumentException("Task " + form.getTaskId()
+ " assigned to "
-                    + checked.getKey().getOwner() + " but submitted by " + authUser));
+                    + checked.getKey().getAssignee() + " but submitted by " + authUser));
         }
 
         User user = userDAO.findByWorkflowId(checked.getKey().getProcessInstanceId());
diff --git a/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/WorkflowAdapter.java
b/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/WorkflowAdapter.java
index 515d05f..f95ede7 100644
--- a/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/WorkflowAdapter.java
+++ b/core/workflow-api/src/main/java/org/apache/syncope/core/workflow/api/WorkflowAdapter.java
@@ -65,6 +65,14 @@ public interface WorkflowAdapter {
     WorkflowFormTO claimForm(String taskId);
 
     /**
+     * Unclaim a form for a given object.
+     *
+     * @param taskId Workflow task to which the form is associated
+     * @return updated form
+     */
+    WorkflowFormTO unclaimForm(String taskId);
+
+    /**
      * Submit a form.
      *
      * @param form to be submitted
diff --git a/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/FlowableUserWorkflowAdapter.java
b/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/FlowableUserWorkflowAdapter.java
index 4e50994..d8d2221 100644
--- a/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/FlowableUserWorkflowAdapter.java
+++ b/core/workflow-flowable/src/main/java/org/apache/syncope/core/workflow/flowable/FlowableUserWorkflowAdapter.java
@@ -51,9 +51,13 @@ import org.activiti.engine.repository.Deployment;
 import org.activiti.engine.repository.Model;
 import org.activiti.engine.repository.ProcessDefinition;
 import org.activiti.engine.runtime.ProcessInstance;
+import org.activiti.engine.task.IdentityLink;
+import org.activiti.engine.task.IdentityLinkType;
 import org.activiti.engine.task.Task;
 import org.activiti.engine.task.TaskQuery;
 import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
 import org.apache.commons.collections4.Transformer;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -766,9 +770,25 @@ public class FlowableUserWorkflowAdapter extends AbstractUserWorkflowAdapter
{
             }
         }
 
+        boolean hasAssignees = IterableUtils.matchesAny(engine.getTaskService().getIdentityLinksForTask(taskId),
+                new Predicate<IdentityLink>() {
+
+            @Override
+            public boolean evaluate(final IdentityLink identityLink) {
+                return IdentityLinkType.ASSIGNEE.equals(identityLink.getType());
+            }
+        });
+        if (hasAssignees) {
+            try {
+                engine.getTaskService().unclaim(taskId);
+            } catch (ActivitiException e) {
+                throw new WorkflowException("While unclaiming task " + taskId, e);
+            }
+        }
+
         Task task;
         try {
-            engine.getTaskService().setOwner(taskId, authUser);
+            engine.getTaskService().claim(taskId, authUser);
             task = engine.getTaskService().createTaskQuery().taskId(taskId).singleResult();
         } catch (ActivitiException e) {
             throw new WorkflowException("While reading task " + taskId, e);
@@ -777,6 +797,22 @@ public class FlowableUserWorkflowAdapter extends AbstractUserWorkflowAdapter
{
         return getFormTO(task, checked.getValue());
     }
 
+    @Override
+    public WorkflowFormTO unclaimForm(final String taskId) {
+        String authUser = AuthContextUtils.getUsername();
+        Pair<Task, TaskFormData> checked = checkTask(taskId, authUser);
+
+        Task task;
+        try {
+            engine.getTaskService().unclaim(taskId);
+            task = engine.getTaskService().createTaskQuery().taskId(taskId).singleResult();
+        } catch (ActivitiException e) {
+            throw new WorkflowException("While unclaiming task " + taskId, e);
+        }
+
+        return getFormTO(task, checked.getValue());
+    }
+
     private Map<String, String> getPropertiesForSubmit(final WorkflowFormTO form) {
         Map<String, String> props = new HashMap<>();
         for (WorkflowFormPropertyTO prop : form.getProperties()) {
@@ -793,9 +829,9 @@ public class FlowableUserWorkflowAdapter extends AbstractUserWorkflowAdapter
{
         String authUser = AuthContextUtils.getUsername();
         Pair<Task, TaskFormData> checked = checkTask(form.getTaskId(), authUser);
 
-        if (!checked.getKey().getOwner().equals(authUser)) {
+        if (!checked.getKey().getAssignee().equals(authUser)) {
             throw new WorkflowException(new IllegalArgumentException("Task " + form.getTaskId()
+ " assigned to "
-                    + checked.getKey().getOwner() + " but submitted by " + authUser));
+                    + checked.getKey().getAssignee() + " but submitted by " + authUser));
         }
 
         User user = userDAO.findByWorkflowId(checked.getKey().getProcessInstanceId());
diff --git a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultAnyObjectWorkflowAdapter.java
b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultAnyObjectWorkflowAdapter.java
index c51d3a4..0975928 100644
--- a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultAnyObjectWorkflowAdapter.java
+++ b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultAnyObjectWorkflowAdapter.java
@@ -91,6 +91,11 @@ public class DefaultAnyObjectWorkflowAdapter extends AbstractAnyObjectWorkflowAd
     }
 
     @Override
+    public WorkflowFormTO unclaimForm(final String taskId) {
+        throw new WorkflowException(new UnsupportedOperationException("Not supported."));
+    }
+
+    @Override
     public WorkflowResult<AnyObjectPatch> submitForm(final WorkflowFormTO form) {
         throw new WorkflowException(new UnsupportedOperationException("Not supported."));
     }
diff --git a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultGroupWorkflowAdapter.java
b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultGroupWorkflowAdapter.java
index c50dcbd..0518e59 100644
--- a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultGroupWorkflowAdapter.java
+++ b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultGroupWorkflowAdapter.java
@@ -89,6 +89,11 @@ public class DefaultGroupWorkflowAdapter extends AbstractGroupWorkflowAdapter
{
     public WorkflowFormTO claimForm(final String taskId) {
         throw new WorkflowException(new UnsupportedOperationException("Not supported."));
     }
+    
+    @Override
+    public WorkflowFormTO unclaimForm(final String taskId) {
+        throw new WorkflowException(new UnsupportedOperationException("Not supported."));
+    }
 
     @Override
     public WorkflowResult<GroupPatch> submitForm(final WorkflowFormTO form) {
diff --git a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java
b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java
index 1847828..7d458cd 100644
--- a/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java
+++ b/core/workflow-java/src/main/java/org/apache/syncope/core/workflow/java/DefaultUserWorkflowAdapter.java
@@ -179,6 +179,11 @@ public class DefaultUserWorkflowAdapter extends AbstractUserWorkflowAdapter
{
     }
 
     @Override
+    public WorkflowFormTO unclaimForm(final String taskId) {
+        throw new WorkflowException(new UnsupportedOperationException("Not supported."));
+    }
+
+    @Override
     public WorkflowResult<UserPatch> submitForm(final WorkflowFormTO form) {
         throw new WorkflowException(new UnsupportedOperationException("Not supported."));
     }
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserSelfITCase.java
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserSelfITCase.java
index 25c8edc..c39a16c 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserSelfITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserSelfITCase.java
@@ -103,7 +103,7 @@ public class UserSelfITCase extends AbstractITCase {
     public void createAndApprove() {
         Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
 
-        // self-create user with membership: goes 'createApproval' with resources and membership
but no propagation
+        // 1. self-create user with membership: goes 'createApproval' with resources and
membership but no propagation
         UserTO userTO = UserITCase.getUniqueSampleTO("anonymous@syncope.apache.org");
         userTO.getMemberships().add(
                 new MembershipTO.Builder().group("29f96485-729e-4d31-88a1-6fc60e4677f3").build());
@@ -126,7 +126,7 @@ public class UserSelfITCase extends AbstractITCase {
             assertEquals(ClientExceptionType.NotFound, e.getType());
         }
 
-        // now approve and verify that propagation has happened
+        // 2. approve and verify that propagation has happened
         WorkflowFormTO form = userWorkflowService.getFormForUser(userTO.getKey());
         form = userWorkflowService.claimForm(form.getTaskId());
         form.getProperty("approveCreate").setValue(Boolean.TRUE.toString());
@@ -137,6 +137,57 @@ public class UserSelfITCase extends AbstractITCase {
     }
 
     @Test
+    public void createAndUnclaim() {
+        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
+
+        // 1. self-create user with membership: goes 'createApproval' with resources and
membership but no propagation
+        UserTO userTO = UserITCase.getUniqueSampleTO("anonymous@syncope.apache.org");
+        userTO.getMemberships().add(
+                new MembershipTO.Builder().group("29f96485-729e-4d31-88a1-6fc60e4677f3").build());
+        userTO.getResources().add(RESOURCE_NAME_TESTDB);
+
+        SyncopeClient anonClient = clientFactory.create();
+        userTO = anonClient.getService(UserSelfService.class).
+                create(userTO, true).
+                readEntity(new GenericType<ProvisioningResult<UserTO>>() {
+                }).getEntity();
+        assertNotNull(userTO);
+        assertEquals("createApproval", userTO.getStatus());
+        assertFalse(userTO.getMemberships().isEmpty());
+        assertFalse(userTO.getResources().isEmpty());
+
+        try {
+            resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(),
userTO.getKey());
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
+        }
+
+        // 2. unclaim and verify that propagation has NOT happened
+        WorkflowFormTO form = userWorkflowService.getFormForUser(userTO.getKey());
+        form = userWorkflowService.unclaimForm(form.getTaskId());
+        assertNull(form.getAssignee());
+        assertNotNull(userTO);
+        assertNotEquals("active", userTO.getStatus());
+        try {
+            resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(),
userTO.getKey());
+            fail();
+        } catch (Exception e) {
+            assertNotNull(e);
+        }
+
+        // 3. approve and verify that propagation has happened
+        form = userWorkflowService.getFormForUser(userTO.getKey());
+        form = userWorkflowService.claimForm(form.getTaskId());
+        form.getProperty("approveCreate").setValue(Boolean.TRUE.toString());
+        assertNotNull(form.getAssignee());
+        userTO = userWorkflowService.submitForm(form);
+        assertNotNull(userTO);
+        assertEquals("active", userTO.getStatus());
+        assertNotNull(resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(),
userTO.getKey()));
+    }
+
+    @Test
     public void read() {
         UserService userService2 = clientFactory.create("rossini", ADMIN_PWD).getService(UserService.class);
 
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserWorkflowITCase.java
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserWorkflowITCase.java
index 0338105..f1f92a8 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserWorkflowITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserWorkflowITCase.java
@@ -93,7 +93,7 @@ public class UserWorkflowITCase extends AbstractITCase {
         assertNotNull(form.getUsername());
         assertEquals(userTO.getUsername(), form.getUsername());
         assertNotNull(form.getTaskId());
-        assertNull(form.getOwner());
+        assertNull(form.getAssignee());
 
         // 3. claim task as rossini, with role "User manager" granting entitlement to claim
forms but not in group 7,
         // designated for approval in workflow definition: fail
@@ -122,7 +122,7 @@ public class UserWorkflowITCase extends AbstractITCase {
         form = userService3.claimForm(form.getTaskId());
         assertNotNull(form);
         assertNotNull(form.getTaskId());
-        assertNotNull(form.getOwner());
+        assertNotNull(form.getAssignee());
 
         // 5. reject user
         form.getProperty("approveCreate").setValue(Boolean.FALSE.toString());
@@ -196,7 +196,7 @@ public class UserWorkflowITCase extends AbstractITCase {
         assertNotNull(form.getUserTO());
         assertEquals(updatedUsername, form.getUserTO().getUsername());
         assertNull(form.getUserPatch());
-        assertNull(form.getOwner());
+        assertNull(form.getAssignee());
 
         // 4. claim task (as admin)
         form = userWorkflowService.claimForm(form.getTaskId());
@@ -205,7 +205,7 @@ public class UserWorkflowITCase extends AbstractITCase {
         assertNotNull(form.getUserTO());
         assertEquals(updatedUsername, form.getUserTO().getUsername());
         assertNull(form.getUserPatch());
-        assertNotNull(form.getOwner());
+        assertNotNull(form.getAssignee());
 
         // 5. approve user (and verify that propagation occurred)
         form.getProperty("approveCreate").setValue(Boolean.TRUE.toString());
@@ -229,6 +229,117 @@ public class UserWorkflowITCase extends AbstractITCase {
     }
 
     @Test
+    public void createAndUnclaim() {
+        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
+
+        // read forms *before* any operation
+        PagedResult<WorkflowFormTO> forms =
+                userWorkflowService.getForms(new WorkflowFormQuery.Builder().page(1).size(1000).build());
+        int preForms = forms.getTotalCount();
+
+        UserTO userTO = UserITCase.getUniqueSampleTO("createWithUnclaim@syncope.apache.org");
+        userTO.getResources().add(RESOURCE_NAME_TESTDB);
+
+        // User with group 0cbcabd2-4410-4b6b-8f05-a052b451d18f are defined in workflow as
subject to approval
+        userTO.getMemberships().add(
+                new MembershipTO.Builder().group("0cbcabd2-4410-4b6b-8f05-a052b451d18f").build());
+
+        // 1. create user and verify that no propagation occurred)
+        ProvisioningResult<UserTO> result = createUser(userTO);
+        assertNotNull(result);
+        userTO = result.getEntity();
+        assertEquals(1, userTO.getMemberships().size());
+        assertEquals("0cbcabd2-4410-4b6b-8f05-a052b451d18f", userTO.getMemberships().get(0).getGroupKey());
+        assertEquals("createApproval", userTO.getStatus());
+        assertEquals(Collections.singleton(RESOURCE_NAME_TESTDB), userTO.getResources());
+
+        assertTrue(result.getPropagationStatuses().isEmpty());
+
+        JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+
+        Exception exception = null;
+        try {
+            jdbcTemplate.queryForObject("SELECT id FROM test WHERE id=?",
+                    new String[] { userTO.getUsername() }, Integer.class);
+        } catch (EmptyResultDataAccessException e) {
+            exception = e;
+        }
+        assertNotNull(exception);
+
+        // 2. request if there is any pending form for user just created
+        forms = userWorkflowService.getForms(new WorkflowFormQuery.Builder().page(1).size(1000).build());
+        assertEquals(preForms + 1, forms.getTotalCount());
+
+        // 3. as admin, request for changes: still pending approval
+        String updatedUsername = "changed-" + UUID.randomUUID().toString();
+        userTO.setUsername(updatedUsername);
+        userWorkflowService.executeTask("default", userTO);
+
+        WorkflowFormTO form = userWorkflowService.getFormForUser(userTO.getKey());
+        assertNotNull(form);
+        assertNotNull(form.getTaskId());
+        assertNotNull(form.getUserTO());
+        assertEquals(updatedUsername, form.getUserTO().getUsername());
+        assertNull(form.getUserPatch());
+        assertNull(form.getAssignee());
+
+        // 4. claim task (as admin)
+        form = userWorkflowService.claimForm(form.getTaskId());
+        assertNotNull(form);
+        assertNotNull(form.getTaskId());
+        assertNotNull(form.getUserTO());
+        assertEquals(updatedUsername, form.getUserTO().getUsername());
+        assertNull(form.getUserPatch());
+        assertNotNull(form.getAssignee());
+
+        // 5. UNclaim task (as admin) and verify there is NO assignee now
+        form = userWorkflowService.unclaimForm(form.getTaskId());
+        assertNotNull(form);
+        assertNotNull(form.getTaskId());
+        assertNotNull(form.getUserTO());
+        assertNull(form.getAssignee());
+
+        // 6. verify that propagation still did NOT occur
+        exception = null;
+        try {
+            jdbcTemplate.queryForObject("SELECT id FROM test WHERE id=?",
+                    new String[] { userTO.getUsername() }, Integer.class);
+        } catch (EmptyResultDataAccessException e) {
+            exception = e;
+        }
+        assertNotNull(exception);
+        
+        // 7. claim task again (as admin)
+        form = userWorkflowService.claimForm(form.getTaskId());
+        assertNotNull(form);
+        assertNotNull(form.getTaskId());
+        assertNotNull(form.getUserTO());
+        assertEquals(updatedUsername, form.getUserTO().getUsername());
+        assertNull(form.getUserPatch());
+        assertNotNull(form.getAssignee());
+
+        // 8. approve user (and verify that propagation occurred)
+        form.getProperty("approveCreate").setValue(Boolean.TRUE.toString());
+        userTO = userWorkflowService.submitForm(form);
+        assertNotNull(userTO);
+        assertEquals(updatedUsername, userTO.getUsername());
+        assertEquals("active", userTO.getStatus());
+        assertEquals(Collections.singleton(RESOURCE_NAME_TESTDB), userTO.getResources());
+
+        String username = queryForObject(
+                jdbcTemplate, 50, "SELECT id FROM test WHERE id=?", String.class, userTO.getUsername());
+        assertEquals(userTO.getUsername(), username);
+
+        // 9. update user
+        UserPatch userPatch = new UserPatch();
+        userPatch.setKey(userTO.getKey());
+        userPatch.setPassword(new PasswordPatch.Builder().value("anotherPassword123").build());
+
+        userTO = updateUser(userPatch).getEntity();
+        assertNotNull(userTO);
+    }
+
+    @Test
     public void updateApproval() {
         Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
 
@@ -257,7 +368,7 @@ public class UserWorkflowITCase extends AbstractITCase {
         WorkflowFormTO form = userWorkflowService.getFormForUser(created.getKey());
         assertNotNull(form);
         assertNotNull(form.getTaskId());
-        assertNull(form.getOwner());
+        assertNull(form.getAssignee());
         assertNotNull(form.getUserTO());
         assertNotNull(form.getUserPatch());
         assertEquals(patch, form.getUserPatch());
@@ -359,7 +470,7 @@ public class UserWorkflowITCase extends AbstractITCase {
         form = userService3.claimForm(form.getTaskId());
         assertNotNull(form);
         assertNotNull(form.getTaskId());
-        assertNotNull(form.getOwner());
+        assertNotNull(form.getAssignee());
 
         // 4. second claim task by admin
         form = userWorkflowService.claimForm(form.getTaskId());


Mime
View raw message