Skip to content

Commit

Permalink
Add PUT support for LTI 1.3 (sakaiproject#6105)
Browse files Browse the repository at this point in the history
  • Loading branch information
csev authored Oct 7, 2018
1 parent ffc2a7a commit ae033fc
Show file tree
Hide file tree
Showing 2 changed files with 150 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,6 @@ protected void doDelete(HttpServletRequest request, HttpServletResponse response

String[] parts = uri.split("/");


// Handle lineitems created by the tool
// /imsblis/lti13/lineitems/{signed-placement}/{lineitem-id}
if (parts.length == 6 && "lineitems".equals(parts[3])) {
Expand All @@ -210,9 +209,27 @@ protected void doDelete(HttpServletRequest request, HttpServletResponse response
return;
}

log.error("Unrecognized GET request parts={} request={}", parts.length, uri);
log.error("Unrecognized DELETE request parts={} request={}", parts.length, uri);
LTI13Util.return400(response, "Unrecognized DELETE request parts="+parts.length+" request="+uri);
}

LTI13Util.return400(response, "Unrecognized GET request parts="+parts.length+" request="+uri);
protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String uri = request.getRequestURI(); // /imsblis/lti13/keys

String[] parts = uri.split("/");


// Handle lineitems created by the tool
// /imsblis/lti13/lineitems/{signed-placement}/{lineitem-id}
if (parts.length == 6 && "lineitems".equals(parts[3])) {
String signed_placement = parts[4];
String lineItem = parts[5];
handleLineItemsUpdate(signed_placement, lineItem, request, response);
return;
}

log.error("Unrecognized DELETE request parts={} request={}", parts.length, uri);
LTI13Util.return400(response, "Unrecognized DELETE request parts="+parts.length+" request="+uri);
}

protected void doPost(HttpServletRequest request, HttpServletResponse response)
Expand Down Expand Up @@ -1059,7 +1076,6 @@ private void handleLineItemsPost(String signed_placement, HttpServletRequest req

// Add the link to this lineitem
item.id = getOurServerUrl() + LTI13_PATH + "lineitems/" + signed_placement + "/" + retval.getId();
// XXX

log.debug("Lineitem item={}",item);
response.setContentType(LineItem.MIME_TYPE);
Expand All @@ -1068,6 +1084,85 @@ private void handleLineItemsPost(String signed_placement, HttpServletRequest req
out.print(JacksonUtil.prettyPrint(item));
}

/**
* Add a new line item for this placement
*
* @param signed_placement
* @param request
* @param response
*/
private void handleLineItemsUpdate(String signed_placement, String lineItem, HttpServletRequest request, HttpServletResponse response) throws IOException {

// Make sure the lineItem id is a long
Long assignment_id;
try {
assignment_id = Long.parseLong(lineItem);
} catch (NumberFormatException e) {
LTI13Util.return400(response, "Bad value for assignment_id "+lineItem);
log.error("Bad value for assignment_id "+lineItem);
return;
}

// Load the access token, checking the the secret
SakaiAccessToken sat = getSakaiAccessToken(tokenKeyPair.getPublic(), request, response);
log.debug("sat={}", sat);

if (sat == null) {
return; // No need - error is already set
}
if (!sat.hasScope(SakaiAccessToken.SCOPE_LINEITEMS)) {
LTI13Util.return400(response, "Scope lineitems not in access token");
log.error("Scope lineitems not in access token");
return;
}

LineItem item = (LineItem) getObjectFromPOST(request, response, LineItem.class);
if ( item == null ) return; // Error alredy handled


Map<String, Object> content = loadContentCheckSignature(signed_placement, response);
if (content == null) {
return;
}

Site site = loadSiteFromContent(content, signed_placement, response);
if (site == null) {
return;
}

Map<String, Object> tool = loadToolForContent(content, site, sat.tool_id, response);
if (tool == null) {
return;
}

Assignment retval;
try {
retval = LineItemUtil.updateLineItem(site, sat.tool_id, assignment_id, item);
} catch (Exception e) {
e.printStackTrace();
LTI13Util.return400(response, "Could not update lineitem: "+e.getMessage());
return;
}

// TODO: Does PUT need to return the entire line item - I think the code below
// actually is wrong - we just need to do a GET to get the entire line
// item after the PUT. It seems wasteful to always do the GET after PUT
// when the tool can do it if it wants the newly updated item. So
// For now I am sending nothing back for a pUT request.
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PUT

/*
// Add the link to this lineitem
item.id = getOurServerUrl() + LTI13_PATH + "lineitems/" + signed_placement + "/" + retval.getId();
log.debug("Lineitem item={}",item);
response.setContentType(LineItem.MIME_TYPE);
PrintWriter out = response.getWriter();
out.print(JacksonUtil.prettyPrint(item));
*/
}

/**
* List all LineItems for this placement ore retrieve the single LineItem created for this placement
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
import java.util.List;
import java.util.Iterator;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import lombok.extern.slf4j.Slf4j;
import org.sakaiproject.authz.api.SecurityAdvisor;
Expand All @@ -38,7 +36,6 @@
import org.sakaiproject.lti.api.LTIService;

import org.sakaiproject.service.gradebook.shared.GradebookService;
import org.sakaiproject.service.gradebook.shared.GradebookExternalAssessmentService;
import org.sakaiproject.service.gradebook.shared.ConflictingAssignmentNameException;
import org.sakaiproject.service.gradebook.shared.Assignment;
import org.sakaiproject.service.gradebook.shared.GradebookNotFoundException;
Expand Down Expand Up @@ -95,17 +92,15 @@ public static String constructExternalId(Long tool_id, Map<String, Object> conte
} else {
retval += ID_SEPARATOR + content.get(LTIService.LTI_ID) + "|";
}
String resourceId = URLEncode(lineItem.resourceId.replace("|", ""));
if ( resourceId == null ) {
if ( lineItem.resourceId == null ) {
retval += ID_SEPARATOR;
} else {
retval += resourceId + ID_SEPARATOR;
retval += URLEncode(lineItem.resourceId.replace("|", "")) + ID_SEPARATOR;
}
String tag = URLEncode(lineItem.tag.replace("|", ""));
if ( tag == null ) {
if ( lineItem.tag == null ) {
retval += ID_SEPARATOR;
} else {
retval += tag + ID_SEPARATOR;
retval += URLEncode(lineItem.tag.replace("|", "")) + ID_SEPARATOR;
}
return retval;
}
Expand Down Expand Up @@ -197,6 +192,52 @@ public static Assignment createLineItem(Site site, Long tool_id, Map<String, Obj
return assignmentObject;
}

public static Assignment updateLineItem(Site site, Long tool_id, Long assignment_id, LineItem lineItem) {
GradebookService g = (GradebookService) ComponentManager
.get("org.sakaiproject.service.gradebook.GradebookService");

String context_id = site.getId();

if ( assignment_id == null ) {
throw new RuntimeException("tool_id is required");
}

if ( tool_id == null ) {
throw new RuntimeException("tool_id is required");
}

Assignment assignmentObject = getAssignmentByKeyDAO(context_id, tool_id, assignment_id);
if ( assignmentObject == null ) return null;

/*
{
"scoreMaximum": 0,
"label": "string",
"tag": "string",
"resourceId": "string"
}
*/

if ( lineItem.scoreMaximum != null ) {
assignmentObject.setPoints(Double.valueOf(lineItem.scoreMaximum));
}

String external_id = constructExternalId(tool_id, null, lineItem);
assignmentObject.setExternalId(external_id);
if ( lineItem.label != null ) {
assignmentObject.setName(lineItem.label);
}

pushAdvisor();
try {
g.updateAssignment(context_id, assignment_id, assignmentObject);
} finally {
popAdvisor();
}

return assignmentObject;
}

/**
* Return a list of assignments associated with this tool in a site
* @param context_id - The site id
Expand Down Expand Up @@ -268,6 +309,7 @@ protected static Assignment getAssignmentByKeyDAO(String context_id, Long tool_i
*/
protected static boolean deleteAssignmentByKeyDAO(String context_id, Long tool_id, Long assignment_id)
{
// Make sure it belongs to us
Assignment a = getAssignmentByKeyDAO(context_id, tool_id, assignment_id);
if ( a == null ) return false;
GradebookService g = (GradebookService) ComponentManager
Expand Down

0 comments on commit ae033fc

Please sign in to comment.