Author: lindner
Date: Fri Mar 27 00:58:35 2009
New Revision: 758949

URL: http://svn.apache.org/viewvc?rev=758949&view=rev
Log:
SHINDIG-995 | Use OAuthProblemException to allow fine-grained error control

Modified:
    
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/AuthenticationServletFilter.java
    
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/oauth/OAuthAuthenticationHandler.java
    
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/oauth/OAuthDataStore.java
    
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/core/oauth/OAuthAuthenticationHanderTest.java

Modified: 
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/AuthenticationServletFilter.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/AuthenticationServletFilter.java?rev=758949&r1=758948&r2=758949&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/AuthenticationServletFilter.java
 (original)
+++ 
incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/AuthenticationServletFilter.java
 Fri Mar 27 00:58:35 2009
@@ -96,7 +96,9 @@
       // We did not find a security token so we will just pass null
       callChain(chain, req, resp);
     } catch (AuthenticationHandler.InvalidAuthenticationException iae) {
-      logger.log(Level.INFO, iae.getMessage(), iae.getCause());
+      Throwable cause = iae.getCause();
+      logger.log(Level.INFO, iae.getMessage(), cause);
+
       if (iae.getAdditionalHeaders() != null) {
         for (Map.Entry<String,String> entry : 
iae.getAdditionalHeaders().entrySet()) {
           resp.addHeader(entry.getKey(), entry.getValue());
@@ -105,7 +107,10 @@
       if (iae.getRedirect() != null) {
         resp.sendRedirect(iae.getRedirect());
       } else {
-        resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, iae.getMessage());
+        // For now append the cause message if set, this allows us to send any 
underlying oauth errors
+        String message = (cause==null) ? iae.getMessage() : iae.getMessage() + 
cause.getMessage();
+
+        resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, message);
       }
     }
   }

Modified: 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/oauth/OAuthAuthenticationHandler.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/oauth/OAuthAuthenticationHandler.java?rev=758949&r1=758948&r2=758949&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/oauth/OAuthAuthenticationHandler.java
 (original)
+++ 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/oauth/OAuthAuthenticationHandler.java
 Fri Mar 27 00:58:35 2009
@@ -27,6 +27,7 @@
 import net.oauth.OAuthMessage;
 import net.oauth.OAuthServiceProvider;
 import net.oauth.SimpleOAuthValidator;
+import net.oauth.OAuthProblemException;
 import net.oauth.server.OAuthServlet;
 
 import org.apache.commons.codec.binary.Base64;
@@ -87,7 +88,7 @@
     }
     try {
       return verifyMessage(message);
-    } catch (InvalidAuthenticationException iae) {
+    } catch (OAuthProblemException oauthException) {
       // Legacy body signing is intended for backwards compatability with 
opensocial clients
       // that assumed they could use the raw request body as a pseudo query 
param to get
       // body signing. This assumption was born out of the limitations of the 
OAuth 1.0 spec which
@@ -103,16 +104,18 @@
         try {
           message.addParameter(readBodyString(request), "");
           return verifyMessage(message);
-        } catch (IOException ioe) {
-          throw iae;
+        } catch (OAuthProblemException ioe) {
+          // ignore, let original exception be thrown
+        } catch (IOException e) {
+          // also ignore;
         }
       }
-      throw iae;
+      throw new InvalidAuthenticationException("OAuth Authentication Failure", 
oauthException);
     }
   }
 
   protected SecurityToken verifyMessage(OAuthMessage message)
