Author: etnu
Date: Fri May  2 16:11:05 2008
New Revision: 652946

URL: http://svn.apache.org/viewvc?rev=652946&view=rev
Log:
Applied SHINDIG-211, allowing for a wider range of parameters in signed 
requests. This patch was contributed by Brian Eaton.


Modified:
    
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetException.java
    
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/SigningFetcher.java
    
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/SigningFetcherTest.java

Modified: 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetException.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetException.java?rev=652946&r1=652945&r2=652946&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetException.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetException.java
 Fri May  2 16:11:05 2008
@@ -68,6 +68,9 @@
     // OAuth
     OAUTH_STORAGE_ERROR,
     OAUTH_APPROVAL_NEEDED,
+    
+    // Signed fetch
+    REQUEST_SIGNING_FAILURE,
   }
 
   private final Code code;

Modified: 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/SigningFetcher.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/SigningFetcher.java?rev=652946&r1=652945&r2=652946&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/SigningFetcher.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/SigningFetcher.java
 Fri May  2 16:11:05 2008
@@ -56,7 +56,7 @@
       = "xoauth_signature_publickey";
 
   protected static final Pattern ALLOWED_PARAM_NAME
-      = Pattern.compile("[-:\\w]+");
+      = Pattern.compile("[-:[EMAIL PROTECTED]()_\\[\\]:,./]+");
 
   protected final TimeSource clock = new TimeSource();
 
@@ -159,6 +159,8 @@
       cache.addContent(cacheableRequest, result);
 
       return result;
+    } catch (GadgetException e) {
+      throw e;
     } catch (Exception e) {
       throw new GadgetException(GadgetException.Code.INTERNAL_SERVER_ERROR, e);
     }
@@ -166,7 +168,7 @@
 
   private RemoteContentRequest makeCacheableRequest(
       RemoteContentRequest request)
-      throws IOException, URISyntaxException {
+      throws IOException, URISyntaxException, RequestSigningException {
     // Create a request without the OAuth params which includes the
     // OpenSocial ones and see if we can find it in the cache
     URI resource = request.getUri();
@@ -238,6 +240,8 @@
           resource.getPort(),
           resource.getRawPath() + "?" + finalQuery);
       return new RemoteContentRequest(url.toURI(), req);
+    } catch (GadgetException e) {
+      throw e;
     } catch (Exception e) {
       throw new GadgetException(GadgetException.Code.INTERNAL_SERVER_ERROR, e);
     }
@@ -319,12 +323,17 @@
 
   /**
    * Strip out any owner or viewer id passed by the client.
+ * @throws RequestSigningException 
    */
