Skip to content

Commit

Permalink
throw error if engagement type participant roles don't match the allo…
Browse files Browse the repository at this point in the history
…wed values in the config
  • Loading branch information
mcanoy committed Jun 17, 2022
1 parent b358e22 commit 4f40806
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,27 @@ public Response invalidateRbacCache() {
@Path("artifact/options")
@SecurityRequirement(name = "jwt")
@APIResponses(value = { @APIResponse(responseCode = "401", description = "Missing or Invalid JWT"),
@APIResponse(responseCode = "200", description = "Artifact ptions success.") })
@Operation(summary = "Returns a map of key value pairs or artifact option.")
@APIResponse(responseCode = "200", description = "Artifact options success.") })
@Operation(summary = "Returns a map of key value pairs of artifact options.")
public Map<String, String> getArtifactOptions() {
return configService.getArtifactOptions();
}

@GET
@Path("participant/options")
@SecurityRequirement(name = "jwt")
@APIResponses(value = { @APIResponse(responseCode = "401", description = "Missing or Invalid JWT"),
@APIResponse(responseCode = "200", description = "Participant options success.") })
@Operation(summary = "Returns a map of key value pairs of participant options. " +
"If the engagement type is not found it will return the default values (Residency)")
public Map<String, String> getParticipantOptions(@QueryParam("engagementType") String type) {
if(type == null) {
return configService.getParticipantOptions();
}

return configService.getParticipantOptions(type);
}

@GET
@Path("engagement/options")
@SecurityRequirement(name = "jwt")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ public interface ConfigApiClient {
@Path("artifact/options")
Map<String, String> getArtifactOptions();

@GET
@Path("participant/options")
Map<String, String> getParticipantOptions(@QueryParam("engagementType") String type);

@GET
@Path("participant/options")
Map<String, String> getParticipantOptions();

@GET
@Path("engagement/options")
Map<String, String> getEngagementOptions();
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/com/redhat/labs/lodestar/service/ConfigService.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,17 @@ public Response getRuntimeConfig(Optional<String> type) {
return configApiClient.getRuntimeConfig(type.isPresent() ? type.get() : null);
}

@CacheResult(cacheName = "participant-options")
public Map<String, String> getParticipantOptions(String type) {
LOGGER.debug("cache miss for participant options ({})", type);
return configApiClient.getParticipantOptions(type);
}
@CacheResult(cacheName = "participant-options-base")
public Map<String, String> getParticipantOptions() {
LOGGER.debug("cache miss for participant options (base)");
return configApiClient.getParticipantOptions();
}

@CacheResult(cacheName = "artifact-options")
public Map<String, String> getArtifactOptions() {
LOGGER.debug("cache miss for artifact options");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ public Engagement create(Engagement engagement) {

/**
* Updates the {@link Engagement} resource in the data store
* This supports the way v1 frontend saves the entire engagement. In the future the FE should use direct
* updates to each component
*
* @param engagement
* @return
Expand Down Expand Up @@ -194,6 +196,20 @@ public Engagement update(Engagement engagement) {
diff = javers.compareCollections(new HashSet<>(participants), engagement.getEngagementUsers(), EngagementUser.class);
if(diff.hasChanges()) {
LOGGER.debug("Participants changed {}", diff);

//Validate participant options
Set<String> allowed = configService.getParticipantOptions(engagement.getType()).keySet();
String errors = "";
for(EngagementUser p : engagement.getEngagementUsers()) {
if(allowed.contains(p.getRole())) {
errors += String.format("Participant %s has invalid role %s. ", p.getEmail(), p.getRole());
LOGGER.error("Participant {} has invalid role {} for engagement type {} - {}", p.getEmail(), p.getRole(), engagement.getType(), engagement.getUuid());
}
}

if(!errors.isEmpty()) {
throw new WebApplicationException(Response.status(400).entity(Map.of("lodestarMessage", errors.trim())).build());
}
participants = participantService.updateParticipantsAndReload(engagementUuid, author, authorEmail,
engagement.getEngagementUsers());
LOGGER.debug("Updated {}", participants);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,19 @@ void testEngagementOptions() throws Exception {
.body("$", Matchers.hasKey("training"));
}

@Test
void testParticipantOptions() throws Exception {
String participants = ResourceLoader.load("config-participant-options.json");
Map<String, String> pariticipantsMap = om.readValue(participants, Map.class);
Mockito.when(configApiClient.getParticipantOptions()).thenReturn(pariticipantsMap);
given().when().auth().oauth2(VALID_TOKEN).get("/participant/options").then().statusCode(200)
.body("$", Matchers.hasKey("arole"))
.body("$", Matchers.hasKey("brole"));

Mockito.when(configApiClient.getParticipantOptions("DO")).thenReturn(pariticipantsMap);
given().queryParam("engagementType", "DO").when().auth().oauth2(VALID_TOKEN).get("/participant/options").then().statusCode(200)
.body("$", Matchers.hasKey("arole"))
.body("$", Matchers.hasKey("brole"));
}

}
4 changes: 4 additions & 0 deletions src/test/resources/config-participant-options.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"arole": "Rolly",
"brole": "Polly"
}

0 comments on commit 4f40806

Please sign in to comment.