This is an automated email from the ASF dual-hosted git repository.
ilgrosso pushed a commit to branch 4_1_X
in repository https://gitbox.apache.org/repos/asf/syncope.git
The following commit(s) were added to refs/heads/4_1_X by this push:
new 4367f4345c [SYNCOPE-1983] Requiring admin approval for self changes
beyond attributes (#1452)
4367f4345c is described below
commit 4367f4345cb298eb0b327f037ca0807b5b84ac76
Author: Francesco Chicchiriccò <[email protected]>
AuthorDate: Mon Jul 13 16:47:05 2026 +0200
[SYNCOPE-1983] Requiring admin approval for self changes beyond attributes
(#1452)
---
.../apache/syncope/common/lib/request/UserCR.java | 11 +
.../apache/syncope/common/lib/request/UserUR.java | 11 +
.../apache/syncope/core/logic/UserSelfLogic.java | 11 +-
.../workflow/java/DefaultUserWorkflowAdapter.java | 14 +
.../src/main/resources/userWorkflow.bpmn20.xml | 655 ++++++++++++++++++---
fit/core-reference/pom.xml | 2 +-
.../src/main/resources/core-wildfly.properties | 2 +-
.../src/main/resources/userWorkflow.bpmn20.xml | 4 +-
.../apache/syncope/fit/core/UserIssuesITCase.java | 3 +
.../apache/syncope/fit/core/UserSelfITCase.java | 83 +++
src/main/asciidoc/images/userWorkflow.png | Bin 28208 -> 115721 bytes
.../configuration/configurationparameters.adoc | 6 +-
12 files changed, 699 insertions(+), 103 deletions(-)
diff --git
a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/UserCR.java
b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/UserCR.java
index 837f65403a..0fe8dae439 100644
---
a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/UserCR.java
+++
b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/UserCR.java
@@ -217,6 +217,17 @@ public class UserCR extends AnyCR implements
GroupableRelatableTO {
return linkedAccounts;
}
+ @JsonIgnore
+ public boolean requiresApproval() {
+ return getUManager() != null
+ || getGManager() != null
+ || !getResources().isEmpty()
+ || !getRelationships().isEmpty()
+ || !memberships.isEmpty()
+ || !roles.isEmpty()
+ || !linkedAccounts.isEmpty();
+ }
+
@Override
public int hashCode() {
return new HashCodeBuilder().
diff --git
a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/UserUR.java
b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/UserUR.java
index 8d6a4eacb9..7e33b9dad3 100644
---
a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/UserUR.java
+++
b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/request/UserUR.java
@@ -195,6 +195,17 @@ public class UserUR extends AnyUR {
return isEmptyNotConsideringPassword() && password == null;
}
+ @JsonIgnore
+ public boolean requiresApproval() {
+ return getUManager() != null
+ || getGManager() != null
+ || !getResources().isEmpty()
+ || !getRelationships().isEmpty()
+ || !memberships.isEmpty()
+ || !roles.isEmpty()
+ || !linkedAccounts.isEmpty();
+ }
+
@Override
public int hashCode() {
return new HashCodeBuilder().
diff --git
a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/UserSelfLogic.java
b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/UserSelfLogic.java
index 8a95f9e4a3..5f474b1136 100644
---
a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/UserSelfLogic.java
+++
b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/UserSelfLogic.java
@@ -129,17 +129,16 @@ public class UserSelfLogic extends AbstractUserLogic {
+ "and not(hasRole('" + IdRepoEntitlement.MUST_CHANGE_PASSWORD +
"'))")
@Transactional(readOnly = true)
public Self read() {
- UserTO authenticatedUser = binder.getAuthenticatedUserTO();
+ UserTO authenticated = binder.getAuthenticatedUserTO();
return new Self(
- authenticatedUser,
+ authenticated,
POJOHelper.serialize(AuthContextUtils.getAuthorizations()),
- POJOHelper.serialize(delegationDAO.findValidDelegating(
- authenticatedUser.getKey(), OffsetDateTime.now())));
+
POJOHelper.serialize(delegationDAO.findValidDelegating(authenticated.getKey(),
OffsetDateTime.now())));
}
@PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
- public ProvisioningResult<UserTO> create(final UserCR createReq, final
boolean nullPriorityAsync) {
+ public ProvisioningResult<UserTO> create(final UserCR userCR, final
boolean nullPriorityAsync) {
if (!confParamOps.get(
AuthContextUtils.getDomain(),
StandardConfParams.SELF_REGISTRATION_ALLOWED, false, boolean.class)) {
@@ -148,7 +147,7 @@ public class UserSelfLogic extends AbstractUserLogic {
throw sce;
}
- return doCreate(createReq, true, nullPriorityAsync);
+ return doCreate(userCR, true, nullPriorityAsync);
}
@PreAuthorize("isAuthenticated() "
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 d7c0cae668..3083fb5423 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
@@ -80,6 +80,16 @@ public class DefaultUserWorkflowAdapter extends
AbstractUserWorkflowAdapter {
this.notificationManager = notificationManager;
}
+ protected void throwApprovalRequired(final String executor, final boolean
condition) {
+ if (!securityProperties.getAdminUser().equals(executor)
+ && confParamOps.get(
+ AuthContextUtils.getDomain(),
"default.workflow.requires.approval", true, boolean.class)
+ && condition) {
+
+ throw new WorkflowException(new
UnsupportedOperationException("This operation requires approval"));
+ }
+ }
+
@Override
protected UserWorkflowResult<Pair<String, Boolean>> doCreate(
final UserCR userCR,
@@ -88,6 +98,8 @@ public class DefaultUserWorkflowAdapter extends
AbstractUserWorkflowAdapter {
final String creator,
final String context) {
+ throwApprovalRequired(creator, userCR.requiresApproval());
+
User user = entityFactory.newEntity(User.class);
dataBinder.create(user, userCR);
@@ -148,6 +160,8 @@ public class DefaultUserWorkflowAdapter extends
AbstractUserWorkflowAdapter {
protected UserWorkflowResult<Pair<UserUR, Boolean>> doUpdate(
final User user, final UserUR userUR, final String updater, final
String context) {
+ throwApprovalRequired(updater, userUR.requiresApproval());
+
UserWorkflowResult.PropagationInfo propInfo = dataBinder.update(user,
userUR);
metadata(user, updater, context);
diff --git
a/ext/flowable/flowable-bpmn/src/main/resources/userWorkflow.bpmn20.xml
b/ext/flowable/flowable-bpmn/src/main/resources/userWorkflow.bpmn20.xml
index 8325733f9b..1f414259bf 100644
--- a/ext/flowable/flowable-bpmn/src/main/resources/userWorkflow.bpmn20.xml
+++ b/ext/flowable/flowable-bpmn/src/main/resources/userWorkflow.bpmn20.xml
@@ -31,14 +31,76 @@ under the License.
<startEvent id="theStart"/>
<sequenceFlow id="flow1" sourceRef="theStart" targetRef="create"/>
<serviceTask id="create" name="Create"
flowable:delegateExpression="${create}"/>
- <sequenceFlow id="flow2" sourceRef="create" targetRef="activate"/>
- <scriptTask id="activate" name="Activate" scriptFormat="groovy"
flowable:autoStoreVariables="false">
- <script><![CDATA[execution.setVariable("propagateEnable",
Boolean.TRUE);]]></script>
+ <sequenceFlow id="flow2" sourceRef="create" targetRef="createGW"/>
+ <exclusiveGateway id="createGW" default="create2Activate"/>
+ <userTask id="createApproval" name="Create approval"
flowable:formKey="createApproval">
+ <extensionElements>
+ <flowable:formProperty id="username" name="Username" type="string"
expression="${userTO.username}" writable="false"/>
+ <flowable:formProperty id="approveCreate" name="Approve?"
type="boolean" variable="approveCreate" required="true"/>
+ <flowable:formProperty id="rejectReason" name="Reason for rejecting"
type="string" variable="rejectReason"/>
+ </extensionElements>
+ </userTask>
+ <scriptTask id="CreateApprovalEvaluation" name="Create approval
evaluation" scriptFormat="groovy" flowable:autoStoreVariables="false">
+ <script><![CDATA[
+try {
+ if (approveCreate){
+ execution.setVariable("task", 'approve');
+ } else {
+ execution.setVariable("task", 'reject');
+ }
+} catch(Exception ae) {
+ try {
+ if (task != 'delete') {
+ execution.setVariable("task", null);
+ }
+ } catch(Exception te) {
+ execution.setVariable("task", null);
+ }
+} finally {
+ execution.removeVariable("approveCreate");
+ execution.removeVariable("rejectReason");
+}]]></script>
</scriptTask>
- <sequenceFlow id="flow3" sourceRef="activate" targetRef="active"/>
+ <exclusiveGateway id="createApprovalGW"
default="sid-76B82B68-099D-4729-B8CF-D028386FE900"/>
+ <exclusiveGateway id="enableGW"/>
+ <sequenceFlow id="enableGW2Activate" sourceRef="enableGW"
targetRef="activate">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${enabled ==
null}]]></conditionExpression>
+ </sequenceFlow>
+ <sequenceFlow id="enableGW2Active" sourceRef="enableGW" targetRef="active">
+ <conditionExpression
xsi:type="tFormalExpression"><![CDATA[${enabled}]]></conditionExpression>
+ </sequenceFlow>
+ <sequenceFlow id="enableGW2Suspended" sourceRef="enableGW"
targetRef="suspend">
+ <conditionExpression
xsi:type="tFormalExpression"><![CDATA[${!enabled}]]></conditionExpression>
+ </sequenceFlow>
+ <serviceTask id="activate" name="Activate"
flowable:delegateExpression="${autoActivate}"/>
+ <sequenceFlow id="flow4" sourceRef="activate" targetRef="active"/>
+ <serviceTask id="generateToken" name="Generate token"
flowable:delegateExpression="${generateToken}"/>
+ <sequenceFlow id="flow5" sourceRef="generateToken" targetRef="created"/>
+ <userTask id="created" name="Created"/>
+ <sequenceFlow id="flow6" sourceRef="created" targetRef="optinGW"/>
+ <exclusiveGateway id="optinGW"/>
+ <sequenceFlow id="created2Activate" sourceRef="optinGW"
targetRef="removeToken">
+ <conditionExpression
xsi:type="tFormalExpression"><![CDATA[${user.checkToken(token)}]]></conditionExpression>
+ </sequenceFlow>
+ <sequenceFlow id="created2Created" sourceRef="optinGW" targetRef="created">
+ <conditionExpression
xsi:type="tFormalExpression"><![CDATA[${!user.checkToken(token)}]]></conditionExpression>
+ </sequenceFlow>
+ <scriptTask id="removeToken" name="Remove Token and Activate"
scriptFormat="groovy" flowable:autoStoreVariables="false">
+ <script><![CDATA[
+ user.removeToken()
+ ]]></script>
+ </scriptTask>
+ <sequenceFlow id="flow7" sourceRef="removeToken" targetRef="active"/>
<userTask id="active" name="Active"/>
<sequenceFlow id="flow8" sourceRef="active" targetRef="activeGw"/>
<exclusiveGateway id="activeGw"/>
+ <sequenceFlow id="active2UpdateApproval" sourceRef="activeGw"
targetRef="updateApproval">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${wfExecutor
== user.getUsername() and task == 'update'
+ and userUR.requiresApproval()}]]></conditionExpression>
+ </sequenceFlow>
+ <sequenceFlow id="active2DeleteApproval" sourceRef="activeGw"
targetRef="deleteApproval">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${wfExecutor
== user.getUsername() and task == 'delete'}]]></conditionExpression>
+ </sequenceFlow>
<sequenceFlow id="active2Update" sourceRef="activeGw" targetRef="update">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${task ==
'update'}]]></conditionExpression>
</sequenceFlow>
@@ -54,13 +116,58 @@ under the License.
<sequenceFlow id="active2ConfirmPasswordReset" sourceRef="activeGw"
targetRef="checkToken4ConfirmPasswordReset">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${task ==
'confirmPasswordReset'}]]></conditionExpression>
</sequenceFlow>
+ <userTask id="updateApproval" name="Update approval"
flowable:formKey="updateApproval">
+ <extensionElements>
+ <flowable:formProperty id="username" name="Username" type="string"
expression="${userTO.username}" writable="false"/>
+ <flowable:formProperty id="approveUpdate" name="Approve?"
type="boolean" variable="approveUpdate" required="true"/>
+ <flowable:formProperty id="rejectReason" name="Reason for rejecting"
type="string" variable="rejectReason"/>
+ </extensionElements>
+ </userTask>
+ <scriptTask id="UpdateApprovalEvaluation" name="Update approval
evaluation" scriptFormat="groovy" flowable:autoStoreVariables="false">
+ <script><![CDATA[
+try {
+ if (approveUpdate){
+ execution.setVariable("task", 'approve');
+ } else {
+ execution.setVariable("task", 'reject');
+ }
+} catch(Exception ae) {
+ try {
+ if (task != 'delete') {
+ execution.setVariable("task", null);
+ }
+ } catch(Exception te) {
+ execution.setVariable("task", null);
+ }
+} finally {
+ execution.removeVariable("approveUpdate");
+ execution.removeVariable("rejectReason");
+}]]></script>
+ </scriptTask>
+ <exclusiveGateway id="updateApprovalGW"
default="sid-E58BBC2D-8831-4CF2-A798-14B258FE569B"/>
+ <sequenceFlow id="sid-E58BBC2D-8831-4CF2-A798-14B258FE569B"
sourceRef="updateApprovalGW" targetRef="updateApproval"/>
+ <sequenceFlow id="updateApprovalGW2Update" sourceRef="updateApprovalGW"
targetRef="update">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${task ==
'approve'}]]></conditionExpression>
+ </sequenceFlow>
+ <sequenceFlow id="updateApprovalGW2Reject" sourceRef="updateApprovalGW"
targetRef="rejectUpdate">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${task ==
'reject'}]]></conditionExpression>
+ </sequenceFlow>
+ <sequenceFlow id="sid-B5FFEBCA-1FBF-457F-BC55-39FD387188B2"
sourceRef="updateApprovalGW" targetRef="delete">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${task ==
'delete'}]]></conditionExpression>
+ </sequenceFlow>
+ <scriptTask id="rejectUpdate" name="Reject update" scriptFormat="groovy"
flowable:autoStoreVariables="false">
+ <script><![CDATA[
+ execution.setVariable("propByResource", null);
+ ]]></script>
+ </scriptTask>
+ <sequenceFlow id="flow8ter" sourceRef="rejectUpdate" targetRef="active"/>
<serviceTask id="update" name="Update"
flowable:delegateExpression="${update}"/>
- <sequenceFlow id="sid-EA22026A-25F0-4ED0-AB6E-9CE9CE74623C"
sourceRef="update" targetRef="active"/>
+ <sequenceFlow id="flow9" sourceRef="update" targetRef="active"/>
<serviceTask id="suspend" name="Suspend"
flowable:delegateExpression="${suspend}"/>
<sequenceFlow id="flow10" sourceRef="suspend" targetRef="suspended"/>
<userTask id="suspended" name="Suspended"/>
<sequenceFlow id="flow11" sourceRef="suspended" targetRef="suspendedGw"/>
- <exclusiveGateway id="suspendedGw"/>
+ <exclusiveGateway id="suspendedGw"
default="sid-26ACDEC4-8BE2-4E70-BB63-36B6375B7EEC"/>
<sequenceFlow id="suspended2Reactivate" sourceRef="suspendedGw"
targetRef="reactivate">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${task ==
'reactivate'}]]></conditionExpression>
</sequenceFlow>
@@ -69,160 +176,524 @@ under the License.
</sequenceFlow>
<serviceTask id="reactivate" name="Reactivate"
flowable:delegateExpression="${reactivate}"/>
<sequenceFlow id="flow12" sourceRef="reactivate" targetRef="active"/>
- <serviceTask id="generateToken4PasswordReset" name="Generate Token"
flowable:delegateExpression="${generateToken}"/>
- <sequenceFlow id="sid-7F78CE07-A7A1-467F-BB4B-40FB234AEFF7"
sourceRef="generateToken4PasswordReset"
targetRef="notify4RequestPasswordReset"/>
+ <scriptTask id="reject" name="Reject" scriptFormat="groovy"
flowable:autoStoreVariables="false">
+ <script><![CDATA[
+ execution.removeVariable("userTO");
+ execution.removeVariable("encryptedPwd");
+ execution.removeVariable("propByResource");
+ ]]></script>
+ </scriptTask>
+ <userTask id="rejected" name="Rejected"/>
+ <sequenceFlow id="flow14" sourceRef="rejected" targetRef="rejectedGw"/>
+ <exclusiveGateway id="rejectedGw"/>
+ <sequenceFlow id="rejected2Delete" sourceRef="rejectedGw"
targetRef="delete">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${task ==
'delete'}]]></conditionExpression>
+ </sequenceFlow>
+ <sequenceFlow id="rejected2Rejected" sourceRef="rejectedGw"
targetRef="rejected">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${empty
task}]]></conditionExpression>
+ </sequenceFlow>
+ <userTask id="deleteApproval" name="Delete approval"
flowable:formKey="deleteApproval">
+ <extensionElements>
+ <flowable:formProperty id="username" name="Username" type="string"
expression="${userTO.username}" writable="false"/>
+ <flowable:formProperty id="approveDelete" name="Approve?"
type="boolean" variable="approveDelete" required="true"/>
+ <flowable:formProperty id="rejectReason" name="Reason for rejecting"
type="string" variable="rejectReason"/>
+ </extensionElements>
+ </userTask>
+ <sequenceFlow id="flow14bis" sourceRef="deleteApproval"
targetRef="deleteApprovalGW"/>
+ <exclusiveGateway id="deleteApprovalGW"/>
+ <sequenceFlow id="deleteApprovalGW2Delete" sourceRef="deleteApprovalGW"
targetRef="delete">
+ <conditionExpression
xsi:type="tFormalExpression"><![CDATA[${approve}]]></conditionExpression>
+ </sequenceFlow>
+ <sequenceFlow id="deleteApprovalGW2Reject" sourceRef="deleteApprovalGW"
targetRef="rejectDelete">
+ <conditionExpression
xsi:type="tFormalExpression"><![CDATA[${!approve}]]></conditionExpression>
+ </sequenceFlow>
+ <scriptTask id="rejectDelete" name="Reject delete" scriptFormat="groovy"
flowable:autoStoreVariables="false">
+ <script><![CDATA[
+ execution.setVariable("propByResource", null);
+ ]]></script>
+ </scriptTask>
+ <sequenceFlow id="flow14ter" sourceRef="rejectDelete" targetRef="active"/>
+ <serviceTask id="generateToken4PasswordReset" name="Generate token"
flowable:delegateExpression="${generateToken}"/>
+ <sequenceFlow id="flow15" sourceRef="generateToken4PasswordReset"
targetRef="notify4RequestPasswordReset"/>
<serviceTask id="notify4RequestPasswordReset" name="Notification"
flowable:delegateExpression="${notify}"/>
- <sequenceFlow id="sid-CF9ACA40-7750-47C3-A508-7250D24D4F1F"
sourceRef="notify4RequestPasswordReset" targetRef="active"/>
+ <sequenceFlow id="flow16" sourceRef="notify4RequestPasswordReset"
targetRef="active"/>
<serviceTask id="checkToken4ConfirmPasswordReset" name="Check token,
remove and update password" flowable:delegateExpression="${passwordReset}"/>
- <sequenceFlow id="sid-3E9FE01D-CC60-4A95-B356-CA0DC000FAD6"
sourceRef="checkToken4ConfirmPasswordReset"
targetRef="notify4ConfirmPasswordReset"/>
+ <sequenceFlow id="flow17" sourceRef="checkToken4ConfirmPasswordReset"
targetRef="notify4ConfirmPasswordReset"/>
<serviceTask id="notify4ConfirmPasswordReset" name="Notification"
flowable:delegateExpression="${notify}"/>
- <sequenceFlow id="sid-A37806A7-6B7B-48A2-BB37-DAE640231144"
sourceRef="notify4ConfirmPasswordReset" targetRef="active"/>
+ <sequenceFlow id="flow18" sourceRef="notify4ConfirmPasswordReset"
targetRef="active"/>
<serviceTask id="delete" name="Delete"
flowable:delegateExpression="${delete}"/>
<sequenceFlow id="flow99" sourceRef="delete" targetRef="theEnd"/>
<endEvent id="theEnd"/>
+ <serviceTask id="updateWhilePendingCreateApproval" name="Update"
flowable:delegateExpression="${update}"/>
+ <sequenceFlow id="sid-76B82B68-099D-4729-B8CF-D028386FE900"
sourceRef="createApprovalGW" targetRef="createApproval"/>
+ <sequenceFlow id="sid-B2EEC511-2924-4A95-B0B8-E35DA268DD58"
sourceRef="createApprovalGW" targetRef="rejectedGw">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${task ==
'delete'}]]></conditionExpression>
+ </sequenceFlow>
+ <exclusiveGateway id="sid-8CFA3152-19AA-4878-AD2C-96B63F6E98C7"
default="flow3"/>
+ <sequenceFlow id="flow13" sourceRef="reject" targetRef="rejected"/>
+ <sequenceFlow id="createApprovalGW2EnableGW" sourceRef="createApprovalGW"
targetRef="enableGW">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${task ==
'approve'}]]></conditionExpression>
+ </sequenceFlow>
+ <sequenceFlow id="createApproval2Reject" sourceRef="createApprovalGW"
targetRef="reject">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${task ==
'reject'}]]></conditionExpression>
+ </sequenceFlow>
+ <sequenceFlow id="create2Activate" sourceRef="createGW"
targetRef="enableGW"/>
+ <sequenceFlow id="flow3"
sourceRef="sid-8CFA3152-19AA-4878-AD2C-96B63F6E98C7"
targetRef="CreateApprovalEvaluation"/>
+ <sequenceFlow id="sid-56E7041A-748A-4C71-ABF3-7DCA0BEC8991"
sourceRef="CreateApprovalEvaluation" targetRef="createApprovalGW"/>
+ <sequenceFlow id="createAsAnonymous2Approval" sourceRef="createGW"
targetRef="createApproval">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${wfExecutor
== 'anonymous' and userCR.requiresApproval()}]]></conditionExpression>
+ </sequenceFlow>
+ <serviceTask id="updateWhilePendingUpdateApproval" name="Update"
flowable:delegateExpression="${update}"/>
+ <exclusiveGateway id="sid-4C9C9117-26DB-4326-A12B-EEDA42EADF07"
default="sid-12E29B94-C369-45C1-BCEF-C165AFDA525A"/>
+ <sequenceFlow id="sid-930DADF1-C361-43DD-A240-582F21DEB9B6"
sourceRef="createApproval"
targetRef="sid-8CFA3152-19AA-4878-AD2C-96B63F6E98C7"/>
+ <sequenceFlow id="sid-A2BDF803-688C-4A4D-9D33-6D859C029245"
sourceRef="updateApproval"
targetRef="sid-4C9C9117-26DB-4326-A12B-EEDA42EADF07"/>
+ <sequenceFlow id="sid-66CDB1C4-7C2F-4BAE-9834-84CF0CF52BF3"
sourceRef="sid-4C9C9117-26DB-4326-A12B-EEDA42EADF07"
targetRef="updateWhilePendingUpdateApproval">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${task ==
'update'}]]></conditionExpression>
+ </sequenceFlow>
+ <sequenceFlow id="sid-C9FA59AF-4F39-489E-B424-5C06B15AE317"
sourceRef="sid-8CFA3152-19AA-4878-AD2C-96B63F6E98C7"
targetRef="updateWhilePendingCreateApproval">
+ <conditionExpression xsi:type="tFormalExpression"><![CDATA[${task ==
'update'}]]></conditionExpression>
+ </sequenceFlow>
+ <sequenceFlow id="sid-F746E78F-F59B-4842-9D88-C9C79474FC06"
sourceRef="updateWhilePendingCreateApproval" targetRef="createApproval"/>
+ <sequenceFlow id="sid-1D0DA593-85D7-412B-8DA3-79DC0CE00E1D"
sourceRef="updateWhilePendingUpdateApproval" targetRef="updateApproval"/>
+ <sequenceFlow id="sid-12E29B94-C369-45C1-BCEF-C165AFDA525A"
sourceRef="sid-4C9C9117-26DB-4326-A12B-EEDA42EADF07"
targetRef="UpdateApprovalEvaluation"/>
+ <sequenceFlow id="sid-53FA7F29-CE60-4AE6-921D-AF7331CDB19F"
sourceRef="UpdateApprovalEvaluation" targetRef="updateApprovalGW"/>
+ <sequenceFlow id="sid-26ACDEC4-8BE2-4E70-BB63-36B6375B7EEC"
sourceRef="suspendedGw" targetRef="suspended"/>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_userWorkflow">
<bpmndi:BPMNPlane bpmnElement="userWorkflow" id="BPMNPlane_userWorkflow">
<bpmndi:BPMNShape bpmnElement="theStart" id="BPMNShape_theStart">
- <omgdc:Bounds height="30.0" width="30.0" x="540.0" y="521.0"/>
+ <omgdc:Bounds height="30.0" width="30.0" x="333.0" y="252.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="create" id="BPMNShape_create">
- <omgdc:Bounds height="60.0" width="100.0" x="620.0" y="509.0"/>
+ <omgdc:Bounds height="60.0" width="100.0" x="300.0" y="323.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="createGW" id="BPMNShape_createGW">
+ <omgdc:Bounds height="40.0" width="40.0" x="330.0" y="507.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="createApproval"
id="BPMNShape_createApproval">
+ <omgdc:Bounds height="60.0" width="100.0" x="420.0" y="560.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="CreateApprovalEvaluation"
id="BPMNShape_CreateApprovalEvaluation">
+ <omgdc:Bounds height="80.0" width="100.0" x="477.5" y="765.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="createApprovalGW"
id="BPMNShape_createApprovalGW">
+ <omgdc:Bounds height="40.0" width="40.0" x="570.0" y="570.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="enableGW" id="BPMNShape_enableGW">
+ <omgdc:Bounds height="40.0" width="40.0" x="690.0" y="429.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="activate" id="BPMNShape_activate">
- <omgdc:Bounds height="80.0" width="100.0" x="828.0" y="500.0"/>
+ <omgdc:Bounds height="60.0" width="100.0" x="810.0" y="610.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="generateToken"
id="BPMNShape_generateToken">
+ <omgdc:Bounds height="60.0" width="100.0" x="810.0" y="213.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="created" id="BPMNShape_created">
+ <omgdc:Bounds height="60.0" width="100.0" x="952.0" y="213.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="optinGW" id="BPMNShape_optinGW">
+ <omgdc:Bounds height="40.0" width="40.0" x="1102.0" y="223.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="removeToken" id="BPMNShape_removeToken">
+ <omgdc:Bounds height="60.0" width="100.0" x="1180.0" y="213.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="active" id="BPMNShape_active">
- <omgdc:Bounds height="60.0" width="100.0" x="1030.0" y="511.0"/>
+ <omgdc:Bounds height="60.0" width="100.0" x="1130.0" y="511.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="activeGw" id="BPMNShape_activeGw">
- <omgdc:Bounds height="40.0" width="40.0" x="1400.0" y="520.0"/>
+ <omgdc:Bounds height="40.0" width="40.0" x="1500.0" y="520.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="updateApproval"
id="BPMNShape_updateApproval">
+ <omgdc:Bounds height="60.0" width="100.0" x="1605.0" y="740.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="UpdateApprovalEvaluation"
id="BPMNShape_UpdateApprovalEvaluation">
+ <omgdc:Bounds height="80.0" width="100.0" x="1740.0" y="855.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="updateApprovalGW"
id="BPMNShape_updateApprovalGW">
+ <omgdc:Bounds height="40.0" width="40.0" x="1770.0" y="750.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="rejectUpdate" id="BPMNShape_rejectUpdate">
+ <omgdc:Bounds height="60.0" width="100.0" x="1890.0" y="840.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="update" id="BPMNShape_update">
- <omgdc:Bounds height="60.0" width="100.0" x="1370.0" y="615.0"/>
+ <omgdc:Bounds height="60.0" width="100.0" x="1890.0" y="700.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="suspend" id="BPMNShape_suspend">
- <omgdc:Bounds height="60.0" width="100.0" x="1490.0" y="370.0"/>
+ <omgdc:Bounds height="60.0" width="100.0" x="1590.0" y="100.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="suspended" id="BPMNShape_suspended">
- <omgdc:Bounds height="60.0" width="100.0" x="1640.0" y="370.0"/>
+ <omgdc:Bounds height="60.0" width="100.0" x="1740.0" y="120.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="suspendedGw" id="BPMNShape_suspendedGw">
- <omgdc:Bounds height="40.0" width="40.0" x="1820.0" y="380.0"/>
+ <omgdc:Bounds height="40.0" width="40.0" x="1920.0" y="180.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="reactivate" id="BPMNShape_reactivate">
- <omgdc:Bounds height="60.0" width="100.0" x="1940.0" y="290.0"/>
+ <omgdc:Bounds height="60.0" width="100.0" x="2040.0" y="110.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="reject" id="BPMNShape_reject">
+ <omgdc:Bounds height="60.0" width="100.0" x="660.0" y="659.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="rejected" id="BPMNShape_rejected">
+ <omgdc:Bounds height="60.0" width="100.0" x="810.0" y="770.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="rejectedGw" id="BPMNShape_rejectedGw">
+ <omgdc:Bounds height="40.0" width="40.0" x="990.0" y="780.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="deleteApproval"
id="BPMNShape_deleteApproval">
+ <omgdc:Bounds height="60.0" width="100.0" x="1590.0" y="280.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="deleteApprovalGW"
id="BPMNShape_deleteApprovalGW">
+ <omgdc:Bounds height="40.0" width="40.0" x="1770.0" y="300.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="rejectDelete" id="BPMNShape_rejectDelete">
+ <omgdc:Bounds height="60.0" width="100.0" x="1890.0" y="240.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="generateToken4PasswordReset"
id="BPMNShape_generateToken4PasswordReset">
- <omgdc:Bounds height="81.0" width="121.0" x="1515.0" y="604.0"/>
+ <omgdc:Bounds height="59.0" width="100.0" x="1643.0" y="452.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="notify4RequestPasswordReset"
id="BPMNShape_notify4RequestPasswordReset">
- <omgdc:Bounds height="81.0" width="121.0" x="1515.0" y="750.0"/>
+ <omgdc:Bounds height="60.0" width="100.0" x="1848.0" y="452.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="checkToken4ConfirmPasswordReset"
id="BPMNShape_checkToken4ConfirmPasswordReset">
- <omgdc:Bounds height="81.0" width="121.0" x="1725.0" y="664.0"/>
+ <omgdc:Bounds height="60.0" width="100.0" x="1643.0" y="561.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="notify4ConfirmPasswordReset"
id="BPMNShape_notify4ConfirmPasswordReset">
- <omgdc:Bounds height="81.0" width="121.0" x="1725.0" y="810.0"/>
+ <omgdc:Bounds height="60.0" width="100.0" x="1848.0" y="561.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="delete" id="BPMNShape_delete">
- <omgdc:Bounds height="60.0" width="100.0" x="1940.0" y="438.0"/>
+ <omgdc:Bounds height="60.0" width="100.0" x="2220.0" y="358.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="theEnd" id="BPMNShape_theEnd">
- <omgdc:Bounds height="28.0" width="28.0" x="2080.0" y="451.0"/>
+ <omgdc:Bounds height="28.0" width="28.0" x="2358.0" y="374.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="updateWhilePendingCreateApproval"
id="BPMNShape_updateWhilePendingCreateApproval">
+ <omgdc:Bounds height="60.0" width="100.0" x="362.5" y="770.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="sid-8CFA3152-19AA-4878-AD2C-96B63F6E98C7"
id="BPMNShape_sid-8CFA3152-19AA-4878-AD2C-96B63F6E98C7">
+ <omgdc:Bounds height="40.0" width="40.0" x="450.0" y="660.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="updateWhilePendingUpdateApproval"
id="BPMNShape_updateWhilePendingUpdateApproval">
+ <omgdc:Bounds height="60.0" width="100.0" x="1455.0" y="865.0"/>
+ </bpmndi:BPMNShape>
+ <bpmndi:BPMNShape bpmnElement="sid-4C9C9117-26DB-4326-A12B-EEDA42EADF07"
id="BPMNShape_sid-4C9C9117-26DB-4326-A12B-EEDA42EADF07">
+ <omgdc:Bounds height="40.0" width="40.0" x="1635.0" y="875.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="active2Update" id="BPMNEdge_active2Update">
- <omgdi:waypoint x="1420.0" y="559.9405090390104"/>
- <omgdi:waypoint x="1420.0" y="615.0"/>
+ <omgdi:waypoint x="1539.9223684210267" y="540.0"/>
+ <omgdi:waypoint x="1556.0" y="540.0"/>
+ <omgdi:waypoint x="1556.0" y="730.0"/>
+ <omgdi:waypoint x="1889.999999999701" y="730.0"/>
</bpmndi:BPMNEdge>
- <bpmndi:BPMNEdge bpmnElement="suspended2Delete"
id="BPMNEdge_suspended2Delete">
- <omgdi:waypoint x="1859.9433544303797" y="400.0"/>
- <omgdi:waypoint x="1990.0" y="400.0"/>
- <omgdi:waypoint x="1990.0" y="438.0"/>
+ <bpmndi:BPMNEdge bpmnElement="sid-1D0DA593-85D7-412B-8DA3-79DC0CE00E1D"
id="BPMNEdge_sid-1D0DA593-85D7-412B-8DA3-79DC0CE00E1D">
+ <omgdi:waypoint x="1540.94" y="865.0"/>
+ <omgdi:waypoint x="1619.0" y="799.9499999999999"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="active2ConfirmPasswordReset"
id="BPMNEdge_active2ConfirmPasswordReset">
- <omgdi:waypoint x="1439.947267871352" y="540.0"/>
- <omgdi:waypoint x="1785.0" y="540.0"/>
- <omgdi:waypoint x="1785.3768996960487" y="664.0"/>
+ <omgdi:waypoint x="1539.9442374350085" y="540.0"/>
+ <omgdi:waypoint x="1693.0" y="540.0"/>
+ <omgdi:waypoint x="1693.0" y="561.0"/>
</bpmndi:BPMNEdge>
- <bpmndi:BPMNEdge bpmnElement="sid-EA22026A-25F0-4ED0-AB6E-9CE9CE74623C"
id="BPMNEdge_sid-EA22026A-25F0-4ED0-AB6E-9CE9CE74623C">
- <omgdi:waypoint x="1370.0" y="645.0"/>
- <omgdi:waypoint x="1080.0" y="645.0"/>
- <omgdi:waypoint x="1080.0" y="570.95"/>
+ <bpmndi:BPMNEdge bpmnElement="sid-76B82B68-099D-4729-B8CF-D028386FE900"
id="BPMNEdge_sid-76B82B68-099D-4729-B8CF-D028386FE900">
+ <omgdi:waypoint x="570.0" y="590.0"/>
+ <omgdi:waypoint x="519.9499999997392" y="590.0"/>
</bpmndi:BPMNEdge>
- <bpmndi:BPMNEdge bpmnElement="suspended2Reactivate"
id="BPMNEdge_suspended2Reactivate">
- <omgdi:waypoint x="1859.9339371980675" y="400.0"/>
- <omgdi:waypoint x="1902.0" y="400.0"/>
- <omgdi:waypoint x="1902.0" y="320.0"/>
- <omgdi:waypoint x="1939.9999999999768" y="320.0"/>
+ <bpmndi:BPMNEdge bpmnElement="sid-930DADF1-C361-43DD-A240-582F21DEB9B6"
id="BPMNEdge_sid-930DADF1-C361-43DD-A240-582F21DEB9B6">
+ <omgdi:waypoint x="470.0" y="619.9499999999999"/>
+ <omgdi:waypoint x="470.0" y="660.0"/>
</bpmndi:BPMNEdge>
- <bpmndi:BPMNEdge bpmnElement="active2Delete" id="BPMNEdge_active2Delete">
- <omgdi:waypoint x="1439.9482503069637" y="540.0"/>
- <omgdi:waypoint x="1990.0" y="540.0"/>
- <omgdi:waypoint x="1990.0" y="497.95"/>
+ <bpmndi:BPMNEdge bpmnElement="rejected2Rejected"
id="BPMNEdge_rejected2Rejected">
+ <omgdi:waypoint x="990.0" y="800.0"/>
+ <omgdi:waypoint x="909.9499999999135" y="800.0"/>
</bpmndi:BPMNEdge>
- <bpmndi:BPMNEdge bpmnElement="sid-7F78CE07-A7A1-467F-BB4B-40FB234AEFF7"
id="BPMNEdge_sid-7F78CE07-A7A1-467F-BB4B-40FB234AEFF7">
- <omgdi:waypoint x="1575.5" y="684.9499999999999"/>
- <omgdi:waypoint x="1575.5" y="750.0"/>
+ <bpmndi:BPMNEdge bpmnElement="sid-56E7041A-748A-4C71-ABF3-7DCA0BEC8991"
id="BPMNEdge_sid-56E7041A-748A-4C71-ABF3-7DCA0BEC8991">
+ <omgdi:waypoint x="577.4499999999488" y="805.0"/>
+ <omgdi:waypoint x="590.0" y="805.0"/>
+ <omgdi:waypoint x="590.0" y="609.9046184271755"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="active2Delete" id="BPMNEdge_active2Delete">
+ <omgdi:waypoint x="1539.9189252336448" y="540.0"/>
+ <omgdi:waypoint x="1552.0" y="540.0"/>
+ <omgdi:waypoint x="1552.0" y="680.0"/>
+ <omgdi:waypoint x="2174.0" y="680.0"/>
+ <omgdi:waypoint x="2260.1369863013697" y="417.95"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
- <omgdi:waypoint x="569.9448521215137" y="536.3898700596537"/>
- <omgdi:waypoint x="620.0" y="537.6956521739131"/>
+ <omgdi:waypoint x="348.3475822648328" y="281.94584310464063"/>
+ <omgdi:waypoint x="349.30232558139534" y="323.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
- <omgdi:waypoint x="719.9499999999825" y="539.2401442307691"/>
- <omgdi:waypoint x="827.9999999999945" y="539.7596153846154"/>
+ <omgdi:waypoint x="350.0" y="382.95"/>
+ <omgdi:waypoint x="350.0" y="507.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
- <omgdi:waypoint x="927.9499999999819" y="540.2472772277227"/>
- <omgdi:waypoint x="1029.9999999999911" y="540.7524752475248"/>
+ <omgdi:waypoint x="489.93253064798597" y="680.0"/>
+ <omgdi:waypoint x="527.0" y="680.0"/>
+ <omgdi:waypoint x="527.34" y="765.0"/>
</bpmndi:BPMNEdge>
- <bpmndi:BPMNEdge bpmnElement="active2RequestPasswordReset"
id="BPMNEdge_active2RequestPasswordReset">
- <omgdi:waypoint x="1439.943568665287" y="540.0"/>
- <omgdi:waypoint x="1575.0" y="540.0"/>
- <omgdi:waypoint x="1575.3062200956938" y="604.0"/>
+ <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
+ <omgdi:waypoint x="909.9499999998994" y="640.0"/>
+ <omgdi:waypoint x="922.0" y="640.0"/>
+ <omgdi:waypoint x="1059.0" y="640.0"/>
+ <omgdi:waypoint x="1143.3333333333333" y="570.95"/>
</bpmndi:BPMNEdge>
- <bpmndi:BPMNEdge bpmnElement="sid-3E9FE01D-CC60-4A95-B356-CA0DC000FAD6"
id="BPMNEdge_sid-3E9FE01D-CC60-4A95-B356-CA0DC000FAD6">
- <omgdi:waypoint x="1785.5" y="744.9499999999999"/>
- <omgdi:waypoint x="1785.5" y="810.0"/>
+ <bpmndi:BPMNEdge bpmnElement="updateApprovalGW2Update"
id="BPMNEdge_updateApprovalGW2Update">
+ <omgdi:waypoint x="1809.9339371980675" y="770.0"/>
+ <omgdi:waypoint x="1852.0" y="770.0"/>
+ <omgdi:waypoint x="1852.0" y="730.0"/>
+ <omgdi:waypoint x="1890.0" y="730.0"/>
</bpmndi:BPMNEdge>
- <bpmndi:BPMNEdge bpmnElement="flow10" id="BPMNEdge_flow10">
- <omgdi:waypoint x="1589.95" y="400.0"/>
- <omgdi:waypoint x="1640.0" y="400.0"/>
+ <bpmndi:BPMNEdge bpmnElement="flow5" id="BPMNEdge_flow5">
+ <omgdi:waypoint x="909.9499999999393" y="243.0"/>
+ <omgdi:waypoint x="952.0" y="243.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6">
+ <omgdi:waypoint x="1002.0" y="272.95"/>
+ <omgdi:waypoint x="1002.0" y="310.0"/>
+ <omgdi:waypoint x="1122.0" y="310.0"/>
+ <omgdi:waypoint x="1122.0" y="262.9148355754858"/>
</bpmndi:BPMNEdge>
- <bpmndi:BPMNEdge bpmnElement="sid-CF9ACA40-7750-47C3-A508-7250D24D4F1F"
id="BPMNEdge_sid-CF9ACA40-7750-47C3-A508-7250D24D4F1F">
- <omgdi:waypoint x="1514.9999999999554" y="790.438950554995"/>
- <omgdi:waypoint x="1080.0" y="790.0"/>
- <omgdi:waypoint x="1080.0" y="570.95"/>
+ <bpmndi:BPMNEdge bpmnElement="flow7" id="BPMNEdge_flow7">
+ <omgdi:waypoint x="1224.96644295302" y="272.95"/>
+ <omgdi:waypoint x="1185.025167785235" y="511.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="sid-66CDB1C4-7C2F-4BAE-9834-84CF0CF52BF3"
id="BPMNEdge_sid-66CDB1C4-7C2F-4BAE-9834-84CF0CF52BF3">
+ <omgdi:waypoint x="1635.0" y="895.0"/>
+ <omgdi:waypoint x="1554.95" y="895.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow8" id="BPMNEdge_flow8">
- <omgdi:waypoint x="1129.9499999999914" y="540.8529411764707"/>
- <omgdi:waypoint x="1400.0586510263724" y="540.058504398827"/>
+ <omgdi:waypoint x="1229.9499999999914" y="540.8529411764707"/>
+ <omgdi:waypoint x="1500.0586510263724" y="540.058504398827"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="active2Suspend"
id="BPMNEdge_active2Suspend">
+ <omgdi:waypoint x="1539.9189252336448" y="540.0"/>
+ <omgdi:waypoint x="1552.0" y="540.0"/>
+ <omgdi:waypoint x="1552.0" y="130.0"/>
+ <omgdi:waypoint x="1589.9999999999768" y="130.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="flow9" id="BPMNEdge_flow9">
+ <omgdi:waypoint x="1989.95" y="730.0"/>
+ <omgdi:waypoint x="2037.0" y="730.0"/>
+ <omgdi:waypoint x="2037.0" y="971.0"/>
+ <omgdi:waypoint x="1334.0" y="971.0"/>
+ <omgdi:waypoint x="1180.0" y="844.0"/>
+ <omgdi:waypoint x="1180.0" y="570.95"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="active2UpdateApproval"
id="BPMNEdge_active2UpdateApproval">
+ <omgdi:waypoint x="1539.9207478005092" y="540.0"/>
+ <omgdi:waypoint x="1554.0" y="540.0"/>
+ <omgdi:waypoint x="1554.0" y="770.0"/>
+ <omgdi:waypoint x="1605.0" y="770.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="sid-B5FFEBCA-1FBF-457F-BC55-39FD387188B2"
id="BPMNEdge_sid-B5FFEBCA-1FBF-457F-BC55-39FD387188B2">
+ <omgdi:waypoint x="1790.0" y="789.9304794520548"/>
+ <omgdi:waypoint x="1790.0" y="821.0"/>
+ <omgdi:waypoint x="2270.0" y="821.0"/>
+ <omgdi:waypoint x="2270.0" y="417.95"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="deleteApprovalGW2Delete"
id="BPMNEdge_deleteApprovalGW2Delete">
+ <omgdi:waypoint x="1809.9339371980677" y="320.0"/>
+ <omgdi:waypoint x="1852.0" y="320.0"/>
+ <omgdi:waypoint x="1852.0" y="388.0"/>
+ <omgdi:waypoint x="2220.0" y="388.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="createAsAnonymous2Approval"
id="BPMNEdge_createAsAnonymous2Approval">
+ <omgdi:waypoint x="369.91892523364487" y="527.0"/>
+ <omgdi:waypoint x="382.0" y="527.0"/>
+ <omgdi:waypoint x="382.0" y="590.0"/>
+ <omgdi:waypoint x="420.0" y="590.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="createApproval2Reject"
id="BPMNEdge_createApproval2Reject">
+ <omgdi:waypoint x="609.9189252336447" y="590.0"/>
+ <omgdi:waypoint x="622.0" y="590.0"/>
+ <omgdi:waypoint x="622.0" y="689.0"/>
+ <omgdi:waypoint x="660.0" y="689.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="sid-53FA7F29-CE60-4AE6-921D-AF7331CDB19F"
id="BPMNEdge_sid-53FA7F29-CE60-4AE6-921D-AF7331CDB19F">
+ <omgdi:waypoint x="1790.0" y="855.0"/>
+ <omgdi:waypoint x="1790.0" y="789.9079463570856"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="rejected2Delete"
id="BPMNEdge_rejected2Delete">
+ <omgdi:waypoint x="1029.9339371980675" y="800.0"/>
+ <omgdi:waypoint x="1072.0" y="800.0"/>
+ <omgdi:waypoint x="1323.0" y="1000.0"/>
+ <omgdi:waypoint x="2270.0" y="1000.0"/>
+ <omgdi:waypoint x="2270.0" y="417.95"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="sid-F746E78F-F59B-4842-9D88-C9C79474FC06"
id="BPMNEdge_sid-F746E78F-F59B-4842-9D88-C9C79474FC06">
+ <omgdi:waypoint x="400.83333333333337" y="770.0"/>
+ <omgdi:waypoint x="367.0" y="683.0"/>
+ <omgdi:waypoint x="436.7741935483871" y="619.9499999999999"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="enableGW2Active"
id="BPMNEdge_enableGW2Active">
+ <omgdi:waypoint x="729.9433984115534" y="449.0"/>
+ <omgdi:waypoint x="861.0" y="449.0"/>
+ <omgdi:waypoint x="861.0" y="541.0"/>
+ <omgdi:waypoint x="1130.0" y="541.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="flow14ter" id="BPMNEdge_flow14ter">
+ <omgdi:waypoint x="1889.9999999999998" y="260.7451923076923"/>
+ <omgdi:waypoint x="1524.0" y="193.0"/>
+ <omgdi:waypoint x="1209.6057471264367" y="511.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="sid-26ACDEC4-8BE2-4E70-BB63-36B6375B7EEC"
id="BPMNEdge_sid-26ACDEC4-8BE2-4E70-BB63-36B6375B7EEC">
+ <omgdi:waypoint x="1940.0" y="180.0"/>
+ <omgdi:waypoint x="1940.0" y="135.0"/>
+ <omgdi:waypoint x="1839.95" y="135.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="suspended2Delete"
id="BPMNEdge_suspended2Delete">
+ <omgdi:waypoint x="1959.9469781884277" y="200.0"/>
+ <omgdi:waypoint x="2270.0" y="200.0"/>
+ <omgdi:waypoint x="2270.0" y="358.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="deleteApprovalGW2Reject"
id="BPMNEdge_deleteApprovalGW2Reject">
+ <omgdi:waypoint x="1809.9339371980677" y="320.0"/>
+ <omgdi:waypoint x="1852.0" y="320.0"/>
+ <omgdi:waypoint x="1852.0" y="270.0"/>
+ <omgdi:waypoint x="1889.9999999999768" y="270.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="createApprovalGW2EnableGW"
id="BPMNEdge_createApprovalGW2EnableGW">
+ <omgdi:waypoint x="609.9189252336447" y="590.0"/>
+ <omgdi:waypoint x="622.0" y="590.0"/>
+ <omgdi:waypoint x="622.0" y="449.0"/>
+ <omgdi:waypoint x="690.0" y="449.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="created2Created"
id="BPMNEdge_created2Created">
+ <omgdi:waypoint x="1102.0" y="243.0"/>
+ <omgdi:waypoint x="1051.95" y="243.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="suspended2Reactivate"
id="BPMNEdge_suspended2Reactivate">
+ <omgdi:waypoint x="1959.9339371980413" y="200.0"/>
+ <omgdi:waypoint x="2002.0" y="200.0"/>
+ <omgdi:waypoint x="2002.0" y="140.0"/>
+ <omgdi:waypoint x="2039.999999999977" y="140.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="active2DeleteApproval"
id="BPMNEdge_active2DeleteApproval">
+ <omgdi:waypoint x="1539.9207478005092" y="540.0"/>
+ <omgdi:waypoint x="1554.0" y="540.0"/>
+ <omgdi:waypoint x="1554.0" y="310.0"/>
+ <omgdi:waypoint x="1590.0" y="310.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="flow17" id="BPMNEdge_flow17">
+ <omgdi:waypoint x="1742.95" y="591.0"/>
+ <omgdi:waypoint x="1848.0" y="591.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="flow18" id="BPMNEdge_flow18">
+ <omgdi:waypoint x="1847.9999999999998" y="619.3716000000001"/>
+ <omgdi:waypoint x="1773.0" y="662.0"/>
+ <omgdi:waypoint x="1229.9499999999998" y="551.1921585160202"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="sid-A2BDF803-688C-4A4D-9D33-6D859C029245"
id="BPMNEdge_sid-A2BDF803-688C-4A4D-9D33-6D859C029245">
+ <omgdi:waypoint x="1655.0" y="799.9499999999999"/>
+ <omgdi:waypoint x="1655.0" y="875.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="flow13" id="BPMNEdge_flow13">
+ <omgdi:waypoint x="759.9499999998994" y="689.0"/>
+ <omgdi:waypoint x="772.0" y="689.0"/>
+ <omgdi:waypoint x="772.0" y="800.0"/>
+ <omgdi:waypoint x="810.0" y="800.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="flow14" id="BPMNEdge_flow14">
+ <omgdi:waypoint x="860.0" y="770.0"/>
+ <omgdi:waypoint x="860.0" y="732.0"/>
+ <omgdi:waypoint x="1010.0" y="732.0"/>
+ <omgdi:waypoint x="1010.0" y="780.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="flow15" id="BPMNEdge_flow15">
+ <omgdi:waypoint x="1742.95" y="481.62182926829274"/>
+ <omgdi:waypoint x="1847.9999999999989" y="481.8780487804878"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="sid-B2EEC511-2924-4A95-B0B8-E35DA268DD58"
id="BPMNEdge_sid-B2EEC511-2924-4A95-B0B8-E35DA268DD58">
+ <omgdi:waypoint x="590.0" y="609.9462931995539"/>
+ <omgdi:waypoint x="590.0" y="859.0"/>
+ <omgdi:waypoint x="1010.0" y="859.0"/>
+ <omgdi:waypoint x="1010.0" y="819.9168505942274"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="updateApprovalGW2Reject"
id="BPMNEdge_updateApprovalGW2Reject">
+ <omgdi:waypoint x="1809.9339371980675" y="770.0"/>
+ <omgdi:waypoint x="1852.0" y="770.0"/>
+ <omgdi:waypoint x="1852.0" y="870.0"/>
+ <omgdi:waypoint x="1890.0" y="870.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="flow16" id="BPMNEdge_flow16">
+ <omgdi:waypoint x="1848.0" y="458.94174757281553"/>
+ <omgdi:waypoint x="1692.0" y="387.0"/>
+ <omgdi:waypoint x="1229.9499999999998" y="525.9609375"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="sid-C9FA59AF-4F39-489E-B424-5C06B15AE317"
id="BPMNEdge_sid-C9FA59AF-4F39-489E-B424-5C06B15AE317">
+ <omgdi:waypoint x="450.0" y="680.0"/>
+ <omgdi:waypoint x="412.0" y="680.0"/>
+ <omgdi:waypoint x="412.375" y="770.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="flow14bis" id="BPMNEdge_flow14bis">
+ <omgdi:waypoint x="1689.949999999984" y="310.0"/>
+ <omgdi:waypoint x="1702.0" y="310.0"/>
+ <omgdi:waypoint x="1702.0" y="320.0"/>
+ <omgdi:waypoint x="1770.0" y="320.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="created2Activate"
id="BPMNEdge_created2Activate">
+ <omgdi:waypoint x="1141.9407724328892" y="243.0"/>
+ <omgdi:waypoint x="1180.0" y="243.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="sid-12E29B94-C369-45C1-BCEF-C165AFDA525A"
id="BPMNEdge_sid-12E29B94-C369-45C1-BCEF-C165AFDA525A">
+ <omgdi:waypoint x="1674.9426165798702" y="895.0"/>
+ <omgdi:waypoint x="1739.9999999997615" y="895.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="sid-E58BBC2D-8831-4CF2-A798-14B258FE569B"
id="BPMNEdge_sid-E58BBC2D-8831-4CF2-A798-14B258FE569B">
+ <omgdi:waypoint x="1770.0" y="770.0"/>
+ <omgdi:waypoint x="1704.95" y="770.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="enableGW2Activate"
id="BPMNEdge_enableGW2Activate">
+ <omgdi:waypoint x="729.9339371980061" y="449.0"/>
+ <omgdi:waypoint x="772.0" y="449.0"/>
+ <omgdi:waypoint x="772.0" y="640.0"/>
+ <omgdi:waypoint x="810.0" y="640.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="enableGW2Suspended"
id="BPMNEdge_enableGW2Suspended">
+ <omgdi:waypoint x="729.9339371980061" y="449.0"/>
+ <omgdi:waypoint x="772.0" y="449.0"/>
+ <omgdi:waypoint x="772.0" y="130.0"/>
+ <omgdi:waypoint x="1590.0" y="130.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="create2Activate"
id="BPMNEdge_create2Activate">
+ <omgdi:waypoint x="369.91892523364487" y="527.0"/>
+ <omgdi:waypoint x="382.0" y="527.0"/>
+ <omgdi:waypoint x="382.0" y="449.0"/>
+ <omgdi:waypoint x="690.0" y="449.0"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="active2RequestPasswordReset"
id="BPMNEdge_active2RequestPasswordReset">
+ <omgdi:waypoint x="1539.9442374350085" y="540.0"/>
+ <omgdi:waypoint x="1693.0" y="540.0"/>
+ <omgdi:waypoint x="1693.0" y="510.95"/>
+ </bpmndi:BPMNEdge>
+ <bpmndi:BPMNEdge bpmnElement="flow10" id="BPMNEdge_flow10">
+ <omgdi:waypoint x="1689.95" y="130.0"/>
+ <omgdi:waypoint x="1702.0" y="130.0"/>
+ <omgdi:waypoint x="1702.0" y="150.0"/>
+ <omgdi:waypoint x="1739.9999999999768" y="150.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow11" id="BPMNEdge_flow11">
- <omgdi:waypoint x="1739.95" y="400.0"/>
- <omgdi:waypoint x="1820.0" y="400.0"/>
+ <omgdi:waypoint x="1839.95" y="165.0"/>
+ <omgdi:waypoint x="1879.0" y="165.0"/>
+ <omgdi:waypoint x="1879.0" y="200.0"/>
+ <omgdi:waypoint x="1920.0" y="200.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow99" id="BPMNEdge_flow99">
- <omgdi:waypoint x="2039.9499999999982" y="466.5576923076923"/>
- <omgdi:waypoint x="2080.005704870052" y="465.4022398573087"/>
- </bpmndi:BPMNEdge>
- <bpmndi:BPMNEdge bpmnElement="active2Suspend"
id="BPMNEdge_active2Suspend">
- <omgdi:waypoint x="1439.9416944213153" y="540.0"/>
- <omgdi:waypoint x="1540.0" y="540.0"/>
- <omgdi:waypoint x="1540.0" y="429.95"/>
+ <omgdi:waypoint x="2319.9499999999875" y="388.0"/>
+ <omgdi:waypoint x="2358.0" y="388.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow12" id="BPMNEdge_flow12">
- <omgdi:waypoint x="1990.0" y="290.0"/>
- <omgdi:waypoint x="1990.0" y="261.0"/>
- <omgdi:waypoint x="1080.0" y="261.0"/>
- <omgdi:waypoint x="1080.0" y="511.0"/>
+ <omgdi:waypoint x="2040.0" y="129.51612903225808"/>
+ <omgdi:waypoint x="2028.0" y="127.0"/>
+ <omgdi:waypoint x="1478.0" y="40.0"/>
+ <omgdi:waypoint x="1197.8145708582833" y="511.0"/>
</bpmndi:BPMNEdge>
- <bpmndi:BPMNEdge bpmnElement="sid-A37806A7-6B7B-48A2-BB37-DAE640231144"
id="BPMNEdge_sid-A37806A7-6B7B-48A2-BB37-DAE640231144">
- <omgdi:waypoint x="1724.9999999998677" y="850.4571226080794"/>
- <omgdi:waypoint x="1080.0" y="850.0"/>
- <omgdi:waypoint x="1080.0" y="570.95"/>
+ <bpmndi:BPMNEdge bpmnElement="flow8ter" id="BPMNEdge_flow8ter">
+ <omgdi:waypoint x="1940.0" y="899.9499999999999"/>
+ <omgdi:waypoint x="1940.0" y="948.0"/>
+ <omgdi:waypoint x="1339.0" y="948.0"/>
+ <omgdi:waypoint x="1214.0" y="837.0"/>
+ <omgdi:waypoint x="1183.4402027027027" y="570.95"/>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
-</definitions>
\ No newline at end of file
+</definitions>
diff --git a/fit/core-reference/pom.xml b/fit/core-reference/pom.xml
index d2d91adc55..1be5c9a51e 100644
--- a/fit/core-reference/pom.xml
+++ b/fit/core-reference/pom.xml
@@ -1393,7 +1393,7 @@ under the License.
<inherited>true</inherited>
<configuration>
<container>
- <containerId>wildfly39x</containerId>
+ <containerId>wildfly40x</containerId>
<zipUrlInstaller>
<url>https://github.com/wildfly/wildfly/releases/download/${wildfly.version}/wildfly-${wildfly.version}.zip</url>
<downloadDir>${settings.localRepository}/org/codehaus/cargo/cargo-container-archives</downloadDir>
diff --git a/fit/core-reference/src/main/resources/core-wildfly.properties
b/fit/core-reference/src/main/resources/core-wildfly.properties
index f8c3e31e9b..3e227ff177 100644
--- a/fit/core-reference/src/main/resources/core-wildfly.properties
+++ b/fit/core-reference/src/main/resources/core-wildfly.properties
@@ -14,7 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-persistence.metaDataFactory=jpa(URLs=vfs:${project.build.directory}/cargo/configurations/wildfly39x/deployments/syncope.war/WEB-INF/lib/syncope-core-persistence-jpa-${syncope.version}.jar;
vfs:${project.build.directory}/cargo/configurations/wildfly39x/deployments/syncope.war/WEB-INF/lib/syncope-core-self-keymaster-starter-${syncope.version}.jar,
Resources=##orm##)
+persistence.metaDataFactory=jpa(URLs=vfs:${project.build.directory}/cargo/configurations/wildfly40x/deployments/syncope.war/WEB-INF/lib/syncope-core-persistence-jpa-${syncope.version}.jar;
vfs:${project.build.directory}/cargo/configurations/wildfly40x/deployments/syncope.war/WEB-INF/lib/syncope-core-self-keymaster-starter-${syncope.version}.jar,
Resources=##orm##)
javadocPaths=/WEB-INF/lib/syncope-common-idrepo-rest-api-${syncope.version}-javadoc.jar,\
/WEB-INF/lib/syncope-common-idm-rest-api-${syncope.version}-javadoc.jar,\
diff --git a/fit/core-reference/src/main/resources/userWorkflow.bpmn20.xml
b/fit/core-reference/src/main/resources/userWorkflow.bpmn20.xml
index 68ea2217a2..697f175951 100644
--- a/fit/core-reference/src/main/resources/userWorkflow.bpmn20.xml
+++ b/fit/core-reference/src/main/resources/userWorkflow.bpmn20.xml
@@ -26,7 +26,7 @@ under the License.
typeLanguage="http://www.w3.org/2001/XMLSchema"
expressionLanguage="http://www.w3.org/1999/XPath"
targetNamespace="http://www.flowable.org/processdef">
-
+
<process id="userWorkflow" name="User Workflow" isExecutable="true">
<startEvent id="theStart"/>
<sequenceFlow id="flow1" sourceRef="theStart" targetRef="create"/>
@@ -99,7 +99,7 @@ try {
<exclusiveGateway id="activeGw"/>
<sequenceFlow id="active2UpdateApproval" sourceRef="activeGw"
targetRef="updateApproval">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${wfExecutor
== user.getUsername() and task == 'update'
- and (!userUR.getMemberships().isEmpty())}]]></conditionExpression>
+ and userUR.requiresApproval()}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="active2DeleteApproval" sourceRef="activeGw"
targetRef="deleteApproval">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${wfExecutor
== user.getUsername() and task == 'delete'}]]></conditionExpression>
diff --git
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserIssuesITCase.java
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserIssuesITCase.java
index 4ee88229e6..a90327a0bf 100644
---
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserIssuesITCase.java
+++
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserIssuesITCase.java
@@ -27,6 +27,7 @@ import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assumptions.assumeFalse;
+import static org.junit.jupiter.api.Assumptions.assumeTrue;
import com.fasterxml.jackson.core.JsonProcessingException;
import jakarta.ws.rs.HttpMethod;
@@ -1550,6 +1551,8 @@ public class UserIssuesITCase extends AbstractITCase {
@Test
public void issueSYNCOPE1793() {
+ assumeTrue(IS_FLOWABLE_ENABLED);
+
RoleTO role = new RoleTO();
role.setKey("syncope1793" + getUUIDString());
role.getRealms().add(SyncopeConstants.ROOT_REALM);
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 ee4981bfa2..538cd23579 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
@@ -807,4 +807,87 @@ public class UserSelfITCase extends AbstractITCase {
UserTO userTO = ADMIN_CLIENT.self().user();
assertEquals(ADMIN_UNAME, userTO.getUsername());
}
+
+ @Test
+ public void issueSYNCOPE1983Default() {
+ assumeFalse(IS_FLOWABLE_ENABLED);
+
+ // 1. create
+ UserCR userCR =
UserITCase.getUniqueSample("[email protected]");
+ userCR.getRoles().add("User manager");
+
+ SyncopeClientException e = assertThrows(
+ SyncopeClientException.class,
+ () ->
ANONYMOUS_CLIENT.getService(UserSelfService.class).create(userCR));
+ assertEquals(ClientExceptionType.Workflow, e.getType());
+
+ // remove roles so self registration can proceed
+ userCR.getRoles().clear();
+
+ UserTO user = ANONYMOUS_CLIENT.getService(UserSelfService.class).
+ create(userCR).
+ readEntity(new GenericType<ProvisioningResult<UserTO>>() {
+ }).getEntity();
+ assertNotNull(user);
+
+ // 2. update
+ UserUR userUR = new UserUR.Builder(user.getKey()).
+ username(new
StringReplacePatchItem.Builder().value(user.getUsername() +
getUUIDString()).build()).
+ role(new StringPatchItem.Builder().value("User
manager").build()).
+ build();
+
+ SyncopeClient authClient = CLIENT_FACTORY.create(user.getUsername(),
"password123");
+ e = assertThrows(
+ SyncopeClientException.class,
+ () ->
authClient.getService(UserSelfService.class).update(userUR));
+ assertEquals(ClientExceptionType.Workflow, e.getType());
+
+ // remove roles so update can proceed
+ userUR.getRoles().clear();
+
+ user = authClient.getService(UserSelfService.class).
+ update(userUR).
+ readEntity(new GenericType<ProvisioningResult<UserTO>>() {
+ }).getEntity();
+ assertNotNull(user);
+ }
+
+ @Test
+ public void issueSYNCOPE1983Flowable() {
+ assumeTrue(IS_FLOWABLE_ENABLED);
+
+ // 1. create
+ UserCR userCR =
UserITCase.getUniqueSample("[email protected]");
+ userCR.getRoles().add("User manager");
+
+ UserTO user = ANONYMOUS_CLIENT.getService(UserSelfService.class).
+ create(userCR).
+ readEntity(new GenericType<ProvisioningResult<UserTO>>() {
+ }).getEntity();
+ assertNotNull(user);
+ assertEquals("createApproval", user.getStatus());
+
+ // approve
+ UserRequestForm form = USER_REQUEST_SERVICE.listForms(
+ new
UserRequestQuery.Builder().user(user.getKey()).build()).getResult().getFirst();
+ form = USER_REQUEST_SERVICE.claimForm(form.getTaskId());
+
form.getProperty("approveCreate").get().setValue(Boolean.TRUE.toString());
+ user = USER_REQUEST_SERVICE.submitForm(form).readEntity(new
GenericType<ProvisioningResult<UserTO>>() {
+ }).getEntity();
+ assertNotNull(user);
+ assertEquals("active", user.getStatus());
+
+ // 2. update
+ UserUR userUR = new UserUR.Builder(user.getKey()).
+ username(new
StringReplacePatchItem.Builder().value(user.getUsername() +
getUUIDString()).build()).
+ role(new StringPatchItem.Builder().value("User
manager").build()).
+ build();
+
+ SyncopeClient authClient = CLIENT_FACTORY.create(user.getUsername(),
"password123");
+ user = authClient.getService(UserSelfService.class).
+ update(userUR).
+ readEntity(new GenericType<ProvisioningResult<UserTO>>() {
+ }).getEntity();
+ assertEquals("updateApproval", user.getStatus());
+ }
}
diff --git a/src/main/asciidoc/images/userWorkflow.png
b/src/main/asciidoc/images/userWorkflow.png
index 04c63722c4..a522f38dce 100644
Binary files a/src/main/asciidoc/images/userWorkflow.png and
b/src/main/asciidoc/images/userWorkflow.png differ
diff --git
a/src/main/asciidoc/reference-guide/configuration/configurationparameters.adoc
b/src/main/asciidoc/reference-guide/configuration/configurationparameters.adoc
index e55ba970f4..e5625a62bb 100644
---
a/src/main/asciidoc/reference-guide/configuration/configurationparameters.adoc
+++
b/src/main/asciidoc/reference-guide/configuration/configurationparameters.adoc
@@ -76,7 +76,11 @@ or to completely disable connector connection testing.
[NOTE]
====
This parameter is useful to avoid waiting for the default resource timeout, by
setting a shorter value;
-or to completely disable resource connection testing.
+or to completely disable resource connection testing;
====
+* `default.workflow.requires.approval` - when using the default
<<workflow,user workflow adapter>> (e.g. not
+<<flowable-user-workflow-adapter,Flowable>>), this option controls whether an
exception shall be raised when any
+requested change requires admin approval.
+
Besides this default set, new configuration parameters can be defined to
support <<customization,custom>> code.