-  private List<Parameter> sanitize(List<Parameter> params) {
+  private List<Parameter> sanitize(List<Parameter> params)
+      throws RequestSigningException {
     ArrayList<Parameter> list = new ArrayList<Parameter>();
     for (Parameter p : params) {
-      if (allowParam(p.getKey())) {
+      String name = p.getKey();
+      if (allowParam(name)) {
         list.add(p);
+      } else {
+         throw new RequestSigningException("invalid parameter name " + name);
       }
     }
     return list;

Modified: 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/SigningFetcherTest.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/SigningFetcherTest.java?rev=652946&r1=652945&r2=652946&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/SigningFetcherTest.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/SigningFetcherTest.java
 Fri May  2 16:11:05 2008
@@ -21,6 +21,8 @@
 import net.oauth.OAuthAccessor;
 import net.oauth.OAuthConsumer;
 import net.oauth.OAuthMessage;
+import net.oauth.OAuthValidator;
+import net.oauth.SimpleOAuthValidator;
 import net.oauth.signature.RSA_SHA1;
 
 import java.net.URI;
@@ -67,6 +69,7 @@
   private SigningFetcher signer;
   private BasicGadgetToken authToken;
   private OAuthAccessor accessor;
+  private OAuthValidator messageValidator;
 
   @Override
   public void setUp() throws Exception {
@@ -78,6 +81,7 @@
     OAuthConsumer consumer = new OAuthConsumer(null, null, null, null);
     consumer.setProperty(RSA_SHA1.X509_CERTIFICATE, CERTIFICATE_TEXT);
     accessor = new OAuthAccessor(consumer);
+    messageValidator = new SimpleOAuthValidator();
   }
 
   private RemoteContentRequest makeContentRequest(String method, String url)
@@ -91,8 +95,9 @@
   }
 
   private RemoteContentRequest signAndInspect(RemoteContentRequest orig)
-      throws GadgetException {
+      throws Exception {
     signer.fetch(orig);
+    assertSignatureOK(interceptor.interceptedRequest);
     return interceptor.interceptedRequest;
   }
 
@@ -113,24 +118,30 @@
     String tricky = "%6fpensocial_owner_id=gotcha";
     RemoteContentRequest unsigned
         = makeContentRequest("GET", "http://test?"; + tricky, null);
-    RemoteContentRequest out = signAndInspect(unsigned);
-    assertFalse(out.getUri().getRawQuery().contains("gotcha"));
-    assertSignatureOK(out);
+    try {
+       RemoteContentRequest out = signAndInspect(unsigned);
+       fail("Should have thrown");
+    } catch (RequestSigningException e) {
+       // good.
+    }
   }
 
   public void testTrickyParametersInBody() throws Exception {
     String tricky = "%6fpensocial_owner_id=gotcha";
     RemoteContentRequest unsigned
         = makeContentRequest("POST", "http://test";, tricky.getBytes());
-    RemoteContentRequest out = signAndInspect(unsigned);
-    assertSignatureInvalid(out);
+    try {
+       RemoteContentRequest out = signAndInspect(unsigned);
+       fail("Should have thrown");
+    } catch (RequestSigningException e) {
+       // good.
+    }
   }
 
   public void testGetNoQuery() throws Exception {
     RemoteContentRequest unsigned
         = makeContentRequest("GET", "http://test";, null);
     RemoteContentRequest out = signAndInspect(unsigned);
-    assertSignatureOK(out);
   }
 
   public void testGetWithQuery() throws Exception {
@@ -140,10 +151,8 @@
     List<OAuth.Parameter> queryParams
         = OAuth.decodeForm(out.getUri().getRawQuery());
     assertTrue(contains(queryParams, "a", "b"));
-    assertSignatureOK(out);
   }
 
-
   public void testGetWithQueryMultiParam() throws Exception {
     RemoteContentRequest unsigned
         = makeContentRequest("GET", "http://test?a=b&a=c";);
@@ -152,13 +161,21 @@
         = OAuth.decodeForm(out.getUri().getRawQuery());
     assertTrue(contains(queryParams, "a", "b"));
     assertTrue(contains(queryParams, "a", "c"));
-    assertSignatureOK(out);
+  }
+  
+  public void testValidParameterCharacters() throws Exception {
+    String weird = "[EMAIL PROTECTED]()-_[]:,./";
+    RemoteContentRequest unsigned
+        = makeContentRequest("GET", "http://test?"; + weird + "=foo");
+    RemoteContentRequest out = signAndInspect(unsigned);
+    List<OAuth.Parameter> queryParams
+        = OAuth.decodeForm(out.getUri().getRawQuery());
+    assertTrue(contains(queryParams, weird, "foo"));
   }
 
   public void testPostNoQueryNoData() throws Exception {
     RemoteContentRequest unsigned = makeContentRequest("GET", "http://test";);
     RemoteContentRequest out = signAndInspect(unsigned);
-    assertSignatureOK(out);
   }
 
   public void testPostWithQueryNoData() throws Exception {
@@ -168,7 +185,6 @@
     List<OAuth.Parameter> queryParams
         = OAuth.decodeForm(out.getUri().getRawQuery());
     assertTrue(contains(queryParams, "name", "value"));
-    assertSignatureOK(out);
   }
 
   public void testPostNoQueryWithData() throws Exception {
@@ -178,7 +194,6 @@
     List<OAuth.Parameter> queryParams
         = OAuth.decodeForm(out.getUri().getRawQuery());
     assertFalse(contains(queryParams, "name", "value"));
-    assertSignatureOK(out);
   }
 
   public void testPostWithQueryWithData() throws Exception {
@@ -188,41 +203,50 @@
     List<OAuth.Parameter> queryParams
         = OAuth.decodeForm(out.getUri().getRawQuery());
     assertTrue(contains(queryParams, "queryName", "queryValue"));
-    assertSignatureOK(out);
   }
 
   public void testStripOpenSocialParamsFromQuery() throws Exception {
     RemoteContentRequest unsigned = makeContentRequest(
         "POST", "http://test?opensocial_foo=bar";);
-    RemoteContentRequest out = signAndInspect(unsigned);
-    List<OAuth.Parameter> queryParams
-        = OAuth.decodeForm(out.getUri().getRawQuery());
-    assertFalse(contains(queryParams, "opensocial_foo", "bar"));
-    assertSignatureOK(out);
+    try {
+      RemoteContentRequest out = signAndInspect(unsigned);
+      fail("Should have thrown");
+    } catch (RequestSigningException e) {
+      // good
+    }
   }
 
   public void testStripOAuthParamsFromQuery() throws Exception {
     RemoteContentRequest unsigned = makeContentRequest(
         "POST", "http://test?oauth_foo=bar";, "name=value".getBytes());
-    RemoteContentRequest out = signAndInspect(unsigned);
-    List<OAuth.Parameter> queryParams
-        = OAuth.decodeForm(out.getUri().getRawQuery());
-    assertFalse(contains(queryParams, "oauth_foo", "bar"));
-    assertSignatureOK(out);
+    try {
+      RemoteContentRequest out = signAndInspect(unsigned);
+      fail("Should have thrown");
+    } catch (RequestSigningException e) {
+      // good
+    }
   }
 
   public void testStripOpenSocialParamsFromBody() throws Exception {
     RemoteContentRequest unsigned = makeContentRequest(
         "POST", "http://test";, "opensocial_foo=bar".getBytes());
-    RemoteContentRequest out = signAndInspect(unsigned);
-    assertSignatureInvalid(out);
+    try {
+       RemoteContentRequest out = signAndInspect(unsigned);
+       fail("Should have thrown");
+    } catch (RequestSigningException e) {
+       // good.
+    }
   }
 
   public void testStripOAuthParamsFromBody() throws Exception {
     RemoteContentRequest unsigned = makeContentRequest(
         "POST", "http://test";, "oauth_foo=bar".getBytes());
-    RemoteContentRequest out = signAndInspect(unsigned);
-    assertSignatureInvalid(out);
+    try {
+       RemoteContentRequest out = signAndInspect(unsigned);
+       fail("Should have thrown");
+    } catch (RequestSigningException e) {
+       // good.
+    }
   }
 
   private void assertSignatureOK(RemoteContentRequest req)
@@ -245,16 +269,7 @@
         msgParams);
 
     // Throws on failure
-    message.validateSignature(accessor);
-  }
-
-  private void assertSignatureInvalid(RemoteContentRequest req) {
-    try {
-      assertSignatureOK(req);
-      fail("Signature verification should have failed");
-    } catch (Exception e) {
-      // good
-    }
+    message.validateMessage(accessor, messageValidator);
   }
 
   // Checks whether the given parameter list contains the specified


Reply via email to