Skip to content

Commit 6e821d9

Browse files
Ticket ## : Fix UpdatePassword BPMN workflow
1 parent 1ecd3eb commit 6e821d9

File tree

18 files changed

+326
-29
lines changed

18 files changed

+326
-29
lines changed

src/CaseManagement.BPMN.AspNetCore/Apis/ProcessInstancesController.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public async Task<IActionResult> Search([FromBody] SearchProcessInstancesQuery s
6464
}
6565

6666
[HttpGet("{id}/start")]
67-
[Authorize("Authenticated")]
67+
// [Authorize("Authenticated")]
6868
public async Task<IActionResult> Start(string id, CancellationToken cancellationToken)
6969
{
7070
try

src/CaseManagement.BPMN.Host/Bpmns/UpdatePassword.bpmn

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<message id="humanTaskCreated" name="humanTaskCreated" />
55
<process id="Process_1" isExecutable="false">
66
<serviceTask id="Task_1hcentk" name="Send Email" implementation="##csharpcallback" cmg:delegateId="SendEmailDelegate">
7-
<incoming>Flow_0dts36d</incoming>
7+
<incoming>Flow_0c7dmuv</incoming>
88
</serviceTask>
99
<userTask id="Activity_0fhwdxz" name="Submit Password" implementation="##WsHumanTask" cmg:wsHumanTaskDefName="updatePassword">
1010
<incoming>Flow_1fdpmlk</incoming>
@@ -25,26 +25,35 @@
2525
</startEvent>
2626
<sequenceFlow id="Flow_1fdpmlk" sourceRef="StartEvent_1y45yut" targetRef="Activity_0fhwdxz" />
2727
<boundaryEvent id="Event_0q7uygb" attachedToRef="Activity_0fhwdxz">
28-
<outgoing>Flow_02s526x</outgoing>
28+
<outgoing>Flow_1n7tsdg</outgoing>
2929
<messageEventDefinition id="MessageEventDefinition_135rspe" messageRef="humanTaskCreated" />
3030
</boundaryEvent>
31-
<sequenceFlow id="Flow_02s526x" sourceRef="Event_0q7uygb" targetRef="Activity_0owchb4" />
32-
<sequenceFlow id="Flow_0dts36d" sourceRef="Activity_0owchb4" targetRef="Task_1hcentk" />
3331
<serviceTask id="Activity_0owchb4" name="Generate OTP" implementation="##csharpcallback" cmg:delegateId="GenerateOTPDelegate">
34-
<incoming>Flow_02s526x</incoming>
35-
<outgoing>Flow_0dts36d</outgoing>
32+
<incoming>Flow_1xgm5e7</incoming>
33+
<outgoing>Flow_0c7dmuv</outgoing>
34+
</serviceTask>
35+
<sequenceFlow id="Flow_1xgm5e7" sourceRef="Activity_13pndds" targetRef="Activity_0owchb4" />
36+
<sequenceFlow id="Flow_0c7dmuv" sourceRef="Activity_0owchb4" targetRef="Task_1hcentk" />
37+
<sequenceFlow id="Flow_1n7tsdg" sourceRef="Event_0q7uygb" targetRef="Activity_13pndds" />
38+
<serviceTask id="Activity_13pndds" name="Assign HumanTask" implementation="##csharpcallback" cmg:delegateId="assignHumanTask">
39+
<incoming>Flow_1n7tsdg</incoming>
40+
<outgoing>Flow_1xgm5e7</outgoing>
3641
</serviceTask>
3742
</process>
3843
<bpmndi:BPMNDiagram id="BpmnDiagram_1">
3944
<bpmndi:BPMNPlane id="BpmnPlane_1" bpmnElement="Process_1">
40-
<bpmndi:BPMNEdge id="Flow_0dts36d_di" bpmnElement="Flow_0dts36d">
41-
<omgdi:waypoint x="490" y="350" />
42-
<omgdi:waypoint x="490" y="440" />
43-
</bpmndi:BPMNEdge>
44-
<bpmndi:BPMNEdge id="Flow_02s526x_di" bpmnElement="Flow_02s526x">
45+
<bpmndi:BPMNEdge id="Flow_1n7tsdg_di" bpmnElement="Flow_1n7tsdg">
4546
<omgdi:waypoint x="490" y="208" />
4647
<omgdi:waypoint x="490" y="270" />
4748
</bpmndi:BPMNEdge>
49+
<bpmndi:BPMNEdge id="Flow_0c7dmuv_di" bpmnElement="Flow_0c7dmuv">
50+
<omgdi:waypoint x="720" y="350" />
51+
<omgdi:waypoint x="720" y="440" />
52+
</bpmndi:BPMNEdge>
53+
<bpmndi:BPMNEdge id="Flow_1xgm5e7_di" bpmnElement="Flow_1xgm5e7">
54+
<omgdi:waypoint x="540" y="310" />
55+
<omgdi:waypoint x="670" y="310" />
56+
</bpmndi:BPMNEdge>
4857
<bpmndi:BPMNEdge id="Flow_1fdpmlk_di" bpmnElement="Flow_1fdpmlk">
4958
<omgdi:waypoint x="188" y="150" />
5059
<omgdi:waypoint x="390" y="150" />
@@ -58,7 +67,7 @@
5867
<omgdi:waypoint x="720" y="150" />
5968
</bpmndi:BPMNEdge>
6069
<bpmndi:BPMNShape id="Activity_1saua76_di" bpmnElement="Task_1hcentk">
61-
<omgdc:Bounds x="440" y="440" width="100" height="80" />
70+
<omgdc:Bounds x="670" y="440" width="100" height="80" />
6271
</bpmndi:BPMNShape>
6372
<bpmndi:BPMNShape id="Activity_1j5vxke_di" bpmnElement="Activity_0fhwdxz">
6473
<omgdc:Bounds x="390" y="110" width="100" height="80" />
@@ -73,6 +82,9 @@
7382
<omgdc:Bounds x="152" y="132" width="36" height="36" />
7483
</bpmndi:BPMNShape>
7584
<bpmndi:BPMNShape id="Activity_0yn3q1b_di" bpmnElement="Activity_0owchb4">
85+
<omgdc:Bounds x="670" y="270" width="100" height="80" />
86+
</bpmndi:BPMNShape>
87+
<bpmndi:BPMNShape id="Activity_1n5f85d_di" bpmnElement="Activity_13pndds">
7688
<omgdc:Bounds x="440" y="270" width="100" height="80" />
7789
</bpmndi:BPMNShape>
7890
<bpmndi:BPMNShape id="Event_10s7arv_di" bpmnElement="Event_0q7uygb">
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
using CaseManagement.BPMN.Domains;
2+
using CaseManagement.BPMN.Exceptions;
3+
using CaseManagement.BPMN.ProcessInstance.Processors;
4+
using IdentityModel.Client;
5+
using Newtonsoft.Json.Linq;
6+
using System;
7+
using System.Collections.Generic;
8+
using System.Linq;
9+
using System.Net.Http;
10+
using System.Text;
11+
using System.Threading;
12+
using System.Threading.Tasks;
13+
14+
namespace CaseManagement.BPMN.Host.Delegates
15+
{
16+
public class AssignHumanTaskInstanceDelegate : IDelegateHandler
17+
{
18+
public async Task<ICollection<MessageToken>> Execute(BPMNExecutionContext context, ICollection<MessageToken> incoming, DelegateConfigurationAggregate delegateConfiguration, CancellationToken cancellationToken)
19+
{
20+
var user = incoming.FirstOrDefault(i => i.Name == "user");
21+
if (user == null)
22+
{
23+
throw new BPMNProcessorException("user must be passed in the request");
24+
}
25+
26+
var userId = user.GetProperty("userId");
27+
if (string.IsNullOrWhiteSpace(userId))
28+
{
29+
throw new BPMNProcessorException("userId is not passed in the request");
30+
}
31+
32+
var humanTaskInstanceId = incoming.First(i => i.Name == "humanTaskCreated").JObjMessageContent.SelectToken("humanTaskInstance.id").ToString();
33+
using (var httpClient = new HttpClient())
34+
{
35+
36+
var parameter = AssignHumanTaskInstanceParameter.Create(delegateConfiguration);
37+
var tokenResponse = await httpClient.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
38+
{
39+
Address = parameter.TokenUrl,
40+
ClientId = parameter.ClientId,
41+
ClientSecret = parameter.ClientSecret,
42+
Scope = "manage_humantaskinstance"
43+
}, cancellationToken);
44+
await Claim(httpClient, parameter, humanTaskInstanceId, userId, tokenResponse.AccessToken, cancellationToken);
45+
await Start(httpClient, parameter, humanTaskInstanceId, userId, tokenResponse.AccessToken, cancellationToken);
46+
}
47+
48+
ICollection<MessageToken> result = new List<MessageToken>
49+
{
50+
MessageToken.EmptyMessage(context.Pointer.InstanceFlowNodeId, "assignHumanTaskInstance")
51+
};
52+
return result;
53+
}
54+
55+
private static async Task Claim(HttpClient httpClient, AssignHumanTaskInstanceParameter parameter, string humanTaskInstanceId, string userId, string accessToken, CancellationToken cancellationToken)
56+
{
57+
var obj = new JObject
58+
{
59+
{ "userId", userId }
60+
};
61+
var content = new StringContent(obj.ToString(), Encoding.UTF8, "application/json");
62+
var url = parameter.HumanTaskInstanceClaimUrl.Replace("{id}", humanTaskInstanceId);
63+
var request = new HttpRequestMessage
64+
{
65+
Method = HttpMethod.Post,
66+
Content = content,
67+
RequestUri = new Uri(url)
68+
};
69+
request.Headers.Add("Authorization", $"Bearer {accessToken}");
70+
var httpResponse = await httpClient.SendAsync(request, cancellationToken);
71+
httpResponse.EnsureSuccessStatusCode();
72+
}
73+
74+
private static async Task Start(HttpClient httpClient, AssignHumanTaskInstanceParameter parameter, string humanTaskInstanceId, string userId, string accessToken, CancellationToken cancellationToken)
75+
{
76+
var obj = new JObject
77+
{
78+
{ "userId", userId }
79+
};
80+
var content = new StringContent(obj.ToString(), Encoding.UTF8, "application/json");
81+
var url = parameter.HumanTaskInstanceStartUrl.Replace("{id}", humanTaskInstanceId);
82+
var request = new HttpRequestMessage
83+
{
84+
Method = HttpMethod.Post,
85+
Content = content,
86+
RequestUri = new Uri(url)
87+
};
88+
request.Headers.Add("Authorization", $"Bearer {accessToken}");
89+
var httpResponse = await httpClient.SendAsync(request, cancellationToken);
90+
httpResponse.EnsureSuccessStatusCode();
91+
}
92+
93+
private class AssignHumanTaskInstanceParameter
94+
{
95+
public string TokenUrl { get; set; }
96+
public string ClientId { get; set; }
97+
public string ClientSecret { get; set; }
98+
public string HumanTaskInstanceClaimUrl { get; set; }
99+
public string HumanTaskInstanceStartUrl { get; set; }
100+
101+
public static AssignHumanTaskInstanceParameter Create(DelegateConfigurationAggregate delegateConfiguration)
102+
{
103+
return new AssignHumanTaskInstanceParameter
104+
{
105+
ClientId = delegateConfiguration.GetValue("clientId"),
106+
ClientSecret = delegateConfiguration.GetValue("clientSecret"),
107+
TokenUrl = delegateConfiguration.GetValue("tokenUrl"),
108+
HumanTaskInstanceClaimUrl = delegateConfiguration.GetValue("humanTaskInstanceClaimUrl"),
109+
HumanTaskInstanceStartUrl = delegateConfiguration.GetValue("humanTaskInstanceStartUrl")
110+
};
111+
}
112+
}
113+
}
114+
}

