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

org.imsglobal.json.IMSJSONRequest Maven / Gradle / Ivy

Go to download

BasicLTI Utilities are a set of utility classes to aid in the development of BasicLTI consumers and providers. They deal with much of the heavy lifting and make the process more opaque to the developer.

The newest version!
package org.imsglobal.json;

import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URLDecoder;
import java.security.MessageDigest;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.logging.Logger;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.oauth.OAuthAccessor;
import net.oauth.OAuthConsumer;
import net.oauth.OAuthMessage;
import net.oauth.OAuthValidator;
import net.oauth.SimpleOAuthValidator;
import net.oauth.server.OAuthServlet;
import net.oauth.signature.OAuthSignatureMethod;
import org.apache.commons.codec.binary.Base64;

import org.json.simple.JSONValue;

public class IMSJSONRequest {

	private final static Logger Log = Logger.getLogger(IMSJSONRequest.class .getName());

    public final static String STATUS = "status";
    public final static String STATUS_CODE = "code";
    public final static String STATUS_DESCRIPTION = "description";

	public final static String CODE_MAJOR_SUCCESS = "success";
	public final static String CODE_MAJOR_FAILURE = "failure";
	public final static String CODE_MAJOR_UNSUPPORTED = "unsupported";

	public String postBody = null;
	private String header = null;
	private String oauth_body_hash = null;
	private String oauth_consumer_key = null;

	public boolean valid = false;
	public String errorMessage = null;
	public String base_string = null;

    private static final String APPLICATION_JSON = "application/json";

	public String getOAuthConsumerKey()
	{
		return oauth_consumer_key;
	}

	public String getPostBody()
	{
		return postBody;
	}

	// Normal Constructor
	public IMSJSONRequest(String oauth_consumer_key, String oauth_secret, HttpServletRequest request) 
	{
		loadFromRequest(request);
		if ( ! valid ) return;
		validateRequest(oauth_consumer_key, oauth_secret, request);
	}

	// Constructor for delayed validation
	public IMSJSONRequest(HttpServletRequest request) 
	{
		loadFromRequest(request);
	}

	// Constructor for testing...
	public IMSJSONRequest(String bodyString)
	{
		postBody = bodyString;
	}

	// Load but do not check the authentication
	@SuppressWarnings("deprecation")
	public void loadFromRequest(HttpServletRequest request) 
	{
		header = request.getHeader("Authorization");
		System.out.println("Header: "+header);
		oauth_body_hash = null;
		if ( header != null ) {
			if (header.startsWith("OAuth ")) header = header.substring(5);
			String [] parms = header.split(",");
			for ( String parm : parms ) {
				parm = parm.trim();
				if ( parm.startsWith("oauth_body_hash=") ) {
					String [] pieces = parm.split("\"");
					if ( pieces.length == 2 ) oauth_body_hash = URLDecoder.decode(pieces[1]);
				}
				if ( parm.startsWith("oauth_consumer_key=") ) {
					String [] pieces = parm.split("\"");
					if ( pieces.length == 2 ) oauth_consumer_key = URLDecoder.decode(pieces[1]);
				}
			}
		}		

		if ( oauth_body_hash == null ) {
			errorMessage = "Did not find oauth_body_hash";
			Log.info(errorMessage+"\n"+header);
			return;
		}

		System.out.println("OBH="+oauth_body_hash);
        byte[] buf = new byte[1024];
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		int chars = 0;
		try {
			ServletInputStream is = request.getInputStream();
			int readNum;
			do {
				readNum = is.read(buf);
				if (readNum>0) {
					bos.write(buf, 0, readNum); 
					chars = chars + readNum;
					// We dont' want a DOS
					if ( chars > 10000000 ) {
						errorMessage = "Message body size exceeded";
						return;
					}
				}
			} while (readNum>=0);
		} catch(Exception e) {
			errorMessage = "Could not read message body:"+e.getMessage();
			return;
		}

        byte[] bytes = bos.toByteArray();

		try {
			postBody = new String(bytes, "UTF-8");
			MessageDigest md = MessageDigest.getInstance("SHA1");
			md.update(bytes); 
			byte[] output = Base64.encodeBase64(md.digest());
			String hash = new String(output);
			System.out.println("HASH="+hash+" bytes="+bytes.length);
			if ( ! hash.equals(oauth_body_hash) ) {
				errorMessage = "Body hash does not match. bytes="+bytes.length;
				System.out.println(postBody);
				return;
			}
		} catch (Exception e) {
			errorMessage = "Could not compute body hash.  bytes="+bytes.length;
			return;
		}
		valid = true;  // So far we are valid
	}

	// Assumes data is all loaded
	public void validateRequest(String oauth_consumer_key, String oauth_secret, HttpServletRequest request) 
	{
		validateRequest(oauth_consumer_key, oauth_secret, request, null) ;
	}

	public void validateRequest(String oauth_consumer_key, String oauth_secret, HttpServletRequest request, String URL) 
	{
		valid = false;
		OAuthMessage oam = OAuthServlet.getMessage(request, URL);
		OAuthValidator oav = new SimpleOAuthValidator();
		OAuthConsumer cons = new OAuthConsumer("about:blank#OAuth+CallBack+NotUsed", 
				oauth_consumer_key, oauth_secret, null);

		OAuthAccessor acc = new OAuthAccessor(cons);

		try {
			base_string = OAuthSignatureMethod.getBaseString(oam);
		} catch (Exception e) {
			base_string = null;
		}

		try {
			oav.validateMessage(oam,acc);
		} catch(Exception e) {
			errorMessage = "Launch fails OAuth validation: "+e.getMessage();
			return;
		}
		valid = true;
	}

