Skip to content

Commit 80cab6b

Browse files
committed
Merge pull request #6 from bluej100/oauth_body_hash
POXRequest replaceResult: oauth_body_hash
2 parents b38d66b + fb402f5 commit 80cab6b

File tree

2 files changed

+92
-39
lines changed

2 files changed

+92
-39
lines changed

src/main/java/org/imsglobal/pox/IMSPOXRequest.java

Lines changed: 70 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import java.io.IOException;
55
import java.io.Reader;
66
import java.net.URLDecoder;
7+
import java.net.URLEncoder;
8+
import java.security.GeneralSecurityException;
79
import java.security.MessageDigest;
810
import java.util.Date;
911
import java.util.Map;
@@ -27,6 +29,7 @@
2729
import net.oauth.signature.OAuthSignatureMethod;
2830
import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer;
2931
import oauth.signpost.exception.OAuthException;
32+
import oauth.signpost.http.HttpParameters;
3033

3134
import org.apache.commons.codec.binary.Base64;
3235
import org.apache.commons.lang3.StringEscapeUtils;
@@ -174,7 +177,6 @@ public IMSPOXRequest(String bodyString)
174177
}
175178

176179
// Load but do not check the authentication
177-
@SuppressWarnings("deprecation")
178180
public void loadFromRequest(HttpServletRequest request)
179181
{
180182
String contentType = request.getContentType();
@@ -184,7 +186,30 @@ public void loadFromRequest(HttpServletRequest request)
184186
return;
185187
}
186188

187-
header = request.getHeader("Authorization");
189+
setAuthHeader(request.getHeader("Authorization"));
190+
if ( oauth_body_hash == null ) {
191+
errorMessage = "Did not find oauth_body_hash";
192+
Log.info(errorMessage+"\n"+header);
193+
return;
194+
}
195+
196+
try {
197+
Reader in = request.getReader();
198+
postBody = readPostBody(in);
199+
} catch(Exception e) {
200+
errorMessage = "Could not read message body:"+e.getMessage();
201+
return;
202+
}
203+
204+
validatePostBody();
205+
if (errorMessage != null) return;
206+
207+
parsePostBody();
208+
}
209+
210+
@SuppressWarnings("deprecation")
211+
public void setAuthHeader(String header) {
212+
this.header = header;
188213
oauth_body_hash = null;
189214
if ( header != null ) {
190215
if (header.startsWith("OAuth ")) header = header.substring(5);
@@ -200,37 +225,33 @@ public void loadFromRequest(HttpServletRequest request)
200225
oauth_consumer_key = URLDecoder.decode(pieces[1]);
201226
}
202227
}
203-
}
204-
205-
if ( oauth_body_hash == null ) {
206-
errorMessage = "Did not find oauth_body_hash";
207-
Log.info(errorMessage+"\n"+header);
208-
return;
209228
}
229+
}
210230

231+
public static String readPostBody(Reader in) throws IOException {
211232
// System.out.println("OBH="+oauth_body_hash);
212233
final char[] buffer = new char[0x10000];
213-
try {
214-
StringBuilder out = new StringBuilder();
215-
Reader in = request.getReader();
216-
int read;
217-
do {
218-
read = in.read(buffer, 0, buffer.length);
219-
if (read>0) {
220-
out.append(buffer, 0, read);
221-
}
222-
} while (read>=0);
223-
postBody = out.toString();
224-
} catch(Exception e) {
225-
errorMessage = "Could not read message body:"+e.getMessage();
226-
return;
227-
}
234+
StringBuilder out = new StringBuilder();
235+
int read;
236+
do {
237+
read = in.read(buffer, 0, buffer.length);
238+
if (read > 0) {
239+
out.append(buffer, 0, read);
240+
}
241+
} while (read >= 0);
242+
return out.toString();
243+
}
244+
245+
public static String getBodyHash(String postBody) throws GeneralSecurityException {
246+
MessageDigest md = MessageDigest.getInstance("SHA1");
247+
md.update(postBody.getBytes());
248+
byte[] output = Base64.encodeBase64(md.digest());
249+
return new String(output);
250+
}
228251

