<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page trimDirectiveWhitespaces="true" %> <%@ page import="org.apache.log4j.Logger" %> <%@ page import="java.util.Set" %> <%@ page import="java.util.HashSet" %> <%@ page import="java.util.List" %> <%@ page import="org.apache.http.NameValuePair" %> <%@ page import="org.apache.http.message.BasicNameValuePair" %> <%@ page import="java.util.ArrayList" %> <%@ page import="java.net.URLEncoder" %> <%@ page import="org.apache.http.client.utils.URLEncodedUtils" %> <%@ page import="org.apache.commons.codec.binary.Base64" %> <%@ page import="javax.crypto.Mac" %> <%@ page import="javax.crypto.SecretKey" %> <%@ page import="javax.crypto.spec.SecretKeySpec" %> <% final String secret = "73319e83e1615bb428b68a9e3ab78dea"; Logger logger = Logger.getLogger("collate"); dumpCallInfo(request, logger); %>

lti_message_type: <%= request.getParameter("lti_message_type") %>

lti_version: <%= request.getParameter("lti_version") %>

resource_link_id (the instance of our app on a page in the lms): <%= request.getParameter("resource_link_id") %>

context_id (any instance of our app within the same course): <%= request.getParameter("context_id") %>

user_id (same across all courses of 1 system): <%= request.getParameter("user_id") %>

roles: <%= request.getParameter("roles") %>

oauth_consumer_key (create new ones and give unique ones out to each lms): <%= request.getParameter("oauth_consumer_key") %>

oauth_nonce (random. don't allow repeated, for security): <%= request.getParameter("oauth_nonce") %>

oauth_timestamp (also for security, make sure not too old): <%= request.getParameter("oauth_timestamp") %>

oauth_signature: <%= request.getParameter("oauth_signature") %>

lis_person_name_full: <%= request.getParameter("lis_person_name_full") %>

lis_person_contact_email_primary: <%= request.getParameter("lis_person_contact_email_primary") %>

lis_person_name_given: <%= request.getParameter("lis_person_name_given") %>

lis_person_name_family: <%= request.getParameter("lis_person_name_family") %>

<% for (String o: java.util.Collections.list(request.getParameterNames())) { if (o.startsWith("custom_")) { %>

<%=o%>: <%= request.getParameter(o) %>

<% } } %>

lis_outcome_service_url (send grades here): <%= request.getParameter("lis_outcome_service_url") %>

<% String nonce = request.getParameter("oauth_nonce"); if (nonce == null || nonce.trim().length() < 1) { out.print("please tell your lms they aren't sending a nonce."); return; } else if (nonces.contains(nonce)) { out.print("bad request. duplicate nonce."); return; } else nonces.add(nonce); boolean goodTime = false; try { int t = Integer.parseInt(request.getParameter("oauth_timestamp")); if (t < System.currentTimeMillis() && t > (System.currentTimeMillis() - (1000 * 60 * 60 * 2))) {} else { goodTime = true; }} catch(Exception e) {} if (!goodTime) { out.print("bad timestamp."); return; } String sig = getSignature(secret, request.getParameter("oauth_consumer_key"), request.getParameter("oauth_nonce"), request.getParameter("oauth_timestamp")); %>

gensig : <%= sig %>

Hello world <%! Setnonces = new HashSet(); public static void dumpCallInfo(HttpServletRequest request, Logger logger) { logger.info("collate called..."); logger.info("request.getContentType: " + request.getContentType()); logger.info("Headers: "); for (Object o: java.util.Collections.list(request.getHeaderNames())) { logger.info(o + "=" + request.getHeader(o.toString())); } logger.info("Attributes: "); for (Object o: java.util.Collections.list(request.getAttributeNames())) { logger.info(o + "=" + request.getAttribute(o.toString())); } logger.info("Parameters: "); for (Object o: java.util.Collections.list(request.getParameterNames())) { for (String v: request.getParameterValues(o.toString())) { logger.info(o + "=" + v); } } } static String getSignature(String secret, String key, String nonce, String timestamp) { try { final String HMAC_SHA1 = "HmacSHA1"; final String ENC = "UTF-8"; Base64 base64 = new Base64(); List qparams = new ArrayList(); // These params should ordered in key qparams.add(new BasicNameValuePair("oauth_callback", "oob")); qparams.add(new BasicNameValuePair("oauth_consumer_key", key)); qparams.add(new BasicNameValuePair("oauth_nonce", nonce)); qparams.add(new BasicNameValuePair("oauth_signature_method", "HMAC-SHA1")); qparams.add(new BasicNameValuePair("oauth_timestamp", timestamp)); qparams.add(new BasicNameValuePair("oauth_version", "1.0")); StringBuilder base = new StringBuilder(); base.append("POST"); base.append("&"); base.append(URLEncoder.encode("https://ntvmr.uni-muenster.de/community/vmr/api/integrations/lti/", ENC)); base.append("&"); base.append(URLEncoder.encode(URLEncodedUtils.format(qparams, ENC), ENC)); System.out.println("String for oauth_signature generation:" + base); // yea, don't ask me why, it is needed to append a "&" to the end of // secret key. Because if you had a token secret, it would go after the '&' byte[] keyBytes = (secret + "&").getBytes(ENC); SecretKey genKey = new SecretKeySpec(keyBytes, HMAC_SHA1); Mac mac = Mac.getInstance(HMAC_SHA1); mac.init(genKey); // encode it, base64 it, change it to string and return. return new String(base64.encode(mac.doFinal(base.toString().getBytes(ENC))), ENC).trim(); } catch (Exception e) {} return null; } %>