All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.tsugi.lti13.DeepLinkResponse Maven / Gradle / Ivy

There is a newer version: 23.3
Show newest version
/*
 * $URL$
 * $Id$
 *
 * Copyright (c) 2015- Charles R. Severance
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

package org.tsugi.lti13;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import java.security.Key;

import javax.servlet.http.HttpServletRequest;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;

import org.tsugi.basiclti.BasicLTIUtil;

// https://www.imsglobal.org/spec/lti-dl/v2p0
/*

{
"iss": "962fa4d8-bcbf-49a0-94b2-2de05ad274af",
"aud": "https://platform.example.org",
"exp": 1510185728,
"iat": 1510185228,
"nonce": "fc5fdc6d-5dd6-47f4-b2c9-5d1216e9b771",
"azp": "962fa4d8-bcbf-49a0-94b2-2de05ad274af",
"https://purl.imsglobal.org/spec/lti/claim/deployment_id":
"07940580-b309-415e-a37c-914d387c1150",
"https://purl.imsglobal.org/spec/lti/claim/message_type":
"LtiDeepLinkingResponse",
"https://purl.imsglobal.org/spec/lti/claim/version": "1.3.0",
"https://purl.imsglobal.org/spec/lti-dl/claim/content_items": [
{
"type": "link",
"title": "My Home Page",
"url": "https://something.example.com/page.html",
"icon": {
  "url": "https://lti.example.com/image.jpg",
  "width": 100,
  "height": 100
},
"thumbnail": {
  "url": "https://lti.example.com/thumb.jpg",
  "width": 90,
  "height": 90
}
},
{
"type": "html",
"html": "

A Custom Title

" }, { "type": "link", "url": "https://www.youtube.com/watch?v=corV3-WsIro", "embed": { "html": "" }, "window": { "targetName": "youtube-corV3-WsIro", "windowFeatures": "height=560,width=315,menubar=no" }, "iframe": { "width": 560, "height": 315, "src": "https://www.youtube.com/embed/corV3-WsIro" } }, { "type": "image", "url": "https://www.example.com/image.png", "https://www.example.com/resourceMetadata": { "license": "CCBY4.0" } }, { "type": "ltiResourceLink", "title": "A title", "text": "This is a link to an activity that will be graded", "url": "https://lti.example.com/launchMe", "icon": { "url": "https://lti.example.com/image.jpg", "width": 100, "height": 100 }, "thumbnail": { "url": "https://lti.example.com/thumb.jpg", "width": 90, "height": 90 }, "lineItem": { "scoreMaximum": 87, "label": "Chapter 12 quiz", "resourceId": "xyzpdq1234", "tag": "originality" }, "available": { "startDateTime": "2018-02-06T20:05:02Z", "endDateTime": "2018-03-07T20:05:02Z" }, "submission": { "endDateTime": "2018-03-06T20:05:02Z" }, "custom": { "quiz_id": "az-123", "duedate": "$Resource.submission.endDateTime" }, "window": { "targetName": "examplePublisherContent" }, "iframe": { "height": 890 } }, { "type": "file", "title": "A file like a PDF that is my assignment submissions", "url": "https://my.example.com/assignment1.pdf", "mediaType": "application/pdf", "expiresAt": "2018-03-06T20:05:02Z" }, { "type": "https://www.example.com/custom_type", "data": "somedata" } ], "https://purl.imsglobal.org/spec/lti-dl/claim/data": "csrftoken:c7fbba78-7b75-46e3-9201-11e6d5f36f53" } */ public class DeepLinkResponse { public static final String DEEP_LINKS = "https://purl.imsglobal.org/spec/lti-dl/claim/content_items"; public static final String DATA = "https://purl.imsglobal.org/spec/lti-dl/claim/data"; public static final String ACCEPT_MEDIA_TYPES = "accept_media_types"; public static String MEDIA_LTILINKITEM = "application/vnd.ims.lti.v1.ltilink"; // http://www.iana.org/assignments/media-types/media-types.xhtml public static final String MEDIA_CC_1_1 = "application/vnd.ims.imsccv1p1"; public static final String MEDIA_CC_1_2 = "application/vnd.ims.imsccv1p2"; public static final String MEDIA_CC_1_3 = "application/vnd.ims.imsccv1p3"; public static final String MEDIA_CC = MEDIA_CC_1_1+","+MEDIA_CC_1_2+","+MEDIA_CC_1_3; public static final String TYPE = "type"; public static final String TYPE_LINKITEM = "link"; public static final String TYPE_LTILINKITEM = "ltiResourceLink"; public static final String TYPE_CONTENTITEM = "html"; public static final String TYPE_FILEITEM = "file"; public static final String TITLE = "title"; public static final String TEXT = "text"; public static final String URL = "url"; public static final String LINEITEM = "lineItem"; public static final String CUSTOM = "custom"; public static final String ICON = "icon"; /** * Indicates the initial start and end time this activity * should be made available to learners. A platform may choose * to make an item not accessible by hiding it, or by * disabling the link, or some other method which prevents * the link from being opened by a learner. The initial value * may subsequently be changed within the platform and the * tool may use the ResourceLink.available.startDateTime * and ResourceLink.available.endDateTime substitution * parameters defined in LTI Core specification [LTI-13] * within custom parameters to get the actual values at launch time. * ISO 8601 date and time */ public static final String AVAILABLE = "available"; public static final String AVAILABLE_STARTDATETIME = "startDateTime"; public static final String AVAILABLE_ENDDATETIME = "endDateTime"; public static final String RESOURCELINK_AVAILABLE_STARTDATETIME = "ResourceLink.available.startDateTime"; public static final String RESOURCELINK_AVAILABLE_ENDDATETIME = "ResourceLink.available.endDateTime"; /** * Indicates the initial start and end time submissions * for this activity can be made by learners. The initial value * may subsequently be changed within the platform and the * tool may use the ResourceLink.submission.startDateTime * and ResourceLink.submission.endDateTime substitution * parameters defined in LTI Core specification [LTI-13] * within custom parameters to get the actual values at launch time. * * ISO 8601 date and time */ public static final String SUBMISSION = "submission"; public static final String SUBMISSION_STARTDATETIME = "startDateTime"; public static final String SUBMISSION_ENDDATETIME = "endDateTime"; public static final String RESOURCELINK_SUBMISSION_STARTDATETIME = "ResourceLink.submission.startDateTime"; public static final String RESOURCELINK_SUBMISSION_ENDDATETIME = "ResourceLink.submission.endDateTime"; private String id_token = null; private JSONObject body = null; private JSONArray deep_links = null; private String returnedData = null; /** * We check for the fields essential for the class to operate here. */ public DeepLinkResponse(String id_token) { this.id_token = id_token; body = (JSONObject) LTI13JwtUtil.jsonJwtBody(id_token); if ( body == null ) { throw new java.lang.RuntimeException("Could not extract body from id_token"); } String message_type = (String) body.get(LTI13ConstantsUtil.MESSAGE_TYPE); if ( ! LTI13ConstantsUtil.MESSAGE_TYPE_LTI_DEEP_LINKING_RESPONSE.equals(message_type) ) { throw new java.lang.RuntimeException("Incorrect MESSAGE_TYPE"); } String returnedData = (String) body.get(DATA); if ( returnedData == null || returnedData.length() < 1 ) { throw new java.lang.RuntimeException("Missing data element from ContentItem return"); } // It is OK for this to be null deep_links = BasicLTIUtil.getArray(body, DEEP_LINKS); } /** * Check if the incoming request is a DeepLinkResponse */ public static boolean isRequest(HttpServletRequest req) { String id_token = req.getParameter(LTI13JwtUtil.ID_TOKEN); return isRequest(id_token); } /** * Check if the incoming request is a DeepLinkResponse */ public static boolean isRequest(String id_token) { if ( ! LTI13JwtUtil.isRequest(id_token) ) return false; JSONObject body = (JSONObject) LTI13JwtUtil.jsonJwtBody(id_token); String message_type = (String) body.get(LTI13ConstantsUtil.MESSAGE_TYPE); return LTI13ConstantsUtil.MESSAGE_TYPE_LTI_DEEP_LINKING_RESPONSE.equals(message_type); } /** * Validate the incoming request * * @param URL The URL of the incoming request. If this in null, the URL is taken * from the request object. Sometimes the request object can be misleading when * sitting behind a load balancer or some kind of proxy. */ public boolean validate(Key publicKey) { // Validate security Jws claims = Jwts.parser().setSigningKey(publicKey).parseClaimsJws(id_token); return claims != null; } /** * Return a string */ public String toString() { return body.toString(); } /** * Retrieve the parsed tool_proxy */ public JSONObject getContentItem() { return body; } /** * Retrieve the @graph from the content item */ public JSONArray getDeepLinks() { return deep_links; } /** * Retrieve a particular type from the graph * * @param String messageType - Which item type you are looking for */ public JSONObject getItemOfType(String itemType) { if ( deep_links == null ) return null; for ( Object i : deep_links ) { if ( ! (i instanceof JSONObject) ) continue; JSONObject item = (JSONObject) i; String type = BasicLTIUtil.getString(item,"type"); if ( type == null ) continue; if ( type.equals(itemType) ) return item; } return null; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy