You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rave.apache.org by ja...@apache.org on 2011/08/17 09:37:24 UTC

svn commit: r1158549 - in /incubator/rave/trunk/rave-shindig/src: main/java/org/apache/rave/gadgets/oauth/ main/java/org/apache/rave/gadgets/oauth/inject/ main/java/org/apache/rave/gadgets/oauth/model/ main/java/org/apache/rave/gadgets/oauth/repository...

Author: jasha
Date: Wed Aug 17 07:37:23 2011
New Revision: 1158549

URL: http://svn.apache.org/viewvc?rev=1158549&view=rev
Log:
RAVE-193 Use 'new' Spring JPA pattern for OAuth persistency

Added:
    incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/
    incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/inject/
    incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/inject/DefaultOAuthStore.java
    incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/inject/OAuthGuiceModule.java
    incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/model/
    incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/model/OAuthConsumerStore.java
    incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/model/OAuthTokenInfo.java
    incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/repository/
    incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/repository/OAuthConsumerStoreRepository.java
    incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/repository/OAuthTokenInfoRepository.java
    incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/repository/impl/
    incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/repository/impl/JpaOAuthConsumerStoreRepository.java
    incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/repository/impl/JpaOAuthTokenInfoRepository.java
    incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/service/
    incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/service/OAuthConsumerStoreService.java
    incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/service/OAuthTokenInfoService.java
    incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/service/impl/
    incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/service/impl/DefaultOAuthConsumerStoreService.java
    incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/service/impl/DefaultOAuthTokenInfoService.java
    incubator/rave/trunk/rave-shindig/src/test/java/org/apache/rave/gadgets/
    incubator/rave/trunk/rave-shindig/src/test/java/org/apache/rave/gadgets/oauth/
    incubator/rave/trunk/rave-shindig/src/test/java/org/apache/rave/gadgets/oauth/inject/
    incubator/rave/trunk/rave-shindig/src/test/java/org/apache/rave/gadgets/oauth/inject/DefaultOAuthStoreTest.java
    incubator/rave/trunk/rave-shindig/src/test/java/org/apache/rave/gadgets/oauth/repository/
    incubator/rave/trunk/rave-shindig/src/test/java/org/apache/rave/gadgets/oauth/repository/JpaOAuthConsumerStoreRepositoryTest.java
    incubator/rave/trunk/rave-shindig/src/test/java/org/apache/rave/gadgets/oauth/repository/JpaOAuthTokenInfoRepositoryTest.java
    incubator/rave/trunk/rave-shindig/src/test/java/org/apache/rave/gadgets/oauth/service/
    incubator/rave/trunk/rave-shindig/src/test/java/org/apache/rave/gadgets/oauth/service/DefaultOAuthConsumerStoreServiceTest.java
    incubator/rave/trunk/rave-shindig/src/test/java/org/apache/rave/gadgets/oauth/service/DefaultOAuthTokenInfoServiceTest.java
Removed:
    incubator/rave/trunk/rave-shindig/src/main/java/org/apache/shindig/gadgets/oauth/
    incubator/rave/trunk/rave-shindig/src/test/java/org/apache/shindig/gadgets/oauth/
Modified:
    incubator/rave/trunk/rave-shindig/src/main/resources/META-INF/persistence.xml
    incubator/rave/trunk/rave-shindig/src/main/resources/modules-context.xml
    incubator/rave/trunk/rave-shindig/src/main/resources/rave.shindig.properties
    incubator/rave/trunk/rave-shindig/src/main/resources/spring-context.xml
    incubator/rave/trunk/rave-shindig/src/test/resources/META-INF/persistence.xml
    incubator/rave/trunk/rave-shindig/src/test/resources/test_data.sql

Added: incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/inject/DefaultOAuthStore.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/inject/DefaultOAuthStore.java?rev=1158549&view=auto
==============================================================================
--- incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/inject/DefaultOAuthStore.java (added)
+++ incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/inject/DefaultOAuthStore.java Wed Aug 17 07:37:23 2011
@@ -0,0 +1,186 @@
+/*
+ * 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.rave.gadgets.oauth.inject;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import net.oauth.OAuth;
+import net.oauth.OAuthConsumer;
+import net.oauth.OAuthServiceProvider;
+import net.oauth.signature.RSA_SHA1;
+import org.apache.commons.io.IOUtils;
+import org.apache.rave.gadgets.oauth.model.OAuthConsumerStore;
+import org.apache.rave.gadgets.oauth.model.OAuthTokenInfo;
+import org.apache.rave.gadgets.oauth.service.OAuthConsumerStoreService;
+import org.apache.rave.gadgets.oauth.service.OAuthTokenInfoService;
+import org.apache.shindig.auth.SecurityToken;
+import org.apache.shindig.gadgets.GadgetException;
+import org.apache.shindig.gadgets.oauth.BasicOAuthStore;
+import org.apache.shindig.gadgets.oauth.BasicOAuthStoreConsumerKeyAndSecret;
+import org.apache.shindig.gadgets.oauth.OAuthStore;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.ClassPathResource;
+
+/**
+ * {@link OAuthStore} that retrieves the consumer_key, consumer_secret and key_type from the database
+ * <p/>
+ * Usage scenario: Rave OpenSocial container is the oauth consumer
+ * (oauth data are stored elsewhere, this container tries to fetch data from e.g. Google)
+ */
+public class DefaultOAuthStore implements OAuthStore {
+
+    @Autowired
+    private OAuthConsumerStoreService consumerStoreService;
+
+    @Autowired
+    private OAuthTokenInfoService tokenInfoService;
+
+    /**
+     * Callback to use when no per-key callback URL is found.
+     */
+    private String defaultCallbackUrl;
+
+    /*
+    * Private key for signing the RSH_PRIVATE oauth requests
+    */
+    private BasicOAuthStoreConsumerKeyAndSecret defaultKey;
+
+    public DefaultOAuthStore(String defaultCallbackUrl,
+                             String pathToPrivateKey,
+                             String privateKeyName) throws IOException {
+        this.defaultCallbackUrl = defaultCallbackUrl;
+        this.defaultKey = loadDefaultKey(pathToPrivateKey, privateKeyName);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public ConsumerInfo getConsumerKeyAndSecret(SecurityToken securityToken, String serviceName,
+                                                OAuthServiceProvider provider) throws GadgetException {
+        String gadgetUri = securityToken.getAppUrl();
+        OAuthConsumerStore consumerStore = consumerStoreService.findByUriAndServiceName(gadgetUri, serviceName);
+        if (consumerStore == null) {
+            return null;
+        }
+        OAuthConsumer consumer = createOAuthConsumer(provider, consumerStore);
+        String callbackUrl = (consumerStore.getCallbackUrl() != null ?
+                consumerStore.getCallbackUrl() : defaultCallbackUrl);
+
+        return new ConsumerInfo(consumer, consumerStore.getKeyName(), callbackUrl);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public TokenInfo getTokenInfo(SecurityToken securityToken, ConsumerInfo consumerInfo, String serviceName,
+                                  String tokenName) throws GadgetException {
+        OAuthTokenInfo oAuthTokenInfo = tokenInfoService.findOAuthTokenInfo(
+                securityToken.getViewerId(), securityToken.getAppUrl(),
+                OAuthTokenInfo.MODULE_ID, tokenName, serviceName);
+        if (oAuthTokenInfo == null) {
+            return null;
+        }
+
+        return new TokenInfo(oAuthTokenInfo.getAccessToken(), oAuthTokenInfo.getTokenSecret(),
+                oAuthTokenInfo.getSessionHandle(), oAuthTokenInfo.getTokenExpireMillis());
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setTokenInfo(SecurityToken securityToken, ConsumerInfo consumerInfo, String serviceName,
+                             String tokenName, TokenInfo tokenInfo) throws GadgetException {
+        OAuthTokenInfo oAuthTokenInfo = new OAuthTokenInfo(securityToken,
+                serviceName, tokenName, tokenInfo);
+        tokenInfoService.saveOAuthTokenInfo(oAuthTokenInfo);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void removeToken(SecurityToken securityToken, ConsumerInfo consumerInfo, String serviceName,
+                            String tokenName) throws GadgetException {
+        tokenInfoService.deleteOAuthTokenInfo(securityToken.getViewerId(), securityToken.getAppUrl(),
+                OAuthTokenInfo.MODULE_ID, tokenName, serviceName);
+    }
+
+    /**
+     * Creates an {@link OAuthConsumer} based on the OAuth signature method
+     *
+     * @param provider      {@link net.oauth.OAuthServiceProvider}
+     * @param consumerStore {@link OAuthConsumerStore}
+     *                      persistent OAuth consumer keys & secrets
+     * @return {@link OAuthConsumer} if the signature method is supported
+     */
+    private OAuthConsumer createOAuthConsumer(OAuthServiceProvider provider,
+                                              OAuthConsumerStore consumerStore) {
+        String consumerKey = consumerStore.getConsumerKey();
+        String consumerSecret = consumerStore.getConsumerSecret();
+
+        OAuthConsumer consumer;
+        switch (consumerStore.getKeyType()) {
+            case RSA_PRIVATE:
+                consumer = new OAuthConsumer(null, consumerKey, null, provider);
+                // The oauth.net java code has lots of magic. By setting this property
+                // here, code thousands of lines away knows that the consumerSecret
+                // value in the consumer should be treated as
+                // an RSA private key and not an HMAC key.
+                consumer.setProperty(OAuth.OAUTH_SIGNATURE_METHOD, OAuth.RSA_SHA1);
+                consumer.setProperty(RSA_SHA1.PRIVATE_KEY, defaultKey.getConsumerSecret());
+                break;
+            case HMAC_SYMMETRIC:
+                consumer = new OAuthConsumer(null, consumerKey, consumerSecret, provider);
+                consumer.setProperty(OAuth.OAUTH_SIGNATURE_METHOD, OAuth.HMAC_SHA1);
+                break;
+            case PLAINTEXT:
+                consumer = new OAuthConsumer(null, consumerKey, consumerSecret, provider);
+                consumer.setProperty(OAuth.OAUTH_SIGNATURE_METHOD, "PLAINTEXT");
+                break;
+            default:
+                throw new IllegalArgumentException("Cannot handle keytype " +
+                        consumerStore.getKeyType());
+        }
+        return consumer;
+    }
+
+
+    /**
+     * Loads {@link BasicOAuthStoreConsumerKeyAndSecret} needed if there is no specific consumer key and secret
+     *
+     * @param signingKeyFile location of the signing key file on the classpath or filesystem
+     * @param signingKeyName name of the signing key file
+     * @return RSA_PRIVATE key and secret read from the classpath or file system
+     * @throws java.io.IOException if the file cannot be read
+     */
+    static BasicOAuthStoreConsumerKeyAndSecret loadDefaultKey(
+            String signingKeyFile, String signingKeyName) throws IOException {
+        InputStream inputStream = new ClassPathResource(signingKeyFile).getInputStream();
+        String privateKey = IOUtils.toString(inputStream);
+        privateKey = BasicOAuthStore.convertFromOpenSsl(privateKey);
+        return new BasicOAuthStoreConsumerKeyAndSecret(null, privateKey,
+                BasicOAuthStoreConsumerKeyAndSecret.KeyType.RSA_PRIVATE, signingKeyName, null);
+
+    }
+}

Added: incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/inject/OAuthGuiceModule.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/inject/OAuthGuiceModule.java?rev=1158549&view=auto
==============================================================================
--- incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/inject/OAuthGuiceModule.java (added)
+++ incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/inject/OAuthGuiceModule.java Wed Aug 17 07:37:23 2011
@@ -0,0 +1,49 @@
+/*
+ * 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.rave.gadgets.oauth.inject;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.name.Names;
+import org.apache.shindig.common.crypto.BlobCrypter;
+import org.apache.shindig.gadgets.oauth.OAuthFetcherConfig;
+import org.apache.shindig.gadgets.oauth.OAuthModule;
+import org.apache.shindig.gadgets.oauth.OAuthRequest;
+
+/**
+ * Replacement for the {@link org.apache.shindig.gadgets.oauth.OAuthModule}.
+ * We can't extend {@link org.apache.shindig.gadgets.oauth.OAuthModule} and call
+ * super.configure, because Guice does not permit bindig the same thing twice.
+ * Therefore some duplicate code, but at least no changes in
+ * {@link org.apache.shindig.gadgets.oauth.OAuthModule}
+ * <p/>
+ * OAuthStore is bound to DefaultOAuthStore using Spring
+ */
+public class OAuthGuiceModule extends AbstractModule {
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void configure() {
+        bind(BlobCrypter.class).annotatedWith(Names.named(OAuthFetcherConfig.OAUTH_STATE_CRYPTER))
+                .toProvider(OAuthModule.OAuthCrypterProvider.class);
+        bind(OAuthRequest.class).toProvider(OAuthModule.OAuthRequestProvider.class);
+    }
+}

Added: incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/model/OAuthConsumerStore.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/model/OAuthConsumerStore.java?rev=1158549&view=auto
==============================================================================
--- incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/model/OAuthConsumerStore.java (added)
+++ incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/model/OAuthConsumerStore.java Wed Aug 17 07:37:23 2011
@@ -0,0 +1,245 @@
+/*
+ * 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.rave.gadgets.oauth.model;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+
+import org.apache.rave.persistence.BasicEntity;
+
+/**
+ * Persistent store for OAuth consumer key & secrets.
+ * Equivalent of:
+ * <pre>
+ * {
+ *    "http://localhost:8080/samplecontainer/examples/oauth.xml" : {
+ *      "" : {
+ *          "consumer_key" : "gadgetConsumer",
+ *          "consumer_secret" : "gadgetSecret",
+ *          "key_type" : "HMAC_SYMMETRIC"
+ *      }
+ *  },
+ *   "http://localhost:8080/samplecontainer/examples/shindigoauth.xml" : {
+ *      "shindig" : {
+ *          "consumer_key" : "http://localhost:8080/samplecontainer/examples/shindigoauth.xml",
+ *          "consumer_secret" : "secret",
+ *          "key_type" : "HMAC_SYMMETRIC"
+ *      }
+ *  }
+ * }
+ * </pre>
+ */
+@Entity
+@Table(name = "oauth_consumer_store",
+        uniqueConstraints = @UniqueConstraint(columnNames = {"gadget_uri", "service_name"}))
+@SequenceGenerator(name = "consumerStoreSeqId", sequenceName = "consumer_store_id_seq")
+@NamedQueries(value = {
+        @NamedQuery(name = OAuthConsumerStore.FIND_BY_URI_AND_SERVICE_NAME,
+                query = "SELECT cs FROM OAuthConsumerStore cs WHERE cs.gadgetUri = :gadgetUriParam AND cs.serviceName = :serviceNameParam")
+        })
+public class OAuthConsumerStore implements BasicEntity {
+
+    public static final String FIND_BY_URI_AND_SERVICE_NAME = "OAuthConsumerStore.findByUriAndServiceName";
+    public static final String GADGET_URI_PARAM = "gadgetUriParam";
+    public static final String SERVICE_NAME_PARAM = "serviceNameParam";
+    private static final int HASH_START = 7;
+    private static final int HASH_INCREASE = 67;
+
+    /**
+     * enum of KeyType's
+     */
+    public static enum KeyType {
+        HMAC_SYMMETRIC, RSA_PRIVATE, PLAINTEXT
+    }
+
+    /**
+     * The internal object ID used for references to this object. Should be generated
+     * by the underlying storage mechanism
+     */
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "consumerStoreSeqId")
+    @Column(name = "id")
+    private Long id;
+
+    /**
+     * URI where the gadget is hosted, e.g. http://www.example.com/mygadget.xml
+     */
+    @Column(name = "gadget_uri", length = 512)
+    private String gadgetUri;
+
+    /**
+     * Name of the oAuth service, matches /Module/ModulePrefs/OAuth/Service/@name
+     * in a gadget definition
+     */
+    @Column(name = "service_name")
+    private String serviceName;
+
+
+    /**
+     * Value for oauth_consumer_key
+     */
+    @Column(name = "consumer_key")
+    private String consumerKey;
+
+    /**
+     * HMAC secret, or RSA private key, depending on KeyType
+     */
+    @Column(name = "consumer_secret")
+    private String consumerSecret;
+
+    /**
+     * Type of key, also known as "OAuth signature method"
+     */
+    @Enumerated(value = EnumType.STRING)
+    @Column(name = "key_type")
+    private KeyType keyType;
+
+    /**
+     * Name of public key to use with xoauth_public_key parameter.
+     * May be {@literal null}.
+     */
+    @Column(name = "key_name")
+    private String keyName;
+
+    /**
+     * Callback URL associated with this consumer key
+     * May be {@literal null}.
+     */
+    @Column(name = "callback_url")
+    private String callbackUrl;
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Long getId() {
+        return id;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getGadgetUri() {
+        return gadgetUri;
+    }
+
+    public void setGadgetUri(String gadgetUri) {
+        this.gadgetUri = gadgetUri;
+    }
+
+    public String getServiceName() {
+        return serviceName;
+    }
+
+    public void setServiceName(String serviceName) {
+        this.serviceName = serviceName;
+    }
+
+    public String getConsumerKey() {
+        return consumerKey;
+    }
+
+    public void setConsumerKey(String consumerKey) {
+        this.consumerKey = consumerKey;
+    }
+
+    public String getConsumerSecret() {
+        return consumerSecret;
+    }
+
+    public void setConsumerSecret(String consumerSecret) {
+        this.consumerSecret = consumerSecret;
+    }
+
+    public KeyType getKeyType() {
+        return keyType;
+    }
+
+    public void setKeyType(KeyType keyType) {
+        this.keyType = keyType;
+    }
+
+    public String getKeyName() {
+        return keyName;
+    }
+
+    public void setKeyName(String keyName) {
+        this.keyName = keyName;
+    }
+
+    public String getCallbackUrl() {
+        return callbackUrl;
+    }
+
+    public void setCallbackUrl(String callbackUrl) {
+        this.callbackUrl = callbackUrl;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final OAuthConsumerStore other = (OAuthConsumerStore) obj;
+        if (this.id != other.id && (this.id == null || !this.id.equals(other.id))) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = HASH_START;
+        hash = HASH_INCREASE * hash + (this.id != null ? this.id.hashCode() : 0);
+        return hash;
+    }
+
+    @Override
+    public String toString() {
+        return "OAuthConsumerStore{" +
+                "id=" + id +
+                ", gadgetUri='" + gadgetUri + '\'' +
+                ", serviceName='" + serviceName + '\'' +
+                ", consumerKey='" + consumerKey + '\'' +
+                ", consumerSecret='" + consumerSecret + '\'' +
+                ", keyType=" + keyType +
+                ", keyName='" + keyName + '\'' +
+                ", callbackUrl='" + callbackUrl + '\'' +
+                '}';
+    }
+}

Added: incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/model/OAuthTokenInfo.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/model/OAuthTokenInfo.java?rev=1158549&view=auto
==============================================================================
--- incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/model/OAuthTokenInfo.java (added)
+++ incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/model/OAuthTokenInfo.java Wed Aug 17 07:37:23 2011
@@ -0,0 +1,259 @@
+/*
+ * 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.rave.gadgets.oauth.model;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+
+import org.apache.rave.persistence.BasicEntity;
+import org.apache.shindig.auth.SecurityToken;
+import org.apache.shindig.gadgets.oauth.OAuthStore;
+
+/**
+ * Bean for OAuth security TokenInfo
+ */
+@Entity
+@Table(name = "oauth_token_info")
+@SequenceGenerator(name = "tokenInfoIdSeq", sequenceName = "token_info_id_seq")
+@NamedQueries(value = {
+        @NamedQuery(name = OAuthTokenInfo.FIND_OAUTH_TOKEN_INFO,
+                query = "SELECT ti FROM OAuthTokenInfo ti WHERE ti.userId = :userIdParam AND ti.appUrl = :appUrlParam AND ti.moduleId = :moduleIdParam AND ti.tokenName = :tokenNameParam AND ti.serviceName = :serviceNameParam")
+})
+public class OAuthTokenInfo implements BasicEntity {
+
+    /**
+     * @see {@link org.apache.shindig.social.core.oauth.OAuthSecurityToken#getModuleId()}
+     */
+    public static final String MODULE_ID = "NOT_USED";
+
+    /**
+     * Named query identifier to find {@link OAuthTokenInfo}
+     */
+    public static final String FIND_OAUTH_TOKEN_INFO = "OAuthTokenInfo.findOAuthTokenInfo";
+
+    /**
+     * Query param for user id
+     */
+    public static final String USER_ID_PARAM = "userIdParam";
+
+    /**
+     * Query param for the app url
+     */
+    public static final String APP_URL_PARAM = "appUrlParam";
+
+    /**
+     * Identifier of the module. In case of Shindig, use {@link #MODULE_ID}
+     */
+    public static final String MODULE_ID_PARAM = "moduleIdParam";
+
+    /**
+     * Name of the Token
+     */
+    public static final String TOKEN_NAME_PARAM = "tokenNameParam";
+
+    /**
+     * Name of the OAuth service
+     */
+    public static final String SERVICE_NAME_PARAM = "serviceNameParam";
+
+    private static final int HASH_START = 7;
+    private static final int HASH_INCREASE = 67;
+
+    /**
+     * The internal object ID used for references to this object. Should be generated
+     * by the underlying storage mechanism
+     */
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "tokenInfoIdSeq")
+    @Column(name = "id")
+    private Long id;
+
+    @Column(name = "access_token")
+    private String accessToken;
+
+    @Column(name = "token_secret")
+    private String tokenSecret;
+
+    @Column(name = "session_handle")
+    private String sessionHandle;
+
+    @Column(name = "token_expire_millis")
+    private long tokenExpireMillis;
+
+    @Column(name = "app_url")
+    private String appUrl;
+
+    @Column(name = "module_id")
+    private String moduleId;
+
+    @Column(name = "service_name")
+    private String serviceName;
+
+    @Column(name = "token_name")
+    private String tokenName;
+
+    @Column(name = "user_id")
+    private String userId;
+
+
+    public OAuthTokenInfo() {
+        super();
+    }
+
+    public OAuthTokenInfo(SecurityToken securityToken, String serviceName,
+                          String tokenName, OAuthStore.TokenInfo tokenInfo) {
+        this.setAccessToken(tokenInfo.getAccessToken());
+        this.setAppUrl(securityToken.getAppUrl());
+        this.setModuleId(MODULE_ID);
+        this.setServiceName(serviceName);
+        this.setSessionHandle(tokenInfo.getSessionHandle());
+        this.setTokenExpireMillis(tokenInfo.getTokenExpireMillis());
+        this.setTokenName(tokenName);
+        this.setTokenSecret(tokenInfo.getTokenSecret());
+        this.setUserId(securityToken.getViewerId());
+    }
+
+    @Override
+    public Long getId() {
+        return id;
+    }
+
+    @Override
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getAccessToken() {
+        return accessToken;
+    }
+
+    public void setAccessToken(String accessToken) {
+        this.accessToken = accessToken;
+    }
+
+    public String getTokenSecret() {
+        return tokenSecret;
+    }
+
+    public void setTokenSecret(String tokenSecret) {
+        this.tokenSecret = tokenSecret;
+    }
+
+    public String getSessionHandle() {
+        return sessionHandle;
+    }
+
+    public void setSessionHandle(String sessionHandle) {
+        this.sessionHandle = sessionHandle;
+    }
+
+    public long getTokenExpireMillis() {
+        return tokenExpireMillis;
+    }
+
+    public void setTokenExpireMillis(long tokenExpireMillis) {
+        this.tokenExpireMillis = tokenExpireMillis;
+    }
+
+    public String getAppUrl() {
+        return appUrl;
+    }
+
+    public void setAppUrl(String appUrl) {
+        this.appUrl = appUrl;
+    }
+
+    public String getModuleId() {
+        return moduleId;
+    }
+
+    public void setModuleId(String moduleId) {
+        this.moduleId = moduleId;
+    }
+
+    public String getServiceName() {
+        return serviceName;
+    }
+
+    public void setServiceName(String serviceName) {
+        this.serviceName = serviceName;
+    }
+
+    public String getTokenName() {
+        return tokenName;
+    }
+
+    public void setTokenName(String tokenName) {
+        this.tokenName = tokenName;
+    }
+
+    public String getUserId() {
+        return userId;
+    }
+
+    public void setUserId(String userId) {
+        this.userId = userId;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final OAuthTokenInfo other = (OAuthTokenInfo) obj;
+        if (this.id != other.id && (this.id == null || !this.id.equals(other.id))) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = HASH_START;
+        hash = HASH_INCREASE * hash + (this.id != null ? this.id.hashCode() : 0);
+        return hash;
+    }
+
+    @Override
+    public String toString() {
+        return "OAuthTokenInfo{" +
+                "id=" + id +
+                ", accessToken='" + accessToken + '\'' +
+                ", tokenSecret='" + tokenSecret + '\'' +
+                ", sessionHandle='" + sessionHandle + '\'' +
+                ", tokenExpireMillis=" + tokenExpireMillis +
+                ", appUrl='" + appUrl + '\'' +
+                ", moduleId='" + moduleId + '\'' +
+                ", serviceName='" + serviceName + '\'' +
+                ", tokenName='" + tokenName + '\'' +
+                ", userId='" + userId + '\'' +
+                '}';
+    }
+}

Added: incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/repository/OAuthConsumerStoreRepository.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/repository/OAuthConsumerStoreRepository.java?rev=1158549&view=auto
==============================================================================
--- incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/repository/OAuthConsumerStoreRepository.java (added)
+++ incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/repository/OAuthConsumerStoreRepository.java Wed Aug 17 07:37:23 2011
@@ -0,0 +1,38 @@
+/*
+ * 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.rave.gadgets.oauth.repository;
+
+import org.apache.rave.gadgets.oauth.model.OAuthConsumerStore;
+import org.apache.rave.persistence.Repository;
+
+/**
+ * Repository interface for {@link OAuthConsumerStore}
+ */
+public interface OAuthConsumerStoreRepository extends Repository<OAuthConsumerStore> {
+
+    /**
+     * Fetches {@link OAuthConsumerStore} based on the gadget location and the service provider
+     *
+     * @param gadgetUri   location of the gadget definition
+     * @param serviceName name of the service provider
+     * @return {@link OAuthConsumerStore} or {@literal null} if none matches the criteria
+     */
+    public OAuthConsumerStore findByUriAndServiceName(String gadgetUri, String serviceName);
+}

Added: incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/repository/OAuthTokenInfoRepository.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/repository/OAuthTokenInfoRepository.java?rev=1158549&view=auto
==============================================================================
--- incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/repository/OAuthTokenInfoRepository.java (added)
+++ incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/repository/OAuthTokenInfoRepository.java Wed Aug 17 07:37:23 2011
@@ -0,0 +1,43 @@
+/*
+ * 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.rave.gadgets.oauth.repository;
+
+import org.apache.rave.gadgets.oauth.model.OAuthTokenInfo;
+import org.apache.rave.persistence.Repository;
+
+/**
+ * Interface for handling {@link OAuthTokenInfo} queries
+ */
+public interface OAuthTokenInfoRepository extends Repository<OAuthTokenInfo> {
+
+    /**
+     * Retrieves {@link OAuthTokenInfo}
+     *
+     * @param userId      unique identifier of gadget viewer
+     * @param appUrl      URL of the gadget
+     * @param moduleId    the module ID of the application
+     * @param tokenName   gadget's nickname for the token to use
+     * @param serviceName name of the service provider
+     * @return {@link OAuthTokenInfo} or {@literal null} if none matches the criteria
+     */
+    public OAuthTokenInfo findOAuthTokenInfo(String userId, String appUrl, String moduleId,
+                                             String tokenName, String serviceName);
+
+}

Added: incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/repository/impl/JpaOAuthConsumerStoreRepository.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/repository/impl/JpaOAuthConsumerStoreRepository.java?rev=1158549&view=auto
==============================================================================
--- incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/repository/impl/JpaOAuthConsumerStoreRepository.java (added)
+++ incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/repository/impl/JpaOAuthConsumerStoreRepository.java Wed Aug 17 07:37:23 2011
@@ -0,0 +1,59 @@
+/*
+ * 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.rave.gadgets.oauth.repository.impl;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.TypedQuery;
+
+import org.apache.rave.gadgets.oauth.model.OAuthConsumerStore;
+import org.apache.rave.gadgets.oauth.repository.OAuthConsumerStoreRepository;
+import org.apache.rave.persistence.jpa.AbstractJpaRepository;
+import org.springframework.stereotype.Repository;
+
+import static org.apache.rave.persistence.jpa.util.JpaUtil.getSingleResult;
+
+/**
+ * JPA implementation for {@link OAuthConsumerStoreRepository}
+ */
+@Repository
+public class JpaOAuthConsumerStoreRepository extends AbstractJpaRepository<OAuthConsumerStore>
+        implements OAuthConsumerStoreRepository {
+
+    @PersistenceContext
+    private EntityManager manager;
+
+
+    public JpaOAuthConsumerStoreRepository() {
+        super(OAuthConsumerStore.class);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public OAuthConsumerStore findByUriAndServiceName(String gadgetUri, String serviceName) {
+        TypedQuery<OAuthConsumerStore> query = manager.createNamedQuery(
+                OAuthConsumerStore.FIND_BY_URI_AND_SERVICE_NAME, OAuthConsumerStore.class);
+        query.setParameter(OAuthConsumerStore.GADGET_URI_PARAM, gadgetUri);
+        query.setParameter(OAuthConsumerStore.SERVICE_NAME_PARAM, serviceName);
+        return getSingleResult(query.getResultList());
+    }
+}

Added: incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/repository/impl/JpaOAuthTokenInfoRepository.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/repository/impl/JpaOAuthTokenInfoRepository.java?rev=1158549&view=auto
==============================================================================
--- incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/repository/impl/JpaOAuthTokenInfoRepository.java (added)
+++ incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/repository/impl/JpaOAuthTokenInfoRepository.java Wed Aug 17 07:37:23 2011
@@ -0,0 +1,63 @@
+/*
+ * 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.rave.gadgets.oauth.repository.impl;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.TypedQuery;
+
+import org.apache.rave.gadgets.oauth.model.OAuthTokenInfo;
+import org.apache.rave.gadgets.oauth.repository.OAuthTokenInfoRepository;
+import org.apache.rave.persistence.jpa.AbstractJpaRepository;
+import org.springframework.stereotype.Repository;
+
+import static org.apache.rave.persistence.jpa.util.JpaUtil.getSingleResult;
+
+/**
+ * JPA implementation for {@link OAuthTokenInfoRepository}
+ */
+@Repository
+public class JpaOAuthTokenInfoRepository extends AbstractJpaRepository<OAuthTokenInfo>
+        implements OAuthTokenInfoRepository {
+
+    @PersistenceContext
+    private EntityManager manager;
+
+    public JpaOAuthTokenInfoRepository() {
+        super(OAuthTokenInfo.class);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public OAuthTokenInfo findOAuthTokenInfo(String userId, String appUrl, String moduleId,
+                                             String tokenName, String serviceName) {
+        TypedQuery<OAuthTokenInfo> query = manager.createNamedQuery(OAuthTokenInfo.FIND_OAUTH_TOKEN_INFO,
+                OAuthTokenInfo.class);
+        query.setParameter(OAuthTokenInfo.USER_ID_PARAM, userId);
+        query.setParameter(OAuthTokenInfo.APP_URL_PARAM, appUrl);
+        query.setParameter(OAuthTokenInfo.MODULE_ID_PARAM, moduleId);
+        query.setParameter(OAuthTokenInfo.TOKEN_NAME_PARAM, tokenName);
+        query.setParameter(OAuthTokenInfo.SERVICE_NAME_PARAM, serviceName);
+        return getSingleResult(query.getResultList());
+    }
+
+}

Added: incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/service/OAuthConsumerStoreService.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/service/OAuthConsumerStoreService.java?rev=1158549&view=auto
==============================================================================
--- incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/service/OAuthConsumerStoreService.java (added)
+++ incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/service/OAuthConsumerStoreService.java Wed Aug 17 07:37:23 2011
@@ -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.rave.gadgets.oauth.service;
+
+import org.apache.rave.gadgets.oauth.model.OAuthConsumerStore;
+
+/**
+ * Service to handle OAuth Consumer store
+ */
+public interface OAuthConsumerStoreService {
+
+    /**
+     * Fetches {@link OAuthConsumerStore} based on the gadget location and the service provider
+     *
+     * @param gadgetUri   location of the gadget definition
+     * @param serviceName name of the service provider
+     * @return {@link OAuthConsumerStore} or {@literal null} if none matches the criteria
+     */
+    public OAuthConsumerStore findByUriAndServiceName(String gadgetUri, String serviceName);
+
+    /**
+     * Persists {@link OAuthConsumerStore}
+     *
+     * @param oAuthConsumerStore {@link OAuthConsumerStore} to store
+     * @return persisted {@link OAuthConsumerStore}
+     */
+
+    public OAuthConsumerStore save(OAuthConsumerStore oAuthConsumerStore);
+
+    /**
+     * Removes the {@link OAuthConsumerStore} from the database
+     *
+     * @param oAuthConsumerStore {@link OAuthConsumerStore} to delete
+     */
+    public void delete(OAuthConsumerStore oAuthConsumerStore);
+}

Added: incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/service/OAuthTokenInfoService.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/service/OAuthTokenInfoService.java?rev=1158549&view=auto
==============================================================================
--- incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/service/OAuthTokenInfoService.java (added)
+++ incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/service/OAuthTokenInfoService.java Wed Aug 17 07:37:23 2011
@@ -0,0 +1,61 @@
+/*
+ * 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.rave.gadgets.oauth.service;
+
+import org.apache.rave.gadgets.oauth.model.OAuthTokenInfo;
+
+/**
+ * Service to handle OAuth Tokens
+ */
+public interface OAuthTokenInfoService {
+    /**
+     * Retrieves {@link OAuthTokenInfo}
+     *
+     * @param userId      unique identifier of gadget viewer
+     * @param appUrl      URL of the gadget
+     * @param moduleId    the module ID of the application
+     * @param tokenName   gadget's nickname for the token to use
+     * @param serviceName name of the service provider
+     * @return {@link OAuthTokenInfo} or {@literal null} if none matches the criteria
+     */
+    public OAuthTokenInfo findOAuthTokenInfo(String userId, String appUrl, String moduleId,
+                                             String tokenName, String serviceName);
+
+    /**
+     * Persists the {@link OAuthTokenInfo} to the data store
+     *
+     * @param tokenInfo {@link OAuthTokenInfo} to save
+     * @return persisted OAuthTokenInfo
+     */
+    OAuthTokenInfo saveOAuthTokenInfo(OAuthTokenInfo tokenInfo);
+
+    /**
+     * Removes the {@link OAuthTokenInfo}'s that match the criteria from the data store
+     *
+     * @param userId      unique identifier of the gadget viewer
+     * @param appUrl      URL of the gadget
+     * @param moduleId    the module ID of the application
+     * @param tokenName   gadget's nickname for the token to use
+     * @param serviceName name of the service provider
+     */
+    void deleteOAuthTokenInfo(String userId, String appUrl, String moduleId,
+                              String tokenName, String serviceName);
+
+}

Added: incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/service/impl/DefaultOAuthConsumerStoreService.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/service/impl/DefaultOAuthConsumerStoreService.java?rev=1158549&view=auto
==============================================================================
--- incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/service/impl/DefaultOAuthConsumerStoreService.java (added)
+++ incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/service/impl/DefaultOAuthConsumerStoreService.java Wed Aug 17 07:37:23 2011
@@ -0,0 +1,64 @@
+/*
+ * 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.rave.gadgets.oauth.service.impl;
+
+import org.apache.rave.gadgets.oauth.model.OAuthConsumerStore;
+import org.apache.rave.gadgets.oauth.repository.OAuthConsumerStoreRepository;
+import org.apache.rave.gadgets.oauth.service.OAuthConsumerStoreService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * JPA implementation for {@link OAuthConsumerStoreService}
+ */
+@Service
+public class DefaultOAuthConsumerStoreService implements OAuthConsumerStoreService {
+
+    private OAuthConsumerStoreRepository repository;
+
+    @Autowired
+    public DefaultOAuthConsumerStoreService(OAuthConsumerStoreRepository repository) {
+        this.repository = repository;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public OAuthConsumerStore findByUriAndServiceName(String gadgetUri, String serviceName) {
+        return repository.findByUriAndServiceName(gadgetUri, serviceName);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public OAuthConsumerStore save(OAuthConsumerStore oAuthConsumerStore) {
+        return repository.save(oAuthConsumerStore);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void delete(OAuthConsumerStore oAuthConsumerStore) {
+        repository.delete(oAuthConsumerStore);
+    }
+}

Added: incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/service/impl/DefaultOAuthTokenInfoService.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/service/impl/DefaultOAuthTokenInfoService.java?rev=1158549&view=auto
==============================================================================
--- incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/service/impl/DefaultOAuthTokenInfoService.java (added)
+++ incubator/rave/trunk/rave-shindig/src/main/java/org/apache/rave/gadgets/oauth/service/impl/DefaultOAuthTokenInfoService.java Wed Aug 17 07:37:23 2011
@@ -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.rave.gadgets.oauth.service.impl;
+
+import org.apache.rave.gadgets.oauth.model.OAuthTokenInfo;
+import org.apache.rave.gadgets.oauth.repository.OAuthTokenInfoRepository;
+import org.apache.rave.gadgets.oauth.service.OAuthTokenInfoService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * Implementation of {@link OAuthTokenInfoService}
+ */
+@Service
+public class DefaultOAuthTokenInfoService implements OAuthTokenInfoService {
+    private final OAuthTokenInfoRepository repository;
+
+    @Autowired
+    public DefaultOAuthTokenInfoService(OAuthTokenInfoRepository repository) {
+        this.repository = repository;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public OAuthTokenInfo findOAuthTokenInfo(String userId, String appUrl, String moduleId,
+                                             String tokenName, String serviceName) {
+        return repository.findOAuthTokenInfo(userId, appUrl, moduleId, tokenName, serviceName);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public OAuthTokenInfo saveOAuthTokenInfo(OAuthTokenInfo tokenInfo) {
+        return repository.save(tokenInfo);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void deleteOAuthTokenInfo(String userId, String appUrl, String moduleId, String tokenName,
+                                     String serviceName) {
+        final OAuthTokenInfo oAuthTokenInfo =
+                findOAuthTokenInfo(userId, appUrl, moduleId, tokenName, serviceName);
+        if (oAuthTokenInfo != null) {
+            repository.delete(oAuthTokenInfo);
+        }
+    }
+}

Modified: incubator/rave/trunk/rave-shindig/src/main/resources/META-INF/persistence.xml
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-shindig/src/main/resources/META-INF/persistence.xml?rev=1158549&r1=1158548&r2=1158549&view=diff
==============================================================================
--- incubator/rave/trunk/rave-shindig/src/main/resources/META-INF/persistence.xml (original)
+++ incubator/rave/trunk/rave-shindig/src/main/resources/META-INF/persistence.xml Wed Aug 17 07:37:23 2011
@@ -23,8 +23,6 @@
   version="2.0">
   <persistence-unit name="raveShindigPersistenceUnit" transaction-type="RESOURCE_LOCAL">
       <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
-      <class>org.apache.shindig.gadgets.oauth.model.OAuthConsumerStoreDb</class>
-      <class>org.apache.shindig.gadgets.oauth.model.OAuthTokenInfoDb</class>
       <class>org.apache.rave.opensocial.model.Person</class>
       <class>org.apache.rave.opensocial.model.Account</class>
       <class>org.apache.rave.opensocial.model.Address</class>
@@ -36,6 +34,8 @@
       <class>org.apache.rave.opensocial.model.PersonProperty</class>
       <class>org.apache.rave.opensocial.model.PersonAssociation</class>
       <class>org.apache.rave.opensocial.model.Url</class>
+      <class>org.apache.rave.gadgets.oauth.model.OAuthTokenInfo</class>
+      <class>org.apache.rave.gadgets.oauth.model.OAuthConsumerStore</class>
 
       <class>org.apache.shindig.social.opensocial.jpa.ApplicationDb</class>
       <class>org.apache.shindig.social.opensocial.jpa.OrganizationDb</class>
@@ -45,9 +45,7 @@
       <class>org.apache.shindig.social.opensocial.jpa.MessageDb</class>
       <class>org.apache.shindig.social.opensocial.jpa.ImDb</class>
       <class>org.apache.shindig.social.opensocial.jpa.AccountDb</class>
-      <class>org.apache.shindig.gadgets.oauth.model.OAuthConsumerStoreDb</class>
       <class>org.apache.shindig.social.opensocial.jpa.ActivityTemplateParamsDb</class>
-      <class>org.apache.shindig.gadgets.oauth.model.OAuthTokenInfoDb</class>
       <class>org.apache.shindig.social.opensocial.jpa.PersonAddressDb</class>
       <class>org.apache.shindig.social.opensocial.jpa.GroupDb</class>
       <class>org.apache.shindig.social.opensocial.jpa.ActivityDb</class>

Modified: incubator/rave/trunk/rave-shindig/src/main/resources/modules-context.xml
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-shindig/src/main/resources/modules-context.xml?rev=1158549&r1=1158548&r2=1158549&view=diff
==============================================================================
--- incubator/rave/trunk/rave-shindig/src/main/resources/modules-context.xml (original)
+++ incubator/rave/trunk/rave-shindig/src/main/resources/modules-context.xml Wed Aug 17 07:37:23 2011
@@ -25,7 +25,7 @@
     <bean class="org.apache.rave.os.JPAOpenSocialModule" />
     <bean class="org.apache.rave.os.SocialApiGuiceModule" />
     <bean class="org.apache.shindig.auth.ClasspathAwareDefaultSecurityTokenCodec$TemporarySecurityTokenGuiceModule" />
-    <bean class="org.apache.shindig.gadgets.oauth.OAuthModule" />
+    <bean class="org.apache.rave.gadgets.oauth.inject.OAuthGuiceModule"/>
     <bean class="org.apache.shindig.gadgets.DefaultGuiceModule" />
     <bean class="org.apache.shindig.common.cache.ehcache.EhCacheModule" />
     <bean class="org.apache.shindig.sample.shiro.ShiroGuiceModule" />

Modified: incubator/rave/trunk/rave-shindig/src/main/resources/rave.shindig.properties
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-shindig/src/main/resources/rave.shindig.properties?rev=1158549&r1=1158548&r2=1158549&view=diff
==============================================================================
--- incubator/rave/trunk/rave-shindig/src/main/resources/rave.shindig.properties (original)
+++ incubator/rave/trunk/rave-shindig/src/main/resources/rave.shindig.properties Wed Aug 17 07:37:23 2011
@@ -18,3 +18,6 @@
 #
 shindig.spring.base-package=org.apache.rave
 
+shindig.signing.key-name=
+shindig.signing.key-file=
+shindig.signing.global-callback-url=http://localhost:8080/gadgets/oauthcallback
\ No newline at end of file

Modified: incubator/rave/trunk/rave-shindig/src/main/resources/spring-context.xml
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-shindig/src/main/resources/spring-context.xml?rev=1158549&r1=1158548&r2=1158549&view=diff
==============================================================================
--- incubator/rave/trunk/rave-shindig/src/main/resources/spring-context.xml (original)
+++ incubator/rave/trunk/rave-shindig/src/main/resources/spring-context.xml Wed Aug 17 07:37:23 2011
@@ -68,4 +68,10 @@
             </map>
         </property>
     </bean>
+
+  <bean id="oAuthStore" class="org.apache.rave.gadgets.oauth.inject.DefaultOAuthStore">
+    <constructor-arg name="defaultCallbackUrl" value="${shindig.signing.global-callback-url}"/>
+    <constructor-arg name="pathToPrivateKey" value="${shindig.signing.key-file}"/>
+    <constructor-arg name="privateKeyName" value="${shindig.signing.key-name}"/>
+  </bean>
 </beans>

Added: incubator/rave/trunk/rave-shindig/src/test/java/org/apache/rave/gadgets/oauth/inject/DefaultOAuthStoreTest.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-shindig/src/test/java/org/apache/rave/gadgets/oauth/inject/DefaultOAuthStoreTest.java?rev=1158549&view=auto
==============================================================================
--- incubator/rave/trunk/rave-shindig/src/test/java/org/apache/rave/gadgets/oauth/inject/DefaultOAuthStoreTest.java (added)
+++ incubator/rave/trunk/rave-shindig/src/test/java/org/apache/rave/gadgets/oauth/inject/DefaultOAuthStoreTest.java Wed Aug 17 07:37:23 2011
@@ -0,0 +1,130 @@
+/*
+ * 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.rave.gadgets.oauth.inject;
+
+import java.io.IOException;
+import java.util.Date;
+
+import net.oauth.OAuth;
+import net.oauth.OAuthServiceProvider;
+import org.apache.rave.gadgets.oauth.model.OAuthConsumerStore;
+import org.apache.rave.gadgets.oauth.model.OAuthTokenInfo;
+import org.apache.rave.gadgets.oauth.service.OAuthConsumerStoreService;
+import org.apache.rave.gadgets.oauth.service.OAuthTokenInfoService;
+import org.apache.shindig.auth.SecurityToken;
+import org.apache.shindig.gadgets.oauth.BasicOAuthStoreConsumerKeyAndSecret;
+import org.apache.shindig.gadgets.oauth.OAuthStore;
+import org.apache.shindig.social.core.oauth.OAuthSecurityToken;
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.test.util.ReflectionTestUtils;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * Test for {@link DefaultOAuthStore}
+ */
+public class DefaultOAuthStoreTest {
+    private static final long NEXT_HOUR = 1000L * 60L * 60L;
+    private static final String GADGET_URI = "http://localhost:8080/samplecontainer/examples/oauth.xml";
+    private static final String SERVICE_NAME = "testService";
+    private static final String CONSUMER_SECRET = "gadgetSecret";
+
+    private SecurityToken token;
+    private DefaultOAuthStore oAuthStore;
+    private OAuthConsumerStoreService consumerStoreService;
+    private OAuthTokenInfoService tokenInfoService;
+
+    @Test
+    public void testGetConsumerKeyAndSecret() throws Exception {
+        OAuthConsumerStore consumerStore = new OAuthConsumerStore();
+        consumerStore.setGadgetUri(GADGET_URI);
+        consumerStore.setConsumerKey("gadgetConsumer");
+        consumerStore.setConsumerSecret(CONSUMER_SECRET);
+        consumerStore.setKeyType(OAuthConsumerStore.KeyType.HMAC_SYMMETRIC);
+        OAuthServiceProvider provider = new OAuthServiceProvider(null, null, null);
+
+        expect(consumerStoreService.findByUriAndServiceName(GADGET_URI, SERVICE_NAME))
+                .andReturn(consumerStore);
+        replay(consumerStoreService);
+
+        final OAuthStore.ConsumerInfo keyAndSecret =
+                oAuthStore.getConsumerKeyAndSecret(token, SERVICE_NAME, provider);
+        assertNotNull(keyAndSecret);
+        assertEquals(OAuth.HMAC_SHA1, keyAndSecret.getConsumer().getProperty(
+                OAuth.OAUTH_SIGNATURE_METHOD));
+
+        verify(consumerStoreService);
+
+    }
+
+    @Test
+    public void testGetTokenInfo() throws Exception {
+        final String testTokenName = "testTokenName";
+
+        OAuthTokenInfo oAuthTokenInfo = new OAuthTokenInfo();
+        oAuthTokenInfo.setTokenName(testTokenName);
+        oAuthTokenInfo.setTokenSecret(CONSUMER_SECRET);
+        OAuthStore.ConsumerInfo consumerInfo = createMock(OAuthStore.ConsumerInfo.class);
+
+        expect(tokenInfoService.findOAuthTokenInfo(token.getViewerId(), token.getAppUrl(),
+                OAuthTokenInfo.MODULE_ID, testTokenName,
+                SERVICE_NAME)).andReturn(oAuthTokenInfo);
+        replay(tokenInfoService);
+
+        final OAuthStore.TokenInfo tokenInfo = oAuthStore.getTokenInfo(token, consumerInfo,
+                SERVICE_NAME, testTokenName);
+
+        assertNotNull("Got TokenInfo", tokenInfo);
+        assertEquals(CONSUMER_SECRET, tokenInfo.getTokenSecret());
+
+        verify(tokenInfoService);
+    }
+
+    @Test
+    public void testSetTokenInfo() throws Exception {
+        BasicOAuthStoreConsumerKeyAndSecret defaultKey =
+                DefaultOAuthStore.loadDefaultKey("keys/oauthkey.pem", "consumer-test-key");
+        assertNotNull("defaultKey", defaultKey);
+        assertEquals(BasicOAuthStoreConsumerKeyAndSecret.KeyType.RSA_PRIVATE,
+                defaultKey.getKeyType());
+        assertEquals("consumer-test-key", defaultKey.getKeyName());
+        final String keyFileContents = "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBANXjbMKL9N+9950V7QaDhr7JbF5uJtFgsiCsRjYDT9SaVCaNk2zXRXzqj2acKpAthV0R+4cVeWBN0mDL8CE/Rjo0r+9375DrSpi+jb+hnhYTGfiGbpJrUfCxlOXrvdsw4kZpLVKaj8wZFPb11Cnl5s1QBpPGWs1ij/qj/V04xRwXAgMBAAECgYEA0jXUPFgE8KjpZQ+Zhl9Z3MRlp2Em8XzRVF88GfWjTdXngoR+MehYuO5mxXgSNOUoP1JfHGI0ijux2cRVWrevMdO+0bkezMmgWlBTAqgoidwauX+0NyIRJOOG0anggmSrrf8jocjDLp7ZEhVjmtMzvys6P4RyFaNKXNyxK7J1/LECQQD/fB8vKvenzm9NNEdQyap3d0LYqWd/47NiOCCoS8K/DGVVIZiQQigUOi3ZTY6LV2Eb2RtwRnwBXMsKuQUTHZGDAkEA1lHU2OYGYP7SMu+fxzwFRNx0DrXWqIe0XFQX6EDRbk5H/eKgVt1tER8Mbin/z5utvXXiGJAj6+Eop6uqNPUq3QJAWbFZwVV0XJU8vf38i4BBOG/GKApRK7Tk5TaPQIZYeHoBmUGSLhMLvw4tynxP7tteXEh8OY6FOnU5UyphfbSDwQJBAIC0oesjsH79aMQ4DS77x3pEHdpbry6EWHb99WF/04W3sxovx/SCgyY+DBv4UuydZCgcLAxuO3RDQkP3Hn8xIG0CQQC9keRoDlA7RkwCXq76vEzLUqWiRSeHbXkaniSp7/xqzlw1IeMTtzoqMcJAulNr9W+vKKBYtE3sjXLcmO/CvWk/";
+        assertEquals(keyFileContents, defaultKey.getConsumerSecret());
+    }
+
+    @Before
+    public void setup() throws IOException {
+        token = new OAuthSecurityToken("john.doe", GADGET_URI,
+                "myapp", "localhost", "default", new Date().getTime() + NEXT_HOUR);
+        consumerStoreService = createNiceMock(OAuthConsumerStoreService.class);
+        tokenInfoService = createNiceMock(OAuthTokenInfoService.class);
+        oAuthStore = new DefaultOAuthStore("http://localhost:8080", "keys/oauthkey.pem",
+                "consumer-test-key");
+        ReflectionTestUtils.setField(oAuthStore, "consumerStoreService", consumerStoreService);
+        ReflectionTestUtils.setField(oAuthStore, "tokenInfoService", tokenInfoService);
+    }
+}

Added: incubator/rave/trunk/rave-shindig/src/test/java/org/apache/rave/gadgets/oauth/repository/JpaOAuthConsumerStoreRepositoryTest.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-shindig/src/test/java/org/apache/rave/gadgets/oauth/repository/JpaOAuthConsumerStoreRepositoryTest.java?rev=1158549&view=auto
==============================================================================
--- incubator/rave/trunk/rave-shindig/src/test/java/org/apache/rave/gadgets/oauth/repository/JpaOAuthConsumerStoreRepositoryTest.java (added)
+++ incubator/rave/trunk/rave-shindig/src/test/java/org/apache/rave/gadgets/oauth/repository/JpaOAuthConsumerStoreRepositoryTest.java Wed Aug 17 07:37:23 2011
@@ -0,0 +1,66 @@
+/*
+ * 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.rave.gadgets.oauth.repository;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+
+import org.apache.rave.gadgets.oauth.model.OAuthConsumerStore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
+
+/**
+ * Test for {@link org.apache.rave.gadgets.oauth.repository.impl.JpaOAuthConsumerStoreRepository}
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"classpath:spring-test.xml"})
+public class JpaOAuthConsumerStoreRepositoryTest {
+    private static final String GADGET_URI = "http://localhost:8080/samplecontainer/examples/oauth.xml";
+    private static final String SERVICE_NAME_GOOGLE = "Google";
+    private static final String SERVICE_NAME_FOO = "Foo";
+
+
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Autowired
+    OAuthConsumerStoreRepository repository;
+
+    @Test
+    public void testFindByUriAndServiceName() throws Exception {
+        final OAuthConsumerStore store = repository.findByUriAndServiceName(GADGET_URI, SERVICE_NAME_GOOGLE);
+        assertNotNull("OAuthConsumerStore In test db", store);
+        assertEquals("gadgetSecret", store.getConsumerSecret());
+        assertEquals(OAuthConsumerStore.KeyType.HMAC_SYMMETRIC, store.getKeyType());
+    }
+
+    @Test
+    public void testFindByUriAndServiceName_nullValue() throws Exception {
+        final OAuthConsumerStore store = repository.findByUriAndServiceName(GADGET_URI, SERVICE_NAME_FOO);
+        assertNull(store);
+    }
+}

Added: incubator/rave/trunk/rave-shindig/src/test/java/org/apache/rave/gadgets/oauth/repository/JpaOAuthTokenInfoRepositoryTest.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-shindig/src/test/java/org/apache/rave/gadgets/oauth/repository/JpaOAuthTokenInfoRepositoryTest.java?rev=1158549&view=auto
==============================================================================
--- incubator/rave/trunk/rave-shindig/src/test/java/org/apache/rave/gadgets/oauth/repository/JpaOAuthTokenInfoRepositoryTest.java (added)
+++ incubator/rave/trunk/rave-shindig/src/test/java/org/apache/rave/gadgets/oauth/repository/JpaOAuthTokenInfoRepositoryTest.java Wed Aug 17 07:37:23 2011
@@ -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.rave.gadgets.oauth.repository;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+
+import org.apache.rave.gadgets.oauth.model.OAuthTokenInfo;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+/**
+ * Test class for {@link org.apache.rave.gadgets.oauth.repository.impl.JpaOAuthTokenInfoRepository}
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"classpath:spring-test.xml"})
+public class JpaOAuthTokenInfoRepositoryTest {
+
+    private static final String INVALID_USER = "Invalid user";
+    private static final String VALID_USER = "john.doe";
+    private static final String APP_URL = "http://localhost:8080/samplecontainer/examples/oauth.xml";
+    private static final String TOKEN_NAME = "tokenName";
+    private static final String SERVICE_NAME = "serviceName";
+
+    @PersistenceContext
+    private EntityManager manager;
+
+    @Autowired
+    OAuthTokenInfoRepository repository;
+
+    @Test
+    public void testFindOAuthTokenInfo() throws Exception {
+        OAuthTokenInfo tokenInfo = repository.findOAuthTokenInfo(VALID_USER,
+                APP_URL, OAuthTokenInfo.MODULE_ID, TOKEN_NAME, SERVICE_NAME);
+        assertNotNull(tokenInfo);
+        assertEquals("accessToken", tokenInfo.getAccessToken());
+    }
+
+    @Test
+    public void testFindOAuthTokenInfo_nullValue() throws Exception {
+        OAuthTokenInfo tokenInfo = repository.findOAuthTokenInfo(INVALID_USER,
+                APP_URL, OAuthTokenInfo.MODULE_ID, TOKEN_NAME, SERVICE_NAME);
+        assertNull(tokenInfo);
+    }
+}

Added: incubator/rave/trunk/rave-shindig/src/test/java/org/apache/rave/gadgets/oauth/service/DefaultOAuthConsumerStoreServiceTest.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-shindig/src/test/java/org/apache/rave/gadgets/oauth/service/DefaultOAuthConsumerStoreServiceTest.java?rev=1158549&view=auto
==============================================================================
--- incubator/rave/trunk/rave-shindig/src/test/java/org/apache/rave/gadgets/oauth/service/DefaultOAuthConsumerStoreServiceTest.java (added)
+++ incubator/rave/trunk/rave-shindig/src/test/java/org/apache/rave/gadgets/oauth/service/DefaultOAuthConsumerStoreServiceTest.java Wed Aug 17 07:37:23 2011
@@ -0,0 +1,83 @@
+/*
+ * 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.rave.gadgets.oauth.service;
+
+import org.apache.rave.gadgets.oauth.model.OAuthConsumerStore;
+import org.apache.rave.gadgets.oauth.repository.OAuthConsumerStoreRepository;
+import org.apache.rave.gadgets.oauth.service.impl.DefaultOAuthConsumerStoreService;
+import org.junit.Before;
+import org.junit.Test;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+
+/**
+ * Test class for {@link DefaultOAuthConsumerStoreService}
+ */
+public class DefaultOAuthConsumerStoreServiceTest {
+    private static final String GADGET_URI = "http://localhost:8080/samplecontainer/examples/oauth.xml";
+    private static final String SERVICE_NAME_GOOGLE = "Google";
+    private static final String SERVICE_NAME_FOO = "FOO";
+
+    private OAuthConsumerStoreService service;
+    private OAuthConsumerStoreRepository repository;
+
+    @Before
+    public void setUp() throws Exception {
+        repository = createNiceMock(OAuthConsumerStoreRepository.class);
+        service = new DefaultOAuthConsumerStoreService(repository);
+    }
+
+    @Test
+    public void testFindByUriAndServiceName() throws Exception {
+        OAuthConsumerStore dbConsumerStore = getOAuthConsumerStore();
+        expect(repository.findByUriAndServiceName(GADGET_URI, SERVICE_NAME_GOOGLE)).andReturn(dbConsumerStore);
+        replay(repository);
+
+        OAuthConsumerStore consumerStore = service.findByUriAndServiceName(GADGET_URI, SERVICE_NAME_GOOGLE);
+        assertNotNull("Found consumerStore in repo", consumerStore);
+        assertEquals("gadgetConsumer", consumerStore.getConsumerKey());
+        assertEquals(OAuthConsumerStore.KeyType.HMAC_SYMMETRIC, consumerStore.getKeyType());
+    }
+
+    @Test
+    public void testFindByUriAndServiceName_nullValue() throws Exception {
+        expect(repository.findByUriAndServiceName(GADGET_URI, SERVICE_NAME_FOO)).andReturn(null);
+        OAuthConsumerStore consumerStore = service.findByUriAndServiceName(GADGET_URI, SERVICE_NAME_FOO);
+        assertNull(consumerStore);
+    }
+
+    OAuthConsumerStore getOAuthConsumerStore() {
+        OAuthConsumerStore consumerStore = new OAuthConsumerStore();
+        consumerStore.setCallbackUrl("http://oauth.gmodules.com/gadgets/oauthcallback");
+        consumerStore.setConsumerKey("gadgetConsumer");
+        consumerStore.setConsumerSecret("gadgetSecret");
+        consumerStore.setGadgetUri(GADGET_URI);
+        consumerStore.setServiceName(SERVICE_NAME_GOOGLE);
+        consumerStore.setKeyName("keyName");
+        consumerStore.setKeyType(OAuthConsumerStore.KeyType.HMAC_SYMMETRIC);
+        return consumerStore;
+    }
+
+}

Added: incubator/rave/trunk/rave-shindig/src/test/java/org/apache/rave/gadgets/oauth/service/DefaultOAuthTokenInfoServiceTest.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-shindig/src/test/java/org/apache/rave/gadgets/oauth/service/DefaultOAuthTokenInfoServiceTest.java?rev=1158549&view=auto
==============================================================================
--- incubator/rave/trunk/rave-shindig/src/test/java/org/apache/rave/gadgets/oauth/service/DefaultOAuthTokenInfoServiceTest.java (added)
+++ incubator/rave/trunk/rave-shindig/src/test/java/org/apache/rave/gadgets/oauth/service/DefaultOAuthTokenInfoServiceTest.java Wed Aug 17 07:37:23 2011
@@ -0,0 +1,97 @@
+/*
+ * 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.rave.gadgets.oauth.service;
+
+import org.apache.rave.gadgets.oauth.model.OAuthTokenInfo;
+import org.apache.rave.gadgets.oauth.repository.OAuthTokenInfoRepository;
+import org.apache.rave.gadgets.oauth.service.impl.DefaultOAuthTokenInfoService;
+import org.apache.shindig.auth.SecurityToken;
+import org.apache.shindig.gadgets.oauth.OAuthStore;
+import org.junit.Before;
+import org.junit.Test;
+
+import static junit.framework.Assert.assertEquals;
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+/**
+ * Test for {@link org.apache.rave.gadgets.oauth.service.impl.DefaultOAuthTokenInfoService}
+ */
+public class DefaultOAuthTokenInfoServiceTest {
+    private SecurityToken securityToken;
+    OAuthStore.TokenInfo tokenInfo;
+    private OAuthTokenInfoService service;
+    private OAuthTokenInfoRepository repository;
+
+    private static final String VALID_USER = "john.doe";
+    private static final String INVALID_USER = "Invalid user";
+    private static final String APP_URL = "http://localhost:8080/samplecontainer/examples/oauth.xml";
+    private static final String NOT_USED = "NOT USED";
+    private static final String TOKEN_NAME = "";
+    private static final String SERVICE_NAME = "testService";
+
+    @Before
+    public void setUp() throws Exception {
+        securityToken = createNiceMock(SecurityToken.class);
+        tokenInfo = createNiceMock(OAuthStore.TokenInfo.class);
+        repository = createNiceMock(OAuthTokenInfoRepository.class);
+        service = new DefaultOAuthTokenInfoService(repository);
+
+    }
+
+    @Test
+    public void testFindOAuthTokenInfo() throws Exception {
+        OAuthTokenInfo dbOAuthTokenInfo = getOAuthTokenInfo();
+        expect(repository.findOAuthTokenInfo(VALID_USER, APP_URL, NOT_USED, TOKEN_NAME, SERVICE_NAME))
+                .andReturn(dbOAuthTokenInfo);
+        replay(repository);
+        OAuthTokenInfo oAuthTokenInfo = service.findOAuthTokenInfo(VALID_USER, APP_URL, NOT_USED,
+                TOKEN_NAME, SERVICE_NAME);
+        assertNotNull(oAuthTokenInfo);
+        assertEquals(APP_URL, oAuthTokenInfo.getAppUrl());
+
+    }
+
+    @Test
+    public void testFindOAuthTokenInfo_nullValue() throws Exception {
+        expect(repository.findOAuthTokenInfo(INVALID_USER, APP_URL, NOT_USED, TOKEN_NAME, SERVICE_NAME))
+                .andReturn(null);
+        replay(repository);
+
+        OAuthTokenInfo oAuthTokenInfo = service.findOAuthTokenInfo(INVALID_USER, APP_URL, NOT_USED,
+                TOKEN_NAME, SERVICE_NAME);
+
+        assertNull(oAuthTokenInfo);
+
+    }
+
+    private OAuthTokenInfo getOAuthTokenInfo() {
+        expect(securityToken.getAppUrl()).andReturn(APP_URL);
+        expect(tokenInfo.getAccessToken()).andReturn("accessToken");
+        expect(tokenInfo.getSessionHandle()).andReturn("sessionHandle");
+        expect(tokenInfo.getTokenExpireMillis()).andReturn(3600000L);
+        expect(tokenInfo.getTokenSecret()).andReturn("tokenSecret");
+        replay(securityToken, tokenInfo);
+        return new OAuthTokenInfo(securityToken, SERVICE_NAME, TOKEN_NAME, tokenInfo);
+    }
+}

Modified: incubator/rave/trunk/rave-shindig/src/test/resources/META-INF/persistence.xml
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-shindig/src/test/resources/META-INF/persistence.xml?rev=1158549&r1=1158548&r2=1158549&view=diff
==============================================================================
--- incubator/rave/trunk/rave-shindig/src/test/resources/META-INF/persistence.xml (original)
+++ incubator/rave/trunk/rave-shindig/src/test/resources/META-INF/persistence.xml Wed Aug 17 07:37:23 2011
@@ -24,8 +24,8 @@
   <!-- Test config -->
   <persistence-unit name="raveShindigPersistenceUnit" transaction-type="RESOURCE_LOCAL">
     <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
-    <class>org.apache.shindig.gadgets.oauth.model.OAuthConsumerStoreDb</class>
-    <class>org.apache.shindig.gadgets.oauth.model.OAuthTokenInfoDb</class>
+    <class>org.apache.rave.gadgets.oauth.model.OAuthConsumerStore</class>
+    <class>org.apache.rave.gadgets.oauth.model.OAuthTokenInfo</class>
     <class>org.apache.shindig.social.opensocial.jpa.PersonDb</class>
     <properties>
       <property name="openjpa.RuntimeUnenhancedClasses" value="supported"/>

Modified: incubator/rave/trunk/rave-shindig/src/test/resources/test_data.sql
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-shindig/src/test/resources/test_data.sql?rev=1158549&r1=1158548&r2=1158549&view=diff
==============================================================================
--- incubator/rave/trunk/rave-shindig/src/test/resources/test_data.sql (original)
+++ incubator/rave/trunk/rave-shindig/src/test/resources/test_data.sql Wed Aug 17 07:37:23 2011
@@ -0,0 +1,22 @@
+ -- 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.
+
+INSERT INTO oauth_token_info(id, access_token, token_secret, session_handle, token_expire_millis, app_url, module_id, token_name, service_name, user_id)
+VALUES (set(@token_info_id_1, next value for token_info_id_seq), 'accessToken', 'tokenSecret', 'sessionHandle', 3600000, 'http://localhost:8080/samplecontainer/examples/oauth.xml', 'NOT_USED', 'tokenName', 'serviceName', 'john.doe');
+
+INSERT INTO oauth_consumer_store(id, gadget_uri, service_name, consumer_key, consumer_secret, key_type, key_name, callback_url)
+VALUES (set(@consumer_store_id_1, next value for consumer_store_id_seq), 'http://localhost:8080/samplecontainer/examples/oauth.xml', 'Google', 'gadgetConsumer', 'gadgetSecret', 'HMAC_SYMMETRIC', 'keyName', 'http://oauth.gmodules.com/gadgets/oauthcallback');
\ No newline at end of file