You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by be...@apache.org on 2008/09/29 23:30:08 UTC

svn commit: r700263 - in /incubator/shindig/trunk: config/ java/common/ java/common/conf/ java/common/src/main/java/org/apache/shindig/auth/ java/common/src/main/java/org/apache/shindig/common/ java/gadgets/ java/gadgets/conf/ java/gadgets/src/main/jav...

Author: beaton
Date: Mon Sep 29 14:30:07 2008
New Revision: 700263

URL: http://svn.apache.org/viewvc?rev=700263&view=rev
Log:
Allow configuration options to control choice of fake vs real gadget
security tokens.

Guice changes:
property file binding moved to new PropertiesModule.
oauth configuration movet to new OAuthModule.
both gadgets and social-api depends on PropertiesModule
gadgets depends on OAuthModule as well.



Added:
    incubator/shindig/trunk/java/common/conf/
    incubator/shindig/trunk/java/common/conf/shindig.properties
      - copied, changed from r698666, incubator/shindig/trunk/java/gadgets/conf/gadgets.properties
    incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/DefaultSecurityTokenDecoder.java   (with props)
    incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/PropertiesModule.java   (with props)
    incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/OAuthModule.java   (with props)
Removed:
    incubator/shindig/trunk/java/gadgets/conf/
    incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/HttpGuiceModule.java
Modified:
    incubator/shindig/trunk/config/container.js
    incubator/shindig/trunk/java/common/pom.xml
    incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BlobCrypterSecurityTokenDecoder.java
    incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/SecurityTokenDecoder.java
    incubator/shindig/trunk/java/gadgets/pom.xml
    incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/DefaultGuiceModule.java
    incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/OAuthFetcherConfig.java
    incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.full.xml
    incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.gadgets.xml
    incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.social.xml
    incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.xml
    incubator/shindig/trunk/java/server/src/test/java/org/apache/shindig/server/endtoend/EndToEndServer.java
    incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/core/config/SocialApiGuiceModuleTest.java
    incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/core/oauth/AuthenticationProviderHandlerTest.java

Modified: incubator/shindig/trunk/config/container.js
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/config/container.js?rev=700263&r1=700262&r2=700263&view=diff
==============================================================================
--- incubator/shindig/trunk/config/container.js (original)
+++ incubator/shindig/trunk/config/container.js Mon Sep 29 14:30:07 2008
@@ -60,6 +60,14 @@
 // DNS domain on which gadgets should render.
 "gadgets.lockedDomainSuffix" : "-a.example.com:8080",
 
+// Use an insecure security token by default
+"gadgets.securityTokenType" : "insecure",
+
+// Uncomment these to switch to a secure version
+// 
+//"gadgets.securityTokenType" : "secure",
+//"gadgets.securityTokenKeyFile" : "/path/to/key/file.txt",
+
 // This config data will be passed down to javascript. Please
 // configure your object using the feature name rather than
 // the javascript name.

Copied: incubator/shindig/trunk/java/common/conf/shindig.properties (from r698666, incubator/shindig/trunk/java/gadgets/conf/gadgets.properties)
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/conf/shindig.properties?p2=incubator/shindig/trunk/java/common/conf/shindig.properties&p1=incubator/shindig/trunk/java/gadgets/conf/gadgets.properties&r1=698666&r2=700263&rev=700263&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/conf/gadgets.properties (original)
+++ incubator/shindig/trunk/java/common/conf/shindig.properties Mon Sep 29 14:30:07 2008
@@ -3,8 +3,9 @@
 shindig.blacklist.file=
 shindig.urls.iframe.prefix=/gadgets/ifr?
 shindig.urls.js.prefix=/gadgets/js/
-#shindig.signing.key-name=
-#shindig.signing.key-file=
+shindig.oauth.state-key=
+shindig.signing.key-name=
+shindig.signing.key-file=
 shindig.locked-domain.enabled=false
 shindig.locked-domain.embed-host=127.0.0.1:8080
 shindig.content-rewrite.include-urls=.*

