Skip to content

Commit 4ec6d03

Browse files
raboergoomens
andauthored
DN-3423 feat: Events occuring multiple times (#34)
* DN-3423 feat: Events occuring multiple times * DN-3423 Fixed some small issues * DN-3423 Added nuget * DN-3423 Store type of operation in eventlog (insert, update). Delete needs to be implmented in other branch * DN-3423 Handle deletion of events * DN-3423 Made eventlog operation enum and did some refactorings * DN-3423 chore: formatting * DN-3423 Fixed issue where enum wasnt serialized as string --------- Co-authored-by: Gerrit Oomens <[email protected]>
1 parent 1619139 commit 4ec6d03

26 files changed

+331
-93
lines changed

UvA.Workflow.Api/Actions/ActionsController.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
using UvA.Workflow.Api.Actions.Dtos;
22
using UvA.Workflow.Api.Infrastructure;
3-
using UvA.Workflow.Api.WorkflowInstances;
43
using UvA.Workflow.Api.WorkflowInstances.Dtos;
54

65
namespace UvA.Workflow.Api.Actions;
76

87
public class ActionsController(
98
IWorkflowInstanceRepository workflowInstanceRepository,
9+
IUserService userService,
1010
RightsService rightsService,
1111
TriggerService triggerService,
1212
WorkflowInstanceDtoFactory workflowInstanceDtoFactory,
@@ -17,6 +17,10 @@ InstanceService instanceService
1717
public async Task<ActionResult<ExecuteActionPayloadDto>> ExecuteAction([FromBody] ExecuteActionInputDto input,
1818
CancellationToken ct)
1919
{
20+
var currentUser = await userService.GetCurrentUser(ct);
21+
if (currentUser == null)
22+
return Unauthorized();
23+
2024
var instance = await workflowInstanceRepository.GetById(input.InstanceId, ct);
2125
if (instance == null)
2226
return WorkflowInstanceNotFound;
@@ -38,7 +42,7 @@ public async Task<ActionResult<ExecuteActionPayloadDto>> ExecuteAction([FromBody
3842
if (action == null)
3943
return Forbidden();
4044

41-
await triggerService.RunTriggers(instance, action.Triggers, ct, input.Mail);
45+
await triggerService.RunTriggers(instance, action.Triggers, currentUser, ct, input.Mail);
4246
await instanceService.UpdateCurrentStep(instance, ct);
4347
break;
4448
}

UvA.Workflow.Api/Authentication/SurfConextAuthenticationHandler.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ namespace UvA.Workflow.Api.Authentication;
88

99
public class SurfConextAuthenticationHandler : AuthenticationHandler<SurfConextOptions>
1010
{
11-
private const string SURFCONEXT_ERROR = "SurfConextError";
12-
public static string Scheme => "SURFconext";
11+
private const string SurfconextError = "SurfConextError";
12+
public static string SchemeName => "SURFconext";
1313

1414
/// <summary>
1515
/// implements the behavior of the SurfConext scheme to authenticate users.
@@ -56,7 +56,7 @@ protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
5656
var cacheKey = $"bt_{bearerToken}";
5757

5858
if (cache.TryGetValue(cacheKey, out ClaimsPrincipal? cachedPrincipal))
59-
return AuthenticateResult.Success(new AuthenticationTicket(cachedPrincipal!, Scheme));
59+
return AuthenticateResult.Success(new AuthenticationTicket(cachedPrincipal!, SchemeName));
6060

6161
var resp = await ValidateSurfBearerToken(bearerToken);
6262
if (resp == null)
@@ -81,7 +81,7 @@ protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
8181

8282
await userService.AddOrUpdateUser(principal.Identity!.Name!, resp.FullName, resp.Email);
8383

84-
return AuthenticateResult.Success(new AuthenticationTicket(principal, Scheme));
84+
return AuthenticateResult.Success(new AuthenticationTicket(principal, SchemeName));
8585
}
8686

8787
protected override Task HandleChallengeAsync(AuthenticationProperties properties)
@@ -91,7 +91,7 @@ protected override Task HandleChallengeAsync(AuthenticationProperties properties
9191
{
9292
Status = StatusCodes.Status401Unauthorized,
9393
Title = "Unauthorized",
94-
Detail = Context.Items[SURFCONEXT_ERROR] as string ?? "Unauthorized",
94+
Detail = Context.Items[SurfconextError] as string ?? "Unauthorized",
9595
Instance = Context.Request.Path.Value
9696
},
9797
new JsonSerializerOptions(JsonSerializerDefaults.Web));
@@ -112,7 +112,7 @@ protected override Task HandleChallengeAsync(AuthenticationProperties properties
112112
"Token validation failed: SurfConext returned status {Code}: {Response}, ClientId:{ClientId}, Secret:{ClientSecret}",
113113
response.StatusCode, content, OptionsMonitor.CurrentValue.ClientId,
114114
OptionsMonitor.CurrentValue.ClientSecret?[..4]);
115-
Context.Items[SURFCONEXT_ERROR] =
115+
Context.Items[SurfconextError] =
116116
$"Token validation failed: SurfConext returned status {response.StatusCode}, check the logs for details";
117117
return null;
118118
}
@@ -124,7 +124,7 @@ protected override Task HandleChallengeAsync(AuthenticationProperties properties
124124
catch (Exception ex)
125125
{
126126
Logger.LogError(ex, "Token validation failed: unable to deserialize response: {Response}", content);
127-
Context.Items[SURFCONEXT_ERROR] =
127+
Context.Items[SurfconextError] =
128128
$"Token validation failed: unable to deserialize response from SurfConext, check the logs for details";
129129
return null;
130130
}
@@ -148,7 +148,7 @@ private static ClaimsPrincipal CreateClaimsPrincipal(IntrospectionResponse r)
148148

149149
if (r.Uids is { Length: > 0 } && !string.IsNullOrWhiteSpace(r.Uids[0]))
150150
{
151-
claims.Add(new Claim(ClaimTypes.NameIdentifier, r.Uids[0]));
151+
claims.Add(new Claim(ClaimTypes.NameIdentifier, UvaClaimTypes.UvanetId));
152152
claims.Add(new Claim(UvaClaimTypes.UvanetId, r.Uids[0]));
153153
}
154154

@@ -177,7 +177,7 @@ private static ClaimsPrincipal CreateClaimsPrincipal(IntrospectionResponse r)
177177
claims.Add(new Claim("updated_at",
178178
r.UpdatedAt.Value.ToString(System.Globalization.CultureInfo.InvariantCulture)));
179179

180-
var identity = new ClaimsIdentity(claims, Scheme, UvaClaimTypes.UvanetId, ClaimTypes.Role);
180+
var identity = new ClaimsIdentity(claims, SchemeName, UvaClaimTypes.UvanetId, ClaimTypes.Role);
181181
return new ClaimsPrincipal(identity);
182182
}
183183
}

UvA.Workflow.Api/Authentication/SurfConextExtensions.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ public static IServiceCollection AddSurfConextAuthentication(this IServiceCollec
3131

3232
services.AddAuthentication(authOptions =>
3333
{
34-
authOptions.AddScheme<SurfConextAuthenticationHandler>(SurfConextAuthenticationHandler.Scheme, null);
34+
authOptions.AddScheme<SurfConextAuthenticationHandler>(SurfConextAuthenticationHandler.SchemeName,
35+
null);
3536
});
3637

3738
services.AddSwaggerGen(c =>
Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,27 @@
11
using UvA.Workflow.Api.Infrastructure;
2+
using UvA.Workflow.Events;
23

34
namespace UvA.Workflow.Api.Events;
45

56
[Route("/WorkflowInstances/{instanceId}/Events")]
6-
public class EventsController(IWorkflowInstanceRepository workflowRepository, InstanceService instanceService)
7+
public class EventsController(
8+
IWorkflowInstanceRepository workflowRepository,
9+
IUserService userService,
10+
IInstanceEventService eventService)
711
: ApiControllerBase
812
{
913
[HttpDelete]
1014
[Route("{eventName}")]
1115
public async Task<IActionResult> DeleteEvent(string instanceId, string eventName, CancellationToken ct)
1216
{
17+
var user = await userService.GetCurrentUser(ct);
18+
if (user == null)
19+
return Unauthorized();
20+
1321
var instance = await workflowRepository.GetById(instanceId, ct);
1422
if (instance == null)
1523
return WorkflowInstanceNotFound;
16-
await instanceService.DeleteEvent(instance, eventName, ct);
24+
await eventService.DeleteEvent(instance, eventName, user, ct);
1725
return Ok();
1826
}
1927
}

UvA.Workflow.Api/Infrastructure/ServiceCollectionExtentions.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using UvA.Workflow.Api.Screens;
22
using UvA.Workflow.Api.Submissions.Dtos;
3+
using UvA.Workflow.Events;
34
using UvA.Workflow.Infrastructure.Database;
45
using UvA.Workflow.Persistence;
56
using UvA.Workflow.Submissions;
@@ -26,6 +27,7 @@ public static IServiceCollection AddWorkflow(this IServiceCollection services, I
2627
// Register repositories - organized by domain feature
2728
services.AddScoped<IWorkflowInstanceRepository, WorkflowInstanceRepository>();
2829
services.AddScoped<IUserRepository, UserRepository>();
30+
services.AddScoped<IInstanceEventRepository, InstanceEventRepository>();
2931

3032
services.AddScoped<WorkflowInstanceService>();
3133
services.AddScoped<IUserService, UserService>();
@@ -39,6 +41,8 @@ public static IServiceCollection AddWorkflow(this IServiceCollection services, I
3941
services.AddScoped<AnswerDtoFactory>();
4042

4143
services.AddScoped<InstanceService>();
44+
services.AddScoped<IInstanceEventService, InstanceEventService>();
45+
4246
services.AddScoped<RightsService>();
4347
services.AddScoped<TriggerService>();
4448
services.AddScoped<AnswerConversionService>();

UvA.Workflow.Api/Screens/ScreenDataService.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using UvA.Workflow.Api.Screens.Dtos;
2+
using UvA.Workflow.Events;
23
using UvA.Workflow.Tools;
34

45
namespace UvA.Workflow.Api.Screens;

UvA.Workflow.Api/Submissions/Dtos/SubmissionDto.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using UvA.Workflow.Api.Infrastructure;
2+
using UvA.Workflow.Events;
23
using UvA.Workflow.Submissions;
34

45
namespace UvA.Workflow.Api.Submissions.Dtos;

UvA.Workflow.Api/Submissions/SubmissionsController.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
namespace UvA.Workflow.Api.Submissions;
77

88
public class SubmissionsController(
9+
IUserService userService,
910
ModelService modelService,
1011
SubmissionService submissionService,
1112
SubmissionDtoFactory submissionDtoFactory,
@@ -26,15 +27,19 @@ public async Task<ActionResult<SubmissionDto>> GetSubmission(string instanceId,
2627
public async Task<ActionResult<SubmitSubmissionResult>> SubmitSubmission(string instanceId, string submissionId,
2728
CancellationToken ct)
2829
{
30+
var currentUser = await userService.GetCurrentUser(ct);
31+
if (currentUser == null)
32+
return Unauthorized();
2933
var context = await submissionService.GetSubmissionContext(instanceId, submissionId, ct);
3034
var (instance, sub, form, _) = context;
31-
var result = await submissionService.SubmitSubmission(context, ct);
35+
var result = await submissionService.SubmitSubmission(context, currentUser, ct);
3236

3337
if (!result.Success)
3438
{
3539
var submissionDto = submissionDtoFactory.Create(instance, form, sub,
3640
modelService.GetQuestionStatus(instance, form, true));
37-
return Ok(new SubmitSubmissionResult(submissionDto, null, result.Errors, false));
41+
42+
return UnprocessableEntity(new SubmitSubmissionResult(submissionDto, null, result.Errors, false));
3843
}
3944

4045
var finalSubmissionDto = submissionDtoFactory.Create(instance, form, instance.Events[submissionId],

UvA.Workflow.Api/WorkflowInstances/Dtos/WorkflowInstanceDto.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using UvA.Workflow.Api.Actions.Dtos;
22
using UvA.Workflow.Api.EntityTypes.Dtos;
33
using UvA.Workflow.Api.Submissions.Dtos;
4+
using UvA.Workflow.Events;
45

56
namespace UvA.Workflow.Api.WorkflowInstances.Dtos;
67

UvA.Workflow.Tests/Builders/EventBuilder.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using UvA.Workflow.Events;
12
using UvA.Workflow.WorkflowInstances;
23

34
namespace UvA.Workflow.Tests;

0 commit comments

Comments
 (0)