You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rave.apache.org by jc...@apache.org on 2011/08/03 19:02:47 UTC

svn commit: r1153583 - in /incubator/rave/trunk/rave-portal: ./ src/main/java/org/apache/rave/provider/opensocial/exception/ src/main/java/org/apache/rave/provider/opensocial/service/ src/main/java/org/apache/rave/provider/opensocial/service/impl/ src/...

Author: jcian
Date: Wed Aug  3 17:02:45 2011
New Revision: 1153583

URL: http://svn.apache.org/viewvc?rev=1153583&view=rev
Log:
Fixes RAVE-151 (generating encrypted security tokens server side).  

https://issues.apache.org/jira/browse/RAVE-151

Added:
    incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/provider/opensocial/exception/
    incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/provider/opensocial/exception/SecurityTokenException.java
    incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/provider/opensocial/service/SecurityTokenService.java
    incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/provider/opensocial/service/impl/EncryptedBlobSecurityTokenService.java
    incubator/rave/trunk/rave-portal/src/main/resources/security_token_encryption_key.txt
    incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/provider/opensocial/service/SecurityTokenServiceTest.java
Removed:
    incubator/rave/trunk/rave-portal/src/main/resources/applicationContext-properties.xml
Modified:
    incubator/rave/trunk/rave-portal/pom.xml
    incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/provider/opensocial/web/renderer/OpenSocialWidgetRenderer.java
    incubator/rave/trunk/rave-portal/src/main/resources/messages.properties
    incubator/rave/trunk/rave-portal/src/main/resources/portal.properties
    incubator/rave/trunk/rave-portal/src/main/webapp/WEB-INF/applicationContext.xml
    incubator/rave/trunk/rave-portal/src/main/webapp/WEB-INF/web.xml
    incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/web/renderer/RenderServiceIntegrationTest.java
    incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/provider/opensocial/web/renderer/OpenSocialWidgetRendererTest.java

Modified: incubator/rave/trunk/rave-portal/pom.xml
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/pom.xml?rev=1153583&r1=1153582&r2=1153583&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/pom.xml (original)
+++ incubator/rave/trunk/rave-portal/pom.xml Wed Aug  3 17:02:45 2011
@@ -60,6 +60,25 @@
             <scope>provided</scope>
         </dependency>
 
