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/02 21:44:15 UTC
svn commit: r1178236 [1/4] - in /shindig/trunk: config/
content/samplecontainer/examples/commoncontainer/
features/src/main/javascript/features/container.util/
features/src/main/javascript/features/container/
features/src/main/javascript/features/rpc/ ...
Author: rbaxter85
Date: Sun Oct 2 19:44:13 2011
New Revision: 1178236
URL: http://svn.apache.org/viewvc?rev=1178236&view=rev
Log:
SHINDIG-1601
Adds some gadget administration features to Shindig. Also enables arbitration of RPC calls.
Added:
shindig/trunk/config/gadget-admin.json
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/BasicGadgetAdminStore.java
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/ContainerAdminData.java
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/FeatureAdminData.java
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/GadgetAdminData.java
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/GadgetAdminModule.java
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/GadgetAdminStore.java
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/ServerAdminData.java
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/admin/
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/admin/BasicGadgetAdminStoreTest.java
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/admin/ContainerAdminDataTest.java
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/admin/FeatureAdminDataTest.java
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/admin/GadgetAdminDataTest.java
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/admin/ServerAdminDataTest.java
Removed:
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/BasicGadgetBlacklist.java
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetBlacklist.java
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/BasicGadgetBlacklistTest.java
Modified:
shindig/trunk/config/container.js
shindig/trunk/content/samplecontainer/examples/commoncontainer/assembler.js
shindig/trunk/content/samplecontainer/examples/commoncontainer/viewController.js
shindig/trunk/features/src/main/javascript/features/container.util/util.js
shindig/trunk/features/src/main/javascript/features/container/container.js
shindig/trunk/features/src/main/javascript/features/rpc/rpc.js
shindig/trunk/java/common/conf/shindig.properties
shindig/trunk/java/common/src/main/java/org/apache/shindig/common/logging/i18n/MessageKeys.java
shindig/trunk/java/common/src/main/resources/org/apache/shindig/common/logging/i18n/resource.properties
shindig/trunk/java/common/src/main/resources/org/apache/shindig/common/logging/i18n/resource_en_US.properties
shindig/trunk/java/gadgets/pom.xml
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetException.java
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RenderingContext.java
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/config/CoreUtilConfigContributor.java
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/features/FeatureRegistry.java
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/process/Processor.java
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.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/main/java/org/apache/shindig/gadgets/servlet/MakeRequestHandler.java
shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/servlet/ProxyHandler.java
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/process/ProcessorTest.java
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriterTest.java
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/RewriteModuleTest.java
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/rewrite/StyleTagProxyEmbeddedUrlsVisitorTest.java
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/FakeProcessor.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/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/MakeRequestHandlerTest.java
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/MakeRequestServletTest.java
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/servlet/ProxyHandlerTest.java
shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/templates/tags/TemplateBasedTagHandlerTest.java
shindig/trunk/java/samples/src/test/java/org/apache/shindig/social/opensocial/jpa/spi/integration/JpaTestGuiceModule.java
shindig/trunk/java/server/src/main/webapp/WEB-INF/web.xml
shindig/trunk/java/server/src/test/java/org/apache/shindig/server/endtoend/EndToEndServer.java
Modified: shindig/trunk/config/container.js
URL: http://svn.apache.org/viewvc/shindig/trunk/config/container.js?rev=1178236&r1=1178235&r2=1178236&view=diff
==============================================================================
--- shindig/trunk/config/container.js (original)
+++ shindig/trunk/config/container.js Sun Oct 2 19:44:13 2011
@@ -131,6 +131,11 @@
"gadgets.uri.proxy.host" : "${Cur['defaultShindigProxyConcatAuthority']}",
"gadgets.uri.proxy.path" : "${CONTEXT_ROOT}/gadgets/proxy",
+//Enables/Disables feature administration
+"gadgets.admin.enableFeatureAdministration" : "false",
+
+//Enables whitelist checks
+"gadgets.admin.enableGadgetWhitelist" : "false",
// This config data will be passed down to javascript. Please
// configure your object using the feature name rather than
@@ -301,6 +306,9 @@
"serverBase": "${CONTEXT_ROOT}/gadgets/"
},
"container" : {
- "relayPath": "${CONTEXT_ROOT}/gadgets/files/container/rpc_relay.html"
+ "relayPath": "${CONTEXT_ROOT}/gadgets/files/container/rpc_relay.html",
+
+ //Enables/Disables the RPC arbitrator functionality in the common container
+ "enableRpcArbitration": false
}
}}
Added: shindig/trunk/config/gadget-admin.json
URL: http://svn.apache.org/viewvc/shindig/trunk/config/gadget-admin.json?rev=1178236&view=auto
==============================================================================
--- shindig/trunk/config/gadget-admin.json (added)
+++ shindig/trunk/config/gadget-admin.json Sun Oct 2 19:44:13 2011
@@ -0,0 +1,22 @@
+{
+ "default" : {
+ "gadgets" : {
+ "http://www.google.com/ig/modules/horoscope.xml" : {
+ "features" : ["views", "tabs", "setprefs", "dynamic-height"],
+ "type" : "blacklist"
+ },
+ "http://www.labpixies.com/campaigns/todo/todo.xml" : {
+ "features" : ["setprefs", "dynamic-height", "views"],
+ "type" : "whitelist"
+ },
+ "http://localhost:8080/samplecontainer/examples/media-openGadgets/Media.xml" : {
+ "features" : [],
+ "type" : "blacklist"
+ },
+ "http://localhost:8080/*" : {
+ "features" : [],
+ "type" : "whitelist"
+ }
+ }
+ }
+}
\ No newline at end of file
Modified: shindig/trunk/content/samplecontainer/examples/commoncontainer/assembler.js
URL: http://svn.apache.org/viewvc/shindig/trunk/content/samplecontainer/examples/commoncontainer/assembler.js?rev=1178236&r1=1178235&r2=1178236&view=diff
==============================================================================
--- shindig/trunk/content/samplecontainer/examples/commoncontainer/assembler.js (original)
+++ shindig/trunk/content/samplecontainer/examples/commoncontainer/assembler.js Sun Oct 2 19:44:13 2011
@@ -28,6 +28,9 @@ testConfig[osapi.container.ContainerConf
// Create the new CommonContainer
var CommonContainer = new osapi.container.Container(testConfig);
+//Gadget site to title id map
+var siteToTitleMap = {};
+
// Default the security token for the container. Using this example security token requires enabling
// the DefaultSecurityTokenCodec to let UrlParameterAuthenticationHandler create valid security token.
shindig.auth.updateSecurityToken('john.doe:john.doe:appid:cont:url:0:default');
@@ -55,6 +58,8 @@ CommonContainer.init = function() {
hub: CommonContainer.managedHub
});
+ CommonContainer.rpcRegister('set_title', setTitleHandler);
+
try {
// Connect to the ManagedHub
Modified: shindig/trunk/content/samplecontainer/examples/commoncontainer/viewController.js
URL: http://svn.apache.org/viewvc/shindig/trunk/content/samplecontainer/examples/commoncontainer/viewController.js?rev=1178236&r1=1178235&r2=1178236&view=diff
==============================================================================
--- shindig/trunk/content/samplecontainer/examples/commoncontainer/viewController.js (original)
+++ shindig/trunk/content/samplecontainer/examples/commoncontainer/viewController.js Sun Oct 2 19:44:13 2011
@@ -79,6 +79,7 @@ $(function() {
if (actionId === 'remove') {
if (confirm('This gadget will be removed, ok?')) {
portlet.remove();
+ delete siteToTitleMap[gadgetSite.getId()];
}
}else if (actionId === 'expand') {
//navigate to currentView prior to colapse gadget
@@ -88,6 +89,12 @@ $(function() {
}
};
+ //RPC handler for the set-title feature
+ setTitleHandler = function(rpcArgs, title) {
+ var titleId = siteToTitleMap[rpcArgs.gs.id_];
+ $('#' + titleId).text(title);
+ };
+
//create a gadget with navigation tool bar header enabling gadget collapse, expand, remove, navigate to view actions.
buildGadget = function(result,gadgetURL) {
var gadgetSiteString = "$(this).closest(\'.portlet\').find(\'.portlet-content\').data(\'gadgetSite\')";
@@ -98,11 +105,13 @@ $(function() {
}
var newGadgetSite = gadgetTemplate;
newGadgetSite = newGadgetSite.replace(/(gadget-site)/g, '$1-' + curId);
+ siteToTitleMap['gadget-site-' + curId] = 'gadget-title-' + curId;
$(newGadgetSite).appendTo($('#gadgetArea')).addClass('ui-widget ui-widget-content ui-helper-clearfix ui-corner-all')
.find('.portlet-header')
.addClass('ui-widget-header ui-corner-all')
- .text(result[gadgetURL]['modulePrefs'].title)
- .append('<ul id="viewsDropdown">' +
+ .text('')
+ .append('<span id="gadget-title-' + curId + '">' + result[gadgetURL]['modulePrefs'].title + '</span>' +
+ '<ul id="viewsDropdown">' +
'<li class="li-header">' +
'<a href="#" class="hidden"><span id="dropdownIcon" class="ui-icon ui-icon-triangle-1-s"></span></a>' +
'<ul>' +
@@ -142,8 +151,10 @@ $(function() {
$('#addGadget').click(function() {
CommonContainer.preloadGadget(newGadgetUrl.val(), function(result) {
for (var gadgetURL in result) {
- buildGadget(result, gadgetURL);
- curId++;
+ if(!result[gadgetURL].error) {
+ buildGadget(result, gadgetURL);
+ curId++;
+ }
}
//Clear Values
@@ -161,8 +172,10 @@ $(function() {
var testGadgets = $('#gadgetCollection').val().split(',');
CommonContainer.preloadGadgets(testGadgets, function(result) {
for (var gadgetURL in result) {
- buildGadget(result, gadgetURL);
- curId++;
+ if(!result[gadgetURL].error) {
+ buildGadget(result, gadgetURL);
+ curId++;
+ }
}
});
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=1178236&r1=1178235&r2=1178236&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 Sun Oct 2 19:44:13 2011
@@ -80,7 +80,8 @@ osapi.container.util.newMetadataRequest
'views.preferredHeight',
'views.preferredWidth',
'expireTimeMs',
- 'responseTimeMs'
+ 'responseTimeMs',
+ 'rpcServiceIds'
]
};
};
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=1178236&r1=1178235&r2=1178236&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/container/container.js (original)
+++ shindig/trunk/features/src/main/javascript/features/container/container.js Sun Oct 2 19:44:13 2011
@@ -134,6 +134,8 @@ osapi.container.Container = function(opt
this.initializeMixins_();
+ this.setupRpcArbitrator_(config);
+
this.preloadCaches(config);
this.registerRpcServices_();
@@ -476,6 +478,11 @@ osapi.container.ContainerConfig.GET_PREF
*/
osapi.container.ContainerConfig.SET_PREFERENCES = 'SET_PREFERENCES';
/**
+ * Used to arbitrate RPC calls.
+ * @type {function}
+ */
+osapi.container.ContainerConfig.RPC_ARBITRATOR = 'rpcArbitrator';
+/**
* Used to retrieve security tokens for gadgets.
* @type {function}
*/
@@ -662,6 +669,42 @@ osapi.container.Container.prototype.regi
});
};
+/**
+ * Sets up the RPC arbitrator if enabled in the container js. If
+ * a function is provided in the containers config the container will use
+ * that, if not it will use the default arbitrator.
+ * @private
+ */
+osapi.container.Container.prototype.setupRpcArbitrator_ = function(config) {
+ var container = gadgets.config.get('container');
+ if(typeof container.enableRpcArbitration !== 'undefined' &&
+ container.enableRpcArbitration) {
+ var arbitrate = osapi.container.util.getSafeJsonValue(
+ config, osapi.container.ContainerConfig.RPC_ARBITRATOR, null);
+ if(!arbitrate) {
+ var self = this;
+ //This implementation uses the metadata cache to check to allowed rpc service ids
+ arbitrate = function(serviceId, from) {
+ var site = self.getGadgetSiteByIframeId_(from);
+ if(site && site.getActiveGadgetHolder()) {
+ var cachedResponse = self.service_.getCachedGadgetMetadata(
+ site.getActiveGadgetHolder().getUrl());
+ if(!cachedResponse.error && cachedResponse.rpcServiceIds) {
+ for(var i = 0, rpcServiceId; rpcServiceId = cachedResponse.rpcServiceIds[i]; i++) {
+ if(rpcServiceId == serviceId) {
+ return true;
+ }
+ }
+ }
+ }
+ gadgets.warn('RPC call to ' + serviceId + ' was not allowed.');
+ return false;
+ };
+ }
+ gadgets.rpc.config({'arbitrator' : arbitrate});
+ }
+};
+
/**
* Keep track of preloaded gadget URLs. These gadgets will have their tokens
Modified: shindig/trunk/features/src/main/javascript/features/rpc/rpc.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/rpc/rpc.js?rev=1178236&r1=1178235&r2=1178236&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/rpc/rpc.js (original)
+++ shindig/trunk/features/src/main/javascript/features/rpc/rpc.js Sun Oct 2 19:44:13 2011
@@ -133,6 +133,7 @@ if (!window['gadgets']['rpc']) { // make
var rpcId = window.name;
var securityCallback = function() {};
+ var arbitrator = null;
var LOAD_TIMEOUT = 0;
var FRAME_PHISH = 1;
var FORGED_MSG = 2;
@@ -285,6 +286,10 @@ if (!window['gadgets']['rpc']) { // make
if (rpc && typeof rpc['s'] === 'string' && typeof rpc['f'] === 'string' &&
rpc['a'] instanceof Array) {
+ if (typeof arbitrate === 'function' && !arbitrate(rpc['s'], rpc['f'])) {
+ return;
+ }
+
// Validate auth token.
if (authToken[rpc['f']]) {
// We don't do type coercion here because all entries in the authToken
@@ -802,6 +807,9 @@ if (!window['gadgets']['rpc']) { // make
if (typeof config.securityCallback === 'function') {
securityCallback = config.securityCallback;
}
+ if (typeof config.arbitrator === 'function') {
+ arbitrate = config.arbitrator;
+ }
},
/**
Modified: shindig/trunk/java/common/conf/shindig.properties
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/conf/shindig.properties?rev=1178236&r1=1178235&r2=1178236&view=diff
==============================================================================
--- shindig/trunk/java/common/conf/shindig.properties (original)
+++ shindig/trunk/java/common/conf/shindig.properties Sun Oct 2 19:44:13 2011
@@ -21,9 +21,6 @@ shindig.features.default=res://features/
# Location of container configurations (comma separated)
shindig.containers.default=res://containers/default/container.js
-# A file containing blacklisted gadgets.
-shindig.blacklist.file=
-
### Inbound OAuth support
# The URL base to use for full OAuth support (three-legged)
shindig.oauth.base-url=/oauth
Modified: shindig/trunk/java/common/src/main/java/org/apache/shindig/common/logging/i18n/MessageKeys.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/logging/i18n/MessageKeys.java?rev=1178236&r1=1178235&r2=1178236&view=diff
==============================================================================
--- shindig/trunk/java/common/src/main/java/org/apache/shindig/common/logging/i18n/MessageKeys.java (original)
+++ shindig/trunk/java/common/src/main/java/org/apache/shindig/common/logging/i18n/MessageKeys.java Sun Oct 2 19:44:13 2011
@@ -83,7 +83,7 @@ public interface MessageKeys {
//PipelineExecutor
public static final String ERROR_PRELOADING="errorPreloading";
//Processor
- public static final String RENDER_BLACKLISTED_GADGET="renderBlacklistedGadget";
+ public static final String RENDER_NON_WHITELISTED_GADGET="renderNonWhitelistedGadget";
//CajaResponseRewriter
public static final String FAILED_TO_RETRIEVE="failedToRetrieve";
public static final String FAILED_TO_READ="failedToRead";
Modified: shindig/trunk/java/common/src/main/resources/org/apache/shindig/common/logging/i18n/resource.properties
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/main/resources/org/apache/shindig/common/logging/i18n/resource.properties?rev=1178236&r1=1178235&r2=1178236&view=diff
==============================================================================
--- shindig/trunk/java/common/src/main/resources/org/apache/shindig/common/logging/i18n/resource.properties (original)
+++ shindig/trunk/java/common/src/main/resources/org/apache/shindig/common/logging/i18n/resource.properties Sun Oct 2 19:44:13 2011
@@ -87,7 +87,7 @@ unableToConvertScript=Unable to convert
errorPreloading=Unexpected error when preloading
##Processor
-renderBlacklistedGadget=Attempted to render blacklisted gadget: {0}
+renderNonWhitelistedGadget=Attempted to render a gadget not on the whitelist: {0}
##CajaResponseRewriter, CajaContentRewriter
failedToRetrieve=Failed to retrieve {0}
Modified: shindig/trunk/java/common/src/main/resources/org/apache/shindig/common/logging/i18n/resource_en_US.properties
URL: http://svn.apache.org/viewvc/shindig/trunk/java/common/src/main/resources/org/apache/shindig/common/logging/i18n/resource_en_US.properties?rev=1178236&r1=1178235&r2=1178236&view=diff
==============================================================================
--- shindig/trunk/java/common/src/main/resources/org/apache/shindig/common/logging/i18n/resource_en_US.properties (original)
+++ shindig/trunk/java/common/src/main/resources/org/apache/shindig/common/logging/i18n/resource_en_US.properties Sun Oct 2 19:44:13 2011
@@ -87,7 +87,7 @@ unableToConvertScript=Unable to convert
errorPreloading=Unexpected error when preloading
##Processor
-renderBlacklistedGadget=Attempted to render blacklisted gadget: {0}
+renderNonWhitelistedGadget=Attempted to render a gadget not on the whitelist: {0}
##CajaResponseRewriter, CajaContentRewriter
failedToRetrieve=Failed to retrieve {0}
Modified: shindig/trunk/java/gadgets/pom.xml
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/pom.xml?rev=1178236&r1=1178235&r2=1178236&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/pom.xml (original)
+++ shindig/trunk/java/gadgets/pom.xml Sun Oct 2 19:44:13 2011
@@ -53,6 +53,7 @@
<includes>
<include>oauth.json</include>
<include>OSML_library.xml</include>
+ <include>gadget-admin.json</include>
</includes>
</resource>
Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetException.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetException.java?rev=1178236&r1=1178235&r2=1178236&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetException.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetException.java Sun Oct 2 19:44:13 2011
@@ -71,7 +71,7 @@ public class GadgetException extends Exc
UNKNOWN_VIEW_SPECIFIED,
// Blacklisting
- BLACKLISTED_GADGET,
+ NON_WHITELISTED_GADGET,
// OAuth
OAUTH_STORAGE_ERROR,
@@ -79,14 +79,18 @@ public class GadgetException extends Exc
// Signed fetch
REQUEST_SIGNING_FAILURE,
-
+
// Error in the JavaScript processing pipeline
JS_PROCESSING_ERROR,
+
+ //Gadget Admin Error
+ GADGET_ADMIN_STORAGE_ERROR,
+ GADGET_ADMIN_FEATURE_NOT_ALLOWED
}
private final Code code;
private final int httpStatusCode;
-
+
public GadgetException(Code code, int httpStatusCode) {
this.code = code;
this.httpStatusCode = httpStatusCode;
Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RenderingContext.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RenderingContext.java?rev=1178236&r1=1178235&r2=1178236&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RenderingContext.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/RenderingContext.java Sun Oct 2 19:44:13 2011
@@ -37,7 +37,7 @@ public enum RenderingContext {
// Used when retrieving metadata about a gadget. Processing is generally
// identical to processing under GADGET, but some operations may be safely
// skipped, such as preload processing.
- METADATA(null, null, null),
+ METADATA("gadget", null, null),
// Allows specification of feature JS with an <all> tag. Specially handled in
// FeatureRegistry: content specified in an <all> tag is chosen if there are
Added: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/BasicGadgetAdminStore.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/BasicGadgetAdminStore.java?rev=1178236&view=auto
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/BasicGadgetAdminStore.java (added)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/BasicGadgetAdminStore.java Sun Oct 2 19:44:13 2011
@@ -0,0 +1,407 @@
+/*
+ * 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.admin;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.shindig.common.uri.Uri;
+import org.apache.shindig.config.ContainerConfig;
+import org.apache.shindig.gadgets.Gadget;
+import org.apache.shindig.gadgets.GadgetContext;
+import org.apache.shindig.gadgets.GadgetException;
+import org.apache.shindig.gadgets.admin.FeatureAdminData.Type;
+import org.apache.shindig.gadgets.features.FeatureRegistry;
+import org.apache.shindig.gadgets.features.FeatureRegistryProvider;
+import org.apache.shindig.gadgets.spec.Feature;
+import org.apache.shindig.gadgets.spec.GadgetSpec;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import com.google.caja.util.Sets;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+/**
+ * A simple implementation of a gadget administration store.
+ *
+ * @version $Id: $
+ */
+@Singleton
+public class BasicGadgetAdminStore implements GadgetAdminStore {
+
+ // Key in the container config which indicated whether white-listing is turned on.
+ private static final String WHITELIST_KEY = "gadgets.admin.enableGadgetWhitelist";
+
+ // Key in the container config which indicates whether feature administration is turned on.
+ private static final String ENABLE_FEATURE_ADMIN = "gadgets.admin.enableFeatureAdministration";
+
+ private static final Logger LOG = Logger.getLogger(BasicGadgetAdminStore.class.getName());
+
+ private static final String GADGETS = "gadgets";
+ private static final String FEATURES = "features";
+ private static final String TYPE = "type";
+ private static final String BLACKLIST = "blacklist";
+ private static final String CORE_FEATURE = "core";
+
+ private ServerAdminData serverAdminData;
+ private FeatureRegistryProvider featureRegistryProvider;
+ private ContainerConfig config;
+
+ /**
+ * Constructor.
+ */
+ @Inject
+ public BasicGadgetAdminStore(FeatureRegistryProvider featureRegistryProvider,
+ ContainerConfig config) {
+ this.serverAdminData = new ServerAdminData();
+ this.featureRegistryProvider = featureRegistryProvider;
+ this.config = config;
+ }
+
+ /**
+ * Inits the store from a JSON String representing the gadget administration information.
+ *
+ * @param store
+ * a JSON String representing the gadget administration information.
+ * @throws GadgetException thrown when the store cannot be initiated.
+ */
+ public void init(String store) throws GadgetException {
+ try {
+ JSONObject json = new JSONObject(store);
+ Iterator<?> iter = json.keys();
+ String container;
+ while (iter.hasNext()) {
+ container = (String) iter.next();
+ serverAdminData.addContainerAdminData(container,
+ createContainerData(container, json.getJSONObject(container)));
+ }
+ } catch (JSONException e) {
+ throw new GadgetException(GadgetException.Code.GADGET_ADMIN_STORAGE_ERROR, e);
+ }
+ }
+
+ /**
+ * Creates container security information from a JSON object.
+ *
+ * @param container
+ * the container the security information is for.
+ * @param containerJson
+ * the JSON object representing the information.
+ * @return container admin data
+ * @throws JSONException
+ * thrown when we cannot get the information from the JSON object
+ */
+ private ContainerAdminData createContainerData(String container, JSONObject containerJson)
+ throws JSONException, GadgetException {
+ ContainerAdminData containerData = new ContainerAdminData();
+ if (containerJson.has(GADGETS)) {
+ containerData = new ContainerAdminData(
+ createGadgetAdminDataMap(containerJson.getJSONObject(GADGETS)));
+ }
+ return containerData;
+ }
+
+ /**
+ * Creates a map of gadget administration data.
+ *
+ * @param gadgetsJson
+ * the JSON object representing the admin data.
+ * @return a map of gadget administration data.
+ * @throws JSONException
+ * thrown when the map cannot be created.
+ */
+ private Map<String, GadgetAdminData> createGadgetAdminDataMap(JSONObject gadgetsJson)
+ throws JSONException {
+ Map<String, GadgetAdminData> map = Maps.newHashMap();
+ Iterator<?> keys = gadgetsJson.keys();
+ String gadgetUrl;
+ JSONObject gadgetJson;
+ while (keys.hasNext()) {
+ gadgetUrl = (String) keys.next();
+ gadgetJson = gadgetsJson.getJSONObject(gadgetUrl);
+ map.put(gadgetUrl, createGadgetAdminData(gadgetJson));
+ }
+ return map;
+ }
+
+ /**
+ * Creates a gadget administration data.
+ *
+ * @param gadgetJson
+ * the gadget JSON object.
+ * @return gadget administration data.
+ * @throws JSONException
+ * thrown when the information cannot found in the JSON object.
+ */
+ private GadgetAdminData createGadgetAdminData(JSONObject gadgetJson) throws JSONException {
+ FeatureAdminData data = new FeatureAdminData();
+ if (gadgetJson.has(FEATURES)) {
+ JSONArray features = gadgetJson.getJSONArray(FEATURES);
+ for (int i = 0; i < features.length(); i++) {
+ data.addFeature(features.getString(i));
+ }
+ }
+
+ data.setType(Type.WHITELIST);
+ if (!data.getFeatures().contains(CORE_FEATURE)) {
+ // Add the core feature since every gadget needs this and it can't be disabled
+ data.addFeature(CORE_FEATURE);
+ }
+ if (gadgetJson.has(TYPE)) {
+ String type = gadgetJson.getString(TYPE);
+ if (type.equalsIgnoreCase(BLACKLIST)) {
+ data.setType(Type.BLACKLIST);
+ //We need core for everything so remove it if it is blacklisted
+ data.removeFeature(CORE_FEATURE);
+ }
+ }
+ return new GadgetAdminData(data);
+ }
+
+ public GadgetAdminData getGadgetAdminData(String container, String gadgetUrl) {
+ GadgetAdminData data = null;
+ if (serverAdminData.hasContainerAdminData(container)) {
+ ContainerAdminData containerData = serverAdminData.getContainerAdminData(container);
+ if (containerData.hasGadgetAdminData(gadgetUrl)) {
+ data = containerData.getGadgetAdminData(gadgetUrl);
+ }
+ }
+ return data;
+ }
+
+ public void setGadgetAdminData(String container, String gadgetUrl, GadgetAdminData adminData) {
+ if (serverAdminData.hasContainerAdminData(container)) {
+ ContainerAdminData containerData = serverAdminData.getContainerAdminData(container);
+ containerData.addGadgetAdminData(gadgetUrl, adminData);
+ }
+ }
+
+ public ContainerAdminData getContainerAdminData(String container) {
+ ContainerAdminData data = null;
+ if (serverAdminData.hasContainerAdminData(container)) {
+ data = serverAdminData.getContainerAdminData(container);
+ }
+ return data;
+ }
+
+ public void setContainerAdminData(String container, ContainerAdminData containerAdminData) {
+ serverAdminData.addContainerAdminData(container, containerAdminData);
+ }
+
+ public ServerAdminData getServerAdminData() {
+ return serverAdminData;
+ }
+
+ /**
+ * Safely gets the container from the gadget by doing null checks.
+ *
+ * @param gadget
+ * The gadget to get the container from.
+ * @return The container.
+ */
+ private String getSafeContainerFromGadget(Gadget gadget) {
+ GadgetContext context = gadget.getContext();
+ if (context != null) {
+ return context.getContainer();
+ }
+ return null;
+ }
+
+ /**
+ * Safely gets the gadget's URL from the gadget by doing null checks.
+ *
+ * @param gadget
+ * The gadget to get the URL from.
+ * @return The gadget's URL.
+ */
+ private String getSafeGadgetUrlFromGadget(Gadget gadget) {
+ GadgetSpec spec = gadget.getSpec();
+ if (spec != null) {
+ Uri gadgetUri = spec.getUrl();
+ if (gadgetUri != null) {
+ return gadgetUri.toString();
+ }
+ }
+ return null;
+ }
+
+ public boolean checkFeatureAdminInfo(Gadget gadget) {
+ String container = getSafeContainerFromGadget(gadget);
+ String gadgetUrl = getSafeGadgetUrlFromGadget(gadget);
+ if (container == null || gadgetUrl == null) {
+ return false;
+ }
+
+ if (!isFeatureAdminEnabled(container)) {
+ return true;
+ }
+
+ GadgetContext context = gadget.getContext();
+ try {
+ FeatureRegistry featureRegistry = featureRegistryProvider.get(context.getRepository());
+ if (!hasGadgetAdminData(container, gadgetUrl)) {
+ return false;
+ }
+
+ FeatureAdminData featureAdminData = this.getGadgetAdminData(container, gadgetUrl)
+ .getFeatureAdminData();
+
+ Set<String> features = featureAdminData.getFeatures();
+ if(featureAdminData.getType() == Type.WHITELIST) {
+ //If the admin has specified a whitelist get all the dependencies for the features the admin
+ //has whitelisted and add them as well. Blacklists need to be more specific.
+ features = Sets.newHashSet(featureRegistry.getFeatures(features));
+ }
+
+ List<String> gadgetFeatures = featureRegistry.getFeatures(getRequiredGadgetFeatures(gadget));
+
+ return areAllFeaturesAllowed(Sets.immutableSet(features),
+ gadgetFeatures, featureAdminData);
+ } catch (GadgetException e) {
+ LOG.log(Level.WARNING, "Exception while getting the FeatureRegistry.");
+ return false;
+ }
+
+ }
+
+ /**
+ * Gets all required gadget features.
+ *
+ * @param gadget
+ * The gadget to get the gadget features for.
+ * @return The required gadget features.
+ */
+ private List<String> getRequiredGadgetFeatures(Gadget gadget) {
+ List<String> featureNames = Lists.newArrayList();
+ List<Feature> features = gadget.getSpec().getModulePrefs().getAllFeatures();
+ for (Feature feature : features) {
+ if (feature.getRequired()) {
+ featureNames.add(feature.getName());
+ }
+ }
+ return featureNames;
+ }
+
+ /**
+ * Checks the features for a gadget to see if they are allowed.
+ *
+ * @param featuresForGadget
+ * a set of features that the admin has either whitelist or blacklisted.
+ * @param gadgetFeatures
+ * a list of features required by the gadget.
+ * @param featureAdminData
+ * the feature admin data for the gadget.
+ * @return true if all the features for the gadget are allowed, false otherwise.
+ */
+ private boolean areAllFeaturesAllowed(Set<String> featuresForGadget, List<String> gadgetFeatures,
+ FeatureAdminData featureAdminData) {
+ switch (featureAdminData.getType()) {
+ case BLACKLIST:
+ for (String feature : gadgetFeatures) {
+ if (featuresForGadget.contains(feature)) {
+ return false;
+ }
+ }
+
+ break;
+ case WHITELIST:
+ default:
+ return featuresForGadget.containsAll(gadgetFeatures);
+ }
+ return true;
+ }
+
+ public boolean isAllowedFeature(Feature feature, Gadget gadget) {
+ String container = getSafeContainerFromGadget(gadget);
+ String gadgetUrl = getSafeGadgetUrlFromGadget(gadget);
+ if (container == null || gadgetUrl == null) {
+ return false;
+ }
+ if (!isFeatureAdminEnabled(container)) {
+ return true;
+ }
+ if (!hasGadgetAdminData(container, gadgetUrl)) {
+ // If feature administration is not enabled assume the feature is allowed
+ return false;
+ }
+ GadgetAdminData gadgetAdminData = getGadgetAdminData(container, gadgetUrl);
+
+ FeatureAdminData featureAdminData = gadgetAdminData.getFeatureAdminData();
+ String featureName = feature.getName();
+ switch (featureAdminData.getType()) {
+ case BLACKLIST:
+ return !featureAdminData.getFeatures().contains(featureName);
+ case WHITELIST:
+ default:
+ return featureAdminData.getFeatures().contains(featureName);
+ }
+ }
+
+ /**
+ * Determines whether we have gadget administration data for a gadget.
+ *
+ * @param container
+ * The container the gadget is in.
+ * @param gadgetUrl
+ * The gadget to check.
+ * @return true if we do have gadget administration data false otherwise.
+ */
+ private boolean hasGadgetAdminData(String container, String gadgetUrl) {
+ return this.getGadgetAdminData(container, gadgetUrl) != null;
+ }
+
+ public boolean isWhitelisted(String container, String gadgetUrl) {
+ if (isWhitelistingEnabled(container)) {
+ return hasGadgetAdminData(container, gadgetUrl);
+ } else {
+ // If the white list checking is not enabled just assume it is there
+ return true;
+ }
+ }
+
+ /**
+ * Determines whether whitelisting is enabled for a container.
+ *
+ * @param container
+ * The container to check.
+ * @return true if whitelisting is enabled for the container false otherwise.
+ */
+ private boolean isWhitelistingEnabled(String container) {
+ return config.getBool(container, WHITELIST_KEY);
+ }
+
+ /**
+ * Determines whether feature administration is enabled for a container.
+ *
+ * @param container
+ * The container to check.
+ * @return true if feature administration is enabled for the container false otherwise.
+ */
+ private boolean isFeatureAdminEnabled(String container) {
+ return config.getBool(container, ENABLE_FEATURE_ADMIN);
+ }
+}
Added: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/ContainerAdminData.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/ContainerAdminData.java?rev=1178236&view=auto
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/ContainerAdminData.java (added)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/ContainerAdminData.java Sun Oct 2 19:44:13 2011
@@ -0,0 +1,168 @@
+/*
+ * 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.admin;
+
+import java.util.Map;
+import java.util.Set;
+
+import com.google.caja.util.Maps;
+import com.google.common.base.Objects;
+
+/**
+ * Container's administration data.
+ *
+ * @version $Id: $
+ */
+public class ContainerAdminData {
+ private Map<String, GadgetAdminData> gadgetAdminMap;
+
+ /**
+ * Constructor
+ */
+ public ContainerAdminData() {
+ this(null);
+ }
+
+ /**
+ * Constructor
+ *
+ * @param gadgetAdminMap
+ * map of gadget URLs to gadget admin data.
+ */
+ public ContainerAdminData(Map<String, GadgetAdminData> gadgetAdminMap) {
+ if (gadgetAdminMap == null) {
+ gadgetAdminMap = Maps.newHashMap();
+ }
+ this.gadgetAdminMap = gadgetAdminMap;
+ }
+
+ /**
+ * Adds gadget administration information for this container.
+ *
+ * @param gadgetUrl
+ * the URL of the gadget the admin data is for.
+ * @param toAdd
+ * the administration data for the gadget.
+ */
+ public void addGadgetAdminData(String gadgetUrl, GadgetAdminData toAdd) {
+ if (gadgetUrl != null) {
+ if (toAdd == null) {
+ toAdd = new GadgetAdminData();
+ }
+ this.gadgetAdminMap.put(gadgetUrl, toAdd);
+ }
+ }
+
+ /**
+ * Removes the gadget administration data.
+ *
+ * @param gadgetUrl
+ * the gadget URL.
+ *
+ * @return The gadget administration data that was removed, or null if there was not gadget
+ * administration data associated with that gadget URL.
+ */
+ public GadgetAdminData removeGadgetAdminData(String gadgetUrl) {
+ return this.gadgetAdminMap.remove(gadgetUrl);
+ }
+
+ /**
+ * Gets the gadget admin data for a given gadget.
+ *
+ * @param gadgetUrl
+ * the URL to the gadget to get the administration data for.
+ * @return the gadget admin data.
+ */
+ public GadgetAdminData getGadgetAdminData(String gadgetUrl) {
+ GadgetAdminData match = this.gadgetAdminMap.get(gadgetUrl);
+ if(match != null) {
+ return match;
+ }
+
+ String key = gadgetUrl != null ? getGadgetAdminDataKey(gadgetUrl) : null;
+ return this.gadgetAdminMap.get(key);
+ }
+
+ /**
+ * Gets the gadget admin map.
+ *
+ * @return the gadget admin map.
+ */
+ public Map<String, GadgetAdminData> getGadgetAdminMap() {
+ return this.gadgetAdminMap;
+ }
+
+ /**
+ * Clears the gadget administration data.
+ */
+ public void clearGadgetAdminData() {
+ this.gadgetAdminMap.clear();
+ }
+
+ /**
+ * Determines whether there is administration data for a gadget.
+ *
+ * @param gadgetUrl
+ * the gadget URL to check.
+ * @return true if there is administration data for a gadget false otherwise.
+ */
+ public boolean hasGadgetAdminData(String gadgetUrl) {
+ if (this.gadgetAdminMap.keySet().contains(gadgetUrl)) {
+ return true;
+ }
+
+ return gadgetUrl != null ? getGadgetAdminDataKey(gadgetUrl) != null : false;
+ }
+
+ /**
+ * Gets the key in the map for the gadget URL.
+ *
+ * @param gadgetUrl
+ * The gadget URL.
+ * @return The key in the map for the gadget URL.
+ */
+ private String getGadgetAdminDataKey(String gadgetUrl) {
+ Set<String> gadgetUrls = this.gadgetAdminMap.keySet();
+ String key = null;
+ for (String url : gadgetUrls) {
+ if (url.endsWith("*") && gadgetUrl.startsWith(url.substring(0, url.length() - 1))) {
+ if (key == null || (key != null && key.length() < url.length())) {
+ key = url;
+ }
+ }
+ }
+ return key;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof ContainerAdminData) {
+ ContainerAdminData test = (ContainerAdminData) obj;
+ Map<String, GadgetAdminData> testGadgetAdminMap = test.getGadgetAdminMap();
+ return testGadgetAdminMap.equals(this.getGadgetAdminMap());
+
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(this.gadgetAdminMap);
+ }
+}
Added: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/FeatureAdminData.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/FeatureAdminData.java?rev=1178236&view=auto
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/FeatureAdminData.java (added)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/FeatureAdminData.java Sun Oct 2 19:44:13 2011
@@ -0,0 +1,190 @@
+/*
+ * 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.admin;
+
+import java.util.Set;
+
+import com.google.caja.util.Sets;
+import com.google.common.base.Objects;
+
+/**
+ * Feature administration data for a gadget.
+ *
+ * @version $Id: $
+ */
+public class FeatureAdminData {
+
+ /**
+ * Enumerates the type of feature list.
+ *
+ * @version $Id: $
+ */
+ public enum Type {
+ WHITELIST, BLACKLIST
+ }
+
+ private Set<String> features;
+ private Type type;
+
+ /**
+ * Constructor
+ */
+ public FeatureAdminData() {
+ this(null, null);
+ }
+
+ /**
+ * Constructor
+ *
+ * @param features
+ * a set of features
+ * @param type
+ * determines which set takes priority over the other
+ */
+ public FeatureAdminData(Set<String> features, Type type) {
+ if (features == null) {
+ features = Sets.newHashSet();
+ }
+ if (type == null) {
+ type = Type.WHITELIST;
+ }
+ this.features = features;
+ this.type = type;
+ }
+
+ private void addFeatures(Set<String> toAdd, Set<String> features) {
+ for (String feature : toAdd) {
+ if (feature != null) {
+ features.add(feature);
+ }
+ }
+ }
+
+ /**
+ * Adds features for this gadget.
+ *
+ * @param toAdd
+ * the features for this gadget.
+ */
+ public void addFeatures(Set<String> toAdd) {
+ addFeatures(toAdd, this.features);
+ }
+
+ private Set<String> createSingleFeatureSet(String feature) {
+ Set<String> features = Sets.newHashSet();
+ if (feature != null) {
+ features.add(feature);
+ }
+ return features;
+ }
+
+ /**
+ * Adds an feature for a gadget.
+ *
+ * @param toAdd
+ * the feature to add.
+ */
+ public void addFeature(String toAdd) {
+ Set<String> features = createSingleFeatureSet(toAdd);
+ addFeatures(features);
+ }
+
+ /**
+ * Clears the set of features.
+ */
+ public void clearFeatures() {
+ this.features.clear();
+ }
+
+ private void removeFeatures(Set<String> toRemove, Set<String> features) {
+ if (toRemove != null && features != null) {
+ for (String feature : toRemove) {
+ features.remove(feature);
+ }
+ }
+ }
+
+ /**
+ * Removes the list of features for a gadget.
+ *
+ * @param toRemove
+ * the features to remove.
+ */
+ public void removeFeatures(Set<String> toRemove) {
+ removeFeatures(toRemove, this.features);
+ }
+
+ /**
+ * Removes an feature for a gadget.
+ *
+ * @param toRemove
+ * the feature to remove.
+ */
+ public void removeFeature(String toRemove) {
+ Set<String> features = createSingleFeatureSet(toRemove);
+ removeFeatures(features, this.features);
+ }
+
+ /**
+ * Gets the features.
+ *
+ * @return the features.
+ */
+ public Set<String> getFeatures() {
+ return this.features;
+ }
+
+ /**
+ * Gets the type of features list.
+ *
+ * @return the type of features list.
+ */
+ public Type getType() {
+ return this.type;
+ }
+
+ /**
+ * Sets the type. If this method is passed null than it will default to WHITELIST.
+ *
+ * @param type
+ * the type to set.
+ */
+ public void setType(Type type) {
+ if (type == null) {
+ type = Type.WHITELIST;
+ }
+ this.type = type;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof FeatureAdminData) {
+ FeatureAdminData test = (FeatureAdminData) obj;
+ return this.getFeatures().equals(test.getFeatures())
+ && this.getType().equals(test.getType());
+ }
+ return false;
+
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(this.features, this.type);
+ }
+}
Added: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/GadgetAdminData.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/GadgetAdminData.java?rev=1178236&view=auto
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/GadgetAdminData.java (added)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/GadgetAdminData.java Sun Oct 2 19:44:13 2011
@@ -0,0 +1,85 @@
+/*
+ * 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.admin;
+
+import com.google.common.base.Objects;
+
+/**
+ * Information about the container's administration data.
+ *
+ * @version 3.0.0
+ */
+public class GadgetAdminData {
+ // In the future as more gadget admin data is created we
+ // should add it here.
+ private FeatureAdminData featureAdminData;
+
+ /**
+ * Constructor
+ */
+ public GadgetAdminData() {
+ this.featureAdminData = new FeatureAdminData();
+ }
+
+ /**
+ * Constructor
+ *
+ * @param featureAdminData
+ * Feature administration data for this gadget
+ */
+ public GadgetAdminData(FeatureAdminData featureAdminData) {
+ if (featureAdminData == null) {
+ featureAdminData = new FeatureAdminData();
+ }
+ this.featureAdminData = featureAdminData;
+ }
+
+ /**
+ * Gets the feature administration data for this gadget.
+ *
+ * @return
+ */
+ public FeatureAdminData getFeatureAdminData() {
+ return this.featureAdminData;
+ }
+
+ /**
+ * Sets the feature admin data.
+ *
+ * @param featureAdminData
+ * the feature admin data to set.
+ */
+ public void setFeatureAdminData(FeatureAdminData featureAdminData) {
+ this.featureAdminData = featureAdminData;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof GadgetAdminData) {
+ GadgetAdminData test = (GadgetAdminData) obj;
+ return this.getFeatureAdminData().equals(test.getFeatureAdminData());
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(this.featureAdminData);
+ }
+}
Added: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/GadgetAdminModule.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/GadgetAdminModule.java?rev=1178236&view=auto
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/GadgetAdminModule.java (added)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/GadgetAdminModule.java Sun Oct 2 19:44:13 2011
@@ -0,0 +1,76 @@
+/*
+ * 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.admin;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.shindig.common.logging.i18n.MessageKeys;
+import org.apache.shindig.common.util.ResourceLoader;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+
+/**
+ * Module to load the gadget administration information.
+ *
+ * @version $Id: $
+ */
+public class GadgetAdminModule extends AbstractModule {
+
+ private static final String GADGET_ADMIN_CONFIG = "config/gadget-admin.json";
+ private static final String classname = GadgetAdminModule.class.getName();
+ private static final Logger LOG = Logger.getLogger(classname, MessageKeys.MESSAGES);
+
+ @Override
+ protected void configure() {
+ bind(GadgetAdminStore.class).toProvider(GadgetAdminStoreProvider.class);
+ }
+
+ @Singleton
+ public static class GadgetAdminStoreProvider implements Provider<GadgetAdminStore> {
+ private BasicGadgetAdminStore store;
+
+ @Inject
+ public GadgetAdminStoreProvider(BasicGadgetAdminStore store) {
+ this.store = store;
+ loadStore();
+ }
+
+ private void loadStore() {
+ try {
+ String gadgetAdminString = ResourceLoader.getContent(GADGET_ADMIN_CONFIG);
+ this.store.init(gadgetAdminString);
+ } catch (Throwable t) {
+ if (LOG.isLoggable(Level.WARNING)) {
+ LOG.logp(Level.WARNING, classname, "loadStore", MessageKeys.FAILED_TO_INIT,
+ new Object[] { GADGET_ADMIN_CONFIG });
+ LOG.log(Level.WARNING, "", t);
+ }
+ }
+ }
+
+ @Override
+ public GadgetAdminStore get() {
+ return store;
+ }
+ }
+}
Added: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/GadgetAdminStore.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/GadgetAdminStore.java?rev=1178236&view=auto
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/GadgetAdminStore.java (added)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/GadgetAdminStore.java Sun Oct 2 19:44:13 2011
@@ -0,0 +1,113 @@
+/*
+ * 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.admin;
+
+import org.apache.shindig.gadgets.Gadget;
+import org.apache.shindig.gadgets.spec.Feature;
+
+/**
+ * Interface for working with the store of gadget administration data.
+ *
+ * @version 3.0.0
+ */
+public interface GadgetAdminStore {
+
+ /**
+ * Gets the administration data for a gadget in a container.
+ *
+ * @param container
+ * the container id.
+ * @param gadgetUrl
+ * the gadget URL.
+ * @return the administration data for a gadget in a container
+ */
+ public GadgetAdminData getGadgetAdminData(String container, String gadgetUrl);
+
+ /**
+ * Sets gadget administration data for a gadget in a container.
+ *
+ * @param container
+ * the container id.
+ * @param gadgetUrl
+ * the gadget URL.
+ * @param adminData
+ * administration data.
+ */
+ public void setGadgetAdminData(String container, String gadgetUrl, GadgetAdminData adminData);
+
+ /**
+ * Gets container administration data.
+ *
+ * @param container
+ * the container to get the administration data for.
+ * @return container administration data.
+ */
+ public ContainerAdminData getContainerAdminData(String container);
+
+ /**
+ * Sets the container administration data..
+ *
+ * @param container
+ * the container to set the administration data for.
+ * @param containerAdminData
+ * the container administration data.
+ */
+ public void setContainerAdminData(String container, ContainerAdminData containerAdminData);
+
+ /**
+ * Gets the administration data for the server.
+ *
+ * @return the administration data for the server.
+ */
+ public ServerAdminData getServerAdminData();
+
+ /**
+ * Checks the feature administration data for a gadget.
+ *
+ * @param gadget
+ * The gadget to check.
+ * @return true if the gadget is allowed to use all the features it requires false otherwise.
+ */
+ public boolean checkFeatureAdminInfo(Gadget gadget);
+
+ /**
+ * If feature administration is enabled for the given container then check to see if the feature
+ * is allowed. If it is not allowed the feature code will not be loaded in the container so we
+ * should not put it in the config.
+ *
+ * @param feature
+ * The feature to check.
+ * @param gadget
+ * The gadget to check.
+ * @return true if the feature is allowed to be used by the gadget in the given container.
+ */
+ public boolean isAllowedFeature(Feature feature, Gadget gadget);
+
+ /**
+ * Determines whether a gadget is on the whitelist of trusted gadgets set by the admin.
+ *
+ * @param container
+ * The container id.
+ * @param gadgetUrl
+ * The gadget URL.
+ * @return true if the gadget is on the whitelist, false otherwise.
+ */
+ public boolean isWhitelisted(String container, String gadgetUrl);
+
+}
Added: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/ServerAdminData.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/ServerAdminData.java?rev=1178236&view=auto
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/ServerAdminData.java (added)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/admin/ServerAdminData.java Sun Oct 2 19:44:13 2011
@@ -0,0 +1,134 @@
+/*
+ * 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.admin;
+
+import java.util.Map;
+
+import com.google.caja.util.Maps;
+import com.google.common.base.Objects;
+
+/**
+ * Administration data for the server.
+ *
+ * @version $Id: $
+ */
+public class ServerAdminData {
+ private Map<String, ContainerAdminData> containerAdminDataMap;
+
+ /**
+ * Constructor.
+ */
+ public ServerAdminData() {
+ this(null);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param containerAdminMap
+ * a map of container IDs to container.
+ */
+ public ServerAdminData(Map<String, ContainerAdminData> containerAdminMap) {
+ if (containerAdminMap == null) {
+ containerAdminMap = Maps.newHashMap();
+ }
+ this.containerAdminDataMap = containerAdminMap;
+ }
+
+ /**
+ * Gets the given containers administration data.
+ *
+ * @param container
+ * the id of the container.
+ * @return the administration data for the container.
+ */
+ public ContainerAdminData getContainerAdminData(String container) {
+ container = container != null ? container.toLowerCase() : container;
+ return this.containerAdminDataMap.get(container);
+ }
+
+ /**
+ * Removes container administration data.
+ *
+ * @param container
+ * the container id.
+ */
+ public void removeContainerAdminData(String container) {
+ this.containerAdminDataMap.remove(container);
+ }
+
+ /**
+ * Adds administration data for a container.
+ *
+ * @param container
+ * the container id the admin data is for.
+ * @param toAdd
+ * the admin data to add.
+ */
+ public void addContainerAdminData(String container, ContainerAdminData toAdd) {
+ if (container != null) {
+ if (toAdd == null) {
+ toAdd = new ContainerAdminData();
+ }
+ this.containerAdminDataMap.put(container.toLowerCase(), toAdd);
+ }
+ }
+
+ /**
+ * Gets the map of container IDs to container admin data.
+ *
+ * @return the map of container IDs to container admin data.
+ */
+ public Map<String, ContainerAdminData> getContainerAdminDataMap() {
+ return this.containerAdminDataMap;
+ }
+
+ /**
+ * Clears all the container administration data.
+ */
+ public void clearContainerAdminData() {
+ this.containerAdminDataMap.clear();
+ }
+
+ /**
+ * Determines whether there is administration data for the container.
+ *
+ * @param container
+ * the container to check.
+ * @return true if there is administration data false otherwise.
+ */
+ public boolean hasContainerAdminData(String container) {
+ container = container != null ? container.toLowerCase() : container;
+ return this.containerAdminDataMap.keySet().contains(container);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof ServerAdminData) {
+ ServerAdminData test = (ServerAdminData) obj;
+ return test.getContainerAdminDataMap().equals(this.containerAdminDataMap);
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(this.containerAdminDataMap);
+ }
+}
Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/config/CoreUtilConfigContributor.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/config/CoreUtilConfigContributor.java?rev=1178236&r1=1178235&r2=1178236&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/config/CoreUtilConfigContributor.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/config/CoreUtilConfigContributor.java Sun Oct 2 19:44:13 2011
@@ -18,16 +18,18 @@
*/
package org.apache.shindig.gadgets.config;
-import com.google.common.collect.Maps;
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
import org.apache.shindig.gadgets.Gadget;
+import org.apache.shindig.gadgets.admin.GadgetAdminStore;
import org.apache.shindig.gadgets.features.FeatureRegistry;
import org.apache.shindig.gadgets.spec.Feature;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Set;
+import com.google.common.collect.Maps;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
/**
* Populates the core.util configuration, which at present includes the list
@@ -37,11 +39,15 @@ import java.util.Set;
*/
@Singleton
public class CoreUtilConfigContributor implements ConfigContributor {
+
private final FeatureRegistry registry;
+ private final GadgetAdminStore gadgetAdminStore;
@Inject
- public CoreUtilConfigContributor(final FeatureRegistry registry) {
+ public CoreUtilConfigContributor(final FeatureRegistry registry,
+ GadgetAdminStore gadgetAdminStore) {
this.registry = registry;
+ this.gadgetAdminStore = gadgetAdminStore;
}
@@ -54,7 +60,8 @@ public class CoreUtilConfigContributor i
for (Feature feature : features) {
// Skip unregistered features
- if (!allFeatureNames.contains(feature.getName())) {
+ if ((!allFeatureNames.contains(feature.getName())) ||
+ (!gadgetAdminStore.isAllowedFeature(feature, gadget))) {
continue;
}
// Flatten out the multimap a bit for backwards compatibility: map keys
Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/features/FeatureRegistry.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/features/FeatureRegistry.java?rev=1178236&r1=1178235&r2=1178236&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/features/FeatureRegistry.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/features/FeatureRegistry.java Sun Oct 2 19:44:13 2011
@@ -635,7 +635,7 @@ public class FeatureRegistry {
String tagMatch = null;
String directTag = rctx.getFeatureBundleTag();
for (FeatureBundle bundle : bundles) {
- if (directTag.equalsIgnoreCase(bundle.getType())) {
+ if (directTag != null && directTag.equalsIgnoreCase(bundle.getType())) {
tagMatch = directTag;
}
}
Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/process/Processor.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/process/Processor.java?rev=1178236&r1=1178235&r2=1178236&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/process/Processor.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/process/Processor.java Sun Oct 2 19:44:13 2011
@@ -17,14 +17,19 @@
*/
package org.apache.shindig.gadgets.process;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.servlet.http.HttpServletResponse;
+
import org.apache.shindig.common.logging.i18n.MessageKeys;
import org.apache.shindig.common.uri.Uri;
import org.apache.shindig.config.ContainerConfig;
import org.apache.shindig.gadgets.Gadget;
-import org.apache.shindig.gadgets.GadgetBlacklist;
import org.apache.shindig.gadgets.GadgetContext;
import org.apache.shindig.gadgets.GadgetException;
import org.apache.shindig.gadgets.GadgetSpecFactory;
+import org.apache.shindig.gadgets.admin.GadgetAdminStore;
import org.apache.shindig.gadgets.features.FeatureRegistry;
import org.apache.shindig.gadgets.features.FeatureRegistryProvider;
import org.apache.shindig.gadgets.spec.GadgetSpec;
@@ -34,11 +39,6 @@ import org.apache.shindig.gadgets.variab
import com.google.inject.Inject;
import com.google.inject.Singleton;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.servlet.http.HttpServletResponse;
-
/**
* Converts an input Context into an output Gadget.
*/
@@ -50,18 +50,18 @@ public class Processor {
private final GadgetSpecFactory gadgetSpecFactory;
private final VariableSubstituter substituter;
private final ContainerConfig containerConfig;
- private final GadgetBlacklist blacklist;
+ private final GadgetAdminStore gadgetAdminStore;
private final FeatureRegistryProvider featureRegistryProvider;
@Inject
public Processor(GadgetSpecFactory gadgetSpecFactory,
VariableSubstituter substituter,
ContainerConfig containerConfig,
- GadgetBlacklist blacklist,
+ GadgetAdminStore gadgetAdminStore,
FeatureRegistryProvider featureRegistryProvider) {
this.gadgetSpecFactory = gadgetSpecFactory;
this.substituter = substituter;
- this.blacklist = blacklist;
+ this.gadgetAdminStore = gadgetAdminStore;
this.containerConfig = containerConfig;
this.featureRegistryProvider = featureRegistryProvider;
}
@@ -104,13 +104,12 @@ public class Processor {
}
validateGadgetUrl(url);
-
- if (blacklist.isBlacklisted(url)) {
+ if (!gadgetAdminStore.isWhitelisted(context.getContainer(), url.toString())) {
if (LOG.isLoggable(Level.INFO)) {
- LOG.logp(Level.INFO, classname, "process", MessageKeys.RENDER_BLACKLISTED_GADGET, new Object[] {url});
+ LOG.logp(Level.INFO, classname, "process", MessageKeys.RENDER_NON_WHITELISTED_GADGET, new Object[] {url});
}
throw new ProcessingException("The requested gadget is unavailable",
- HttpServletResponse.SC_FORBIDDEN);
+ HttpServletResponse.SC_FORBIDDEN);
}
return new Gadget()
Modified: shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.java
URL: http://svn.apache.org/viewvc/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.java?rev=1178236&r1=1178235&r2=1178236&view=diff
==============================================================================
--- shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.java (original)
+++ shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RenderingGadgetRewriter.java Sun Oct 2 19:44:13 2011
@@ -18,6 +18,13 @@
*/
package org.apache.shindig.gadgets.render;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
import org.apache.commons.lang.StringUtils;
import org.apache.shindig.common.JsonSerializer;
import org.apache.shindig.common.logging.i18n.MessageKeys;
@@ -32,6 +39,7 @@ import org.apache.shindig.gadgets.Gadget
import org.apache.shindig.gadgets.MessageBundleFactory;
import org.apache.shindig.gadgets.RenderingContext;
import org.apache.shindig.gadgets.UnsupportedFeatureException;
+import org.apache.shindig.gadgets.admin.GadgetAdminStore;
import org.apache.shindig.gadgets.config.ConfigProcessor;
import org.apache.shindig.gadgets.features.FeatureRegistry;
import org.apache.shindig.gadgets.features.FeatureRegistryProvider;
@@ -58,13 +66,6 @@ import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
@@ -112,6 +113,7 @@ public class RenderingGadgetRewriter imp
protected final JsServingPipeline jsServingPipeline;
protected final JsUriManager jsUriManager;
protected final ConfigProcessor configProcessor;
+ protected final GadgetAdminStore gadgetAdminStore;
protected Set<String> defaultExternLibs = ImmutableSet.of();
@@ -131,13 +133,15 @@ public class RenderingGadgetRewriter imp
FeatureRegistryProvider featureRegistryProvider,
JsServingPipeline jsServingPipeline,
JsUriManager jsUriManager,
- ConfigProcessor configProcessor) {
+ ConfigProcessor configProcessor,
+ GadgetAdminStore gadgetAdminStore) {
this.messageBundleFactory = messageBundleFactory;
this.containerConfig = containerConfig;
this.featureRegistryProvider = featureRegistryProvider;
this.jsServingPipeline = jsServingPipeline;
this.jsUriManager = jsUriManager;
this.configProcessor = configProcessor;
+ this.gadgetAdminStore = gadgetAdminStore;
}
public void setDefaultDoctypeQName(String qname) {
@@ -297,6 +301,10 @@ public class RenderingGadgetRewriter imp
FeatureRegistry featureRegistry = featureRegistryProvider.get(repository);
checkRequiredFeatures(gadget, featureRegistry);
+ //Check to make sure all the required features that are about to be injected are allowed
+ if(!gadgetAdminStore.checkFeatureAdminInfo(gadget)) {
+ throw new GadgetException(Code.GADGET_ADMIN_FEATURE_NOT_ALLOWED);
+ }
// Set of extern libraries requested by the container
Set<String> externForcedLibs = defaultExternLibs;
@@ -312,7 +320,15 @@ public class RenderingGadgetRewriter imp
injectScript(externForcedLibs, null, false, gadget, headTag, firstHeadChild, "");
}
- Collection<String> gadgetLibs = gadget.getDirectFeatureDeps();
+ Collection<String> gadgetLibs = Lists.newArrayList(gadget.getDirectFeatureDeps());
+ List<Feature> gadgetFeatures = gadget.getSpec().getModulePrefs().getAllFeatures();
+ for(Feature feature : gadgetFeatures) {
+ if(!feature.getRequired() &&
+ !gadgetAdminStore.isAllowedFeature(feature, gadget)) {
+ //If the feature is optional and the admin has not allowed it don't include it
+ gadgetLibs.remove(feature.getName());
+ }
+ }
// Get config for all features
Set<String> allLibs = ImmutableSet.<String>builder()
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=1178236&r1=1178235&r2=1178236&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 Sun Oct 2 19:44:13 2011
@@ -18,19 +18,15 @@
*/
package org.apache.shindig.gadgets.servlet;
-import com.google.common.collect.Multimap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
import org.apache.shindig.common.uri.Uri;
-import org.apache.shindig.gadgets.spec.OAuthService.EndPoint;
-import org.apache.shindig.gadgets.spec.OAuthService.Location;
-import org.apache.shindig.gadgets.spec.OAuthService.Method;
import org.apache.shindig.protocol.conversion.BeanFilter.Unfiltered;
-// Keep imports clean, so it is clear what is used by API
-
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
+import com.google.common.collect.Multimap;
/**
* Gadget Handler Interface data.
@@ -100,6 +96,7 @@ public class GadgetsHandlerApi {
public Map<String, UserPref> getUserPrefs();
public Map<String, View> getViews();
public Boolean getNeedsTokenRefresh();
+ public Set<String> getRpcServiceIds();
}
public enum ViewContentType {
@@ -251,9 +248,9 @@ public class GadgetsHandlerApi {
}
public enum Location {
- HEADER("auth-header"),
- URL("uri-query"),
- BODY("post-body");
+ HEADER("auth-header"),
+ URL("uri-query"),
+ BODY("post-body");
private String locationString;
private Location(String locationString) {
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=1178236&r1=1178235&r2=1178236&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 Sun Oct 2 19:44:13 2011
@@ -25,12 +25,6 @@ import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-import com.google.inject.Inject;
-import com.google.inject.name.Named;
import javax.servlet.http.HttpServletResponse;
@@ -46,6 +40,12 @@ import org.apache.shindig.gadgets.Gadget
import org.apache.shindig.gadgets.GadgetContext;
import org.apache.shindig.gadgets.GadgetException;
import org.apache.shindig.gadgets.RenderingContext;
+import org.apache.shindig.gadgets.admin.GadgetAdminStore;
+import org.apache.shindig.gadgets.features.ApiDirective;
+import org.apache.shindig.gadgets.features.FeatureRegistry;
+import org.apache.shindig.gadgets.features.FeatureRegistry.FeatureBundle;
+import org.apache.shindig.gadgets.features.FeatureRegistry.LookupResult;
+import org.apache.shindig.gadgets.features.FeatureRegistryProvider;
import org.apache.shindig.gadgets.http.HttpResponse;
import org.apache.shindig.gadgets.js.JsException;
import org.apache.shindig.gadgets.js.JsRequestBuilder;
@@ -61,12 +61,12 @@ import org.apache.shindig.gadgets.spec.M
import org.apache.shindig.gadgets.spec.OAuthService;
import org.apache.shindig.gadgets.spec.OAuthSpec;
import org.apache.shindig.gadgets.spec.UserPref;
-import org.apache.shindig.gadgets.spec.View;
import org.apache.shindig.gadgets.spec.UserPref.EnumValuePair;
+import org.apache.shindig.gadgets.spec.View;
import org.apache.shindig.gadgets.uri.IframeUriManager;
import org.apache.shindig.gadgets.uri.JsUriManager;
-import org.apache.shindig.gadgets.uri.ProxyUriManager;
import org.apache.shindig.gadgets.uri.JsUriManager.JsUri;
+import org.apache.shindig.gadgets.uri.ProxyUriManager;
import org.apache.shindig.gadgets.uri.ProxyUriManager.ProxyUri;
import org.apache.shindig.protocol.conversion.BeanDelegator;
import org.apache.shindig.protocol.conversion.BeanFilter;
@@ -78,6 +78,13 @@ import com.google.caja.render.JsMinimalP
import com.google.caja.render.JsPrettyPrinter;
import com.google.caja.reporting.MessageContext;
import com.google.caja.reporting.RenderContext;
+import com.google.caja.util.Sets;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
/**
* Service that interfaces with the system to provide information about gadgets.
@@ -142,6 +149,8 @@ public class GadgetsHandlerService {
protected final long specRefreshInterval;
protected final BeanFilter beanFilter;
protected final CajaContentRewriter cajaContentRewriter;
+ protected final GadgetAdminStore gadgetAdminStore;
+ protected final FeatureRegistryProvider featureRegistryProvider;
@Inject
public GadgetsHandlerService(TimeSource timeSource, Processor processor,
@@ -149,7 +158,9 @@ public class GadgetsHandlerService {
ProxyUriManager proxyUriManager, JsUriManager jsUriManager, ProxyHandler proxyHandler,
JsServingPipeline jsPipeline, JsRequestBuilder jsRequestBuilder,
@Named("shindig.cache.xml.refreshInterval") long specRefreshInterval,
- BeanFilter beanFilter, CajaContentRewriter cajaContentRewriter) {
+ BeanFilter beanFilter, CajaContentRewriter cajaContentRewriter,
+ GadgetAdminStore gadgetAdminStore,
+ FeatureRegistryProvider featureRegistryProvider) {
this.timeSource = timeSource;
this.processor = processor;
this.iframeUriManager = iframeUriManager;
@@ -162,6 +173,8 @@ public class GadgetsHandlerService {
this.specRefreshInterval = specRefreshInterval;
this.beanFilter = beanFilter;
this.cajaContentRewriter = cajaContentRewriter;
+ this.gadgetAdminStore = gadgetAdminStore;
+ this.featureRegistryProvider = featureRegistryProvider;
this.beanDelegator = new BeanDelegator(API_CLASSES, ENUM_CONVERSION_MAP);
}
@@ -179,17 +192,59 @@ public class GadgetsHandlerService {
GadgetContext context = new MetadataGadgetContext(request);
Gadget gadget = processor.process(context);
+
boolean needIfrUrl = isFieldIncluded(fields, "iframeurl");
- if (needIfrUrl && gadget.getCurrentView() == null) {
- throw new ProcessingException("View " + request.getView() + " does not exist",
- HttpResponse.SC_BAD_REQUEST);
+ if (needIfrUrl) {
+ if(!gadgetAdminStore.checkFeatureAdminInfo(gadget)) {
+ throw new ProcessingException("Gadget is not trusted to render in this container.",
+ HttpResponse.SC_BAD_REQUEST);
+ }
+
+ if(gadget.getCurrentView() == null) {
+ throw new ProcessingException("View " + request.getView() + " does not exist",
+ HttpResponse.SC_BAD_REQUEST);
+ }
}
String iframeUrl = needIfrUrl ? iframeUriManager.makeRenderingUri(gadget).toString() : null;
Boolean needsTokenRefresh =
isFieldIncluded(fields, "needstokenrefresh") ?
gadget.getAllFeatures().contains("auth-refresh") : null;
+
+ Set<String> rpcServiceIds = getRpcServiceIds(gadget);
return createMetadataResponse(context.getUrl(), gadget.getSpec(), iframeUrl,
- needsTokenRefresh, fields, timeSource.currentTimeMillis() + specRefreshInterval);
+ needsTokenRefresh, fields, timeSource.currentTimeMillis() + specRefreshInterval,
+ rpcServiceIds);
+ }
+
+ /**
+ * Gets the set of allowed RPC service ids.
+ *
+ * @param gadget
+ * the gadget to get the service ids for.
+ * @return the set of allowed RPC service ids.
+ */
+ private Set<String> getRpcServiceIds(Gadget gadget) {
+ GadgetContext context = gadget.getContext();
+ Set<String> rpcEndpoints = Sets.newHashSet();
+ List<Feature> modulePrefFeatures = gadget.getSpec().getModulePrefs().getAllFeatures();
+ List<String> featureNames = Lists.newArrayList();
+ for(Feature feature : modulePrefFeatures) {
+ if(gadgetAdminStore.isAllowedFeature(feature, gadget)) {
+ featureNames.add(feature.getName());
+ }
+ }
+ try {
+ FeatureRegistry featureRegistry = featureRegistryProvider.get(context.getRepository());
+ LookupResult result = featureRegistry.getFeatureResources(context, featureRegistry.getFeatures(featureNames),
+ null);
+ List<FeatureBundle> bundles = result.getBundles();
+ for (FeatureBundle bundle : bundles) {
+ rpcEndpoints.addAll(bundle.getApis(ApiDirective.Type.RPC, false));
+ }
+ } catch (GadgetException e) {
+ LOG.log(Level.WARNING, "Error getting features from feature registry", e);
+ }
+ return rpcEndpoints;
}
private boolean isFieldIncluded(Set<String> fields, String name) {
@@ -471,7 +526,7 @@ public class GadgetsHandlerService {
@VisibleForTesting
GadgetsHandlerApi.MetadataResponse createMetadataResponse(
Uri url, GadgetSpec spec, String iframeUrl, Boolean needsTokenRefresh,
- Set<String> fields, Long expireTime) {
+ Set<String> fields, Long expireTime, Set<String> rpcServiceIds) {
return (GadgetsHandlerApi.MetadataResponse) beanFilter.createFilteredBean(
beanDelegator.createDelegator(spec, GadgetsHandlerApi.MetadataResponse.class,
ImmutableMap.<String, Object>builder()
@@ -480,7 +535,8 @@ public class GadgetsHandlerService {
.put("iframeurl", BeanDelegator.nullable(iframeUrl))
.put("needstokenrefresh", BeanDelegator.nullable(needsTokenRefresh))
.put("responsetimems", timeSource.currentTimeMillis())
- .put("expiretimems", BeanDelegator.nullable(expireTime)).build()),
+ .put("expiretimems", BeanDelegator.nullable(expireTime))
+ .put("rpcserviceids", BeanDelegator.nullable(rpcServiceIds)).build()),
fields);
}