-      throws InvalidAuthenticationException {
+      throws OAuthProblemException {
     OAuthEntry entry = getOAuthEntry(message);
     OAuthConsumer authConsumer = getConsumer(message);
 
@@ -128,43 +131,46 @@
     try {
       message.validateMessage(accessor, new SimpleOAuthValidator());
     } catch (OAuthException e) {
-      throw new InvalidAuthenticationException("Unable to verify OAuth 
request", e);
+      throw new OAuthProblemException();
     } catch (IOException e) {
-      throw new InvalidAuthenticationException("Unable to verify OAuth 
request", e);
+      throw new OAuthProblemException();
     } catch (URISyntaxException e) {
-      throw new InvalidAuthenticationException("Unable to verify OAuth 
request", e);
+      throw new OAuthProblemException();
     }
     return getTokenFromVerifiedRequest(message, entry, authConsumer);
   }
 
-  protected OAuthEntry getOAuthEntry(OAuthMessage message) throws 
InvalidAuthenticationException {
+  protected OAuthEntry getOAuthEntry(OAuthMessage message) throws 
OAuthProblemException {
     OAuthEntry entry = null;
     String token = getParameter(message, OAuth.OAUTH_TOKEN);
     if (!StringUtils.isEmpty(token))  {
       entry = store.getEntry(token);
       if (entry == null) {
-        throw new InvalidAuthenticationException("No oauth entry for token: " 
+ token, null);
+        OAuthProblemException e = new 
OAuthProblemException(OAuth.Problems.TOKEN_REJECTED);
+        e.setParameter(OAuth.Problems.OAUTH_PROBLEM_ADVICE, "cannot find 
token");
+        throw e;
       } else if (entry.type != OAuthEntry.Type.ACCESS) {
-        throw new InvalidAuthenticationException("token is not an access 
token.", null);
+        OAuthProblemException e = new 
OAuthProblemException(OAuth.Problems.TOKEN_REJECTED);
+        e.setParameter(OAuth.Problems.OAUTH_PROBLEM_ADVICE, "token is not an 
access token");
+        throw e;
       } else if (entry.isExpired()) {
-        throw new InvalidAuthenticationException("access token has expired.", 
null);
+        throw new OAuthProblemException(OAuth.Problems.TOKEN_EXPIRED);
       }
     }
     return entry;
   }
 
-  protected OAuthConsumer getConsumer(OAuthMessage message) throws 
InvalidAuthenticationException {
+  protected OAuthConsumer getConsumer(OAuthMessage message) throws 
OAuthProblemException {
     String consumerKey = getParameter(message, OAuth.OAUTH_CONSUMER_KEY);
     OAuthConsumer authConsumer = store.getConsumer(consumerKey);
     if (authConsumer == null) {
-      throw new InvalidAuthenticationException("No consumer registered for key 
" + consumerKey,
-          null);
+      throw new OAuthProblemException(OAuth.Problems.CONSUMER_KEY_UNKNOWN);
     }
     return authConsumer;
   }
 
   protected SecurityToken getTokenFromVerifiedRequest(OAuthMessage message, 
OAuthEntry entry,
-      OAuthConsumer authConsumer) {
+      OAuthConsumer authConsumer) throws OAuthProblemException {
     if (entry != null) {
       return new OAuthSecurityToken(entry.userId, entry.callbackUrl, 
entry.appId,
           entry.domain, entry.container);

Modified: 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/oauth/OAuthDataStore.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/oauth/OAuthDataStore.java?rev=758949&r1=758948&r2=758949&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/oauth/OAuthDataStore.java
 (original)
+++ 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/oauth/OAuthDataStore.java
 Fri Mar 27 00:58:35 2009
@@ -18,6 +18,7 @@
 package org.apache.shindig.social.opensocial.oauth;
 
 import net.oauth.OAuthConsumer;
+import net.oauth.OAuthProblemException;
 
 import org.apache.shindig.auth.SecurityToken;
 
@@ -43,11 +44,15 @@
    * for the given consumerKey. App specific checks like making sure the 
requested user has the
    * app installed should take place in this method.
    *
+   * Returning null may allow for other authentication schemes to be used.  
Throwing an
+   * OAuthProblemException will allows errors to be returned to the caller.
+   *
    * @param consumerKey A consumer key
    * @param userId The userId to validate.
    * @return A valid Security Token
+   * @throws OAuthProblemException when there are errors
    */
-  SecurityToken getSecurityTokenForConsumerRequest(String consumerKey, String 
userId);
+  SecurityToken getSecurityTokenForConsumerRequest(String consumerKey, String 
userId) throws OAuthProblemException;
 
   /**
    * Lookup consumers.  Generally this corresponds to an opensocial Application
@@ -58,18 +63,23 @@
    * plus you should consider setting properties that correspond to the 
metadata
    * in the opensocial app like icon, description, etc.
    *
+   * Returning null will inform the client that the consumer key does not 
exist.  If you
+   * want to control the error response throw an OAuthProblemException
+   *
    * @param consumerKey A valid, non-null ConsumerKey
    * @return the consumer object corresponding to the specified key.
+   * @throws OAuthProblemException when the implementing class wants to signal 
errors
    */
-  OAuthConsumer getConsumer(String consumerKey);
+  OAuthConsumer getConsumer(String consumerKey) throws OAuthProblemException;
 
   /**
    * Generate a valid requestToken for the given consumerKey.
    *
    * @param consumerKey A valid consumer key
    * @return An OAuthEntry containing a valid request token.
+   * @throws OAuthProblemException when the implementing class wants to 
control the error response
    */
-  OAuthEntry generateRequestToken(String consumerKey);
+  OAuthEntry generateRequestToken(String consumerKey) throws 
OAuthProblemException;
 
 
   /**
@@ -77,9 +87,10 @@
    * in the final phase of 3-legged OAuth after the user authorizes the app.
    *
    * @param entry The Entry to convert
-   * @return a new entry wiht type Type.ACCESS
+   * @return a new entry with type Type.ACCESS
+   * @throws OAuthProblemException when the implementing class wants to 
control the error response
    */
-  OAuthEntry convertToAccessToken(OAuthEntry entry);
+  OAuthEntry convertToAccessToken(OAuthEntry entry) throws 
OAuthProblemException;
 
 
   /**
@@ -87,6 +98,7 @@
    *
    * @param entry A valid OAuthEntry
    * @param userId A user id
+   * @throws OAuthProblemException when the implementing class wants to 
control the error response
    */
-  void authorizeToken(OAuthEntry entry, String userId);
+  void authorizeToken(OAuthEntry entry, String userId) throws 
OAuthProblemException;
 }

Modified: 
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/core/oauth/OAuthAuthenticationHanderTest.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/core/oauth/OAuthAuthenticationHanderTest.java?rev=758949&r1=758948&r2=758949&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/core/oauth/OAuthAuthenticationHanderTest.java
 (original)
+++ 
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/core/oauth/OAuthAuthenticationHanderTest.java
 Fri Mar 27 00:58:35 2009
@@ -20,6 +20,7 @@
 import net.oauth.OAuth;
 import net.oauth.OAuthConsumer;
 import net.oauth.OAuthServiceProvider;
+import net.oauth.OAuthProblemException;
 
 import org.apache.commons.codec.binary.Base64;
 import org.apache.commons.codec.digest.DigestUtils;
@@ -92,17 +93,25 @@
   }
 
   private void expectConsumer() {
-    EasyMock.expect(mockStore.getConsumer(
-        EasyMock.eq(FakeOAuthRequest.CONSUMER_KEY))).
-          andReturn(new OAuthConsumer(null, FakeOAuthRequest.CONSUMER_KEY,
+    try {
+      EasyMock.expect(mockStore.getConsumer(
+          EasyMock.eq(FakeOAuthRequest.CONSUMER_KEY))).
+            andReturn(new OAuthConsumer(null, FakeOAuthRequest.CONSUMER_KEY,
               FakeOAuthRequest.CONSUMER_SECRET, new OAuthServiceProvider(null, 
null, null)))
-        .anyTimes();
+          .anyTimes();
+    } catch (OAuthProblemException e) {
+
+    }
   }
 
   private void expectSecurityToken() {
-    EasyMock.expect(mockStore.getSecurityTokenForConsumerRequest(
-        EasyMock.eq(FakeOAuthRequest.CONSUMER_KEY), 
EasyMock.eq(FakeOAuthRequest.REQUESTOR))).
-          andReturn(new AnonymousSecurityToken());
+    try {
+      EasyMock.expect(mockStore.getSecurityTokenForConsumerRequest(
+          EasyMock.eq(FakeOAuthRequest.CONSUMER_KEY), 
EasyMock.eq(FakeOAuthRequest.REQUESTOR))).
+            andReturn(new AnonymousSecurityToken());
+    } catch (OAuthProblemException e) {
+
+    }
   }
 
   @Test


Reply via email to