	public boolean inArray(final String [] theArray, final String theString)
	{
		if ( theString == null ) return false;
		for ( String str : theArray ) {
			if ( theString.equals(str) ) return true;
		}
		return false;
	}

	public static Map getStatusUnsupported(String desc)
	{
		return getStatus(desc, CODE_MAJOR_UNSUPPORTED);
	}

	public static Map getStatusFailure(String desc)
	{
		return getStatus(desc, CODE_MAJOR_FAILURE);
	}

	public static Map getStatusSuccess(String desc)
	{
		return getStatus(desc, CODE_MAJOR_SUCCESS);
	}

	public static Map getStatus(String description, String major)
	{
		Map retval = new LinkedHashMap();
		retval.put(STATUS_CODE,major);
		retval.put(STATUS_DESCRIPTION,description);
		return retval;
	}

	/* IMS JSON version of Errors - does the complet request - returns the JSON in case
	   the code above us wants to log it. */
	@SuppressWarnings("static-access")
	public static String doErrorJSON(HttpServletRequest request,HttpServletResponse response, 
			IMSJSONRequest json, String message, Exception e) 
		throws java.io.IOException 
	{
		response.setContentType(APPLICATION_JSON);
		Map jsonResponse = new TreeMap();

		Map status = null;
		if ( json == null ) {
			status = IMSJSONRequest.getStatusFailure(message);
		} else {
			status = json.getStatusFailure(message);
			if ( json.base_string != null ) {
				jsonResponse.put("base_string", json.base_string);
			}
		}
		jsonResponse.put(IMSJSONRequest.STATUS, status);
		if ( e != null ) {
			jsonResponse.put("exception", e.getLocalizedMessage());
			try {
				StringWriter sw = new StringWriter();
				PrintWriter pw = new PrintWriter(sw, true);
				e.printStackTrace(pw);
				pw.flush();
				sw.flush();
				jsonResponse.put("traceback", sw.toString() );
			} catch ( Exception f ) {
				jsonResponse.put("traceback", f.getLocalizedMessage());
			}
		}
		String jsonText = JSONValue.toJSONString(jsonResponse);
		PrintWriter out = response.getWriter();
		out.println(jsonText);
		return jsonText;
	}

	/** Unit Tests */
	static final String inputTestData = "\n" +  
		"\n" + 
		"\n" + 
		"\n" + 
		"V1.0\n" + 
		"999999123\n" + 
		"\n" + 
		"\n" + 
		"\n" + 
		"\n" + 
		"\n" + 
		"\n" + 
		"3124567\n" + 
		"\n" + 
		"\n" + 
		"\n" + 
		"en-us\n" + 
		"A\n" + 
		"\n" + 
		"\n" + 
		"\n" + 
		"\n" + 
		"\n" + 
		"";

	public static void runTest() {
/*
		System.out.println("Runnig test.");
		IMSJSONRequest pox = new IMSJSONRequest(inputTestData);
		System.out.println("Version = "+pox.getHeaderVersion());
		System.out.println("Operation = "+pox.getOperation());
		Map bodyMap = pox.getBodyMap();
		String guid = bodyMap.get("/resultRecord/sourcedGUID/sourcedId");
		System.out.println("guid="+guid);
		String grade = bodyMap.get("/resultRecord/result/resultScore/textString");
		System.out.println("grade="+grade);

		String desc = "Message received and validated operation="+pox.getOperation()+
			" guid="+guid+" grade="+grade;

		String output = pox.getResponseUnsupported(desc);
		System.out.println("---- Unsupported ----");
		System.out.println(output);

		Properties props = new Properties();
		props.setProperty("fred","zap");
		props.setProperty("sam",IMSPOXRequest.MINOR_IDALLOC);
		System.out.println("---- Generate Log Error ----");
		output = pox.getResponseFailure(desc,props);
		System.out.println("---- Failure ----");
		System.out.println(output);



		Map theMap = new TreeMap ();
		theMap.put("/readMembershipResponse/membershipRecord/sourcedId", "123course456");

		List> lm = new ArrayList>();
		Map mm = new TreeMap();
		mm.put("/personSourcedId","123user456");
		mm.put("/role/roleType","Learner");
		lm.add(mm);

		mm = new TreeMap();
		mm.put("/personSourcedId","789user123");
		mm.put("/role/roleType","Instructor");
		lm.add(mm);
		theMap.put("/readMembershipResponse/membershipRecord/membership/member", lm);

		String theXml = XMLMap.getXMLFragment(theMap, true);
		// System.out.println("th="+theXml);
		output = pox.getResponseSuccess(desc,theXml);
		System.out.println("---- Success String ----");
		System.out.println(output);
*/
	}

	/*

roleType:
Learner
Instructor
ContentDeveloper
Member
Manager
Mentor
Administrator
TeachingAssistant

fieldType:
Boolean
Integer
Real
String



GUID.TYPE

GUID.TYPE
MEMBERSHIPIDTYPE.TYPE

GUID.TYPE

STRING
STRING

DATETIME
DATETIME
BOOLEAN

LANGUAGESET.TYPE
STRING


STATUS.TYPE
DATETIME
GUID.TYPE


STRING
FIELDTYPE.TYPE
STRING




STRING
FIELDTYPE.TYPE
STRING




INTEGER
GUID.TYPE



	 */
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy