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")));