252+
public void validatePostBody() {
229253
try {
230-
MessageDigest md = MessageDigest.getInstance("SHA1");
231-
md.update(postBody.getBytes());
232-
byte[] output = Base64.encodeBase64(md.digest());
233-
String hash = new String(output);
254+
String hash = getBodyHash(postBody);
234255
// System.out.println("HASH="+hash);
235256
if ( ! hash.equals(oauth_body_hash) ) {
236257
errorMessage = "Body hash does not match header";
@@ -240,7 +261,6 @@ public void loadFromRequest(HttpServletRequest request)
240261
errorMessage = "Could not compute body hash";
241262
return;
242263
}
243-
parsePostBody();
244264
}
245265

246266
public void parsePostBody()
@@ -516,33 +536,44 @@ public String getResponse(String description, String major, String severity,
516536

517537
static final String resultDataUrl = "<resultData><url>%s</url></resultData>";
518538

519-
public static void sendReplaceResult(String url, String key, String secret, String sourcedid, String score) throws IOException, OAuthException {
539+
public static void sendReplaceResult(String url, String key, String secret, String sourcedid, String score) throws IOException, OAuthException, GeneralSecurityException {
520540
sendReplaceResult(url, key, secret, sourcedid, score, null);
521541
}
522-
523-
public static void sendReplaceResult(String url, String key, String secret, String sourcedid, String score, String resultData) throws IOException, OAuthException {
542+
543+
public static void sendReplaceResult(String url, String key, String secret, String sourcedid, String score, String resultData) throws IOException, OAuthException, GeneralSecurityException {
524544
sendReplaceResult(url, key, secret, sourcedid, score, resultData, false);
525545
}
526-
527-
public static void sendReplaceResult(String url, String key, String secret, String sourcedid, String score, String resultData, Boolean isUrl) throws IOException, OAuthException {
546+
547+
public static void sendReplaceResult(String url, String key, String secret, String sourcedid, String score, String resultData, Boolean isUrl) throws IOException, OAuthException, GeneralSecurityException {
548+
HttpPost request = buildReplaceResult(url, key, secret, sourcedid, score, resultData, isUrl);
549+
DefaultHttpClient client = new DefaultHttpClient();
550+
HttpResponse response = client.execute(request);
551+
if (response.getStatusLine().getStatusCode() >= 400) {
552+
throw new HttpResponseException(response.getStatusLine().getStatusCode(),
553+
response.getStatusLine().getReasonPhrase());
554+
}
555+
}
556+
557+
public static HttpPost buildReplaceResult(String url, String key, String secret, String sourcedid, String score, String resultData, Boolean isUrl) throws IOException, OAuthException, GeneralSecurityException {
528558
String dataXml = "";
529559
if (resultData != null) {
530560
String format = isUrl ? resultDataUrl : resultDataText;
531561
dataXml = String.format(format, StringEscapeUtils.escapeXml(resultData));
532562
}
533563
String xml = String.format(replaceResultMessage, StringEscapeUtils.escapeXml(sourcedid),
534564
StringEscapeUtils.escapeXml(score), dataXml);
535-
565+
566+
HttpParameters parameters = new HttpParameters();
567+
String hash = getBodyHash(xml);
568+
parameters.put("oauth_body_hash", URLEncoder.encode(hash, "UTF-8"));
569+
536570
CommonsHttpOAuthConsumer signer = new CommonsHttpOAuthConsumer(key, secret);
537571
HttpPost request = new HttpPost(url);
538572
request.setHeader("Content-Type", "application/xml");
539573
request.setEntity(new StringEntity(xml, "UTF-8"));
574+
signer.setAdditionalParameters(parameters);
540575
signer.sign(request);
541-
DefaultHttpClient client = new DefaultHttpClient();
542-
HttpResponse response = client.execute(request);
543-
if (response.getStatusLine().getStatusCode() >= 400) {
544-
throw new HttpResponseException(response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase());
545-
}
576+
return request;
546577
}
547578

548579
/*

src/test/java/org/imsglobal/lti/pox/IMSPOXRequestTest.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
package org.imsglobal.lti.pox;
22

3+
import net.oauth.OAuthMessage;
4+
5+
import org.apache.http.Header;
6+
import org.apache.http.client.methods.HttpPost;
7+
import org.apache.http.params.HttpParams;
38
import org.imsglobal.pox.IMSPOXRequest;
49
import org.junit.Assert;
510
import org.junit.Before;
611
import org.junit.Test;
712

13+
import java.io.InputStream;
14+
import java.io.InputStreamReader;
15+
import java.io.Reader;
816
import java.util.*;
917

1018
/**
@@ -31,4 +39,18 @@ public void test(){
3139
Assert.assertEquals("A", grade);
3240

3341
}
42+
43+
@Test
44+
public void testBuildReplaceResult() throws Exception {
45+
HttpPost post = IMSPOXRequest.buildReplaceResult("http://example.com", "key", "secret", "sourcedid", "0.95", "A", false);
46+
String header = post.getHeaders("Authorization")[0].getValue();
47+
InputStream input = post.getEntity().getContent();
48+
Reader reader = new InputStreamReader(input);
49+
String body = IMSPOXRequest.readPostBody(reader);
50+
51+
IMSPOXRequest pox = new IMSPOXRequest(body);
52+
pox.setAuthHeader(header);
53+
pox.validatePostBody();
54+
Assert.assertNull(pox.errorMessage);
55+
}
3456
}

0 commit comments

Comments
 (0)