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/11/02 01:53:42 UTC
svn commit: r1196414 - in /shindig/trunk:
features/src/main/javascript/features/container.util/
features/src/main/javascript/features/container/
java/common/src/main/java/org/apache/shindig/auth/
java/common/src/test/java/org/apache/shindig/auth/ java/...
Author: rbaxter85
Date: Wed Nov 2 00:53:41 2011
New Revision: 1196414
URL: http://svn.apache.org/viewvc?rev=1196414&view=rev
Log:
SHINDIG-1646
Committed for Dan Dumont.
Push down the token TTL to container page so it can schedule token refreshes accordingly.
Modified:
shindig/trunk/features/src/main/javascript/features/container.util/constant.js
shindig/trunk/features/src/main/javascript/features/container.util/util.js
shindig/trunk/features/src/main/javascript/features/container/container.js
shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/AbstractSecurityToken.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/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/SecurityTokenCodec.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/testing/FakeGadgetToken.java
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerApi.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/servlet/GadgetsHandlerServiceTest.java
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerTest.java
Modified: shindig/trunk/features/src/main/javascript/features/container.util/constant.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/container.util/constant.js?rev=1196414&r1=1196413&r2=1196414&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/container.util/constant.js (original)
+++ shindig/trunk/features/src/main/javascript/features/container.util/constant.js Wed Nov 2 00:53:41 2011
@@ -56,7 +56,8 @@ osapi.container.MetadataResponse = {
PREFERRED_HEIGHT: 'preferredHeight',
PREFERRED_WIDTH: 'preferredWidth',
RESPONSE_TIME_MS: 'responseTimeMs',
- WIDTH: 'width'
+ WIDTH: 'width',
+ TOKEN_TTL: 'tokenTTL'
};
Modified: shindig/trunk/features/src/main/javascript/features/container.util/util.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/container.util/util.js?rev=1196414&r1=1196413&r2=1196414&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/container.util/util.js (original)
+++ shindig/trunk/features/src/main/javascript/features/container.util/util.js Wed Nov 2 00:53:41 2011
@@ -81,7 +81,8 @@ osapi.container.util.newMetadataRequest
'views.preferredWidth',
'expireTimeMs',
'responseTimeMs',
- 'rpcServiceIds'
+ 'rpcServiceIds',
+ 'tokenTTL'
]
};
};
Modified: shindig/trunk/features/src/main/javascript/features/container/container.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/container/container.js?rev=1196414&r1=1196413&r2=1196414&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/container/container.js (original)
+++ shindig/trunk/features/src/main/javascript/features/container/container.js Wed Nov 2 00:53:41 2011
@@ -103,13 +103,24 @@ osapi.container.Container = function(opt
osapi.container.ContainerConfig.RENDER_TEST, false));
/**
- * Security token refresh interval (in ms) for debugging.
+ * Security token refresh interval (in ms). Set to < 0 in config to disable
+ * token refresh.
+ *
+ * Provided this number is >= 0, the smallest encountered token ttl or this
+ * number will be used as the refresh interval, whichever is smaller.
+ *
* @type {number}
* @private
*/
this.tokenRefreshInterval_ = Number(osapi.container.util.getSafeJsonValue(
- config, osapi.container.ContainerConfig.TOKEN_REFRESH_INTERVAL,
- 30 * 60 * 1000));
+ config, osapi.container.ContainerConfig.TOKEN_REFRESH_INTERVAL, 0));
+
+ /**
+ * The time of the last token refresh.
+ * @type {number}
+ * @private
+ */
+ this.lastRefresh_ = 0;
/**
* @type {number}
@@ -211,7 +222,7 @@ osapi.container.Container.prototype.navi
gadgets.warn(['Failed to possibly schedule token refresh for gadget ',
gadgetUrl, '.'].join(''));
} else if (gadgetInfo[osapi.container.MetadataResponse.NEEDS_TOKEN_REFRESH]) {
- self.scheduleRefreshTokens_();
+ self.scheduleRefreshTokens_(gadgetInfo[osapi.container.MetadataResponse.TOKEN_TTL]);
}
self.applyLifecycleCallbacks_(osapi.container.CallbackType.ON_NAVIGATED,
@@ -527,7 +538,7 @@ osapi.container.Container.prototype.addP
this.addPreloadedGadgetUrl_(id);
if (response[id][osapi.container.MetadataResponse.NEEDS_TOKEN_REFRESH]) {
// Safe to re-schedule many times.
- this.scheduleRefreshTokens_();
+ this.scheduleRefreshTokens_(response[id][osapi.container.MetadataResponse.TOKEN_TTL]);
}
}
}
@@ -584,25 +595,50 @@ osapi.container.Container.prototype.getG
return null;
};
-
/**
* Start to schedule refreshing of tokens.
+ * @param {number} Encountered token time to live in seconds.
* @private
*/
-osapi.container.Container.prototype.scheduleRefreshTokens_ = function() {
- // TODO: Obtain the interval time by taking the minimum of expiry time of
- // token in all preloaded- and navigated-to- gadgets. This should be obtained
- // from the server. For now, constant on 50% of long-lived tokens (1 hour),
- // which is 30 minutes.
- if (this.isRefreshTokensEnabled_() && !this.tokenRefreshTimer_) {
- var self = this;
- this.tokenRefreshTimer_ = window.setInterval(function() {
- self.refreshTokens_();
- }, this.tokenRefreshInterval_);
+osapi.container.Container.prototype.scheduleRefreshTokens_ = function(tokenTTL) {
+ var self = this,
+ oldInterval = this.tokenRefreshInterval_,
+ newInterval = tokenTTL ? this.setRefreshTokenInterval_(tokenTTL * 1000) : oldInterval,
+ refresh = function() {
+ self.lastRefresh_ = osapi.container.util.getCurrentTimeMs();
+ // Schedule the next refresh.
+ self.tokenRefreshTimer_ = setTimeout(refresh, newInterval);
+
+ // Do this last so that if it ever errors, we maintain the refresh schedule.
+ self.refreshTokens_();
+ };
+
+ // If enabled, check to see if we no schedule or if the two intervals are different and update the schedule.
+ if (this.isRefreshTokensEnabled_() && (!this.tokenRefreshTimer_ || newInterval != oldInterval)) {
+ var now = osapi.container.util.getCurrentTimeMs();
+ if (!this.tokenRefreshTimer_) {
+ this.lastRefresh_ = now;
+ this.tokenRefreshTimer_ = setTimeout(refresh, newInterval);
+ }
+ else {
+ var futureRefresh = (this.lastRefresh_ || 0) + oldInterval;
+ if (futureRefresh < now) {
+ // This really shouldn't happen, but if for some reason we missed a
+ // refresh, make sure we cancel any timer we have and schedule
+ // a new one.
+ futureRefresh = now + newInterval;
+ newInterval = 1;
+ }
+ if (futureRefresh > now + newInterval) {
+ // Cancel the old timer and create a new one if the next refresh is
+ // too far away.
+ clearTimeout(this.tokenRefreshTimer_);
+ this.tokenRefreshTimer_ = setTimeout(refresh, newInterval);
+ }
+ }
}
};
-
/**
* Stop already-scheduled refreshing of tokens.
* @private
@@ -619,10 +655,8 @@ osapi.container.Container.prototype.unsc
/**
- * Provides a manual override to disable token refresh to avoid gadgets.rpc
- * warning of service not found. We can do better to detect if token refresh is
- * even necessary, by inspecting the gadget transitively depend on
- * feature=security-token.
+ * Token refresh gets enabled if the value of refresh interval is > 0;
+ *
* @return {Boolean} if token refresh interval is of valid value.
* @private
*/
@@ -630,6 +664,30 @@ osapi.container.Container.prototype.isRe
return this.tokenRefreshInterval_ > 0;
};
+/**
+ * If the refresh interval is < 0, does nothing. Otherwise updates the tokenTTL
+ * to the smallest value encountered.
+ *
+ * @param {number} Encountered token time to live in milliseconds.
+ * @return {Boolean} The ttl if the set succeeded, otherwise false.
+ * @private
+ */
+osapi.container.Container.prototype.setRefreshTokenInterval_ = function(tokenTTL) {
+ // TODO: Handle the case where we've closed the gadget responsible for the
+ // shortest refresh time, and can now safely extend this.tokenRefreshInterval_
+ if (tokenTTL) {
+ tokenTTL *= .8; // 80% of the TTL value, for buffer.
+ var refresh = this.tokenRefreshInterval_;
+ if (refresh < 0) {
+ return refresh;
+ }
+ else {
+ return this.tokenRefreshInterval_ =
+ refresh == 0 ? tokenTTL : Math.min(refresh, tokenTTL);
+ }
+ }
+};
+
/**
* Register standard RPC services
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=1196414&r1=1196413&r2=1196414&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 Wed Nov 2 00:53:41 2011
@@ -38,8 +38,8 @@ public abstract class AbstractSecurityTo
/** 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;
+ // TODO: Make configurable.
+ public static final int MAX_TOKEN_TTL = 3600; // 1 hour
private static final TimeSource TIME_SOURCE = new TimeSource();
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=1196414&r1=1196413&r2=1196414&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 Wed Nov 2 00:53:41 2011
@@ -18,15 +18,15 @@
*/
package org.apache.shindig.auth;
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
import org.apache.shindig.common.crypto.BlobCrypterException;
import org.apache.shindig.common.util.Utf8UrlCoder;
-import org.apache.commons.lang.StringUtils;
import com.google.common.base.Joiner;
import com.google.inject.Singleton;
-import java.util.Map;
-
/**
* A SecurityTokenCodec implementation that just provides dummy data to satisfy
* tests and API calls. Do not use this for any security applications.
@@ -109,9 +109,12 @@ public class BasicSecurityTokenCodec imp
}
}
+ public int getTokenTimeToLive() {
+ return AbstractSecurityToken.MAX_TOKEN_TTL;
+ }
+
/**
- * Creates a signer with 24 hour token expiry
+ * Creates a basic signer
*/
- public BasicSecurityTokenCodec() {
- }
+ public BasicSecurityTokenCodec() {}
}
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=1196414&r1=1196413&r2=1196414&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 Wed Nov 2 00:53:41 2011
@@ -187,4 +187,8 @@ public class BlobCrypterSecurityTokenCod
throw new SecurityTokenException(e);
}
}
+
+ public int getTokenTimeToLive() {
+ return AbstractSecurityToken.MAX_TOKEN_TTL;
+ }
}
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=1196414&r1=1196413&r2=1196414&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 Wed Nov 2 00:53:41 2011
@@ -44,7 +44,6 @@ import java.util.Map;
*/
@Singleton
public class DefaultSecurityTokenCodec implements SecurityTokenCodec {
-
private static final String SECURITY_TOKEN_TYPE = "gadgets.securityTokenType";
private final SecurityTokenCodec codec;
@@ -52,6 +51,7 @@ public class DefaultSecurityTokenCodec i
@Inject
public DefaultSecurityTokenCodec(ContainerConfig config) {
String tokenType = config.getString(ContainerConfig.DEFAULT_CONTAINER, SECURITY_TOKEN_TYPE);
+
if ("insecure".equals(tokenType)) {
codec = new BasicSecurityTokenCodec();
} else if ("secure".equals(tokenType)) {
@@ -74,4 +74,8 @@ public class DefaultSecurityTokenCodec i
}
return codec.encodeToken(token);
}
+
+ public int getTokenTimeToLive() {
+ return codec.getTokenTimeToLive();
+ }
}
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=1196414&r1=1196413&r2=1196414&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 Wed Nov 2 00:53:41 2011
@@ -53,4 +53,9 @@ public interface SecurityTokenCodec {
throws SecurityTokenException;
String encodeToken(SecurityToken token) throws SecurityTokenException;
+
+ /**
+ * @return The amount of time a token generated by this codec can be expected to live.
+ */
+ int getTokenTimeToLive();
}
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=1196414&r1=1196413&r2=1196414&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 Wed Nov 2 00:53:41 2011
@@ -46,6 +46,10 @@ public class UrlParameterAuthenticationH
public String encodeToken(SecurityToken token) throws SecurityTokenException {
return null;
}
+
+ public int getTokenTimeToLive() {
+ return 0; // Not used.
+ }
};
authHandler = new UrlParameterAuthenticationHandler(codec, true);
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=1196414&r1=1196413&r2=1196414&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 Wed Nov 2 00:53:41 2011
@@ -89,6 +89,10 @@ public class FakeGadgetToken extends Abs
public String encodeToken(SecurityToken token) throws SecurityTokenException {
return null; // NOT USED
}
+
+ public int getTokenTimeToLive() {
+ return 0; // Not used.
+ }
}
public FakeGadgetToken setAuthenticationMode(String authMode) {
Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerApi.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerApi.java?rev=1196414&r1=1196413&r2=1196414&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerApi.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerApi.java Wed Nov 2 00:53:41 2011
@@ -97,6 +97,7 @@ public class GadgetsHandlerApi {
public Map<String, View> getViews();
public Boolean getNeedsTokenRefresh();
public Set<String> getRpcServiceIds();
+ public Integer getTokenTTL();
}
public enum ViewContentType {
Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerService.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerService.java?rev=1196414&r1=1196413&r2=1196414&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerService.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerService.java Wed Nov 2 00:53:41 2011
@@ -212,8 +212,12 @@ public class GadgetsHandlerService {
gadget.getAllFeatures().contains("auth-refresh") : null;
Set<String> rpcServiceIds = getRpcServiceIds(gadget);
+
+ Integer tokenTTL = isFieldIncluded(fields, "tokenTTL") ?
+ securityTokenCodec.getTokenTimeToLive() : null;
+
return createMetadataResponse(context.getUrl(), gadget.getSpec(), iframeUrl,
- needsTokenRefresh, fields, timeSource.currentTimeMillis() + specRefreshInterval,
+ needsTokenRefresh, fields, timeSource.currentTimeMillis() + specRefreshInterval, tokenTTL,
rpcServiceIds);
}
@@ -524,7 +528,7 @@ public class GadgetsHandlerService {
@VisibleForTesting
GadgetsHandlerApi.MetadataResponse createMetadataResponse(
Uri url, GadgetSpec spec, String iframeUrl, Boolean needsTokenRefresh,
- Set<String> fields, Long expireTime, Set<String> rpcServiceIds) {
+ Set<String> fields, Long expireTime, Integer tokenTTL, Set<String> rpcServiceIds) {
return (GadgetsHandlerApi.MetadataResponse) beanFilter.createFilteredBean(
beanDelegator.createDelegator(spec, GadgetsHandlerApi.MetadataResponse.class,
ImmutableMap.<String, Object>builder()
@@ -534,7 +538,8 @@ public class GadgetsHandlerService {
.put("needstokenrefresh", BeanDelegator.nullable(needsTokenRefresh))
.put("responsetimems", timeSource.currentTimeMillis())
.put("expiretimems", BeanDelegator.nullable(expireTime))
- .put("rpcserviceids", BeanDelegator.nullable(rpcServiceIds)).build()),
+ .put("rpcserviceids", BeanDelegator.nullable(rpcServiceIds))
+ .put("tokenttl", BeanDelegator.nullable(tokenTTL)).build()),
fields);
}
Modified: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerServiceTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerServiceTest.java?rev=1196414&r1=1196413&r2=1196414&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerServiceTest.java (original)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerServiceTest.java Wed Nov 2 00:53:41 2011
@@ -744,5 +744,9 @@ public class GadgetsHandlerServiceTest e
}
return authContext;
}
+
+ public int getTokenTimeToLive() {
+ return 0; // Not used.
+ }
}
}
Modified: shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerTest.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerTest.java?rev=1196414&r1=1196413&r2=1196414&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerTest.java (original)
+++ shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/GadgetsHandlerTest.java Wed Nov 2 00:53:41 2011
@@ -30,6 +30,7 @@ import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.codec.binary.Base64;
+import org.apache.shindig.auth.BasicSecurityTokenCodec;
import org.apache.shindig.auth.SecurityToken;
import org.apache.shindig.auth.SecurityTokenCodec;
import org.apache.shindig.auth.SecurityTokenException;
@@ -440,6 +441,36 @@ public class GadgetsHandlerTest extends
}
@Test
+ public void testMetadataOneGadgetRequestTokenTTLParam() throws Exception {
+ SecurityTokenCodec codec = createMock(SecurityTokenCodec.class);
+ expect(codec.getTokenTimeToLive()).andReturn(42).anyTimes();
+ replay(codec);
+
+ registerGadgetsHandler(codec);
+ setupGadgetAdminStore();
+ setupMockRegistry(Lists.newArrayList("core"));
+ JSONObject request = makeMetadataRequest(null, null, new String[]{"tokenTTL", "iframeurl"}, GADGET1_URL);
+ RpcHandler operation = registry.getRpcHandler(request);
+ Object responseObj = operation.execute(emptyFormItems, authContext, converter).get();
+ JSONObject response = new JSONObject(converter.convertToString(responseObj));
+
+ assertEquals(42, response.getJSONObject(FakeProcessor.SPEC_URL.toString()).getInt("tokenTTL"));
+ }
+
+ @Test
+ public void testMetadataOneGadgetNoRequestTokenTTLParam() throws Exception {
+ registerGadgetsHandler(null);
+ setupGadgetAdminStore();
+ setupMockRegistry(Lists.newArrayList("core"));
+ JSONObject request = makeMetadataRequest(null, null, null, GADGET1_URL);
+ RpcHandler operation = registry.getRpcHandler(request);
+ Object responseObj = operation.execute(emptyFormItems, authContext, converter).get();
+ JSONObject response = new JSONObject(converter.convertToString(responseObj));
+
+ assertFalse(response.getJSONObject(FakeProcessor.SPEC_URL.toString()).has("tokenTTL"));
+ }
+
+ @Test
public void testAllowedRpcSecurityIds() throws Exception {
registerGadgetsHandler(null);
setupMockRegistry(Lists.newArrayList("core"));