src/CaseManagement.BPMN.Host/Startup.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ private static ConcurrentBag<DelegateConfigurationAggregate> GetDelegateConfigur
198198
var sendEmailDelegate = DelegateConfigurationAggregate.Create("SendEmailDelegate", typeof(SendEmailDelegate).FullName);
199199
sendEmailDelegate.AddDisplayName("fr", "Envoyer un email");
200200
sendEmailDelegate.AddDisplayName("en", "Send email");
201-
sendEmailDelegate.AddRecord("httpBody", "Please update the password by clicking on the website {{configuration.Get('humanTaskUrl')}}/humantasks/{{messages.Get('humanTaskCreated', 'humanTaskInstance.fileId')}}/instances/{{messages.Get('humanTaskCreated', 'humanTaskInstance.id')}}?auth=email, the OTP code is {{messages.Get('otp', 'otpCode')}}");
201+
sendEmailDelegate.AddRecord("httpBody", "Please update the password by clicking on the website {{configuration.Get('humanTaskUrl')}}/humantaskinstances/{{messages.Get('humanTaskCreated', 'humanTaskInstance.id')}}?auth=email, the OTP code is {{messages.Get('otp', 'otpCode')}}");
202202
sendEmailDelegate.AddRecord("subject", "Update password");
203203
sendEmailDelegate.AddRecord("fromEmail", credential.Login);
204204
sendEmailDelegate.AddRecord("smtpHost", "smtp.gmail.com");
@@ -226,12 +226,22 @@ private static ConcurrentBag<DelegateConfigurationAggregate> GetDelegateConfigur
226226
generateOTPDelegate.AddRecord("userUrl", "https://localhost:60000/management/users/{id}/otp");
227227
generateOTPDelegate.AddRecord("scope", "manage_users");
228228

