Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

26 api restrict user scope #30

Merged
merged 4 commits into from
Mar 26, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 33 additions & 16 deletions src/main/java/org/orph2020/pst/apiimpl/rest/ProposalResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.persistence.TypedQuery;
import org.eclipse.microprofile.jwt.JsonWebToken;
import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
Expand All @@ -26,11 +28,7 @@

import org.orph2020.pst.common.json.ProposalValidation;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.function.Supplier;
import java.util.*;

/*
For use cases see:
Expand All @@ -55,6 +53,10 @@ public ProposalResource(Logger logger) {
TechnicalGoalResource technicalGoalResource;
@Inject
ProposalCyclesResource proposalCyclesResource;
@Inject
SubjectMapResource subjectMapResource;
@Inject
JsonWebToken accessToken;

private static final String proposalRoot = "{proposalCode}";

Expand Down Expand Up @@ -92,30 +94,46 @@ private ProposalSynopsis createSynopsisFromProposal(ObservingProposal proposal)

@GET
@Operation(summary = "get the synopsis for each Proposal in the database, optionally provide an investigator name and/or a proposal title to see specific proposals. Filters out submitted copies.")
@RolesAllowed("default-roles-orppst")
public List<ProposalSynopsis> getProposals(@RestQuery String investigatorName, @RestQuery String title) {

boolean noQuery = investigatorName == null && title == null;
boolean investigatorOnly = investigatorName != null && title == null;
boolean titleOnly = investigatorName == null && title != null;
Long personId = subjectMapResource.subjectMap(accessToken.getSubject()).getPerson().getId();

//if 'ProposalSynopsis' is modified we should check these Strings for suitability
String baseStr = "select distinct o._id,o.title,o.summary,o.kind,o.submitted from ObservingProposal o ";
//Investigator table is joined twice, once for user view scope and again for searching other investigators.
String baseStr = "select distinct o._id,o.title,o.summary,o.kind,o.submitted from ObservingProposal o, Investigator inv, Investigator i "
+ "where inv member of o.investigators and inv.person._id = " + personId + " and i member of o.investigators ";
String submittedStr = "(o.submitted is null OR not o.submitted) ";
String orderByStr = "order by o.title";
String investigatorLikeStr = ", Investigator i where i member of o.investigators and i.person.fullName like '" +investigatorName+ "' ";
String investigatorLikeStr = "and i.person.fullName like '" +investigatorName+ "' ";
String titleLikeStr = "o.title like '" +title+ "' ";

if (noQuery) {
return getSynopses(baseStr + "where " + submittedStr + orderByStr);
return getSynopses(baseStr + "and " + submittedStr + orderByStr);
} else if (investigatorOnly) {
return getSynopses(baseStr + investigatorLikeStr + "and " + submittedStr + orderByStr);
} else if (titleOnly) {
return getSynopses(baseStr + "where " + titleLikeStr + "and " + submittedStr + orderByStr);
return getSynopses(baseStr + "and " + titleLikeStr + "and " + submittedStr + orderByStr);
} else { //name and title given as queries
return getSynopses(baseStr + investigatorLikeStr + "and " + titleLikeStr + "and " + submittedStr + orderByStr);
}
}

private ObservingProposal singleObservingProposal(Long proposalCode)
{
TypedQuery<ObservingProposal> q = em.createQuery(
"Select o From ObservingProposal o, Investigator i where i member of o.investigators "
+ "and o._id = :pid and i.person._id = :uid",
ObservingProposal.class
);
q.setParameter("pid", proposalCode);
q.setParameter("uid", subjectMapResource.subjectMap(accessToken.getSubject()).getPerson().getId());
return q.getSingleResult();
}

@GET
@Operation(summary = "get the Proposal specified by the 'proposalCode'")
@APIResponse(
Expand All @@ -127,7 +145,7 @@ public List<ProposalSynopsis> getProposals(@RestQuery String investigatorName, @
public ObservingProposal getObservingProposal(@PathParam("proposalCode") Long proposalCode)
throws WebApplicationException
{
return findObject(ObservingProposal.class, proposalCode);
return singleObservingProposal(proposalCode);
}

@POST
Expand Down Expand Up @@ -158,7 +176,7 @@ public Response deleteObservingProposal(@PathParam("proposalCode") long code)
@Path(proposalRoot + "/title")
@Operation(summary = "get the title of the ObservingProposal specified by 'proposalCode'")
public Response getObservingProposalTitle(@PathParam("proposalCode") Long proposalCode) {
ObservingProposal proposal = findObject(ObservingProposal.class, proposalCode);
ObservingProposal proposal = singleObservingProposal(proposalCode);
return responseWrapper(proposal.getTitle(), 200);
}

Expand All @@ -167,7 +185,7 @@ public Response getObservingProposalTitle(@PathParam("proposalCode") Long propos
@Path(proposalRoot + "/validate")
@Operation(summary = "validate the proposal, get summary strings of it's state. Optionally pass a cycle to compare dates with.")
public ProposalValidation validateObservingProposal(@PathParam("proposalCode") Long proposalCode, @RestQuery long cycleId) {
ObservingProposal proposal = findObject(ObservingProposal.class, proposalCode);
ObservingProposal proposal = singleObservingProposal(proposalCode);
boolean valid = true;
String info = "Your proposal is ready for submission";
StringBuilder warn = new StringBuilder();
Expand Down Expand Up @@ -228,6 +246,7 @@ public ProposalValidation validateObservingProposal(@PathParam("proposalCode") L
@PUT
@Operation(summary = "change the title of an ObservingProposal")
@Consumes(MediaType.TEXT_PLAIN)
//@RolesAllowed("default-roles-orppst")
@Transactional(rollbackOn = {WebApplicationException.class})
@Path(proposalRoot +"/title")
public Response replaceTitle(
Expand All @@ -236,9 +255,7 @@ public Response replaceTitle(
throws WebApplicationException
{
ObservingProposal proposal = findObject(ObservingProposal.class, proposalCode);

proposal.setTitle(replacementTitle);

return responseWrapper(proposal.getTitle(), 201);
}

Expand All @@ -264,7 +281,7 @@ public Response replaceSummary(@PathParam("proposalCode") long proposalCode, Str
@Path(proposalRoot + "/kind")
@Operation(summary = "get the 'kind' of ObservingProposal specified by the 'proposalCode")
public ProposalKind getObservingProposalKind(@PathParam("proposalCode") Long proposalCode) {
ObservingProposal proposal = findObject(ObservingProposal.class, proposalCode);
ObservingProposal proposal = getObservingProposal(proposalCode);
return proposal.getKind();
}

Expand Down Expand Up @@ -296,7 +313,7 @@ public Justification getJustification(@PathParam("proposalCode") Long proposalCo
@PathParam("which") String which)
throws WebApplicationException
{
ObservingProposal observingProposal = findObject(ObservingProposal.class, proposalCode);
ObservingProposal observingProposal = getObservingProposal(proposalCode);

//avoid returning nulls to frontend clients
return switch (which) {
Expand Down
Loading