You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by rb...@apache.org on 2011/10/21 16:19:34 UTC
svn commit: r1187358 [1/2] - in /shindig/trunk/java:
common/src/main/java/org/apache/shindig/auth/
common/src/main/java/org/apache/shindig/common/crypto/
common/src/test/java/org/apache/shindig/auth/
common/src/test/java/org/apache/shindig/common/crypt...
Author: rbaxter85
Date: Fri Oct 21 14:19:33 2011
New Revision: 1187358
URL: http://svn.apache.org/viewvc?rev=1187358&view=rev
Log:
SHINDIG-1645
Committed For Dan Dumont
Security Token Cleanup in preparation for ContainerConfig controlled token expirations
Added:
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/OAuthCallbackStateToken.java
Modified:
shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/AbstractSecurityToken.java
shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/AnonymousSecurityToken.java
shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BasicSecurityToken.java
shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BasicSecurityTokenCodec.java
shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BlobCrypterSecurityToken.java
shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BlobCrypterSecurityTokenCodec.java
shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/DefaultSecurityTokenCodec.java
shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/SecurityToken.java
shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/SecurityTokenCodec.java
shindig/trunk/java/common/src/main/java/org/apache/shindig/common/crypto/BasicBlobCrypter.java
shindig/trunk/java/common/src/main/java/org/apache/shindig/common/crypto/BlobCrypter.java
shindig/trunk/java/common/src/main/java/org/apache/shindig/common/crypto/BlobExpiredException.java
shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/BasicSecurityTokenCodecTest.java
shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/BlobCrypterSecurityTokenCodecTest.java
shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/BlobCrypterSecurityTokenTest.java
shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/DefaultSecurityTokenCodecTest.java
shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/UrlParameterAuthenticationHandlerTest.java
shindig/trunk/java/common/src/test/java/org/apache/shindig/common/crypto/BlobCrypterTest.java
shindig/trunk/java/common/src/test/java/org/apache/shindig/common/testing/FakeGadgetToken.java
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/config/ShindigAuthConfigContributor.java
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/OAuthCallbackState.java
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/OAuthClientState.java
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerService.java
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/oauth/OAuthClientStateTest.java
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/oauth2/MockUtils.java
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerServiceTest.java
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerTest.java
shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/oauth/OAuthSecurityToken.java
Modified: shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/AbstractSecurityToken.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/AbstractSecurityToken.java?rev=1187358&r1=1187357&r2=1187358&view=diff
==============================================================================
--- shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/AbstractSecurityToken.java (original)
+++ shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/AbstractSecurityToken.java Fri Oct 21 14:19:33 2011
@@ -18,19 +18,358 @@
*/
package org.apache.shindig.auth;
+import java.util.EnumSet;
+import java.util.Map;
+
+import org.apache.shindig.common.crypto.BlobExpiredException;
+import org.apache.shindig.common.util.TimeSource;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Maps;
+
/**
- * A base class for SecurityToken Implementations. Currently provides an isExpired() method
+ * A base class for SecurityToken Implementations.
+ * Currently provides an isExpired() method and getters/setters for nearly
+ * every field of the token.
*
* @since 2.0.0
*/
public abstract class AbstractSecurityToken implements SecurityToken {
+ /** allow three minutes for clock skew */
+ private static final long CLOCK_SKEW_ALLOWANCE = 180;
+
+ // TODO: Make configurable by ContainerConfig
+ private static final int MAX_TOKEN_TTL = 3600;
+
+ private static final TimeSource TIME_SOURCE = new TimeSource();
+
+ public enum Keys {
+ OWNER("o") {
+ public String getValue(SecurityToken token) {
+ return token.getOwnerId();
+ }
+ public void loadFromMap(AbstractSecurityToken token, Map<String, String> map) {
+ token.setOwnerId(map.get(key));
+ }
+ },
+ VIEWER("v") {
+ public String getValue(SecurityToken token) {
+ return token.getViewerId();
+ }
+ public void loadFromMap(AbstractSecurityToken token, Map<String, String> map) {
+ token.setViewerId(map.get(key));
+ }
+ },
+ APP_ID("i") {
+ public String getValue(SecurityToken token) {
+ return token.getAppId();
+ }
+ public void loadFromMap(AbstractSecurityToken token, Map<String, String> map) {
+ token.setAppId(map.get(key));
+ }
+ },
+ DOMAIN("d") {
+ public String getValue(SecurityToken token) {
+ return token.getDomain();
+ }
+ public void loadFromMap(AbstractSecurityToken token, Map<String, String> map) {
+ token.setDomain(map.get(key));
+ }
+ },
+ CONTAINER("c") {
+ public String getValue(SecurityToken token) {
+ return token.getContainer();
+ }
+ public void loadFromMap(AbstractSecurityToken token, Map<String, String> map) {
+ token.setContainer(map.get(key));
+ }
+ },
+ APP_URL("u") {
+ public String getValue(SecurityToken token) {
+ return token.getAppUrl();
+ }
+ public void loadFromMap(AbstractSecurityToken token, Map<String, String> map) {
+ token.setAppUrl(map.get(key));
+ }
+ },
+ MODULE_ID("m") {
+ public String getValue(SecurityToken token) {
+ long value = token.getModuleId();
+ if (value == 0) {
+ return null;
+ }
+ return Long.toString(token.getModuleId(), 10);
+ }
+ public void loadFromMap(AbstractSecurityToken token, Map<String, String> map) {
+ String value = map.get(key);
+ if (value != null) {
+ token.setModuleId(Long.parseLong(value, 10));
+ }
+ }
+ },
+ EXPIRES("x") {
+ public String getValue(SecurityToken token) {
+ Long value = token.getExpiresAt();
+ if (value == null) {
+ return null;
+ }
+ return Long.toString(token.getExpiresAt(), 10);
+ }
+ public void loadFromMap(AbstractSecurityToken token, Map<String, String> map) {
+ String value = map.get(key);
+ if (value != null) {
+ token.setExpiresAt(Long.parseLong(value, 10));
+ }
+ }
+ },
+ TRUSTED_JSON("j") {
+ public String getValue(SecurityToken token) {
+ return token.getTrustedJson();
+ }
+ public void loadFromMap(AbstractSecurityToken token, Map<String, String> map) {
+ token.setTrustedJson(map.get(key));
+ }
+ };
+
+ protected String key;
+ private Keys(String key) {
+ this.key = key;
+ }
+
+ /**
+ * @return The key this {@link Keys} is bound to.
+ */
+ public String getKey() {
+ return key;
+ }
+
+ /**
+ * Gets the {@link String} value from the {@link SecurityToken} using the getter that
+ * this {@link Keys} is bound to.
+ *
+ * @param token The token to get the value from.
+ * @return The value
+ */
+ public abstract String getValue(SecurityToken token);
+
+ /**
+ * Loads from the map the value bound to this {@link Keys} and sets it on the
+ * {@link SecurityToken}
+ *
+ * @param token The token to insert set the value on.
+ * @param map The map to read the value from.
+ */
+ public abstract void loadFromMap(AbstractSecurityToken token, Map<String, String> map);
+ }
+
+ private String ownerId;
+ private String viewerId;
+ private String appId;
+ private String domain;
+ private String container;
+ private String appUrl;
+ private long moduleId = 0;
+ private Long expiresAt;
+ private String trustedJson;
+ private String activeUrl;
+
+ private TimeSource timeSource = AbstractSecurityToken.TIME_SOURCE;
+
+ /**
+ * This method is mostly used for test code to test the expire methods.
+ *
+ * @param timeSource The new {@link TimeSource} for this token to use.
+ * @return This object.
+ */
+ @VisibleForTesting
+ protected AbstractSecurityToken setTimeSource(TimeSource timeSource) {
+ this.timeSource = timeSource;
+ return this;
+ }
+
+ protected TimeSource getTimeSource() {
+ return timeSource;
+ }
+
+ public String getOwnerId() {
+ return ownerId;
+ }
+
+ protected AbstractSecurityToken setOwnerId(String ownerId) {
+ this.ownerId = ownerId;
+ return this;
+ }
+
+ public String getViewerId() {
+ return viewerId;
+ }
+
+ protected AbstractSecurityToken setViewerId(String viewerId) {
+ this.viewerId = viewerId;
+ return this;
+ }
+
+ public String getAppId() {
+ return appId;
+ }
+
+ protected AbstractSecurityToken setAppId(String appId) {
+ this.appId = appId;
+ return this;
+ }
+
+ public String getDomain() {
+ return domain;
+ }
+
+ protected AbstractSecurityToken setDomain(String domain) {
+ this.domain = domain;
+ return this;
+ }
+
+ public String getContainer() {
+ return container;
+ }
+
+ protected AbstractSecurityToken setContainer(String container) {
+ this.container = container;
+ return this;
+ }
+
+ public String getAppUrl() {
+ return appUrl;
+ }
+
+ protected AbstractSecurityToken setAppUrl(String appUrl) {
+ this.appUrl = appUrl;
+ return this;
+ }
+
+ public long getModuleId() {
+ return moduleId;
+ }
+
+ protected AbstractSecurityToken setModuleId(long moduleId) {
+ this.moduleId = moduleId;
+ return this;
+ }
+
+ public Long getExpiresAt() {
+ return expiresAt;
+ }
+
+ /**
+ * Compute and set the expiration time for this token.
+ *
+ * @return This security token.
+ */
+ protected AbstractSecurityToken setExpires() {
+ return setExpiresAt((getTimeSource().currentTimeMillis() / 1000) + getMaxTokenTTL());
+ }
+
+ /**
+ * Set the expiration time for this token.
+ *
+ * @param expiresAt When this token expires, in seconds since epoch.
+ * @return This security token.
+ */
+ protected AbstractSecurityToken setExpiresAt(Long expiresAt) {
+ this.expiresAt = expiresAt;
+ return this;
+ }
+
+ public String getTrustedJson() {
+ return trustedJson;
+ }
+
+ protected AbstractSecurityToken setTrustedJson(String trustedJson) {
+ this.trustedJson = trustedJson;
+ return this;
+ }
public boolean isExpired() {
+ try {
+ enforceNotExpired();
+ } catch (BlobExpiredException e) {
+ return true;
+ }
+ return false;
+ }
+
+ public AbstractSecurityToken enforceNotExpired() throws BlobExpiredException {
Long expiresAt = getExpiresAt();
- return (expiresAt == null) ? false : (System.currentTimeMillis() >expiresAt);
+ if (expiresAt != null) {
+ long maxTime = expiresAt + CLOCK_SKEW_ALLOWANCE;
+ long now = getTimeSource().currentTimeMillis() / 1000;
+
+ if (!(now < maxTime)) {
+ throw new BlobExpiredException(now, maxTime);
+ }
+ }
+ return this;
}
public String getActiveUrl() {
- throw new UnsupportedOperationException("No active URL available");
+ return activeUrl;
+ }
+
+ protected AbstractSecurityToken setActiveUrl(String activeUrl) {
+ this.activeUrl = activeUrl;
+ return this;
+ }
+
+ /**
+ * A {@link Map} representation of this {@link SecurityToken}. Implementors that
+ * handle additional keys not contained in {@link Keys} should override and
+ * supplement the functionality of this method.
+ *
+ * @return A map of serialized token values keyed according to {@link Keys}.
+ * @see #getMapKeys()
+ * @see #loadFromMap(Map)
+ */
+ public Map<String, String> toMap() {
+ Map<String, String> map = Maps.newHashMap();
+ for (Keys key : getMapKeys()) {
+ String value = key.getValue(this);
+ if (value != null) {
+ map.put(key.getKey(), key.getValue(this));
+ }
+ }
+ return map;
+ }
+
+ /**
+ * @return Maximum allowable time in seconds for a token to live.
+ */
+ protected int getMaxTokenTTL() {
+ return MAX_TOKEN_TTL;
+ }
+
+ /**
+ * A helper to help load known supported keys from a provided map.
+ *
+ * @param map The map of values.
+ * @see #getMapKeys()
+ * @see #toMap()
+ */
+ protected AbstractSecurityToken loadFromMap(Map<String, String> map) {
+ for (Keys key : getMapKeys()) {
+ key.loadFromMap(this, map);
+ }
+ return this;
}
+
+ /**
+ * This method will govern the effectiveness of the protected {@link #toMap()} and
+ * {@link #loadFromMap(SecurityToken, Map)} helper methods.
+ * <br><br>
+ * If your implementation throws an exception on any of the get methods, you
+ * should not include the associated key here, and those values should be handled
+ * in an overridden implementation of {@link #toMap()} if they might contain
+ * useful information.
+ *
+ * @return An EnumSet of the Enums supported by the implementation of this
+ * {@link AbstractSecurityToken}.
+ */
+ protected abstract EnumSet<Keys> getMapKeys();
}
Modified: shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/AnonymousSecurityToken.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/AnonymousSecurityToken.java?rev=1187358&r1=1187357&r2=1187358&view=diff
==============================================================================
--- shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/AnonymousSecurityToken.java (original)
+++ shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/AnonymousSecurityToken.java Fri Oct 21 14:19:33 2011
@@ -18,66 +18,41 @@
*/
package org.apache.shindig.auth;
+import java.util.EnumSet;
+
import org.apache.shindig.config.ContainerConfig;
/**
* A special class of Token representing the anonymous viewer/owner
*/
public class AnonymousSecurityToken extends AbstractSecurityToken implements SecurityToken {
- private final String container;
- private final long moduleId;
- private final String appUrl;
- private final Long expiresAt;
+ private static final EnumSet<Keys> MAP_KEYS = EnumSet.of(
+ Keys.OWNER, Keys.VIEWER, Keys.APP_URL, Keys.MODULE_ID, Keys.EXPIRES, Keys.TRUSTED_JSON
+ );
public AnonymousSecurityToken() {
this(ContainerConfig.DEFAULT_CONTAINER);
}
-
+
public AnonymousSecurityToken(String container) {
this(container, 0L, "", null);
}
- public AnonymousSecurityToken(String container, long moduleId, String appUrl, Long expiresAt) {
- this.container = container;
- this.moduleId = moduleId;
- this.appUrl = appUrl;
- this.expiresAt = expiresAt;
- }
-
- public boolean isAnonymous() {
- return true;
- }
-
- public String getOwnerId() {
- return "-1";
- }
-
- public String getViewerId() {
- return "-1";
+ public AnonymousSecurityToken(String container, Long moduleId, String appUrl, Long expiresAt) {
+ setContainer(container).setModuleId(moduleId).setAppUrl(appUrl).setExpiresAt(expiresAt)
+ .setOwnerId("-1")
+ .setViewerId("-1")
+ .setDomain("*")
+ .setTrustedJson("");
}
+ @Override
public String getAppId() {
- return appUrl;
- }
-
- public String getDomain() {
- return "*";
+ return getAppUrl();
}
- public String getContainer() {
- return this.container;
- }
-
- public String getAppUrl() {
- return appUrl;
- }
-
- public long getModuleId() {
- return moduleId;
- }
-
- public Long getExpiresAt() {
- return expiresAt;
+ public boolean isAnonymous() {
+ return true;
}
public String getUpdatedToken() {
@@ -88,7 +63,11 @@ public class AnonymousSecurityToken exte
return AuthenticationMode.UNAUTHENTICATED.name();
}
- public String getTrustedJson() {
- return "";
+ public String getActiveUrl() {
+ throw new UnsupportedOperationException("No active URL available");
+ }
+
+ protected EnumSet<Keys> getMapKeys() {
+ return MAP_KEYS;
}
}
Modified: shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BasicSecurityToken.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BasicSecurityToken.java?rev=1187358&r1=1187357&r2=1187358&view=diff
==============================================================================
--- shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BasicSecurityToken.java (original)
+++ shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BasicSecurityToken.java Fri Oct 21 14:19:33 2011
@@ -18,134 +18,24 @@
*/
package org.apache.shindig.auth;
-import org.apache.shindig.common.crypto.BasicBlobCrypter;
-import org.apache.shindig.common.crypto.BlobCrypter;
-import org.apache.shindig.common.crypto.BlobCrypterException;
-
-import com.google.common.collect.Maps;
-
-import java.util.Map;
+import java.util.EnumSet;
/**
* Primitive token implementation that uses strings as tokens.
*/
-public class BasicSecurityToken extends AbstractSecurityToken implements SecurityToken {
- /** serialized form of the token */
- private final String token;
-
- /** data from the token */
- private final Map<String, String> tokenData;
-
- /** tool to use for signing and encrypting the token */
- private final BlobCrypter crypter = new BasicBlobCrypter(INSECURE_KEY);
-
- private final String activeUrl;
-
- private static final byte[] INSECURE_KEY =
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-
- private static final String OWNER_KEY = "o";
- private static final String APP_KEY = "a";
- private static final String VIEWER_KEY = "v";
- private static final String DOMAIN_KEY = "d";
- private static final String APPURL_KEY = "u";
- private static final String MODULE_KEY = "m";
- private static final String CONTAINER_KEY = "c";
- private static final String EXPIRES_KEY = "x";
-
- /**
- * Generates a token from an input string
- * @param token String form of token
- * @param maxAge max age of the token (in seconds)
- * @throws BlobCrypterException never
- */
- public BasicSecurityToken(String token, int maxAge, String activeUrl)
- throws BlobCrypterException {
- this.token = token;
- this.tokenData = crypter.unwrap(token, maxAge);
- this.activeUrl = activeUrl;
- }
+public class BasicSecurityToken extends AbstractSecurityToken {
+ private static final EnumSet<Keys> SUPPORTED = EnumSet.noneOf(Keys.class);
public BasicSecurityToken(String owner, String viewer, String app,
- String domain, String appUrl, String moduleId, String container, String activeUrl, Long expiresAt)
- throws BlobCrypterException {
- tokenData = Maps.newHashMapWithExpectedSize(7);
- putNullSafe(OWNER_KEY, owner);
- putNullSafe(VIEWER_KEY, viewer);
- putNullSafe(APP_KEY, app);
- putNullSafe(DOMAIN_KEY, domain);
- putNullSafe(APPURL_KEY, appUrl);
- putNullSafe(MODULE_KEY, moduleId);
- putNullSafe(CONTAINER_KEY, container);
- if (expiresAt != null)
- putNullSafe(EXPIRES_KEY, expiresAt.toString());
-
- token = crypter.wrap(tokenData);
- this.activeUrl = activeUrl;
- }
-
- private void putNullSafe(String key, String value) {
- if (value != null) {
- tokenData.put(key, value);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public String getAppId() {
- return tokenData.get(APP_KEY);
- }
-
- /**
- * {@inheritDoc}
- */
- public String getDomain() {
- return tokenData.get(DOMAIN_KEY);
- }
-
- /**
- * {@inheritDoc}
- */
- public String getContainer() {
- return tokenData.get(CONTAINER_KEY);
- }
-
- /**
- * {@inheritDoc}
- */
- public String getOwnerId() {
- return tokenData.get(OWNER_KEY);
- }
-
- /**
- * {@inheritDoc}
- */
- public String getViewerId() {
- return tokenData.get(VIEWER_KEY);
- }
-
- /**
- * {@inheritDoc}
- */
- public String getAppUrl() {
- return tokenData.get(APPURL_KEY);
+ String domain, String appUrl, String moduleId, String container, String activeUrl, Long expiresAt) {
+ setOwnerId(owner).setViewerId(viewer).setAppId(app).setDomain(domain).setAppUrl(appUrl);
+ if (moduleId != null)
+ setModuleId(Long.parseLong(moduleId));
+ setContainer(container).setActiveUrl(activeUrl).setExpiresAt(expiresAt);
}
- /**
- * {@inheritDoc}
- */
- public long getModuleId() {
- return Long.parseLong(tokenData.get(MODULE_KEY));
- }
-
- public Long getExpiresAt() {
- return Long.parseLong(tokenData.get(EXPIRES_KEY));
- }
+ public BasicSecurityToken() { }
- /**
- * {@inheritDoc}
- */
public String getUpdatedToken() {
return null;
}
@@ -154,24 +44,25 @@ public class BasicSecurityToken extends
return AuthenticationMode.SECURITY_TOKEN_URL_PARAMETER.name();
}
- /**
- * {@inheritDoc}
- */
- public String getTrustedJson() {
- return null;
- }
-
- /**
- * {@inheritDoc}
- */
public boolean isAnonymous() {
return false;
}
public String getActiveUrl() {
+ String activeUrl = super.getActiveUrl();
if (activeUrl == null) {
throw new UnsupportedOperationException("No active URL available");
}
return activeUrl;
}
+
+ /* (non-Javadoc)
+ * @see org.apache.shindig.auth.AbstractSecurityToken#getSupportedKeys()
+ *
+ * The codec for this token does not use a BlobCrypter, so we don't need the
+ * toMap and loadFromMap functionality.
+ */
+ protected EnumSet<Keys> getMapKeys() {
+ return SUPPORTED;
+ }
}
Modified: shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BasicSecurityTokenCodec.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BasicSecurityTokenCodec.java?rev=1187358&r1=1187357&r2=1187358&view=diff
==============================================================================
--- shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BasicSecurityTokenCodec.java (original)
+++ shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BasicSecurityTokenCodec.java Fri Oct 21 14:19:33 2011
@@ -43,6 +43,7 @@ public class BasicSecurityTokenCodec imp
private static final int APP_URL_INDEX = 4;
private static final int MODULE_ID_INDEX = 5;
private static final int CONTAINER_ID_INDEX = 6;
+ private static final int EXPIRY_INDEX = 7; // for back compat, conditionally check later
private static final int TOKEN_COUNT = CONTAINER_ID_INDEX + 1;
/**
@@ -51,14 +52,17 @@ public class BasicSecurityTokenCodec imp
* @return token with values separated by colons
*/
public String encodeToken(SecurityToken token) {
+ BasicSecurityToken basicToken = new BasicSecurityToken();
+ basicToken.setExpires(); // Quick and dirty token expire calculation.
return Joiner.on(":").join(
Utf8UrlCoder.encode(token.getOwnerId()),
Utf8UrlCoder.encode(token.getViewerId()),
Utf8UrlCoder.encode(token.getAppId()),
Utf8UrlCoder.encode(token.getDomain()),
Utf8UrlCoder.encode(token.getAppUrl()),
- Long.toString(token.getModuleId()),
- Utf8UrlCoder.encode(token.getContainer()));
+ Long.toString(token.getModuleId(), 10),
+ Utf8UrlCoder.encode(token.getContainer()),
+ Long.toString(basicToken.getExpiresAt(), 10));
}
@@ -78,11 +82,16 @@ public class BasicSecurityTokenCodec imp
try {
String[] tokens = StringUtils.split(token, ':');
- if (tokens.length != TOKEN_COUNT) {
+ if (tokens.length < TOKEN_COUNT) {
throw new SecurityTokenException("Malformed security token");
}
- return new BasicSecurityToken(
+ Long expires = null;
+ if (tokens.length > TOKEN_COUNT && !tokens[EXPIRY_INDEX].equals("")) {
+ expires = Long.parseLong(Utf8UrlCoder.decode(tokens[EXPIRY_INDEX]), 10);
+ }
+
+ BasicSecurityToken basicToken = new BasicSecurityToken(
Utf8UrlCoder.decode(tokens[OWNER_INDEX]),
Utf8UrlCoder.decode(tokens[VIEWER_INDEX]),
Utf8UrlCoder.decode(tokens[APP_ID_INDEX]),
@@ -91,7 +100,8 @@ public class BasicSecurityTokenCodec imp
Utf8UrlCoder.decode(tokens[MODULE_ID_INDEX]),
Utf8UrlCoder.decode(tokens[CONTAINER_ID_INDEX]),
parameters.get(SecurityTokenCodec.ACTIVE_URL_NAME),
- null);
+ expires);
+ return basicToken.enforceNotExpired();
} catch (BlobCrypterException e) {
throw new SecurityTokenException(e);
} catch (ArrayIndexOutOfBoundsException e) {
@@ -99,11 +109,6 @@ public class BasicSecurityTokenCodec imp
}
}
- public Long getTokenExpiration(SecurityToken token) {
- // TODO: Support and/or implement this operation.
- return null;
- }
-
/**
* Creates a signer with 24 hour token expiry
*/
Modified: shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BlobCrypterSecurityToken.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BlobCrypterSecurityToken.java?rev=1187358&r1=1187357&r2=1187358&view=diff
==============================================================================
--- shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BlobCrypterSecurityToken.java (original)
+++ shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BlobCrypterSecurityToken.java Fri Oct 21 14:19:33 2011
@@ -18,13 +18,8 @@
*/
package org.apache.shindig.auth;
-import org.apache.shindig.common.crypto.BlobCrypter;
-import org.apache.shindig.common.crypto.BlobCrypterException;
-
-import com.google.common.collect.Maps;
-
+import java.util.EnumSet;
import java.util.Map;
-
/**
* Authentication based on a provided BlobCrypter.
*
@@ -32,161 +27,24 @@ import java.util.Map;
*
* Container is included so different containers can use different security tokens if necessary.
*/
-public class BlobCrypterSecurityToken extends AbstractSecurityToken implements SecurityToken {
-
- protected static final int MAX_TOKEN_LIFETIME_SECS = 3600;
-
- protected static final String OWNER_KEY = "o";
- protected static final String VIEWER_KEY = "v";
- protected static final String GADGET_KEY = "g";
- protected static final String GADGET_INSTANCE_KEY = "i";
- protected static final String TRUSTED_JSON_KEY = "j";
- protected static final String EXPIRES_KEY = "x";
-
- protected final String container;
- protected final String domain;
-
- protected String ownerId;
- protected String viewerId;
- protected String appUrl;
- protected long moduleId;
- protected Long expiresAt;
-
- protected String trustedJson;
- protected String activeUrl;
+public class BlobCrypterSecurityToken extends AbstractSecurityToken {
+ private static final EnumSet<Keys> MAP_KEYS = EnumSet.of(
+ Keys.OWNER, Keys.VIEWER, Keys.APP_URL, Keys.MODULE_ID, Keys.EXPIRES, Keys.TRUSTED_JSON
+ );
/**
* Create a new security token.
*
- * @param crypter used for encryption and signing
* @param container container that is issuing the token
* @param domain domain to use for signed fetch with default signed fetch key.
+ * @param activeUrl
+ * @param values Other values to init into the token.
*/
- public BlobCrypterSecurityToken(String container, String domain) {
- this.container = container;
- this.domain = domain;
- }
-
- /**
- * Decrypt and verify a token. Note that this is a low level API dealing directly with encrypted
- * data, for a higher level API consider using the BlobCrypterSecurityTokenCodec instead.
- *
- * @param crypter crypter to use for decryption
- * @param container container that minted the token
- * @param domain oauth_consumer_key to use for signed fetch with default key
- * @param token the encrypted token (just the portion after the first ":")
- * @return the decrypted, verified token.
- *
- * @throws BlobCrypterException
- */
- public static BlobCrypterSecurityToken decrypt(BlobCrypter crypter, String container, String domain,
- String token, String activeUrl) throws BlobCrypterException {
- Map<String, String> values = crypter.unwrap(token, MAX_TOKEN_LIFETIME_SECS);
- BlobCrypterSecurityToken t = new BlobCrypterSecurityToken(container, domain);
- setTokenValues(t, values);
- t.setActiveUrl(activeUrl);
- return t;
- }
-
- protected static void setTokenValues(BlobCrypterSecurityToken token, Map<String, String> values) {
- token.setOwnerId(values.get(OWNER_KEY));
- token.setViewerId(values.get(VIEWER_KEY));
- token.setAppUrl(values.get(GADGET_KEY));
- String moduleId = values.get(GADGET_INSTANCE_KEY);
- if (moduleId != null) {
- token.setModuleId(Long.parseLong(moduleId));
- }
- String expiresAt = values.get(EXPIRES_KEY);
- if (expiresAt != null) {
- token.setExpiresAt(Long.parseLong(expiresAt));
- }
- token.setTrustedJson(values.get(TRUSTED_JSON_KEY));
- }
-
- /**
- * Encrypt and sign the token. The returned value is *not* web safe, it should be URL
- * encoded before being used as a form parameter.
- */
- public static String encrypt(SecurityToken token, BlobCrypter crypter) throws BlobCrypterException {
- Map<String, String> values = buildValuesMap(token);
- return token.getContainer() + ':' + crypter.wrap(values);
- }
-
- protected static Map<String, String> buildValuesMap(SecurityToken token) {
- Map<String, String> values = Maps.newHashMap();
- if (token.getOwnerId() != null) {
- values.put(OWNER_KEY, token.getOwnerId());
- }
- if (token.getViewerId() != null) {
- values.put(VIEWER_KEY, token.getViewerId());
- }
- if (token.getAppUrl() != null) {
- values.put(GADGET_KEY, token.getAppUrl());
+ public BlobCrypterSecurityToken(String container, String domain, String activeUrl, Map<String, String> values) {
+ if (values != null) {
+ loadFromMap(values);
}
- if (token.getModuleId() != 0) {
- values.put(GADGET_INSTANCE_KEY, Long.toString(token.getModuleId()));
- }
- if (token.getExpiresAt() != null) {
- values.put(EXPIRES_KEY, Long.toString(token.getExpiresAt()));
- }
- if (token.getTrustedJson() != null) {
- values.put(TRUSTED_JSON_KEY, token.getTrustedJson());
- }
- return values;
- }
-
- // Legacy value for signed fetch, opensocial 0.8 prefers opensocial_app_url
- public String getAppId() {
- return appUrl;
- }
-
- public String getAppUrl() {
- return appUrl;
- }
-
- public void setAppUrl(String appUrl) {
- this.appUrl = appUrl;
- }
-
- public String getContainer() {
- return container;
- }
-
- // Used for oauth_consumer_key for signed fetch with default key. This is a weird spot for this.
- public String getDomain() {
- return domain;
- }
-
- public long getModuleId() {
- return moduleId;
- }
-
- public void setModuleId(long moduleId) {
- this.moduleId = moduleId;
- }
-
- public Long getExpiresAt() {
- return expiresAt;
- }
-
- public void setExpiresAt(Long expiresAt) {
- this.expiresAt = expiresAt;
- }
-
- public String getOwnerId() {
- return ownerId;
- }
-
- public void setOwnerId(String ownerId) {
- this.ownerId = ownerId;
- }
-
- public String getTrustedJson() {
- return trustedJson;
- }
-
- public void setTrustedJson(String trustedJson) {
- this.trustedJson = trustedJson;
+ setContainer(container).setDomain(domain).setActiveUrl(activeUrl);
}
// Our tokens are static, we could change this to periodically update the token.
@@ -198,26 +56,45 @@ public class BlobCrypterSecurityToken ex
return AuthenticationMode.SECURITY_TOKEN_URL_PARAMETER.name();
}
- public String getViewerId() {
- return viewerId;
- }
-
- public void setViewerId(String viewerId) {
- this.viewerId = viewerId;
- }
-
public boolean isAnonymous() {
return false;
}
- public void setActiveUrl(String activeUrl) {
- this.activeUrl = activeUrl;
- }
-
public String getActiveUrl() {
+ String activeUrl = super.getActiveUrl();
if (activeUrl == null) {
throw new UnsupportedOperationException("No active URL available");
}
return activeUrl;
}
+
+ // Legacy value for signed fetch, opensocial 0.8 prefers opensocial_app_url
+ @Override
+ public String getAppId() {
+ return getAppUrl();
+ }
+
+ protected EnumSet<Keys> getMapKeys() {
+ return MAP_KEYS;
+ }
+
+ public static BlobCrypterSecurityToken fromToken(SecurityToken token) {
+ String activeUrl = null;
+ try {
+ activeUrl = token.getActiveUrl();
+ } catch (UnsupportedOperationException e) {}
+
+ BlobCrypterSecurityToken interpretedToken = new BlobCrypterSecurityToken(
+ token.getContainer(), token.getDomain(), activeUrl, null);
+ interpretedToken
+ .setAppId(token.getAppId())
+ .setAppUrl(token.getAppUrl())
+ .setExpiresAt(token.getExpiresAt())
+ .setModuleId(token.getModuleId())
+ .setOwnerId(token.getOwnerId())
+ .setTrustedJson(token.getTrustedJson())
+ .setViewerId(token.getViewerId());
+
+ return interpretedToken;
+ }
}
Modified: shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BlobCrypterSecurityTokenCodec.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BlobCrypterSecurityTokenCodec.java?rev=1187358&r1=1187357&r2=1187358&view=diff
==============================================================================
--- shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BlobCrypterSecurityTokenCodec.java (original)
+++ shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BlobCrypterSecurityTokenCodec.java Fri Oct 21 14:19:33 2011
@@ -18,6 +18,12 @@
*/
package org.apache.shindig.auth;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.shindig.common.crypto.BasicBlobCrypter;
@@ -30,13 +36,6 @@ import com.google.common.collect.Maps;
import com.google.inject.Inject;
import com.google.inject.Singleton;
-import java.io.File;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
/**
* Provides security token decoding services. Configuration is via containers.js. Each container
* should specify (or inherit)
@@ -103,7 +102,7 @@ public class BlobCrypterSecurityTokenCod
crypters = newCrypters;
domains = newDomains;
}
-
+
private void loadContainers(ContainerConfig config, Collection<String> containers,
Map<String, BlobCrypter> crypters, Map<String, String> domains) throws IOException {
for (String container : containers) {
@@ -153,32 +152,39 @@ public class BlobCrypterSecurityTokenCod
String activeUrl = tokenParameters.get(SecurityTokenCodec.ACTIVE_URL_NAME);
String crypted = fields[1];
try {
- return BlobCrypterSecurityToken.decrypt(crypter, container, domain, crypted, activeUrl);
+ BlobCrypterSecurityToken st = new BlobCrypterSecurityToken(container, domain, activeUrl,
+ crypter.unwrap(crypted));
+ return st.enforceNotExpired();
} catch (BlobCrypterException e) {
throw new SecurityTokenException(e);
}
}
+ /**
+ * Encrypt and sign the token. The returned value is *not* web safe, it should be URL
+ * encoded before being used as a form parameter.
+ */
public String encodeToken(SecurityToken token) throws SecurityTokenException {
if (!token.getAuthenticationMode().equals(
AuthenticationMode.SECURITY_TOKEN_URL_PARAMETER.name())) {
throw new SecurityTokenException("Can only encode BlogCrypterSecurityTokens");
}
- BlobCrypter crypter = crypters.get(token.getContainer());
+ // Test code sends in real AbstractTokens, they have modified time sources in them so
+ // that we can test token expiration, production tokens are proxied via the SecurityToken interface.
+ AbstractSecurityToken aToken = token instanceof AbstractSecurityToken ?
+ (AbstractSecurityToken)token : BlobCrypterSecurityToken.fromToken(token);
+
+ BlobCrypter crypter = crypters.get(aToken.getContainer());
if (crypter == null) {
- throw new SecurityTokenException("Unknown container " + token.getContainer());
+ throw new SecurityTokenException("Unknown container " + aToken.getContainer());
}
-
+
try {
- return BlobCrypterSecurityToken.encrypt(token, crypter);
+ aToken.setExpires();
+ return aToken.getContainer() + ':' + crypter.wrap(aToken.toMap());
} catch (BlobCrypterException e) {
throw new SecurityTokenException(e);
}
}
-
- public Long getTokenExpiration(SecurityToken token) {
- // TODO: Support and/or implement this operation.
- return null;
- }
}
Modified: shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/DefaultSecurityTokenCodec.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/DefaultSecurityTokenCodec.java?rev=1187358&r1=1187357&r2=1187358&view=diff
==============================================================================
--- shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/DefaultSecurityTokenCodec.java (original)
+++ shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/DefaultSecurityTokenCodec.java Fri Oct 21 14:19:33 2011
@@ -74,8 +74,4 @@ public class DefaultSecurityTokenCodec i
}
return codec.encodeToken(token);
}
-
- public Long getTokenExpiration(SecurityToken token) throws SecurityTokenException {
- return codec.getTokenExpiration(token);
- }
}
Modified: shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/SecurityToken.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/SecurityToken.java?rev=1187358&r1=1187357&r2=1187358&view=diff
==============================================================================
--- shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/SecurityToken.java (original)
+++ shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/SecurityToken.java Fri Oct 21 14:19:33 2011
@@ -60,12 +60,13 @@ public interface SecurityToken {
long getModuleId();
/**
- * @return the timestamp that this token expires or null if unknown or indeterminate
+ * @return The time in seconds since epoc that this token expires or
+ * <code>null</code> if unknown or indeterminate.
*/
Long getExpiresAt();
/**
- * @return true if the token is no longer valid
+ * @return true if the token is no longer valid.
*/
boolean isExpired();
@@ -91,14 +92,14 @@ public interface SecurityToken {
* @return true if the token is for an anonymous viewer/owner
*/
boolean isAnonymous();
-
+
/**
* @return the URL being used by the current request
- *
+ *
* The returned URL must contain at least protocol, host, and port.
- *
+ *
* The returned URL may contain path or query parameters.
- *
+ *
* @throws UnsupportedOperationException if the URL is not available.
*/
String getActiveUrl();
Modified: shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/SecurityTokenCodec.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/SecurityTokenCodec.java?rev=1187358&r1=1187357&r2=1187358&view=diff
==============================================================================
--- shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/SecurityTokenCodec.java (original)
+++ shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/SecurityTokenCodec.java Fri Oct 21 14:19:33 2011
@@ -53,7 +53,4 @@ public interface SecurityTokenCodec {
throws SecurityTokenException;
String encodeToken(SecurityToken token) throws SecurityTokenException;
-
- Long getTokenExpiration(SecurityToken token) throws SecurityTokenException;
-
}
Modified: shindig/trunk/java/common/src/main/java/org/apache/shindig/common/crypto/BasicBlobCrypter.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/crypto/BasicBlobCrypter.java?rev=1187358&r1=1187357&r2=1187358&view=diff
==============================================================================
--- shindig/trunk/java/common/src/main/java/org/apache/shindig/common/crypto/BasicBlobCrypter.java (original)
+++ shindig/trunk/java/common/src/main/java/org/apache/shindig/common/crypto/BasicBlobCrypter.java Fri Oct 21 14:19:33 2011
@@ -48,15 +48,9 @@ public class BasicBlobCrypter implements
private static final byte CIPHER_KEY_LABEL = 0;
private static final byte HMAC_KEY_LABEL = 1;
- /** Key used for time stamp (in seconds) of data */
- public static final String TIMESTAMP_KEY = "t";
-
/** minimum length of master key */
public static final int MASTER_KEY_MIN_LEN = 16;
- /** allow three minutes for clock skew */
- private static final long CLOCK_SKEW_ALLOWANCE = 180;
-
public TimeSource timeSource = new TimeSource();
private byte[] cipherKey;
private byte[] hmacKey;
@@ -149,13 +143,9 @@ public class BasicBlobCrypter implements
/* (non-Javadoc)
* @see org.apache.shindig.util.BlobCrypter#wrap(java.util.Map)
*/
- public String wrap(Map<String, String> in)
- throws BlobCrypterException {
- Preconditions.checkArgument(!in.containsKey(TIMESTAMP_KEY),
- "No '%s' key allowed for BlobCrypter", TIMESTAMP_KEY);
-
+ public String wrap(Map<String, String> in) throws BlobCrypterException {
try {
- byte[] encoded = serializeAndTimestamp(in);
+ byte[] encoded = serialize(in);
byte[] cipherText = Crypto.aes128cbcEncrypt(cipherKey, encoded);
byte[] hmac = Crypto.hmacSha1(hmacKey, cipherText);
byte[] b64 = Base64.encodeBase64URLSafe(Bytes.concat(cipherText, hmac));
@@ -167,10 +157,10 @@ public class BasicBlobCrypter implements
/**
* Encode the input for transfer. We use something a lot like HTML form
- * encodings. The time stamp is in seconds since the epoch.
+ * encodings.
* @param in map of parameters to encode
*/
- private byte[] serializeAndTimestamp(Map<String, String> in) {
+ private byte[] serialize(Map<String, String> in) {
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> val : in.entrySet()) {
@@ -179,17 +169,16 @@ public class BasicBlobCrypter implements
sb.append(Utf8UrlCoder.encode(val.getValue()));
sb.append('&');
}
- sb.append(TIMESTAMP_KEY);
- sb.append('=');
- sb.append(timeSource.currentTimeMillis()/1000);
+ if (sb.length() > 0) {
+ sb.deleteCharAt(sb.length() - 1); // Remove the last &
+ }
return CharsetUtil.getUtf8Bytes(sb.toString());
}
/* (non-Javadoc)
* @see org.apache.shindig.util.BlobCrypter#unwrap(java.lang.String, int)
*/
- public Map<String, String> unwrap(String in, int maxAgeSec)
- throws BlobCrypterException {
+ public Map<String, String> unwrap(String in) throws BlobCrypterException {
try {
byte[] bin = Base64.decodeBase64(CharsetUtil.getUtf8Bytes(in));
byte[] hmac = new byte[Crypto.HMAC_SHA1_LEN];
@@ -199,7 +188,6 @@ public class BasicBlobCrypter implements
Crypto.hmacSha1Verify(hmacKey, cipherText, hmac);
byte[] plain = Crypto.aes128cbcDecrypt(cipherKey, cipherText);
Map<String, String> out = deserialize(plain);
- checkTimestamp(out, maxAgeSec);
return out;
} catch (GeneralSecurityException e) {
throw new BlobCrypterException("Invalid token signature", e);
@@ -223,20 +211,4 @@ public class BasicBlobCrypter implements
}
return map;
}
-
- /**
- * We allow a few minutes on either side of the validity window to account
- * for clock skew.
- */
- private void checkTimestamp(Map<String, String> out, int maxAge)
- throws BlobExpiredException {
- long origin = Long.parseLong(out.get(TIMESTAMP_KEY));
- long minTime = origin - CLOCK_SKEW_ALLOWANCE;
- long maxTime = origin + maxAge + CLOCK_SKEW_ALLOWANCE;
- long now = timeSource.currentTimeMillis()/1000;
- if (!(minTime < now && now < maxTime)) {
- throw new BlobExpiredException(minTime, now, maxTime);
- }
- }
-
}
Modified: shindig/trunk/java/common/src/main/java/org/apache/shindig/common/crypto/BlobCrypter.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/crypto/BlobCrypter.java?rev=1187358&r1=1187357&r2=1187358&view=diff
==============================================================================
--- shindig/trunk/java/common/src/main/java/org/apache/shindig/common/crypto/BlobCrypter.java (original)
+++ shindig/trunk/java/common/src/main/java/org/apache/shindig/common/crypto/BlobCrypter.java Fri Oct 21 14:19:33 2011
@@ -21,16 +21,15 @@ package org.apache.shindig.common.crypto
import java.util.Map;
/**
- * Utility interface for managing signed, encrypted, and time stamped blobs.
- * Blobs are made up of name/value pairs. Time stamps are automatically
- * included and checked.
+ * Utility interface for managing signed and encrypted blobs.
+ * Blobs are made up of name/value pairs.
*
* Thread safe.
*/
public interface BlobCrypter {
/**
- * Time stamps, encrypts, and signs a blob.
+ * Encrypts and signs a blob.
*
* @param in name/value pairs to encrypt
* @return a base64 encoded blob
@@ -43,12 +42,9 @@ public interface BlobCrypter {
* Unwraps a blob.
*
* @param in blob
- * @param maxAgeSec maximum age for the blob
- * @return the name/value pairs, including the origin timestamp.
+ * @return the name/value pairs.
*
- * @throws BlobExpiredException if the blob is too old to be accepted.
* @throws BlobCrypterException if the blob can't be decoded.
*/
- Map<String, String> unwrap(String in, int maxAgeSec)
- throws BlobCrypterException;
+ Map<String, String> unwrap(String in) throws BlobCrypterException;
}
Modified: shindig/trunk/java/common/src/main/java/org/apache/shindig/common/crypto/BlobExpiredException.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/crypto/BlobExpiredException.java?rev=1187358&r1=1187357&r2=1187358&view=diff
==============================================================================
--- shindig/trunk/java/common/src/main/java/org/apache/shindig/common/crypto/BlobExpiredException.java (original)
+++ shindig/trunk/java/common/src/main/java/org/apache/shindig/common/crypto/BlobExpiredException.java Fri Oct 21 14:19:33 2011
@@ -25,20 +25,16 @@ import java.util.Date;
*/
public class BlobExpiredException extends BlobCrypterException {
- public final Date minDate;
public final Date used;
public final Date maxDate;
- public BlobExpiredException(long minTime, long now, long maxTime) {
- this(new Date(minTime*1000), new Date(now*1000), new Date(maxTime*1000));
+ public BlobExpiredException(long now, long maxTime) {
+ this(new Date(now*1000), new Date(maxTime*1000));
}
- public BlobExpiredException(Date minTime, Date now, Date maxTime) {
- super("Blob expired, was valid from " + minTime + " to " + maxTime
- + ", attempted use at " + now);
- this.minDate = minTime;
+ public BlobExpiredException(Date now, Date maxTime) {
+ super("Blob expired. Was valid until " + maxTime + ", attempted use at " + now);
this.used = now;
this.maxDate = maxTime;
}
-
}
Modified: shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/BasicSecurityTokenCodecTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/BasicSecurityTokenCodecTest.java?rev=1187358&r1=1187357&r2=1187358&view=diff
==============================================================================
--- shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/BasicSecurityTokenCodecTest.java (original)
+++ shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/BasicSecurityTokenCodecTest.java Fri Oct 21 14:19:33 2011
@@ -18,10 +18,7 @@
*/
package org.apache.shindig.auth;
-import static junit.framework.Assert.assertNull;
-
import org.junit.Before;
-import org.junit.Test;
public class BasicSecurityTokenCodecTest {
@@ -31,9 +28,4 @@ public class BasicSecurityTokenCodecTest
public void setUp() throws Exception {
codec = new BasicSecurityTokenCodec();
}
-
- @Test
- public void testGetTokenExpiration() throws Exception {
- assertNull(codec.getTokenExpiration(null));
- }
}
Modified: shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/BlobCrypterSecurityTokenCodecTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/BlobCrypterSecurityTokenCodecTest.java?rev=1187358&r1=1187357&r2=1187358&view=diff
==============================================================================
--- shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/BlobCrypterSecurityTokenCodecTest.java (original)
+++ shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/BlobCrypterSecurityTokenCodecTest.java Fri Oct 21 14:19:33 2011
@@ -22,24 +22,22 @@ import static org.junit.Assert.assertEqu
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.shindig.auth.AbstractSecurityToken.Keys;
import org.apache.shindig.common.crypto.BasicBlobCrypter;
import org.apache.shindig.common.crypto.BlobCrypter;
import org.apache.shindig.common.util.CharsetUtil;
import org.apache.shindig.common.util.FakeTimeSource;
import org.apache.shindig.config.BasicContainerConfig;
import org.apache.shindig.config.ContainerConfig;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-import junit.framework.Assert;
-
import org.junit.Before;
import org.junit.Test;
-import java.io.File;
-import java.io.IOException;
-import java.util.Map;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
/**
* Tests for BlobCrypterSecurityTokenCodec
@@ -47,7 +45,7 @@ import java.util.Map;
public class BlobCrypterSecurityTokenCodecTest {
private BlobCrypterSecurityTokenCodec codec;
- private final FakeTimeSource timeSource = new FakeTimeSource();
+ private FakeTimeSource timeSource;
private ContainerConfig config;
@Before
@@ -60,8 +58,9 @@ public class BlobCrypterSecurityTokenCod
.addContainer(makeContainer("example"))
.commit();
codec = new CodecWithLoadStubbedOut(config);
+ timeSource = new FakeTimeSource();
}
-
+
protected Map<String, Object> makeContainer(String container) {
return ImmutableMap.<String, Object>of(ContainerConfig.CONTAINER_KEY,
ImmutableList.of(container),
@@ -70,7 +69,7 @@ public class BlobCrypterSecurityTokenCod
BlobCrypterSecurityTokenCodec.SIGNED_FETCH_DOMAIN,
container + ".com");
}
-
+
protected String getContainerKey(String container) {
return "KEY FOR CONTAINER " + container;
}
@@ -106,17 +105,17 @@ public class BlobCrypterSecurityTokenCod
@Test
public void testCreateToken() throws Exception {
- BlobCrypterSecurityToken t = new BlobCrypterSecurityToken("container", null);
- t.setAppUrl("http://www.example.com/gadget.xml");
- t.setModuleId(12345L);
- t.setOwnerId("owner");
- t.setViewerId("viewer");
- t.setTrustedJson("trusted");
- String encrypted = BlobCrypterSecurityToken.encrypt(t,
- getBlobCrypter(getContainerKey("container")));
+ Map<String, String> values = new HashMap<String, String>();
+ values.put(Keys.APP_URL.getKey(), "http://www.example.com/gadget.xml");
+ values.put(Keys.MODULE_ID.getKey(), Long.toString(12345L, 10));
+ values.put(Keys.OWNER.getKey(), "owner");
+ values.put(Keys.VIEWER.getKey(), "viewer");
+ values.put(Keys.TRUSTED_JSON.getKey(), "trusted");
- SecurityToken t2 = codec.createToken(
- ImmutableMap.of(SecurityTokenCodec.SECURITY_TOKEN_NAME, encrypted));
+ BlobCrypterSecurityToken t = new BlobCrypterSecurityToken("container", null, null, values);
+ String encrypted = t.getContainer() + ":" + getBlobCrypter(getContainerKey("container")).wrap(t.toMap());
+
+ SecurityToken t2 = codec.createToken(ImmutableMap.of(SecurityTokenCodec.SECURITY_TOKEN_NAME, encrypted));
assertEquals("http://www.example.com/gadget.xml", t2.getAppId());
assertEquals("http://www.example.com/gadget.xml", t2.getAppUrl());
@@ -129,14 +128,15 @@ public class BlobCrypterSecurityTokenCod
@Test
public void testUnknownContainer() throws Exception {
- BlobCrypterSecurityToken t = new BlobCrypterSecurityToken("container", null);
- t.setAppUrl("http://www.example.com/gadget.xml");
- t.setModuleId(12345L);
- t.setOwnerId("owner");
- t.setViewerId("viewer");
- t.setTrustedJson("trusted");
- String encrypted = BlobCrypterSecurityToken.encrypt(t,
- getBlobCrypter(getContainerKey("container")));
+ Map<String, String> values = new HashMap<String, String>();
+ values.put(Keys.APP_URL.getKey(), "http://www.example.com/gadget.xml");
+ values.put(Keys.MODULE_ID.getKey(), Long.toString(12345L, 10));
+ values.put(Keys.OWNER.getKey(), "owner");
+ values.put(Keys.VIEWER.getKey(), "viewer");
+ values.put(Keys.TRUSTED_JSON.getKey(), "trusted");
+
+ BlobCrypterSecurityToken t = new BlobCrypterSecurityToken("container", null, null, values);
+ String encrypted = t.getContainer() + ":" + getBlobCrypter(getContainerKey("container")).wrap(t.toMap());
encrypted = encrypted.replace("container:", "other:");
try {
@@ -149,14 +149,15 @@ public class BlobCrypterSecurityTokenCod
@Test
public void testWrongContainer() throws Exception {
- BlobCrypterSecurityToken t = new BlobCrypterSecurityToken("container", null);
- t.setAppUrl("http://www.example.com/gadget.xml");
- t.setModuleId(12345L);
- t.setOwnerId("owner");
- t.setViewerId("viewer");
- t.setTrustedJson("trusted");
- String encrypted = BlobCrypterSecurityToken.encrypt(t,
- getBlobCrypter(getContainerKey("container")));
+ Map<String, String> values = new HashMap<String, String>();
+ values.put(Keys.APP_URL.getKey(), "http://www.example.com/gadget.xml");
+ values.put(Keys.MODULE_ID.getKey(), Long.toString(12345L, 10));
+ values.put(Keys.OWNER.getKey(), "owner");
+ values.put(Keys.VIEWER.getKey(), "viewer");
+ values.put(Keys.TRUSTED_JSON.getKey(), "trusted");
+
+ BlobCrypterSecurityToken t = new BlobCrypterSecurityToken("container", null, null, values);
+ String encrypted = t.getContainer() + ":" + getBlobCrypter(getContainerKey("container")).wrap(t.toMap());
encrypted = encrypted.replace("container:", "example:");
try {
@@ -169,16 +170,17 @@ public class BlobCrypterSecurityTokenCod
@Test
public void testExpired() throws Exception {
- BlobCrypterSecurityToken t = new BlobCrypterSecurityToken("container", null);
- t.setAppUrl("http://www.example.com/gadget.xml");
- t.setModuleId(12345L);
- t.setOwnerId("owner");
- t.setViewerId("viewer");
- t.setTrustedJson("trusted");
- String encrypted = BlobCrypterSecurityToken.encrypt(t,
- getBlobCrypter(getContainerKey("container")));
-
- timeSource.incrementSeconds(3600 + 181); // one hour plus clock skew
+ Map<String, String> values = new HashMap<String, String>();
+ values.put(Keys.APP_URL.getKey(), "http://www.example.com/gadget.xml");
+ values.put(Keys.MODULE_ID.getKey(), Long.toString(12345L, 10));
+ values.put(Keys.OWNER.getKey(), "owner");
+ values.put(Keys.VIEWER.getKey(), "viewer");
+ values.put(Keys.TRUSTED_JSON.getKey(), "trusted");
+
+ BlobCrypterSecurityToken token = new BlobCrypterSecurityToken("container", null, null, values);
+ token.setTimeSource(timeSource);
+ timeSource.incrementSeconds(-1 * (3600 + 181)); // one hour plus clock skew
+ String encrypted = codec.encodeToken(token);
try {
codec.createToken(ImmutableMap.of(SecurityTokenCodec.SECURITY_TOKEN_NAME, encrypted));
fail("should have expired");
@@ -223,14 +225,15 @@ public class BlobCrypterSecurityTokenCod
@Test
public void testChangingContainers() throws Exception {
String newContainer = "newcontainer";
- BlobCrypterSecurityToken t = new BlobCrypterSecurityToken(newContainer, null);
- t.setAppUrl("http://www.example.com/gadget.xml");
- t.setModuleId(12345L);
- t.setOwnerId("owner");
- t.setViewerId("viewer");
- t.setTrustedJson("trusted");
- String encrypted = BlobCrypterSecurityToken.encrypt(t,
- getBlobCrypter(getContainerKey(newContainer)));
+ Map<String, String> values = new HashMap<String, String>();
+ values.put(Keys.APP_URL.getKey(), "http://www.example.com/gadget.xml");
+ values.put(Keys.MODULE_ID.getKey(), Long.toString(12345L, 10));
+ values.put(Keys.OWNER.getKey(), "owner");
+ values.put(Keys.VIEWER.getKey(), "viewer");
+ values.put(Keys.TRUSTED_JSON.getKey(), "trusted");
+
+ BlobCrypterSecurityToken t = new BlobCrypterSecurityToken(newContainer, null, null, values);
+ String encrypted = t.getContainer() + ":" + getBlobCrypter(getContainerKey(newContainer)).wrap(t.toMap());
// fails when trying to create a token for a non-existing container
try {
@@ -251,9 +254,4 @@ public class BlobCrypterSecurityTokenCod
// pass
}
}
-
- @Test
- public void testGetTokenExpiration() throws Exception {
- Assert.assertNull(codec.getTokenExpiration(null));
- }
}
Modified: shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/BlobCrypterSecurityTokenTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/BlobCrypterSecurityTokenTest.java?rev=1187358&r1=1187357&r2=1187358&view=diff
==============================================================================
--- shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/BlobCrypterSecurityTokenTest.java (original)
+++ shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/BlobCrypterSecurityTokenTest.java Fri Oct 21 14:19:33 2011
@@ -18,16 +18,18 @@
*/
package org.apache.shindig.auth;
-import org.apache.commons.lang.StringUtils;
-import org.apache.shindig.common.crypto.BasicBlobCrypter;
-import org.apache.shindig.common.crypto.BlobExpiredException;
-import org.apache.shindig.common.crypto.Crypto;
-import org.apache.shindig.common.util.FakeTimeSource;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.shindig.auth.AbstractSecurityToken.Keys;
+import org.apache.shindig.common.crypto.BasicBlobCrypter;
+import org.apache.shindig.common.crypto.Crypto;
+import org.apache.shindig.common.util.FakeTimeSource;
import org.junit.Before;
import org.junit.Test;
@@ -50,12 +52,12 @@ public class BlobCrypterSecurityTokenTes
@Test(expected=UnsupportedOperationException.class)
public void testNullValues() throws Exception {
- BlobCrypterSecurityToken t = new BlobCrypterSecurityToken(CONTAINER, DOMAIN);
- String token = BlobCrypterSecurityToken.encrypt(t, crypter);
+ BlobCrypterSecurityToken t = new BlobCrypterSecurityToken(CONTAINER, DOMAIN, null, null);
+ String token = t.getContainer() + ":" + crypter.wrap(t.toMap());
assertTrue("should start with container: " + token, token.startsWith("container:"));
String[] fields = StringUtils.split(token, ':');
- BlobCrypterSecurityToken t2 =
- BlobCrypterSecurityToken.decrypt(crypter, CONTAINER, DOMAIN, fields[1], null);
+ BlobCrypterSecurityToken t2 = new BlobCrypterSecurityToken(CONTAINER, DOMAIN, null, crypter.unwrap(fields[1]));
+
assertNull(t2.getAppId(), t2.getAppId());
assertNull(t2.getAppUrl(), t2.getAppUrl());
assertEquals(DOMAIN, t2.getDomain());
@@ -72,17 +74,18 @@ public class BlobCrypterSecurityTokenTes
@Test
public void testRealValues() throws Exception {
- BlobCrypterSecurityToken t = new BlobCrypterSecurityToken(CONTAINER, DOMAIN);
- t.setAppUrl("http://www.example.com/gadget.xml");
- t.setModuleId(12345L);
- t.setOwnerId("owner");
- t.setViewerId("viewer");
- t.setTrustedJson("trusted");
- String token = BlobCrypterSecurityToken.encrypt(t, crypter);
+ Map<String, String> values = new HashMap<String, String>();
+ values.put(Keys.APP_URL.getKey(), "http://www.example.com/gadget.xml");
+ values.put(Keys.MODULE_ID.getKey(), Long.toString(12345L, 10));
+ values.put(Keys.OWNER.getKey(), "owner");
+ values.put(Keys.VIEWER.getKey(), "viewer");
+ values.put(Keys.TRUSTED_JSON.getKey(), "trusted");
+
+ BlobCrypterSecurityToken t = new BlobCrypterSecurityToken(CONTAINER, DOMAIN, null, values);
+ String token = t.getContainer() + ":" + crypter.wrap(t.toMap());
assertTrue("should start with container: " + token, token.startsWith("container:"));
String[] fields = StringUtils.split(token, ':');
- BlobCrypterSecurityToken t2 =
- BlobCrypterSecurityToken.decrypt(crypter, CONTAINER, DOMAIN, fields[1], "active");
+ BlobCrypterSecurityToken t2 = new BlobCrypterSecurityToken(CONTAINER, DOMAIN, "active", crypter.unwrap(fields[1]));
assertEquals("http://www.example.com/gadget.xml", t2.getAppId());
assertEquals("http://www.example.com/gadget.xml", t2.getAppUrl());
assertEquals(DOMAIN, t2.getDomain());
@@ -93,16 +96,4 @@ public class BlobCrypterSecurityTokenTes
assertEquals(CONTAINER, t2.getContainer());
assertEquals("active", t2.getActiveUrl());
}
-
- @Test(expected=BlobExpiredException.class)
- public void testExpired() throws Exception {
- BlobCrypterSecurityToken t = new BlobCrypterSecurityToken(CONTAINER, DOMAIN);
- String token = BlobCrypterSecurityToken.encrypt(t, crypter);
- // one hour plus clock skew
- timeSource.incrementSeconds(3600 + 181);
- String[] fields = StringUtils.split(token, ':');
-
- // expect an exception
- BlobCrypterSecurityToken.decrypt(crypter, CONTAINER, DOMAIN, fields[1], "active");
- }
}
Modified: shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/DefaultSecurityTokenCodecTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/DefaultSecurityTokenCodecTest.java?rev=1187358&r1=1187357&r2=1187358&view=diff
==============================================================================
--- shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/DefaultSecurityTokenCodecTest.java (original)
+++ shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/DefaultSecurityTokenCodecTest.java Fri Oct 21 14:19:33 2011
@@ -19,21 +19,19 @@
package org.apache.shindig.auth;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import org.apache.shindig.config.BasicContainerConfig;
-
-import com.google.common.collect.Lists;
-
-import org.junit.Test;
-
import java.io.FileNotFoundException;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
+import org.apache.shindig.config.BasicContainerConfig;
+import org.junit.Test;
+
+import com.google.common.collect.Lists;
+
/**
* Tests of DefaultSecurityTokenCodec
*/
@@ -68,7 +66,8 @@ public class DefaultSecurityTokenCodecTe
public void testBasicDecoder() throws Exception {
DefaultSecurityTokenCodec codec = new DefaultSecurityTokenCodec(
new FakeContainerConfig("insecure"));
- String token = "o:v:app:domain:appurl:12345:container";
+ Long expires = System.currentTimeMillis() / 1000 + 500; // 50 seconds in the future
+ String token = "o:v:app:domain:appurl:12345:container:" + Long.toString(expires, 10);
Map<String, String> parameters = Collections.singletonMap(
SecurityTokenCodec.SECURITY_TOKEN_NAME, token);
SecurityToken st = codec.createToken(parameters);
@@ -76,7 +75,7 @@ public class DefaultSecurityTokenCodecTe
assertEquals("v", st.getViewerId());
assertEquals("appurl", st.getAppUrl());
assertEquals("container", st.getContainer());
- assertNull(codec.getTokenExpiration(st));
+ assertEquals(expires, st.getExpiresAt());
}
@Test
Modified: shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/UrlParameterAuthenticationHandlerTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/UrlParameterAuthenticationHandlerTest.java?rev=1187358&r1=1187357&r2=1187358&view=diff
==============================================================================
--- shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/UrlParameterAuthenticationHandlerTest.java (original)
+++ shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/UrlParameterAuthenticationHandlerTest.java Fri Oct 21 14:19:33 2011
@@ -35,7 +35,7 @@ public class UrlParameterAuthenticationH
public void setup() throws Exception {
expectedToken = new BasicSecurityToken(
"owner", "viewer", "app",
- "domain", "appUrl", "moduleId", "container", "activeUrl", 1000L);
+ "domain", "appUrl", "0", "container", "activeUrl", 1000L);
// Mock token codec
codec = new SecurityTokenCodec() {
public SecurityToken createToken(Map<String, String> tokenParameters) throws SecurityTokenException {
@@ -46,10 +46,6 @@ public class UrlParameterAuthenticationH
public String encodeToken(SecurityToken token) throws SecurityTokenException {
return null;
}
-
- public Long getTokenExpiration(SecurityToken token) throws SecurityTokenException {
- return null;
- }
};
authHandler = new UrlParameterAuthenticationHandler(codec, true);
Modified: shindig/trunk/java/common/src/test/java/org/apache/shindig/common/crypto/BlobCrypterTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/test/java/org/apache/shindig/common/crypto/BlobCrypterTest.java?rev=1187358&r1=1187357&r2=1187358&view=diff
==============================================================================
--- shindig/trunk/java/common/src/test/java/org/apache/shindig/common/crypto/BlobCrypterTest.java (original)
+++ shindig/trunk/java/common/src/test/java/org/apache/shindig/common/crypto/BlobCrypterTest.java Fri Oct 21 14:19:33 2011
@@ -59,7 +59,7 @@ public class BlobCrypterTest {
in.put("a", string);
}
String blob = crypter.wrap(in);
- Map<String, String> out = crypter.unwrap(blob, 0);
+ Map<String, String> out = crypter.unwrap(blob);
assertEquals(string, out.get("a"));
}
@@ -74,7 +74,7 @@ public class BlobCrypterTest {
private void assertThrowsBlobCrypterException(String in) {
try {
- crypter.unwrap(in, 1000);
+ crypter.unwrap(in);
fail("Should have thrown BlobCrypterException for input " + in);
} catch (BlobCrypterException e) {
// Good.
@@ -88,33 +88,12 @@ public class BlobCrypterTest {
in.put(Integer.toString(i), Integer.toString(i));
}
String blob = crypter.wrap(in);
- Map<String, String> out = crypter.unwrap(blob, 0);
+ Map<String, String> out = crypter.unwrap(blob);
for (int i=0; i < 1000; i++) {
assertEquals(out.get(Integer.toString(i)), Integer.toString(i));
}
}
- @Test
- public void testTimeStamping() throws Exception {
- long start = 1201917724000L;
- long skew = 180000;
- int maxAge = 300; // 5 minutes
- int realAge = 600; // 10 minutes
- try {
-
- timeSource.setCurrentTimeMillis(start);
- Map<String, String> in = ImmutableMap.of("a","b");
- String blob = crypter.wrap(in);
- timeSource.incrementSeconds(realAge);
- crypter.unwrap(blob, maxAge);
- fail("Blob should have expired");
- } catch (BlobExpiredException e) {
- assertEquals(start-skew, e.minDate.getTime());
- assertEquals(start+realAge*1000L, e.used.getTime());
- assertEquals(start+skew+maxAge*1000L, e.maxDate.getTime());
- }
- }
-
@Test(expected=BlobCrypterException.class)
public void testTamperIV() throws Exception {
Map<String, String> in = ImmutableMap.of("a","b");
@@ -123,7 +102,7 @@ public class BlobCrypterTest {
byte[] blobBytes = Base64.decodeBase64(blob.getBytes());
blobBytes[0] ^= 0x01;
String tampered = new String(Base64.encodeBase64(blobBytes));
- crypter.unwrap(tampered, 30);
+ crypter.unwrap(tampered);
}
@Test(expected=BlobCrypterException.class)
@@ -133,7 +112,7 @@ public class BlobCrypterTest {
byte[] blobBytes = Base64.decodeBase64(blob.getBytes());
blobBytes[30] ^= 0x01;
String tampered = new String(Base64.encodeBase64(blobBytes));
- crypter.unwrap(tampered, 30);
+ crypter.unwrap(tampered);
}
@Test(expected=BlobCrypterException.class)
@@ -144,7 +123,7 @@ public class BlobCrypterTest {
byte[] blobBytes = Base64.decodeBase64(blob.getBytes());
blobBytes[blobBytes.length-1] ^= 0x01;
String tampered = new String(Base64.encodeBase64(blobBytes));
- crypter.unwrap(tampered, 30);
+ crypter.unwrap(tampered);
}
@Test
@@ -153,7 +132,7 @@ public class BlobCrypterTest {
Map<String, String> in = ImmutableMap.of("a","b");
String blob = crypter.wrap(in);
- Map<String, String> out = alt.unwrap(blob, 30);
+ Map<String, String> out = alt.unwrap(blob);
assertEquals("b", out.get("a"));
}
@@ -163,7 +142,7 @@ public class BlobCrypterTest {
Map<String, String> in = ImmutableMap.of("a","b");
String blob = crypter.wrap(in);
- alt.unwrap(blob, 30);
+ alt.unwrap(blob);
}
@Test(expected=IllegalArgumentException.class)
Modified: shindig/trunk/java/common/src/test/java/org/apache/shindig/common/testing/FakeGadgetToken.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/test/java/org/apache/shindig/common/testing/FakeGadgetToken.java?rev=1187358&r1=1187357&r2=1187358&view=diff
==============================================================================
--- shindig/trunk/java/common/src/test/java/org/apache/shindig/common/testing/FakeGadgetToken.java (original)
+++ shindig/trunk/java/common/src/test/java/org/apache/shindig/common/testing/FakeGadgetToken.java Fri Oct 21 14:19:33 2011
@@ -18,212 +18,136 @@
*/
package org.apache.shindig.common.testing;
+import java.util.EnumSet;
+import java.util.Map;
+
import org.apache.shindig.auth.AbstractSecurityToken;
import org.apache.shindig.auth.AuthenticationMode;
import org.apache.shindig.auth.SecurityToken;
import org.apache.shindig.auth.SecurityTokenCodec;
-
-import com.google.common.collect.Maps;
import org.apache.shindig.auth.SecurityTokenException;
-import java.util.Map;
-
/**
* A fake SecurityToken implementation to help testing.
*/
-public class FakeGadgetToken extends AbstractSecurityToken implements SecurityToken {
-
- private String updatedToken = null;
- private String trustedJson = null;
+public class FakeGadgetToken extends AbstractSecurityToken {
- private String ownerId = null;
- private String viewerId = null;
- private String appId = null;
- private String domain = null;
- private String container = null;
- private String appUrl = null;
- private String activeUrl = null;
private String authMode = AuthenticationMode.SECURITY_TOKEN_URL_PARAMETER.name();
- private int moduleId = 0;
- private Long expiresAt = null;
-
- public FakeGadgetToken setUpdatedToken(String updatedToken) {
- this.updatedToken = updatedToken;
- return this;
- }
-
- public FakeGadgetToken setTrustedJson(String trustedJson) {
- this.trustedJson = trustedJson;
- return this;
- }
-
- public FakeGadgetToken setOwnerId(String ownerId) {
- this.ownerId = ownerId;
- return this;
- }
+ private String updated;
- public FakeGadgetToken setViewerId(String viewerId) {
- this.viewerId = viewerId;
- return this;
+ public String getAuthenticationMode() {
+ return authMode;
}
- public FakeGadgetToken setAppId(String appId) {
- this.appId = appId;
- return this;
+ public boolean isAnonymous() {
+ return false;
}
- public FakeGadgetToken setDomain(String domain) {
- this.domain = domain;
- return this;
- }
+ public FakeGadgetToken() {}
+ /**
+ * Create a fake security token from a map of parameter strings, keys are one of:
+ * ownerId, viewerId, domain, appUrl, appId, trustedJson, module
+ *
+ * @param paramMap
+ * @return The fake token
+ */
+ public FakeGadgetToken(Map<String, String> paramMap) {
+ this(
+ paramMap.get("appId"),
+ paramMap.get("appUrl"),
+ paramMap.get("domain"),
+ paramMap.get("ownerId"),
+ paramMap.get("trustedJson"),
+ paramMap.get("viewerId"),
+ paramMap.get("module")
+ );
+ }
+
+ public FakeGadgetToken(String appId, String appUrl, String domain, String ownerId, String trustedJson, String viewerId, String moduleId) {
+ setAppId(appId);
+ setAppUrl(appUrl);
+ setDomain(domain);
+ setOwnerId(ownerId);
+ setTrustedJson(trustedJson);
+ setViewerId(viewerId);
- public FakeGadgetToken setContainer(String container) {
- this.container = container;
- return this;
+ if (moduleId != null) {
+ setModuleId(Long.parseLong(moduleId));
+ }
}
- public FakeGadgetToken setAppUrl(String appUrl) {
- this.appUrl = appUrl;
- return this;
- }
+ /**
+ * SecurityTokenCodec for testing - this allows passing around a
+ * security token of format key=value&key2=value2, where key is one of:
+ * ownerId, viewerId, domain, appUrl, appId, trustedJson, module
+ */
+ public static class Codec implements SecurityTokenCodec {
+ public SecurityToken createToken(Map<String, String> tokenParameters) {
+ return new FakeGadgetToken(tokenParameters);
+ }
- public FakeGadgetToken setModuleId(int moduleId) {
- this.moduleId = moduleId;
- return this;
+ public String encodeToken(SecurityToken token) throws SecurityTokenException {
+ return null; // NOT USED
+ }
}
- public FakeGadgetToken setExpiresAt(Long expiresAt) {
- this.expiresAt = expiresAt;
+ public FakeGadgetToken setAuthenticationMode(String authMode) {
+ this.authMode = authMode;
return this;
}
- public FakeGadgetToken setActiveUrl(String activeUrl) {
- this.activeUrl = activeUrl;
+ public FakeGadgetToken setUpdatedToken(String updated) {
+ this.updated = updated;
return this;
}
- public void setAuthenticationMode(String authMode) {
- this.authMode = authMode;
- }
-
- public String getOwnerId() {
- return ownerId;
- }
-
- public String getViewerId() {
- return viewerId;
- }
-
- public String getAppId() {
- return appId;
- }
-
- public String getDomain() {
- return domain;
- }
-
- public String getContainer() {
- return container;
+ @Override
+ public String getUpdatedToken() {
+ return updated;
}
- public String getAppUrl() {
- return appUrl;
+ @Override
+ protected EnumSet<Keys> getMapKeys() {
+ return EnumSet.noneOf(Keys.class);
}
- public long getModuleId() {
- return moduleId;
+ public FakeGadgetToken setAppUrl(String appUrl) {
+ return (FakeGadgetToken)super.setAppUrl(appUrl);
}
- public Long getExpiresAt() {
- return expiresAt;
+ public FakeGadgetToken setOwnerId(String ownerId) {
+ return (FakeGadgetToken)super.setOwnerId(ownerId);
}
- public String getUpdatedToken() {
- return updatedToken;
+ public FakeGadgetToken setViewerId(String viewerId) {
+ return (FakeGadgetToken)super.setViewerId(viewerId);
}
- public String getAuthenticationMode() {
- return authMode;
+ public FakeGadgetToken setAppId(String appId) {
+ return (FakeGadgetToken)super.setAppId(appId);
}
- public String getTrustedJson() {
- return trustedJson;
+ public FakeGadgetToken setDomain(String domain) {
+ return (FakeGadgetToken)super.setDomain(domain);
}
- public boolean isAnonymous() {
- return false;
+ public FakeGadgetToken setContainer(String container) {
+ return (FakeGadgetToken)super.setContainer(container);
}
- @Override
- public String getActiveUrl() {
- return activeUrl;
+ public FakeGadgetToken setModuleId(long moduleId) {
+ return (FakeGadgetToken)super.setModuleId(moduleId);
}
- /**
- * Create a fake security token parameter string, allows passing around a
- * security token of format key=value&key2=value2, where key is one of:
- * ownerId, viewerId, domain, appUrl, appId, trustedJson, module.
- *
- * Useful for creating tokens that can be decoded with FakeGadgetToken.Decoder
- *
- * @param tokenString the parameter string
- * @return The fake token
- */
- public static SecurityToken createToken(String tokenString) {
- String keyValuePairs[] = tokenString.split("&");
- Map<String, String> paramMap = Maps.newHashMap();
-
- for (String keyValuePair : keyValuePairs) {
- String[] keyAndValue = keyValuePair.split("=");
- if (keyAndValue.length == 2) {
- paramMap.put(keyAndValue[0], keyAndValue[1]);
- }
- }
-
- return createToken(paramMap);
+ public FakeGadgetToken setExpiresAt(Long expiresAt) {
+ return (FakeGadgetToken)super.setExpiresAt(expiresAt);
}
- /**
- * Create a fake security token from a map of parameter strings, keys are one of:
- * ownerId, viewerId, domain, appUrl, appId, trustedJson, module
- *
- * @param paramMap
- * @return The fake token
- */
- public static FakeGadgetToken createToken(Map<String, String> paramMap) {
- FakeGadgetToken fakeToken = new FakeGadgetToken();
-
- fakeToken.setAppId(paramMap.get("appId"));
- fakeToken.setAppUrl(paramMap.get("appUrl"));
- fakeToken.setDomain(paramMap.get("domain"));
- fakeToken.setOwnerId(paramMap.get("ownerId"));
- fakeToken.setTrustedJson(paramMap.get("trustedJson"));
- fakeToken.setViewerId(paramMap.get("viewerId"));
-
- String moduleIdStr = paramMap.get("module");
- if (moduleIdStr != null) {
- fakeToken.setModuleId(Integer.parseInt(moduleIdStr));
- }
-
- return fakeToken;
+ public FakeGadgetToken setTrustedJson(String trustedJson) {
+ return (FakeGadgetToken)super.setTrustedJson(trustedJson);
}
- /**
- * SecurityTokenCodec for testing - this allows passing around a
- * security token of format key=value&key2=value2, where key is one of:
- * ownerId, viewerId, domain, appUrl, appId, trustedJson, module
- */
- public static class Codec implements SecurityTokenCodec {
- public SecurityToken createToken(Map<String, String> tokenParameters) {
- return FakeGadgetToken.createToken(tokenParameters);
- }
-
- public String encodeToken(SecurityToken token) throws SecurityTokenException {
- return null; // NOT USED
- }
-
- public Long getTokenExpiration(SecurityToken token) throws SecurityTokenException {
- return null; // NOT USED
- }
+ public FakeGadgetToken setActiveUrl(String activeUrl) {
+ return (FakeGadgetToken)super.setActiveUrl(activeUrl);
}
}
Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/config/ShindigAuthConfigContributor.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/config/ShindigAuthConfigContributor.java?rev=1187358&r1=1187357&r2=1187358&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/config/ShindigAuthConfigContributor.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/config/ShindigAuthConfigContributor.java Fri Oct 21 14:19:33 2011
@@ -67,7 +67,7 @@ public class ShindigAuthConfigContributo
/** {@inheritDoc} */
public void contribute(Map<String,Object> config, String container, String host) {
// Inject an anonymous security token TODO set TTL based on cachability of this JS?
- SecurityToken containerToken = new AnonymousSecurityToken(container, 0,"*", 1000L * 60 * 60 * 24);
+ SecurityToken containerToken = new AnonymousSecurityToken(container, 0L,"*", null);
Map<String, String> authConfig = Maps.newHashMapWithExpectedSize(2);
try {
Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/OAuthCallbackState.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/OAuthCallbackState.java?rev=1187358&r1=1187357&r2=1187358&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/OAuthCallbackState.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/OAuthCallbackState.java Fri Oct 21 14:19:33 2011
@@ -32,43 +32,44 @@ import java.util.Map;
*/
public class OAuthCallbackState {
- private static final int CALLBACK_STATE_MAX_AGE_SECS = 600;
-
- private static final String REAL_CALLBACK_URL_KEY = "u";
-
private final BlobCrypter crypter;
- private final Map<String, String> state;
-
+ private OAuthCallbackStateToken state;
+
public OAuthCallbackState(BlobCrypter crypter) {
this.crypter = crypter;
- this.state = Maps.newHashMap();
+ this.state = new OAuthCallbackStateToken();
}
-
+
public OAuthCallbackState(BlobCrypter crypter, String stateBlob) {
this.crypter = crypter;
- Map<String, String> state = Maps.newHashMap();
+ Map<String, String> state = null;
if (stateBlob != null) {
try {
- state = crypter.unwrap(stateBlob, CALLBACK_STATE_MAX_AGE_SECS);
+ state = crypter.unwrap(stateBlob);
+ if (state == null) {
+ state = Maps.newHashMap();
+ }
+ this.state = new OAuthCallbackStateToken(state);
+ this.state.enforceNotExpired();
} catch (BlobCrypterException e) {
// Too old, or corrupt. Ignore it.
+ state = null;
}
}
if (state == null) {
- state = Maps.newHashMap();
+ this.state = new OAuthCallbackStateToken();
}
- this.state = state;
}
-
+
public String getEncryptedState() throws BlobCrypterException {
- return crypter.wrap(state);
+ return crypter.wrap(state.toMap());
}
-
+
public String getRealCallbackUrl() {
- return state.get(REAL_CALLBACK_URL_KEY);
+ return state.getRealCallbackUrl();
}
-
+
public void setRealCallbackUrl(String realCallbackUrl) {
- state.put(REAL_CALLBACK_URL_KEY, realCallbackUrl);
+ state.setRealCallbackUrl(realCallbackUrl);
}
}
Added: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/OAuthCallbackStateToken.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/OAuthCallbackStateToken.java?rev=1187358&view=auto
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/OAuthCallbackStateToken.java (added)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/oauth/OAuthCallbackStateToken.java Fri Oct 21 14:19:33 2011
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.shindig.gadgets.oauth;
+
+import java.util.EnumSet;
+import java.util.Map;
+
+import org.apache.shindig.auth.AbstractSecurityToken;
+
+
+/**
+ * Token used to persist information for the {@link OAuthCallbackState}
+ */
+public class OAuthCallbackStateToken extends AbstractSecurityToken {
+ private static final EnumSet<Keys> MAP_KEYS = EnumSet.of(Keys.EXPIRES);
+ private static final String REAL_CALLBACK_URL_KEY = "u";
+
+ private String realCallbackUrl;
+
+ public OAuthCallbackStateToken () {}
+
+ public OAuthCallbackStateToken (Map<String, String> values) {
+ loadFromMap(values);
+ setRealCallbackUrl(values.get(REAL_CALLBACK_URL_KEY));
+ }
+
+ public String getUpdatedToken() {
+ return null;
+ }
+
+ public String getAuthenticationMode() {
+ return null;
+ }
+
+ public boolean isAnonymous() {
+ return false;
+ }
+
+ protected EnumSet<Keys> getMapKeys() {
+ return MAP_KEYS;
+ }
+
+ public OAuthCallbackStateToken setRealCallbackUrl(String realCallbackUrl) {
+ this.realCallbackUrl = realCallbackUrl;
+ return this;
+ }
+
+ @Override
+ protected int getMaxTokenTTL() {
+ return 600;
+ }
+
+ public String getRealCallbackUrl() {
+ return realCallbackUrl;
+ }
+
+ @Override
+ public Map<String, String> toMap() {
+ Map<String, String> map = super.toMap();
+ map.put(REAL_CALLBACK_URL_KEY, getRealCallbackUrl());
+ return map;
+ }
+}
+