229+
var assignHumanTaskInstanceDelegate = DelegateConfigurationAggregate.Create("assignHumanTask", typeof(AssignHumanTaskInstanceDelegate).FullName);
230+
assignHumanTaskInstanceDelegate.AddDisplayName("fr", "Assigner la tâche humaine");
231+
assignHumanTaskInstanceDelegate.AddDisplayName("en", "Assign human task");
232+
assignHumanTaskInstanceDelegate.AddRecord("clientId", "humanTaskClient");
233+
assignHumanTaskInstanceDelegate.AddRecord("clientSecret", "humanTaskClientSecret");
234+
assignHumanTaskInstanceDelegate.AddRecord("tokenUrl", "https://localhost:60000/token");
235+
assignHumanTaskInstanceDelegate.AddRecord("humanTaskInstanceClaimUrl", "http://localhost:60006/humantaskinstances/{id}/force/claim");
236+
assignHumanTaskInstanceDelegate.AddRecord("humanTaskInstanceStartUrl", "http://localhost:60006/humantaskinstances/{id}/force/start");
237+
229238
return new ConcurrentBag<DelegateConfigurationAggregate>
230239
{
231240
getWeatherInformationDelegate,
232241
sendEmailDelegate,
233242
updateUserPasswordDelegate,
234-
generateOTPDelegate
243+
generateOTPDelegate,
244+
assignHumanTaskInstanceDelegate
235245
};
236246
}
237247

