Author: doll
Date: Fri Jun 20 18:00:35 2008
New Revision: 670110

URL: http://svn.apache.org/viewvc?rev=670110&view=rev
Log:
SHINDIG-290
Patch from Dirk Balfanz. First impl of some basic oauth code. These classes 
still need to be filled in, this is just a start. 


Added:
    
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/oauth/
    
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/oauth/OAuthContext.java
    
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/oauth/OAuthServletFilter.java
    
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/oauth/
    
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/oauth/OAuthContextTest.java
    
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/oauth/OAuthServletFilterTest.java
Modified:
    incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.social.xml
    incubator/shindig/trunk/java/social-api/pom.xml

Modified: 
incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.social.xml
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.social.xml?rev=670110&r1=670109&r2=670110&view=diff
==============================================================================
--- incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.social.xml 
(original)
+++ incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.social.xml 
Fri Jun 20 18:00:35 2008
@@ -29,6 +29,16 @@
     
<param-value>org.apache.shindig.common.CommonGuiceModule:org.apache.shindig.social.SocialApiGuiceModule</param-value>
   </context-param>
 
+  <filter>
+    <filter-name>oauthFilter</filter-name>
+    
<filter-class>org.apache.shindig.social.oauth.OAuthServletFilter</filter-class>
+  </filter>
+
+  <filter-mapping>
+    <filter-name>oauthFilter</filter-name>
+    <url-pattern>/social/*</url-pattern>
+  </filter-mapping>
+
   <listener>
     
<listener-class>org.apache.shindig.common.servlet.GuiceServletContextListener</listener-class>
   </listener>

Modified: incubator/shindig/trunk/java/social-api/pom.xml
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/pom.xml?rev=670110&r1=670109&r2=670110&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/pom.xml (original)
+++ incubator/shindig/trunk/java/social-api/pom.xml Fri Jun 20 18:00:35 2008
@@ -100,5 +100,10 @@
       <artifactId>jetty</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>net.oauth</groupId>
+      <artifactId>core</artifactId>
+      <scope>compile</scope>
+    </dependency>
   </dependencies>
 </project>

Added: 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/oauth/OAuthContext.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/oauth/OAuthContext.java?rev=670110&view=auto
==============================================================================
--- 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/oauth/OAuthContext.java
 (added)
+++ 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/oauth/OAuthContext.java
 Fri Jun 20 18:00:35 2008
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.shindig.social.oauth;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * A class that encapsulates the OAuth-related authentication information about
+ * an HTTP request. If a servlet requires that a request was made by a specific
+ * client, it could to the following:
+ *
+ * public void doGet(HttpServletRequest req, HttpServletResponse resp) {
+ *   ...
+ *   OAuthContext authContext = OAuthContext.forRequest(req);
+ *   if (authContext.getAuthMethod() == OAuthContext.AuthMethod.NONE) {
+ *     respondWithError();
+ *   } else {
+ *      String consumer = authContext.getConsumerKey();
+ *      if (clientIsAllowed(consumer)) {
+ *        handleRequest(req, resp);
+ *      } else {
+ *        respondWithError():
+ *      }
+ *   }
+ */
+public class OAuthContext {
+
+  /*
+   * The different authentication methods.
+   */
+  public enum AuthMethod {
+    NONE,  // no authentication attempted, or authentication failed
+
+    OAUTH, // OAuth succeeded, which means we'll have a consumer key and an
+           // OAuth token
+
+    SIGNED // SignedFetch succeeded, in which case we'll just have a consumer
+           // key
+  }
+
+  static final String OAUTH_CONTEXT =
+    "org.apache.shindig.social.oauth.context";
+
+  private AuthMethod authMethod;
+  private String consumerKey;
+  private String oauthToken;
+
+  /**
+   * Returns the OAuth context object for this http request. If no OAuth
+   * context object exists, then a newly-created context object for this
+   * request is returned.
+   */
+  public static OAuthContext fromRequest(HttpServletRequest req) {
+    OAuthContext result = (OAuthContext)req.getAttribute(OAUTH_CONTEXT);
+    return (result == null)
+           ? newContextForRequest(req)
+           : result;
+  }
+
+  /**
+   * Makes a new OAuth context object and stores it in the HttpServletRequest
+   * @param req
+   * @return the newly-created object.
+   */
+  static OAuthContext newContextForRequest(HttpServletRequest req) {
+    OAuthContext context = new OAuthContext();
+    req.setAttribute(OAUTH_CONTEXT, context);
+    return context;
+  }
+
+  // newly-created contexts know of no authentication
+  OAuthContext() {
+    this.authMethod = AuthMethod.NONE;
+    this.consumerKey = null;
+    this.oauthToken = null;
+  }
+
+  /**
+   * Returns the method of authentication used by the client.
+   */
+  public AuthMethod getAuthMethod() {
+    return authMethod;
+  }
+
+  public void setAuthMethod(AuthMethod method) {
+    authMethod = method;
+  }
+
+  /**
+   * Returns the consumer key that was authenticated by the server. This value
+   * should only be trusted if getAuthMethod() returns OAUTH or SIGNED.
+   */
+  public String getConsumerKey() {
+    return consumerKey;
+  }
+
+  public void setConsumerKey(String key) {
+    consumerKey = key;
+  }
+
+  /**
+   * Returns the OAuth token that was authenticated by the server. This value
+   * should only be trusted if getAuthMethod() return OAUTH.
+   */
+  public String getOAuthToken() {
+    return oauthToken;
+  }
+
+  public void setOAuthToken(String token) {
+    oauthToken = token;
+  }
+}