+        <!-- Shindig -->
+        <dependency>
+            <groupId>org.apache.shindig</groupId>
+            <artifactId>shindig-common</artifactId>
+            <type>jar</type>
+            <scope>compile</scope>
+            <version>${apache.shindig.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.apache.tomcat</groupId>
+                    <artifactId>jasper-el</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.apache.tomcat</groupId>
+                    <artifactId>el-api</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
         <!-- Spring -->
         <dependency>
             <groupId>org.springframework</groupId>

Added: incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/provider/opensocial/exception/SecurityTokenException.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/provider/opensocial/exception/SecurityTokenException.java?rev=1153583&view=auto
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/provider/opensocial/exception/SecurityTokenException.java (added)
+++ incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/provider/opensocial/exception/SecurityTokenException.java Wed Aug  3 17:02:45 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.provider.opensocial.exception;
+
+public class SecurityTokenException extends RuntimeException {
+    public SecurityTokenException() {
+        super();
+    }
+
+    public SecurityTokenException(String message) {
+        super(message);
+    }
+
+    public SecurityTokenException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public SecurityTokenException(Throwable cause) {
+        super(cause);
+    }
+}
\ No newline at end of file

Added: incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/provider/opensocial/service/SecurityTokenService.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/provider/opensocial/service/SecurityTokenService.java?rev=1153583&view=auto
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/provider/opensocial/service/SecurityTokenService.java (added)
+++ incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/provider/opensocial/service/SecurityTokenService.java Wed Aug  3 17:02:45 2011
@@ -0,0 +1,34 @@
+/*
+ * 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.provider.opensocial.service;
+
+import org.apache.rave.portal.model.RegionWidget;
+import org.apache.rave.provider.opensocial.exception.SecurityTokenException;
+import org.apache.shindig.auth.SecurityToken;
+
+public interface SecurityTokenService {
+    SecurityToken getSecurityToken(RegionWidget regionWidget) throws SecurityTokenException;
+
+    String getEncryptedSecurityToken(RegionWidget regionWidget) throws SecurityTokenException;
+
+    SecurityToken decryptSecurityToken(String encryptedSecurityToken) throws SecurityTokenException;
+
+    String refreshEncryptedSecurityToken(String encryptedSecurityToken) throws SecurityTokenException;
+}
\ No newline at end of file

Added: incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/provider/opensocial/service/impl/EncryptedBlobSecurityTokenService.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/provider/opensocial/service/impl/EncryptedBlobSecurityTokenService.java?rev=1153583&view=auto
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/provider/opensocial/service/impl/EncryptedBlobSecurityTokenService.java (added)
+++ incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/provider/opensocial/service/impl/EncryptedBlobSecurityTokenService.java Wed Aug  3 17:02:45 2011
@@ -0,0 +1,183 @@
+/*
+ * 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.provider.opensocial.service.impl;
+
+import org.apache.rave.portal.model.*;
+import org.apache.rave.portal.service.UserService;
+import org.apache.rave.provider.opensocial.exception.SecurityTokenException;
+import org.apache.rave.provider.opensocial.service.SecurityTokenService;
+import org.apache.shindig.auth.BlobCrypterSecurityToken;
+import org.apache.shindig.auth.SecurityToken;
+import org.apache.shindig.common.crypto.BasicBlobCrypter;
+import org.apache.shindig.common.crypto.BlobCrypter;
+import org.apache.shindig.common.util.CharsetUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.stereotype.Service;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Method;
+
+@Service
+public class EncryptedBlobSecurityTokenService implements SecurityTokenService {
+    private static Logger logger = LoggerFactory.getLogger(EncryptedBlobSecurityTokenService.class);
+
+    public static final String EMBEDDED_KEY_PREFIX = "embedded:";
+    public static final String CLASSPATH_KEY_PREFIX = "classpath:";
+
+    private UserService userService;
+    private String container;
+    private String domain;
+
+    private BlobCrypter blobCrypter;
+
+    @Autowired
+    public EncryptedBlobSecurityTokenService(UserService userService,
+                                             @Value("${portal.opensocial_security.container}") String container,
+                                             @Value("${portal.opensocial_security.domain}") String domain,
+                                             @Value("${portal.opensocial_security.encryptionkey}") String encryptionKey) {
+        this.userService = userService;
+        this.container = container;
+        this.domain = domain;
+
+        if (encryptionKey.startsWith(EMBEDDED_KEY_PREFIX)) {
+            byte[] key = CharsetUtil.getUtf8Bytes(encryptionKey.substring(EMBEDDED_KEY_PREFIX.length()));
+            this.blobCrypter = new BasicBlobCrypter(key);
+        } else if (encryptionKey.startsWith(CLASSPATH_KEY_PREFIX)) {
+            try {
+                File file = new ClassPathResource(encryptionKey.substring(CLASSPATH_KEY_PREFIX.length())).getFile();
+                this.blobCrypter = new BasicBlobCrypter(file);
+            } catch (IOException e) {
+                throw new SecurityException("Unable to load encryption key from classpath resource: " + encryptionKey);
+            }
+        } else {
+            try {
+                this.blobCrypter = new BasicBlobCrypter(new File(encryptionKey));
+            } catch (IOException e) {
+                throw new SecurityException("Unable to load encryption key from file: " + encryptionKey);
+            }
+        }
+    }
+
+    @Override
+    public SecurityToken getSecurityToken(RegionWidget regionWidget) throws SecurityTokenException {
+        return this.getBlobCrypterSecurityToken(regionWidget);
+    }
+
+    @Override
+    public String getEncryptedSecurityToken(RegionWidget regionWidget) throws SecurityTokenException {
+        String encryptedToken = null;
+
+        try {
+            BlobCrypterSecurityToken securityToken = this.getBlobCrypterSecurityToken(regionWidget);
+            encryptedToken = this.encryptSecurityToken(securityToken);
+        } catch (Exception e) {
+            throw new SecurityTokenException("Error creating security token from regionWidget", e);
+        }
+
+        return encryptedToken;
+    }
+
+    @Override
+    public SecurityToken decryptSecurityToken(String encryptedSecurityToken) throws SecurityTokenException {
+        SecurityToken securityToken;
+
+        try {
+            if (logger.isTraceEnabled()) {
+                logger.trace("Decrypting security token: " + encryptedSecurityToken);
+            }
+
+            //Remove the header container string and :
+            encryptedSecurityToken = encryptedSecurityToken.substring((container + ":").length());
+
+            //Decrypt
+            //TODO: This hack is in place until we can get a patch applied to shindig to make the target method public
+            Method decryptMethod = BlobCrypterSecurityToken.class.getDeclaredMethod("decrypt", BlobCrypter.class,
+                    String.class, String.class, String.class, String.class);
+            decryptMethod.setAccessible(true);
+            securityToken = (SecurityToken) decryptMethod.invoke(null, blobCrypter, container, domain,
+                    encryptedSecurityToken, null);
+        } catch (Exception e) {
+            throw new SecurityTokenException("Error creating security token from encrypted string: " +
+                    encryptedSecurityToken, e);
+        }
+
+        return securityToken;
+    }
+
+    @Override
+    public String refreshEncryptedSecurityToken(String encryptedSecurityToken) throws SecurityTokenException {
+        //Decrypt the current token
+        SecurityToken securityToken = this.decryptSecurityToken(encryptedSecurityToken);
+
+        //Make sure the person is authorized to refresh this token
+        String userId = String.valueOf(userService.getAuthenticatedUser().getId());
+        if (!securityToken.getViewerId().equalsIgnoreCase(userId)) {
+            throw new SecurityTokenException("Illegal attempt by user " + userId +
+                    " to refresh security token with a viewerId of " + securityToken.getViewerId());
+        }
+
+        //Create a new RegionWidget instance from it so we can use it to generate a new encrypted token
+        RegionWidget regionWidget = new RegionWidget(securityToken.getModuleId(),
+                new Widget(-1L, securityToken.getAppUrl()),
+                new Region(-1L, new Page(-1L, new User(Long.valueOf(securityToken.getOwnerId())))));
+
+        //Create and return the newly encrypted token
+        return getEncryptedSecurityToken(regionWidget);
+    }
+
+    private BlobCrypterSecurityToken getBlobCrypterSecurityToken(RegionWidget regionWidget)
+            throws SecurityTokenException {
+        User user = userService.getAuthenticatedUser();
+
+        BlobCrypterSecurityToken securityToken = new BlobCrypterSecurityToken(blobCrypter, container, domain);
+        securityToken.setAppUrl(regionWidget.getWidget().getUrl());
+        securityToken.setModuleId(regionWidget.getId());
+        securityToken.setOwnerId(String.valueOf(regionWidget.getRegion().getPage().getOwner().getId()));
+        securityToken.setViewerId(String.valueOf(user.getId()));
+        securityToken.setTrustedJson("");
+
+        if (logger.isTraceEnabled()) {
+            logger.trace("Token created for regionWidget " + regionWidget.toString() + " and user " + user.toString());
+        }
+
+        return securityToken;
+    }
+
+    private String encryptSecurityToken(BlobCrypterSecurityToken securityToken) throws SecurityTokenException {
+        String encryptedToken = null;
+
+        try {
+            encryptedToken = securityToken.encrypt();
+            if (logger.isTraceEnabled()) {
+                logger.trace("Encrypted token created from security token: " + securityToken.toString() +
+                        " -- encrypted token is: " + encryptedToken);
+            }
+        } catch (Exception e) {
+            throw new SecurityTokenException("Error creating security token from person gadget", e);
+        }
+
+        return encryptedToken;
+    }
+}
\ No newline at end of file

Modified: incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/provider/opensocial/web/renderer/OpenSocialWidgetRenderer.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/provider/opensocial/web/renderer/OpenSocialWidgetRenderer.java?rev=1153583&r1=1153582&r2=1153583&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/provider/opensocial/web/renderer/OpenSocialWidgetRenderer.java (original)
+++ incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/provider/opensocial/web/renderer/OpenSocialWidgetRenderer.java Wed Aug  3 17:02:45 2011
@@ -25,6 +25,7 @@ import org.apache.rave.portal.model.Regi
 import org.apache.rave.portal.web.renderer.RegionWidgetRenderer;
 import org.apache.rave.provider.opensocial.Constants;
 import org.apache.rave.provider.opensocial.service.OpenSocialService;
+import org.apache.rave.provider.opensocial.service.SecurityTokenService;
 import org.json.JSONException;
 import org.json.JSONObject;
 import org.slf4j.Logger;
@@ -42,10 +43,12 @@ public class OpenSocialWidgetRenderer im
     private static Logger logger = LoggerFactory.getLogger(OpenSocialWidgetRenderer.class);
 
     private OpenSocialService openSocialService;
+    private SecurityTokenService securityTokenService;
 
     @Autowired
-    public OpenSocialWidgetRenderer(OpenSocialService openSocialService) {
+    public OpenSocialWidgetRenderer(OpenSocialService openSocialService, SecurityTokenService securityTokenService) {
         this.openSocialService = openSocialService;
+        this.securityTokenService = securityTokenService;
     }
 
     //Note the widgets.push() call.  This defines the widget objects, which are
@@ -54,8 +57,9 @@ public class OpenSocialWidgetRenderer im
             "widgets.push({type: '%1$s'," +
             " regionWidgetId: %2$s," +
             " widgetUrl: '%3$s', " +
-            " metadata: %4$s," +
-            " userPrefs: %5$s});";
+            " securityToken: '%4$s', " +
+            " metadata: %5$s," +
+            " userPrefs: %6$s});";
 
     @Override
     public String getSupportedContext() {
@@ -87,6 +91,7 @@ public class OpenSocialWidgetRenderer im
         }
 
         return String.format(IFRAME_MARKUP, Constants.WIDGET_TYPE, item.getId(), item.getWidget().getUrl(),
+                securityTokenService.getEncryptedSecurityToken(item),
                 openSocialService.getGadgetMetadata(item.getWidget().getUrl()), userPrefs.toString());
     }
 }
\ No newline at end of file

Modified: incubator/rave/trunk/rave-portal/src/main/resources/messages.properties
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/resources/messages.properties?rev=1153583&r1=1153582&r2=1153583&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/resources/messages.properties (original)
+++ incubator/rave/trunk/rave-portal/src/main/resources/messages.properties Wed Aug  3 17:02:45 2011
@@ -1,3 +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.
+#
+
 username.required=Username required
 username.invalid.length=Username must be atleast 2 characters long
 username.exits=Username already exists

Modified: incubator/rave/trunk/rave-portal/src/main/resources/portal.properties
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/resources/portal.properties?rev=1153583&r1=1153582&r2=1153583&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/resources/portal.properties (original)
+++ incubator/rave/trunk/rave-portal/src/main/resources/portal.properties Wed Aug  3 17:02:45 2011
@@ -24,4 +24,8 @@
 #
 portal.opensocial_engine.protocol=http
 portal.opensocial_engine.root=localhost:8080
-portal.opensocial_engine.gadget_path=/gadgets
\ No newline at end of file
+portal.opensocial_engine.gadget_path=/gadgets
+
+portal.opensocial_security.encryptionkey=classpath:security_token_encryption_key.txt
+portal.opensocial_security.container=default
+portal.opensocial_security.domain=default
\ No newline at end of file

Added: incubator/rave/trunk/rave-portal/src/main/resources/security_token_encryption_key.txt
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/resources/security_token_encryption_key.txt?rev=1153583&view=auto
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/resources/security_token_encryption_key.txt (added)
+++ incubator/rave/trunk/rave-portal/src/main/resources/security_token_encryption_key.txt Wed Aug  3 17:02:45 2011
@@ -0,0 +1 @@
+insecure-security-token-test-key
\ No newline at end of file

Modified: incubator/rave/trunk/rave-portal/src/main/webapp/WEB-INF/applicationContext.xml
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/webapp/WEB-INF/applicationContext.xml?rev=1153583&r1=1153582&r2=1153583&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/webapp/WEB-INF/applicationContext.xml (original)
+++ incubator/rave/trunk/rave-portal/src/main/webapp/WEB-INF/applicationContext.xml Wed Aug  3 17:02:45 2011
@@ -34,6 +34,13 @@
         http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd
         http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
 
+    <!-- make the the portal.properties props available to autowire injectors, location of the properties can
+     be overridden by setting a system property "portal.override.properties" -->
+    <bean id="portalPropertyPlaceholder" class="org.apache.rave.util.OverridablePropertyPlaceholderConfigurer">
+        <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
+        <property name="location" value="classpath:portal.properties"/>
+    </bean>
+
     <context:component-scan base-package="org.apache.rave" annotation-config="true" />
 
     <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">

Modified: incubator/rave/trunk/rave-portal/src/main/webapp/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/webapp/WEB-INF/web.xml?rev=1153583&r1=1153582&r2=1153583&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/webapp/WEB-INF/web.xml (original)
+++ incubator/rave/trunk/rave-portal/src/main/webapp/WEB-INF/web.xml Wed Aug  3 17:02:45 2011
@@ -32,7 +32,6 @@
         <param-name>contextConfigLocation</param-name>
         <param-value>
             /WEB-INF/dataContext.xml
-            classpath:applicationContext-properties.xml
             /WEB-INF/applicationContext.xml
             /WEB-INF/applicationContext-security.xml
         </param-value>

Modified: incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/web/renderer/RenderServiceIntegrationTest.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/web/renderer/RenderServiceIntegrationTest.java?rev=1153583&r1=1153582&r2=1153583&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/web/renderer/RenderServiceIntegrationTest.java (original)
+++ incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/web/renderer/RenderServiceIntegrationTest.java Wed Aug  3 17:02:45 2011
@@ -20,18 +20,23 @@
 package org.apache.rave.portal.web.renderer;
 
 
-import org.apache.rave.portal.model.RegionWidget;
-import org.apache.rave.portal.model.Widget;
+import org.apache.rave.portal.model.*;
 import org.apache.rave.provider.opensocial.repository.impl.ShindigGadgetMetadataRepository;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.AbstractAuthenticationToken;
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.context.SecurityContextImpl;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 import org.springframework.test.util.ReflectionTestUtils;
 import org.springframework.web.client.RestOperations;
 
+import java.util.Arrays;
+
 import static org.easymock.EasyMock.*;
 import static org.hamcrest.CoreMatchers.*;
 import static org.junit.Assert.assertThat;
@@ -51,6 +56,9 @@ public class RenderServiceIntegrationTes
     private static final String VALID_METADATA = "[{\"id\":\"gadgets.metadata\",\"result\"" +
             ":{\"http://www.example.com/gadget.xml\":{\"data-snipped\":\"here-for-brevity\"}}}]";
 
+    private static final Long VALID_USER_ID = 1234L;
+    private static final String VALID_USER_NAME = "jdoe";
+
     @Before
     public void setup() {
         restOperations = createNiceMock(RestOperations.class);
@@ -61,6 +69,16 @@ public class RenderServiceIntegrationTes
         //Replace the real restOperations instance with a mock -- otherwise the call for gadget metadata would fail since
         //we don't have a shindig server available to hit.
         ReflectionTestUtils.setField(metadataRepository, "restOperations", restOperations);
+
+        //Setup a mock authenticated user
+        final User authUser = new User(VALID_USER_ID, VALID_USER_NAME);
+        AbstractAuthenticationToken auth = createNiceMock(AbstractAuthenticationToken.class);
+        expect(auth.getPrincipal()).andReturn(authUser).anyTimes();
+        replay(auth);
+
+        SecurityContext context = new SecurityContextImpl();
+        context.setAuthentication(auth);
+        SecurityContextHolder.setContext(context);
     }
 
     @Test
@@ -72,15 +90,18 @@ public class RenderServiceIntegrationTes
 
     @Test
     public void renderOpenSocial() {
+        Page page = new Page(1L, new User(VALID_USER_ID, VALID_USER_NAME));
+        Region region = new Region(1L, page);
+        page.setRegions(Arrays.asList(region));
+
         Widget w = new Widget();
         w.setType("OpenSocial");
         w.setId(1L);
         w.setTitle("Gadget Title");
         w.setUrl("http://www.example.com/gadget.xml");
 
-        RegionWidget rw = new RegionWidget();
-        rw.setId(2L);
-        rw.setWidget(w);
+        RegionWidget rw = new RegionWidget(1L, w, region);
+        region.setRegionWidgets(Arrays.asList(rw));
 
         String rendered = service.render(rw);
         assertThat(rendered, is(notNullValue()));

Added: incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/provider/opensocial/service/SecurityTokenServiceTest.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/provider/opensocial/service/SecurityTokenServiceTest.java?rev=1153583&view=auto
==============================================================================
--- incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/provider/opensocial/service/SecurityTokenServiceTest.java (added)
+++ incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/provider/opensocial/service/SecurityTokenServiceTest.java Wed Aug  3 17:02:45 2011
@@ -0,0 +1,164 @@
+/*
+ * 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.provider.opensocial.service;
+
+import org.apache.rave.portal.model.*;
+import org.apache.rave.portal.service.UserService;
+import org.apache.rave.provider.opensocial.service.impl.EncryptedBlobSecurityTokenService;
+import org.apache.shindig.auth.SecurityToken;
+import org.apache.shindig.auth.SecurityTokenException;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.springframework.core.io.ClassPathResource;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.Arrays;
+import java.util.Collection;
+
+import static org.easymock.EasyMock.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+@RunWith(Parameterized.class)
+public class SecurityTokenServiceTest {
+    private UserService userService;
+    private SecurityTokenService securityTokenService;
+    private String encryptionKey;
+
+    private User validPerson;
+    private Page validPage;
+    private Region validRegion;
+    private RegionWidget validRegionWidget;
+    private Widget validWidget;
+
+    private final Long VALID_REGION_WIDGET_ID = 1L;
+    private final Long VALID_USER_ID = 1L;
+    private final String VALID_USER_NAME = "jdoe";
+    private final String VALID_URL = "http://example.com/test.xml";
+
+    @Parameterized.Parameters
+    public static Collection<Object[]> data() throws IOException {
+        return Arrays.asList(new Object[][]{
+                //Run the tests once using an embedded key
+                {EncryptedBlobSecurityTokenService.EMBEDDED_KEY_PREFIX + "insecure-security-token-test-key"},
+
+                //And again with a classpath reference to an external key file
+                {EncryptedBlobSecurityTokenService.CLASSPATH_KEY_PREFIX + "security_token_encryption_key.txt"},
+
+                //And again with a direct filesystem reference to an external key file
+                {new ClassPathResource("security_token_encryption_key.txt").getFile().getAbsolutePath()}
+        });
+    }
+
+    public SecurityTokenServiceTest(String encryptionKey) {
+        this.encryptionKey = encryptionKey;
+    }
+
+    @Before
+    public void setup() throws MalformedURLException {
+        userService = createMock(UserService.class);
+        securityTokenService = new EncryptedBlobSecurityTokenService(userService, "default", "default",
+                encryptionKey);
+
+        validPerson = new User(VALID_USER_ID, VALID_USER_NAME);
+
+        validPage = new Page(1L, validPerson);
+        validRegion = new Region(1L, validPage);
+        validPage.setRegions(Arrays.asList(validRegion));
+
+        validWidget = new Widget(1L, VALID_URL);
+        validWidget.setType("OpenSocial");
+        validWidget.setTitle("Widget Title");
+
+        validRegionWidget = new RegionWidget(VALID_REGION_WIDGET_ID, validWidget, validRegion);
+        validRegion.setRegionWidgets(Arrays.asList(validRegionWidget));
+    }
+
+    @Test
+    public void getSecurityToken_validWidget() throws SecurityTokenException {
+        expect(userService.getAuthenticatedUser()).andReturn(validPerson).anyTimes();
+        replay(userService);
+
+        SecurityToken securityToken = securityTokenService.getSecurityToken(validRegionWidget);
+        validateSecurityToken(securityToken);
+    }
+
+    @Test
+    public void getSecurityToken_validWidget_ownerIsNotViewer() throws SecurityTokenException {
+        Long expectedOwnerId = 99999L;
+        validPage.setOwner(new User(expectedOwnerId));
+
+        expect(userService.getAuthenticatedUser()).andReturn(validPerson).anyTimes();
+        replay(userService);
+
+        SecurityToken securityToken = securityTokenService.getSecurityToken(validRegionWidget);
+        validateSecurityToken(securityToken, expectedOwnerId);
+    }
+
+    @Test
+    public void getEncryptedSecurityToken_validWidget_validToken() throws SecurityTokenException {
+        expect(userService.getAuthenticatedUser()).andReturn(validPerson).anyTimes();
+        replay(userService);
+
+        String token = securityTokenService.getEncryptedSecurityToken(validRegionWidget);
+        assertNotNull(token);
+    }
+
+    @Test
+    public void decryptSecurityToken_validTokenString() throws SecurityTokenException {
+        expect(userService.getAuthenticatedUser()).andReturn(validPerson).anyTimes();
+        replay(userService);
+
+        String encryptedToken = securityTokenService.getEncryptedSecurityToken(validRegionWidget);
+        assertNotNull(encryptedToken);
+
+        SecurityToken securityToken = securityTokenService.decryptSecurityToken(encryptedToken);
+        validateSecurityToken(securityToken);
+    }
+
+    @Test
+    public void refreshEncryptedSecurityToken_validTokenString() throws SecurityTokenException {
+        expect(userService.getAuthenticatedUser()).andReturn(validPerson).anyTimes();
+        replay(userService);
+
+        String encryptedToken = securityTokenService.getEncryptedSecurityToken(validRegionWidget);
+        assertNotNull(encryptedToken);
+
+        encryptedToken = securityTokenService.refreshEncryptedSecurityToken(encryptedToken);
+
+        SecurityToken securityToken = securityTokenService.decryptSecurityToken(encryptedToken);
+        validateSecurityToken(securityToken);
+    }
+
+    private void validateSecurityToken(SecurityToken securityToken) {
+        validateSecurityToken(securityToken, VALID_USER_ID);
+    }
+
+    private void validateSecurityToken(SecurityToken securityToken, Long expectedOwnerId) {
+        assertNotNull(securityToken);
+        assertEquals(VALID_REGION_WIDGET_ID.longValue(), securityToken.getModuleId());
+        assertEquals(expectedOwnerId, Long.valueOf(securityToken.getOwnerId()));
+        assertEquals(VALID_USER_ID, Long.valueOf(securityToken.getViewerId()));
+        assertEquals(VALID_URL, securityToken.getAppUrl());
+    }
+}
\ No newline at end of file

Modified: incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/provider/opensocial/web/renderer/OpenSocialWidgetRendererTest.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/provider/opensocial/web/renderer/OpenSocialWidgetRendererTest.java?rev=1153583&r1=1153582&r2=1153583&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/provider/opensocial/web/renderer/OpenSocialWidgetRendererTest.java (original)
+++ incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/provider/opensocial/web/renderer/OpenSocialWidgetRendererTest.java Wed Aug  3 17:02:45 2011
@@ -26,6 +26,7 @@ import org.apache.rave.portal.model.Widg
 import org.apache.rave.portal.web.renderer.Renderer;
 import org.apache.rave.provider.opensocial.Constants;
 import org.apache.rave.provider.opensocial.service.OpenSocialService;
+import org.apache.rave.provider.opensocial.service.SecurityTokenService;
 import org.json.JSONException;
 import org.json.JSONObject;
 import org.junit.Before;
@@ -40,15 +41,18 @@ import static org.junit.Assert.assertTha
 
 public class OpenSocialWidgetRendererTest {
     private OpenSocialService openSocialService;
+    private SecurityTokenService securityTokenService;
     private Renderer<RegionWidget> renderer;
 
     private static final String VALID_GADGET_URL = "http://www.example.com/gadget.xml";
     private static final String VALID_METADATA = "metadata";
+    private static final String VALID_SECURITY_TOKEN = "securityToken";
 
     @Before
     public void setup() {
         openSocialService = createNiceMock(OpenSocialService.class);
-        renderer = new OpenSocialWidgetRenderer(openSocialService);
+        securityTokenService = createNiceMock(SecurityTokenService.class);
+        renderer = new OpenSocialWidgetRenderer(openSocialService, securityTokenService);
     }
 
     @Test
@@ -71,12 +75,16 @@ public class OpenSocialWidgetRendererTes
         rw.setPreferences(Arrays.asList(new RegionWidgetPreference(1L, 1L, "color", "blue"),
                 new RegionWidgetPreference(2L, 1L, "speed", "fast")));
 
+        expect(securityTokenService.getEncryptedSecurityToken(rw)).andReturn(VALID_SECURITY_TOKEN);
+        replay(securityTokenService);
+
         String result = renderer.render(rw);
+
         /*
             result should look like:
 
             widgets.push({type: 'OpenSocial', regionWidgetId: 1, widgetUrl: 'http://www.example.com/gadget.xml',
-                metadata: metadata, userPrefs: {"speed":"fast","color":"blue"}});
+                securityToken: 'securityToken',  metadata: metadata, userPrefs: {"speed":"fast","color":"blue"}});
         */
 
         JSONObject jsonObject = new JSONObject(
@@ -85,6 +93,7 @@ public class OpenSocialWidgetRendererTes
         assertThat((Integer) jsonObject.get("regionWidgetId"), is(equalTo(1)));
         assertThat((String) jsonObject.get("type"), is(equalTo("OpenSocial")));
         assertThat((String) jsonObject.get("widgetUrl"), is(equalTo("http://www.example.com/gadget.xml")));
+        assertThat((String) jsonObject.get("securityToken"), is(equalTo(VALID_SECURITY_TOKEN)));
         assertThat((String) jsonObject.get("metadata"), is(equalTo(VALID_METADATA)));
         assertThat((String) ((JSONObject) jsonObject.get("userPrefs")).get("color"), is(equalTo("blue")));
         assertThat((String) ((JSONObject) jsonObject.get("userPrefs")).get("speed"), is(equalTo("fast")));