src/CaseManagement.BPMN/ProcessInstance/Processors/Activities/Handlers/WsHumanTaskHandler.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public async Task<ICollection<MessageToken>> Execute(BPMNExecutionContext execut
6666
Address = _options.OAuthTokenEndpoint,
6767
ClientId = _options.ClientId,
6868
ClientSecret = _options.ClientSecret,
69-
Scope = "create_humantaskinstance"
69+
Scope = "manage_humantaskinstance"
7070
}, token);
7171
if (tokenResponse.IsError)
7272
{
@@ -91,10 +91,11 @@ public async Task<ICollection<MessageToken>> Execute(BPMNExecutionContext execut
9191
var str = await httpResult.Content.ReadAsStringAsync();
9292
var o = JObject.Parse(str);
9393
var humanTaskInstanceId = o["id"].ToString();
94+
var humanTaskDefId = o["defId"].ToString();
9495
executionContext.Instance.UpdateMetadata(pointer.InstanceFlowNodeId, HUMANTASK_INSTANCE_ID_NAME, humanTaskInstanceId);
9596
var humanTaskInstance = new JObject();
9697
humanTaskInstance.Add("id", humanTaskInstanceId);
97-
humanTaskInstance.Add("fileId", userTask.HumanTaskName);
98+
humanTaskInstance.Add("fileId", humanTaskDefId);
9899
var messageContent = new JObject();
99100
messageContent.Add("humanTaskInstance", humanTaskInstance);
100101
executionContext.Instance.ConsumeMessage(new MessageToken

src/CaseManagement.HumanTask.AspNetCore/Apis/HumanTaskInstancesController.cs

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public HumanTaskInstancesController(IMediator mediator)
2727
#region Actions
2828

2929
[HttpPost]
30-
[Authorize(HumanTaskConstants.ScopeNames.CreateHumanTaskInstance)]
30+
[Authorize(HumanTaskConstants.ScopeNames.ManageHumanTaskInstance)]
3131
public Task<IActionResult> Add([FromBody] CreateHumanTaskInstanceCommand parameter, CancellationToken token)
3232
{
3333
parameter.IgnorePermissions = true;
@@ -113,6 +113,25 @@ public async Task<IActionResult> Claim(string id, CancellationToken token)
113113
}
114114
}
115115

116+
[HttpPost("{id}/force/claim")]
117+
[Authorize(HumanTaskConstants.ScopeNames.ManageHumanTaskInstance)]
118+
public async Task<IActionResult> Claim(string id, [FromBody] ForceClaimHumanTaskInstanceCommand cmd, CancellationToken token)
119+
{
120+
try
121+
{
122+
cmd.HumanTaskInstanceId = id;
123+
await _mediator.Send(cmd, token);
124+
return new NoContentResult();
125+
}
126+
catch (UnknownHumanTaskInstanceException ex)
127+
{
128+
return this.ToError(new List<KeyValuePair<string, string>>
129+
{
130+
new KeyValuePair<string, string>("bad_request", ex.Message)
131+
}, HttpStatusCode.NotFound, Request);
132+
}
133+
}
134+
116135
[HttpGet("{id}/start")]
117136
[Authorize("Authenticated")]
118137
public async Task<IActionResult> Start(string id, CancellationToken token)
@@ -144,6 +163,26 @@ public async Task<IActionResult> Start(string id, CancellationToken token)
144163
}
145164
}
146165