Added: 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/oauth/OAuthServletFilter.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/oauth/OAuthServletFilter.java?rev=670110&view=auto
==============================================================================
--- 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/oauth/OAuthServletFilter.java
 (added)
+++ 
incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/oauth/OAuthServletFilter.java
 Fri Jun 20 18:00:35 2008
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.shindig.social.oauth;
+
+import net.oauth.OAuth;
+import net.oauth.OAuthMessage;
+import net.oauth.server.OAuthServlet;
+
+import org.apache.commons.lang.NotImplementedException;
+
+import java.io.IOException;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+public class OAuthServletFilter implements Filter {
+
+
+  public void init(FilterConfig filterConfig) {
+  }
+
+  public void destroy() {
+  }
+
+  public void doFilter(ServletRequest request, ServletResponse response,
+      FilterChain chain) throws IOException, ServletException {
+
+    if (!(request instanceof HttpServletRequest)) {
+      throw new ServletException("OAuth filter can only handle HTTP");
+    }
+
+    if (!(response instanceof HttpServletResponse)) {
+      throw new ServletException("OAuth filter can only handle HTTP");
+    }
+
+    HttpServletRequest req = (HttpServletRequest)request;
+    HttpServletResponse res = (HttpServletResponse)response;
+    OAuthContext authContext = OAuthContext.newContextForRequest(req);
+
+    OAuthMessage requestMessage = OAuthServlet.getMessage(req, null);
+
+    if (requestMessage.getParameter(OAuth.OAUTH_SIGNATURE) == null) {
+      // doesn't seem to be an OAuth request
+      chain.doFilter(request, response);
+      return;
+    }
+
+    if (requestMessage.getToken() == null) {
+      handleSignedFetch(requestMessage, authContext);
+    } else {
+      handleFullOAuth(requestMessage, authContext);
+    }
+
+    chain.doFilter(request, response);
+  }
+
+  private void handleFullOAuth(OAuthMessage requestMessage,
+      OAuthContext authContext) {
+    throw new NotImplementedException("full OAuth support not yet 
implemented");
+  }
+
+  private void handleSignedFetch(OAuthMessage requestMessage,
+      OAuthContext context) {
+    // TODO implement this method
+  }
+}

Added: 
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/oauth/OAuthContextTest.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/oauth/OAuthContextTest.java?rev=670110&view=auto
==============================================================================
--- 
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/oauth/OAuthContextTest.java
 (added)
+++ 
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/oauth/OAuthContextTest.java
 Fri Jun 20 18:00:35 2008
@@ -0,0 +1,303 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.shindig.social.oauth;
+
+import junit.framework.TestCase;
+
+import org.apache.shindig.social.oauth.OAuthContext.AuthMethod;
+
+import java.io.BufferedReader;
+import java.security.Principal;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+public class OAuthContextTest extends TestCase {
+
+  public void testGettersAndSetters() throws Exception {
+    OAuthContext context = new OAuthContext();
+
+    // first, make sure it's constructed in the right state
+    assertEquals(OAuthContext.AuthMethod.NONE, context.getAuthMethod());
+    assertNull(context.getConsumerKey());
+    assertNull(context.getOAuthToken());
+
+    // then, test the getters and setters
+    context.setAuthMethod(AuthMethod.OAUTH);
+    assertEquals(OAuthContext.AuthMethod.OAUTH, context.getAuthMethod());
+
+    context.setConsumerKey("consumer");
+    assertEquals("consumer", context.getConsumerKey());
+
+    context.setOAuthToken("token");
+    assertEquals("token", context.getOAuthToken());
+  }
+
+  public void testCreationAndOverriding() throws Exception {
+
+    HttpServletRequest request = new FakeHttpServletRequest();
+
+    // make sure that we always get a OAuthContext object
+    OAuthContext context = OAuthContext.fromRequest(request);
+
+    assertNotNull(context);
+
+    // make sure that we can override existing contexts
+    OAuthContext context2 = OAuthContext.newContextForRequest(request);
+
+    assertNotSame(context, context2);
+    assertEquals(OAuthContext.AuthMethod.NONE, context2.getAuthMethod());
+
+    OAuthContext context3 = OAuthContext.fromRequest(request);
+    assertSame(context2, context3);
+  }
+
+  public static class FakeHttpServletRequest implements HttpServletRequest {
+
+    private HashMap<String, Object> attributes = new HashMap<String, Object>();
+
+    public String getAuthType() {
+      return null;
+    }
+
+    public String getContextPath() {
+      return null;
+    }
+
+    public Cookie[] getCookies() {
+      return null;
+    }
+
+    public long getDateHeader(String name) {
+      return 0;
+    }
+
+    public String getHeader(String name) {
+      return null;
+    }
+
+    @SuppressWarnings("unchecked")
+    public Enumeration getHeaderNames() {
+      return null;
+    }
+
+    @SuppressWarnings("unchecked")
+    public Enumeration getHeaders(String name) {
+      return null;
+    }
+
+    public int getIntHeader(String name) {
+      return 0;
+    }
+
+    public String getMethod() {
+      return null;
+    }
+
+    public String getPathInfo() {
+      return null;
+    }
+
+    public String getPathTranslated() {
+      return null;
+    }
+
+    public String getQueryString() {
+      return null;
+    }
+
+    public String getRemoteUser() {
+      return null;
+    }
+
+    public String getRequestURI() {
+      return null;
+    }
+
+    public StringBuffer getRequestURL() {
+      return new StringBuffer("http://foo.com/bar";);
+    }
+
+    public String getRequestedSessionId() {
+      return null;
+    }
+
+    public String getServletPath() {
+      return null;
+    }
+
+    public HttpSession getSession() {
+      return null;
+    }
+
+    public HttpSession getSession(boolean create) {
+      return null;
+    }
+
+    public Principal getUserPrincipal() {
+      return null;
+    }
+
+    public boolean isRequestedSessionIdFromCookie() {
+      return false;
+    }
+
+    public boolean isRequestedSessionIdFromURL() {
+      return false;
+    }
+
+    public boolean isRequestedSessionIdFromUrl() {
+      return false;
+    }
+
+    public boolean isRequestedSessionIdValid() {
+      return false;
+    }
+
+    public boolean isUserInRole(String role) {
+      return false;
+    }
+
+    public Object getAttribute(String name) {
+      return attributes.get(name);
+    }
+
+    @SuppressWarnings("unchecked")
+    public Enumeration getAttributeNames() {
+      return Collections.enumeration(attributes.keySet());
+    }
+
+    public String getCharacterEncoding() {
+      return null;
+    }
+
+    public int getContentLength() {
+      return 0;
+    }
+
+    public String getContentType() {
+      return null;
+    }
+
+    public ServletInputStream getInputStream() {
+      return null;
+    }
+
+    public String getLocalAddr() {
+      return null;
+    }
+
+    public String getLocalName() {
+      return null;
+    }
+
+    public int getLocalPort() {
+      return 0;
+    }
+
+    public Locale getLocale() {
+      return null;
+    }
+
+    @SuppressWarnings("unchecked")
+    public Enumeration getLocales() {
+      return null;
+    }
+
+    public String getParameter(String name) {
+      return null;
+    }
+
+    @SuppressWarnings("unchecked")
+    public Map getParameterMap() {
+      return new HashMap();
+    }
+
+    @SuppressWarnings("unchecked")
+    public Enumeration getParameterNames() {
+      return null;
+    }
+
+    public String[] getParameterValues(String name) {
+      return new String[0];
+    }
+
+    public String getProtocol() {
+      return null;
+    }
+
+    public BufferedReader getReader() {
+      return null;
+    }
+
+    public String getRealPath(String path) {
+      return null;
+    }
+
+    public String getRemoteAddr() {
+      return null;
+    }
+
+    public String getRemoteHost() {
+      return null;
+    }
+
+    public int getRemotePort() {
+      return 0;
+    }
+
+    public RequestDispatcher getRequestDispatcher(String path) {
+      return null;
+    }
+
+    public String getScheme() {
+      return null;
+    }
+
+    public String getServerName() {
+      return null;
+    }
+
+    public int getServerPort() {
+      return 0;
+    }
+
+    public boolean isSecure() {
+      return false;
+    }
+
+    public void removeAttribute(String name) {
+      attributes.remove(name);
+    }
+
+    public void setAttribute(String name, Object o) {
+      attributes.put(name, o);
+    }
+
+    public void setCharacterEncoding(String env) {
+    }
+  }
+}

Added: 
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/oauth/OAuthServletFilterTest.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/oauth/OAuthServletFilterTest.java?rev=670110&view=auto
==============================================================================
--- 
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/oauth/OAuthServletFilterTest.java
 (added)
+++ 
incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/oauth/OAuthServletFilterTest.java
 Fri Jun 20 18:00:35 2008
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.shindig.social.oauth;
+
+import org.apache.shindig.social.EasyMockTestCase;
+import org.apache.shindig.social.oauth.OAuthContextTest.FakeHttpServletRequest;
+
+import javax.servlet.FilterChain;
+import javax.servlet.http.HttpServletResponse;
+
+public class OAuthServletFilterTest extends EasyMockTestCase {
+
+  private FakeHttpServletRequest request;
+  private HttpServletResponse response;
+  private FilterChain chain;
+
+  private OAuthServletFilter filter;
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+
+    request = new FakeHttpServletRequest();
+    response = mock(HttpServletResponse.class);
+    chain = mock(FilterChain.class);
+
+    filter = new OAuthServletFilter();
+  }
+
+  public void testUnauthenticated() throws Exception {
+    filter.doFilter(request, response, chain);
+
+    assertEquals(OAuthContext.AuthMethod.NONE,
+        OAuthContext.fromRequest(request).getAuthMethod());
+  }
+
+
+}


Reply via email to