Modified: incubator/shindig/trunk/java/common/pom.xml
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/pom.xml?rev=700263&r1=700262&r2=700263&view=diff
==============================================================================
--- incubator/shindig/trunk/java/common/pom.xml (original)
+++ incubator/shindig/trunk/java/common/pom.xml Mon Sep 29 14:30:07 2008
@@ -54,6 +54,9 @@
           <include>**/*</include>
         </includes>
       </resource>
+      <resource>
+        <directory>conf</directory>
+      </resource>
     </resources>
   </build>
 

Modified: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BlobCrypterSecurityTokenDecoder.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BlobCrypterSecurityTokenDecoder.java?rev=700263&r1=700262&r2=700263&view=diff
==============================================================================
--- incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BlobCrypterSecurityTokenDecoder.java (original)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BlobCrypterSecurityTokenDecoder.java Mon Sep 29 14:30:07 2008
@@ -47,9 +47,9 @@
 @Singleton
 public class BlobCrypterSecurityTokenDecoder implements SecurityTokenDecoder {
 
-  public static final String SECURITY_TOKEN_KEY_FILE = "securityTokenKeyFile";
+  public static final String SECURITY_TOKEN_KEY_FILE = "gadgets.securityTokenKeyFile";
   
-  public static final String SIGNED_FETCH_DOMAIN = "signedFetchDomain";
+  public static final String SIGNED_FETCH_DOMAIN = "gadgets.signedFetchDomain";
   
   /**
    * Keys are container ids, values are crypters

Added: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/DefaultSecurityTokenDecoder.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/DefaultSecurityTokenDecoder.java?rev=700263&view=auto
==============================================================================
--- incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/DefaultSecurityTokenDecoder.java (added)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/DefaultSecurityTokenDecoder.java Mon Sep 29 14:30:07 2008
@@ -0,0 +1,69 @@
+/*
+ * 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.auth;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+import org.apache.shindig.common.ContainerConfig;
+
+import java.util.Map;
+
+/**
+ * Default implementation of security tokens.  Decides based on default container configuration
+ * whether to use real crypto for security tokens or to use a simple insecure implementation that
+ * is useful for testing.
+ * 
+ * Example configuration in container.js for insecure security tokens:
+ *    gadgets.securityTokenType = insecure
+ *    
+ * Example configuration in container.js for blob crypter based security tokens:
+ *    gadgets.securityTokenType = secure
+ * 
+ * The insecure implementation is BasicSecurityTokenDecoder.
+ * 
+ * The secure implementation is BlobCrypterSecurityTokenDecoder.
+ */
+@Singleton
+public class DefaultSecurityTokenDecoder implements SecurityTokenDecoder {
+
+  private static final String SECURITY_TOKEN_TYPE = "gadgets.securityTokenType";
+  
+  private final SecurityTokenDecoder decoder;
+  
+  @Inject
+  public DefaultSecurityTokenDecoder(ContainerConfig config) {
+    String tokenType = config.get(ContainerConfig.DEFAULT_CONTAINER, SECURITY_TOKEN_TYPE);
+    if ("insecure".equals(tokenType)) {
+      decoder = new BasicSecurityTokenDecoder();
+    } else if ("secure".equals(tokenType)) {
+      decoder = new BlobCrypterSecurityTokenDecoder(config);
+    } else {
+      throw new RuntimeException("Unknown security token type specified in " +
+          ContainerConfig.DEFAULT_CONTAINER + " container configuration. " +
+          SECURITY_TOKEN_TYPE + ": " + tokenType);
+    }
+  }
+  
+  public SecurityToken createToken(Map<String, String> tokenParameters)
+      throws SecurityTokenException {
+    return decoder.createToken(tokenParameters);
+  }
+  
+}

Propchange: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/DefaultSecurityTokenDecoder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/SecurityTokenDecoder.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/SecurityTokenDecoder.java?rev=700263&r1=700262&r2=700263&view=diff
==============================================================================
--- incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/SecurityTokenDecoder.java (original)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/SecurityTokenDecoder.java Mon Sep 29 14:30:07 2008
@@ -25,7 +25,7 @@
 /**
  *  Handles verification of gadget security tokens.
  */
-@ImplementedBy(BasicSecurityTokenDecoder.class)
+@ImplementedBy(DefaultSecurityTokenDecoder.class)
 public interface SecurityTokenDecoder {
 
   /**

Added: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/PropertiesModule.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/PropertiesModule.java?rev=700263&view=auto
==============================================================================
--- incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/PropertiesModule.java (added)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/PropertiesModule.java Mon Sep 29 14:30:07 2008
@@ -0,0 +1,72 @@
+/*
+ * 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.common;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.CreationException;
+import com.google.inject.name.Names;
+import com.google.inject.spi.Message;
+
+import org.apache.shindig.common.util.ResourceLoader;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Properties;
+
+/**
+ * Injects everything from the shindig.properties as a Named value.
+ */
+public class PropertiesModule extends AbstractModule {
+
+  private final static String DEFAULT_PROPERTIES = "shindig.properties";
+  
+  private final Properties properties;
+  
+  public PropertiesModule() {
+    InputStream is = null;
+    try {
+      is = ResourceLoader.openResource(DEFAULT_PROPERTIES);
+      properties = new Properties();
+      properties.load(is);
+    } catch (IOException e) {
+      throw new CreationException(Arrays.asList(
+          new Message("Unable to load properties: " + DEFAULT_PROPERTIES)));
+    } finally {
+      try {
+        if (is != null) {
+          is.close();
+        }
+      } catch (IOException e) {
+        // weird
+      }
+    }
+  }
+  
+  public PropertiesModule(Properties properties) {
+    this.properties = properties;
+  }
+
+  @Override
+  protected void configure() {
+    Names.bindProperties(this.binder(), properties);
+  }
+
+}

Propchange: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/PropertiesModule.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/shindig/trunk/java/gadgets/pom.xml
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/pom.xml?rev=700263&r1=700262&r2=700263&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/pom.xml (original)
+++ incubator/shindig/trunk/java/gadgets/pom.xml Mon Sep 29 14:30:07 2008
@@ -95,9 +95,6 @@
           <include>oauth.json</include>
         </includes>
       </resource>
-      <resource>
-        <directory>conf</directory>
-      </resource>
     </resources>
   </build>
 

Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/DefaultGuiceModule.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/DefaultGuiceModule.java?rev=700263&r1=700262&r2=700263&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/DefaultGuiceModule.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/DefaultGuiceModule.java Mon Sep 29 14:30:07 2008
@@ -18,15 +18,7 @@
  */
 package org.apache.shindig.gadgets;
 
-import org.apache.shindig.common.crypto.BasicBlobCrypter;
-import org.apache.shindig.common.crypto.BlobCrypter;
-import org.apache.shindig.common.crypto.Crypto;
-import org.apache.shindig.common.util.ResourceLoader;
 import org.apache.shindig.gadgets.http.HttpResponse;
-import org.apache.shindig.gadgets.oauth.BasicOAuthStore;
-import org.apache.shindig.gadgets.oauth.BasicOAuthStoreConsumerKeyAndSecret;
-import org.apache.shindig.gadgets.oauth.OAuthStore;
-import org.apache.shindig.gadgets.oauth.BasicOAuthStoreConsumerKeyAndSecret.KeyType;
 import org.apache.shindig.gadgets.preload.HttpPreloader;
 import org.apache.shindig.gadgets.preload.Preloader;
 import org.apache.shindig.gadgets.render.RenderingContentRewriter;
@@ -36,49 +28,23 @@
 
 import com.google.common.collect.Lists;
 import com.google.inject.AbstractModule;
-import com.google.inject.CreationException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.TypeLiteral;
-import com.google.inject.name.Names;
-import com.google.inject.spi.Message;
 
-import org.apache.commons.io.IOUtils;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Arrays;
 import java.util.List;
-import java.util.Properties;
 import java.util.concurrent.Executor;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
-import java.util.logging.Level;
-import java.util.logging.Logger;
 
 /**
  * Creates a module to supply all of the Basic* classes
  */
 public class DefaultGuiceModule extends AbstractModule {
 
-  private static final Logger logger
-      = Logger.getLogger(DefaultGuiceModule.class.getName());
-
-  private final Properties properties;
-  private final String oauthConfig;
-
-  private final static String DEFAULT_PROPERTIES = "gadgets.properties";
-  private final static String OAUTH_CONFIG = "config/oauth.json";
-
-  public final static String OAUTH_STATE_CRYPTER_ANNOTATION = "shindig.oauth.state-key";
-  public final static String OAUTH_SIGNING_KEY_NAME = "shindig.signing.key-name";
-  public final static String OAUTH_SIGNING_KEY_FILE = "shindig.signing.key-file";
-
   /** {@inheritDoc} */
   @Override
   protected void configure() {
-    Names.bindProperties(this.binder(), properties);
 
     ExecutorService service = Executors.newCachedThreadPool();
     bind(Executor.class).toInstance(service);
@@ -87,124 +53,10 @@
     bind(new TypeLiteral<List<ContentRewriter>>(){}).toProvider(ContentRewritersProvider.class);
     bind(new TypeLiteral<List<Preloader>>(){}).toProvider(PreloaderProvider.class);
 
-    // TODO: This is not the proper way to use a Guice module. It needs to be fixed before we can
-    // do a release.
-    try {
-      configureOAuthStore();
-    } catch (Throwable t) {
-      // Since this happens at startup, we don't want to kill the server just
-      // because we can't initialize the OAuth config.
-      logger.log(Level.WARNING, "Failed to initialize OAuth", t);
-    }
-    try {
-      configureOAuthStateCrypter();
-    } catch (Throwable t) {
-      // Since this happens at startup, we don't want to kill the server just
-      // because we can't initialize the OAuth config.
-      logger.log(Level.WARNING, "Failed to initialize Crypter", t);
-    }
-
     // We perform static injection on HttpResponse for cache TTLs.
     requestStaticInjection(HttpResponse.class);
   }
 
-  /**
-   * Create a store for OAuth consumer keys and access tokens.  By default consumer keys are read
-   * from config/oauth.json, and access tokens are stored in memory.
-   *
-   * We read the default key from disk, in a location specified in our properties file.
-   *
-   * TODO: This doesn't belong here! It can't be reused by anyone who wants to customize shindig,
-   * which *FORCES* everyone to re-implement it.
-   */
-  private void configureOAuthStore() throws GadgetException {
-    BasicOAuthStore store = new BasicOAuthStore();
-    bind(OAuthStore.class).toInstance(store);
-    store.initFromConfigString(oauthConfig);
-
-    String keyName = properties.getProperty(OAUTH_SIGNING_KEY_NAME);
-    String keyFile = properties.getProperty(OAUTH_SIGNING_KEY_FILE);
-    BasicOAuthStoreConsumerKeyAndSecret defaultKey = null;
-    if (keyFile != null) {
-      try {
-        logger.info("Loading OAuth signing key from " + keyFile);
-        String privateKey = IOUtils.toString(ResourceLoader.open(keyFile), "UTF-8");
-        privateKey = BasicOAuthStore.convertFromOpenSsl(privateKey);
-        defaultKey = new BasicOAuthStoreConsumerKeyAndSecret(null, privateKey, KeyType.RSA_PRIVATE,
-            keyName);
-      } catch (IOException e) {
-        logger.log(Level.WARNING, "Couldn't load key file " + keyFile, e);
-      }
-    }
-    if (defaultKey != null) {
-      store.setDefaultKey(defaultKey);
-    } else {
-      logger.log(Level.WARNING, "Couldn't load OAuth signing key.  To create a key, run:\n" +
-      		"  openssl req -newkey rsa:1024 -days 365 -nodes -x509 -keyout testkey.pem \\\n" +
-      		"     -out testkey.pem -subj '/CN=mytestkey'\n" +
-      		"  openssl pkcs8 -in testkey.pem -out oauthkey.pem -topk8 -nocrypt -outform PEM\n" +
-      		"\n" +
-      		"Then edit gadgets.properties and add these lines:\n" +
-      		OAUTH_SIGNING_KEY_FILE + "=<path-to-oauthkey.pem>\n" +
-      		OAUTH_SIGNING_KEY_NAME + "=mykey\n");
-    }
-  }
-
-  /**
-   * Create a crypter to handle OAuth state.  This can be loaded from disk, if
-   * shindig.oauth.state-key-file is specified in your gadgets.properties file, or it can be
-   * created using a random key.
-   */
-  private void configureOAuthStateCrypter() {
-    // Create the oauth state crypter based on a file from disk
-    BasicBlobCrypter oauthCrypter = null;
-    String keyFileName = properties.getProperty("shindig.oauth.state-key-file");
-    if (keyFileName != null) {
-      logger.info("Loading OAuth state crypter from " + keyFileName);
-      try {
-        oauthCrypter = new BasicBlobCrypter(new File(keyFileName));
-      } catch (IOException e) {
-        logger.log(Level.SEVERE, "Failed to load " + keyFileName, e);
-      }
-    }
-    if (oauthCrypter == null) {
-      logger.info("Creating OAuth state crypter with random key");
-      oauthCrypter = new BasicBlobCrypter(
-          Crypto.getRandomBytes(BasicBlobCrypter.MASTER_KEY_MIN_LEN));
-    }
-    bind(BlobCrypter.class).annotatedWith(
-        Names.named(OAUTH_STATE_CRYPTER_ANNOTATION))
-        .toInstance(oauthCrypter);
-  }
-
-  public DefaultGuiceModule(Properties properties, String oauthConfig) {
-    this.properties = properties;
-    this.oauthConfig = oauthConfig;
-  }
-
-  /**
-   * Creates module with standard properties.
-   */
-  public DefaultGuiceModule() {
-    Properties properties = null;
-    String oauthConfig = null;
-    try {
-      InputStream is = ResourceLoader.openResource(DEFAULT_PROPERTIES);
-      properties = new Properties();
-      properties.load(is);
-      try {
-        oauthConfig = ResourceLoader.getContent(OAUTH_CONFIG);
-      } catch (IOException e) {
-        logger.log(Level.WARNING, "Can't load " + OAUTH_CONFIG, e);
-      }
-    } catch (IOException e) {
-      throw new CreationException(Arrays.asList(
-          new Message("Unable to load properties: " + DEFAULT_PROPERTIES)));
-    }
-    this.properties = properties;
-    this.oauthConfig = oauthConfig;
-  }
-
   private static class ContentRewritersProvider implements Provider<List<ContentRewriter>> {
     private final List<ContentRewriter> rewriters;
 

Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/OAuthFetcherConfig.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/OAuthFetcherConfig.java?rev=700263&r1=700262&r2=700263&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/OAuthFetcherConfig.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/OAuthFetcherConfig.java Mon Sep 29 14:30:07 2008
@@ -21,7 +21,6 @@
 import com.google.inject.name.Named;
 
 import org.apache.shindig.common.crypto.BlobCrypter;
-import org.apache.shindig.gadgets.DefaultGuiceModule;
 import org.apache.shindig.gadgets.http.HttpCache;
 
 /**
@@ -29,13 +28,15 @@
  */
 public class OAuthFetcherConfig {
   
+  public static final String OAUTH_STATE_CRYPTER = "shindig.oauth.state-crypter";
+  
   private final BlobCrypter stateCrypter;
   private final GadgetOAuthTokenStore tokenStore;
   private final HttpCache httpCache;
   
   @Inject
   public OAuthFetcherConfig(
-      @Named(DefaultGuiceModule.OAUTH_STATE_CRYPTER_ANNOTATION) BlobCrypter stateCrypter,
+      @Named(OAUTH_STATE_CRYPTER) BlobCrypter stateCrypter,
       GadgetOAuthTokenStore tokenStore,
       HttpCache httpCache) {
     this.stateCrypter = stateCrypter;

Added: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/OAuthModule.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/OAuthModule.java?rev=700263&view=auto
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/OAuthModule.java (added)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/OAuthModule.java Mon Sep 29 14:30:07 2008
@@ -0,0 +1,134 @@
+/*
+ * 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.gadgets.oauth;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.shindig.common.crypto.BasicBlobCrypter;
+import org.apache.shindig.common.crypto.BlobCrypter;
+import org.apache.shindig.common.crypto.Crypto;
+import org.apache.shindig.common.util.ResourceLoader;
+import org.apache.shindig.gadgets.oauth.BasicOAuthStoreConsumerKeyAndSecret.KeyType;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.name.Named;
+import com.google.inject.name.Names;
+
+/**
+ * Loads pre-reqs for OAuth.
+ */
+public class OAuthModule extends AbstractModule {
+
+  private static final Logger logger = Logger.getLogger(OAuthModule.class.getName());
+
+  private static final String OAUTH_CONFIG = "config/oauth.json";
+  private static final String OAUTH_SIGNING_KEY_FILE = "shindig.signing.key-file";
+  private static final String OAUTH_SIGNING_KEY_NAME = "shindig.signing.key-name";
+
+  @Override
+  protected void configure() {
+    // Used for encrypting client-side OAuth state.
+    bind(BlobCrypter.class).annotatedWith(Names.named(OAuthFetcherConfig.OAUTH_STATE_CRYPTER))
+        .toProvider(OAuthCrypterProvider.class);
+    
+    // Used for persistent storage of OAuth access tokens.
+    bind(OAuthStore.class).toProvider(OAuthStoreProvider.class);
+  }
+
+  public static class OAuthCrypterProvider implements Provider<BlobCrypter> {
+
+    private final BlobCrypter crypter;
+
+    @Inject
+    public OAuthCrypterProvider(@Named("shindig.oauth.state-key") String stateCrypterPath)
+        throws IOException {
+      if (StringUtils.isBlank(stateCrypterPath)) {
+        logger.info("Using random key for OAuth client-side state encryption");
+        crypter = new BasicBlobCrypter(Crypto.getRandomBytes(BasicBlobCrypter.MASTER_KEY_MIN_LEN));
+      } else {
+        logger.info("Using file " + stateCrypterPath + " for OAuth client-side state encryption");
+        crypter = new BasicBlobCrypter(new File(stateCrypterPath));
+      }
+    }
+
+    public BlobCrypter get() {
+      return crypter;
+    }
+  }
+
+  public static class OAuthStoreProvider implements Provider<OAuthStore> {
+
+    private BasicOAuthStore store;
+
+    @Inject
+    public OAuthStoreProvider(
+        @Named(OAUTH_SIGNING_KEY_FILE) String signingKeyFile,
+        @Named(OAUTH_SIGNING_KEY_NAME) String signingKeyName) {
+      store = new BasicOAuthStore();
+      loadDefaultKey(signingKeyFile, signingKeyName);
+      loadConsumers();
+    }
+
+    private void loadDefaultKey(String signingKeyFile, String signingKeyName) {
+      BasicOAuthStoreConsumerKeyAndSecret key = null;
+      if (!StringUtils.isBlank(signingKeyFile)) {
+        try {
+          logger.info("Loading OAuth signing key from " + signingKeyFile);
+          String privateKey = IOUtils.toString(ResourceLoader.open(signingKeyFile), "UTF-8");
+          privateKey = BasicOAuthStore.convertFromOpenSsl(privateKey);
+          key = new BasicOAuthStoreConsumerKeyAndSecret(null, privateKey, KeyType.RSA_PRIVATE,
+              signingKeyName);
+        } catch (Throwable t) {
+          logger.log(Level.WARNING, "Couldn't load key file " + signingKeyFile, t);
+        }
+      }
+      if (key != null) {
+        store.setDefaultKey(key);
+      } else {
+        logger.log(Level.WARNING, "Couldn't load OAuth signing key.  To create a key, run:\n" +
+            "  openssl req -newkey rsa:1024 -days 365 -nodes -x509 -keyout testkey.pem \\\n" +
+            "     -out testkey.pem -subj '/CN=mytestkey'\n" +
+            "  openssl pkcs8 -in testkey.pem -out oauthkey.pem -topk8 -nocrypt -outform PEM\n" +
+            "\n" +
+            "Then edit gadgets.properties and add these lines:\n" +
+            OAUTH_SIGNING_KEY_FILE + "=<path-to-oauthkey.pem>\n" +
+            OAUTH_SIGNING_KEY_NAME + "=mykey\n");    
+      }
+    }
+
+    private void loadConsumers() {
+      try {
+        String oauthConfigString = ResourceLoader.getContent(OAUTH_CONFIG);
+        store.initFromConfigString(oauthConfigString);
+      } catch (Throwable t) {
+        logger.log(Level.WARNING, "Failed to initialize OAuth consumers from " + OAUTH_CONFIG, t);
+      }
+    }
+
+    public OAuthStore get() {
+      return store;
+    }
+  }
+}

Propchange: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/OAuthModule.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.full.xml
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.full.xml?rev=700263&r1=700262&r2=700263&view=diff
==============================================================================
--- incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.full.xml (original)
+++ incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.full.xml Mon Sep 29 14:30:07 2008
@@ -27,7 +27,7 @@
   <context-param>
     <param-name>guice-modules</param-name>
     <param-value>
-      org.apache.shindig.gadgets.servlet.HttpGuiceModule:org.apache.shindig.social.core.config.SocialApiGuiceModule
+      org.apache.shindig.common.PropertiesModule:org.apache.shindig.gadgets.DefaultGuiceModule:org.apache.shindig.social.core.config.SocialApiGuiceModule:org.apache.shindig.gadgets.oauth.OAuthModule
     </param-value>
   </context-param>
 

Modified: incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.gadgets.xml
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.gadgets.xml?rev=700263&r1=700262&r2=700263&view=diff
==============================================================================
--- incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.gadgets.xml (original)
+++ incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.gadgets.xml Mon Sep 29 14:30:07 2008
@@ -26,7 +26,7 @@
   <!-- If you have your own Guice module(s), put them here as a colon-separated list. -->
   <context-param>
     <param-name>guice-modules</param-name>
-    <param-value>org.apache.shindig.gadgets.servlet.HttpGuiceModule:org.apache.shindig.gadgets.servlet.AuthenticationModule</param-value>
+    <param-value>org.apache.shindig.common.PropertiesModule:org.apache.shindig.gadgets.DefaultGuiceModule:org.apache.shindig.gadgets.servlet.AuthenticationModule:org.apache.shindig.gadgets.oauth.OAuthModule</param-value>
   </context-param>
 
   <listener>

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=700263&r1=700262&r2=700263&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 Mon Sep 29 14:30:07 2008
@@ -26,7 +26,7 @@
   <!-- If you have your own Guice module(s), put them here as a colon-separated list. -->
   <context-param>
     <param-name>guice-modules</param-name>
-    <param-value>org.apache.shindig.social.core.config.SocialApiGuiceModule</param-value>
+    <param-value>org.apache.shindig.common.PropertiesModule:org.apache.shindig.social.core.config.SocialApiGuiceModule</param-value>
   </context-param>
 
   <filter>

Modified: incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.xml?rev=700263&r1=700262&r2=700263&view=diff
==============================================================================
--- incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.xml (original)
+++ incubator/shindig/trunk/java/server/src/main/webapp/WEB-INF/web.xml Mon Sep 29 14:30:07 2008
@@ -27,7 +27,7 @@
   <context-param>
     <param-name>guice-modules</param-name>
     <param-value>
-      org.apache.shindig.gadgets.servlet.HttpGuiceModule:org.apache.shindig.social.core.config.SocialApiGuiceModule
+      org.apache.shindig.common.PropertiesModule:org.apache.shindig.gadgets.DefaultGuiceModule:org.apache.shindig.social.core.config.SocialApiGuiceModule:org.apache.shindig.gadgets.oauth.OAuthModule
     </param-value>
   </context-param>
 

Modified: incubator/shindig/trunk/java/server/src/test/java/org/apache/shindig/server/endtoend/EndToEndServer.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/server/src/test/java/org/apache/shindig/server/endtoend/EndToEndServer.java?rev=700263&r1=700262&r2=700263&view=diff
==============================================================================
--- incubator/shindig/trunk/java/server/src/test/java/org/apache/shindig/server/endtoend/EndToEndServer.java (original)
+++ incubator/shindig/trunk/java/server/src/test/java/org/apache/shindig/server/endtoend/EndToEndServer.java Mon Sep 29 14:30:07 2008
@@ -18,8 +18,10 @@
 package org.apache.shindig.server.endtoend;
 
 import org.apache.shindig.auth.AuthenticationServletFilter;
+import org.apache.shindig.common.PropertiesModule;
 import org.apache.shindig.common.servlet.GuiceServletContextListener;
 import org.apache.shindig.gadgets.DefaultGuiceModule;
+import org.apache.shindig.gadgets.oauth.OAuthModule;
 import org.apache.shindig.gadgets.servlet.ConcatProxyServlet;
 import org.apache.shindig.gadgets.servlet.GadgetRenderingServlet;
 import org.apache.shindig.social.opensocial.service.DataServiceServlet;
@@ -104,7 +106,8 @@
 
     Map<String, String> initParams = Maps.newHashMap();
     String modules = Join
-        .join(":", EndToEndModule.class.getName(), DefaultGuiceModule.class.getName());
+        .join(":", EndToEndModule.class.getName(), DefaultGuiceModule.class.getName(),
+            PropertiesModule.class.getName(), OAuthModule.class.getName());
 
     initParams.put(GuiceServletContextListener.MODULES_ATTRIBUTE, modules);
     context.setInitParams(initParams);

Modified: incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/core/config/SocialApiGuiceModuleTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/core/config/SocialApiGuiceModuleTest.java?rev=700263&r1=700262&r2=700263&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/core/config/SocialApiGuiceModuleTest.java (original)
+++ incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/core/config/SocialApiGuiceModuleTest.java Mon Sep 29 14:30:07 2008
@@ -18,6 +18,7 @@
 package org.apache.shindig.social.core.config;
 
 import org.apache.shindig.auth.AuthenticationHandler;
+import org.apache.shindig.common.PropertiesModule;
 import org.apache.shindig.social.core.oauth.AuthenticationHandlerProvider;
 
 import com.google.inject.Guice;
@@ -34,7 +35,7 @@
 
   @Override public void setUp() throws Exception {
     super.setUp();
-    injector = Guice.createInjector(new SocialApiGuiceModule());
+    injector = Guice.createInjector(new SocialApiGuiceModule(), new PropertiesModule());
   }
 
   /**

Modified: incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/core/oauth/AuthenticationProviderHandlerTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/core/oauth/AuthenticationProviderHandlerTest.java?rev=700263&r1=700262&r2=700263&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/core/oauth/AuthenticationProviderHandlerTest.java (original)
+++ incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/core/oauth/AuthenticationProviderHandlerTest.java Mon Sep 29 14:30:07 2008
@@ -18,6 +18,7 @@
 package org.apache.shindig.social.core.oauth;
 
 import org.apache.shindig.auth.AuthenticationHandler;
+import org.apache.shindig.common.PropertiesModule;
 import org.apache.shindig.social.core.config.SocialApiGuiceModule;
 
 import com.google.inject.AbstractModule;
@@ -39,7 +40,7 @@
    */
   public void testCustomHandler() {
     Injector injector = Guice.createInjector(new SocialApiGuiceModule(),
-        new CustomAuthHandlerProviderModule());
+        new CustomAuthHandlerProviderModule(), new PropertiesModule());
 
     AuthenticationHandlerProvider provider = injector.getInstance(
         AuthenticationHandlerProvider.class);