166+
167+
[HttpPost("{id}/force/start")]
168+
[Authorize(HumanTaskConstants.ScopeNames.ManageHumanTaskInstance)]
169+
public async Task<IActionResult> Start(string id, [FromBody] ForceStartHumanTaskInstanceCommand cmd, CancellationToken token)
170+
{
171+
try
172+
{
173+
cmd.HumanTaskInstanceId = id;
174+
await _mediator.Send(cmd, token);
175+
return new NoContentResult();
176+
}
177+
catch (UnknownHumanTaskInstanceException ex)
178+
{
179+
return this.ToError(new List<KeyValuePair<string, string>>
180+
{
181+
new KeyValuePair<string, string>("bad_request", ex.Message)
182+
}, HttpStatusCode.NotFound, Request);
183+
}
184+
}
185+
147186
[HttpPost("{id}/complete")]
148187
[Authorize("Authenticated")]
149188
public async Task<IActionResult> Complete(string id, [FromBody] CompleteHumanTaskInstanceCommand parameter, CancellationToken token)
@@ -309,7 +348,7 @@ private async Task<IActionResult> SharedAdd(CreateHumanTaskInstanceCommand param
309348
{
310349
parameter.Claims = User.GetClaims();
311350
var result = await _mediator.Send(parameter, token);
312-
return new CreatedResult(string.Empty, new { id = result });
351+
return new CreatedResult(string.Empty, result);
313352
}
314353
catch (UnknownHumanTaskDefException ex)
315354
{

src/CaseManagement.HumanTask.AspNetCore/AuthorizationOptionsExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ public static class AuthorizationOptionsExtensions
1010
public static void AddDefaultHumanTaskAuthorizationPolicy(this AuthorizationOptions opts)
1111
{
1212
opts.AddPolicy("Authenticated", p => p.RequireAuthenticatedUser());
13-
opts.AddPolicy(HumanTaskConstants.ScopeNames.CreateHumanTaskInstance, p =>
13+
opts.AddPolicy(HumanTaskConstants.ScopeNames.ManageHumanTaskInstance, p =>
1414
{
15-
p.RequireClaim("scope", HumanTaskConstants.ScopeNames.CreateHumanTaskInstance);
15+
p.RequireClaim("scope", HumanTaskConstants.ScopeNames.ManageHumanTaskInstance);
1616
});
1717
}
1818
}

src/CaseManagement.HumanTask.Host/Startup.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ public void ConfigureServices(IServiceCollection services)
157157
"bpmnClient",
158158
"caseManagementTasklistWebsite",
159159
"caseManagementWebsite",
160+
"simpleIdServerWebsite",
161+
"humanTaskClient",
160162
"https://localhost:60000",
161163
"https://simpleidserver.northeurope.cloudapp.azure.com/openid"
162164
},

src/CaseManagement.HumanTask/Authorization/AuthorizationHelper.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ protected virtual async Task<bool> IsAuthorized(ICollection<PeopleAssignmentInst
116116

117117
private static bool IsAdmin(IEnumerable<KeyValuePair<string, string>> claims)
118118
{
119-
return claims.Any(_ => _.Key == "scope" && _.Value == HumanTaskConstants.ScopeNames.CreateHumanTaskInstance);
119+
return claims.Any(_ => _.Key == "scope" && _.Value == HumanTaskConstants.ScopeNames.ManageHumanTaskInstance);
120120
}
121121
}
122122
}

src/CaseManagement.HumanTask/HumanTaskConstants.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public static class RouteNames
1212

1313
public static class ScopeNames
1414
{
15-
public const string CreateHumanTaskInstance = "create_humantaskinstance";
15+
public const string ManageHumanTaskInstance = "manage_humantaskinstance";
1616
}
1717
}
1818
}

0 commit comments

Comments
 (0)