You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@wookie.apache.org by sc...@apache.org on 2010/02/23 21:26:50 UTC

svn commit: r915501 - in /incubator/wookie/trunk: scripts/derby/ scripts/mysql/ src-tests/org/apache/wookie/tests/ src-tests/org/apache/wookie/tests/functional/ src/org/apache/wookie/beans/ src/org/apache/wookie/manager/ src/org/apache/wookie/manager/i...

Author: scottbw
Date: Tue Feb 23 20:26:50 2010
New Revision: 915501

URL: http://svn.apache.org/viewvc?rev=915501&view=rev
Log:
Implemented W3C WARP spec (see WOOKIE-85). This automatically adds access request beans for widgets based on the content of the <access> element in config.xml. These are granted by default if the widget is deployed to the local deploy folder, but otherwise are not granted. There is currently however no UI for administrators to grant or revoke these access requests. Note that this update includes a database schema change to add a new table for AccessRequest.

Added:
    incubator/wookie/trunk/src-tests/org/apache/wookie/tests/AccessRequestTest.java
    incubator/wookie/trunk/src/org/apache/wookie/beans/AccessRequest.java
Modified:
    incubator/wookie/trunk/scripts/derby/widgetdb.sql
    incubator/wookie/trunk/scripts/mysql/widgetdb.sql
    incubator/wookie/trunk/src-tests/org/apache/wookie/tests/functional/AbstractControllerTest.java
    incubator/wookie/trunk/src-tests/org/apache/wookie/tests/functional/ProxyTest.java
    incubator/wookie/trunk/src/org/apache/wookie/beans/schema.hbm.xml
    incubator/wookie/trunk/src/org/apache/wookie/manager/IWidgetAdminManager.java
    incubator/wookie/trunk/src/org/apache/wookie/manager/impl/WidgetAdminManager.java
    incubator/wookie/trunk/src/org/apache/wookie/proxy/ProxyServlet.java
    incubator/wookie/trunk/src/org/apache/wookie/server/ContextListener.java

Modified: incubator/wookie/trunk/scripts/derby/widgetdb.sql
URL: http://svn.apache.org/viewvc/incubator/wookie/trunk/scripts/derby/widgetdb.sql?rev=915501&r1=915500&r2=915501&view=diff
==============================================================================
--- incubator/wookie/trunk/scripts/derby/widgetdb.sql (original)
+++ incubator/wookie/trunk/scripts/derby/widgetdb.sql Tue Feb 23 20:26:50 2010
@@ -9,5 +9,5 @@
 INSERT INTO WidgetService VALUES (1,'unsupported'),(2,'chat'),(3,'games'),(4,'voting'),(5,'weather');
 INSERT INTO WidgetType VALUES (1,1,'unsupported');
 INSERT INTO WidgetIcon VALUES (1,'/wookie/shared/images/defaultwidget.png',80,80,'en',1);
-INSERT INTO Whitelist VALUES (1,'http://127.0.0.1'),(2,'http://localhost'),(3,'http://feeds.bbc.co.uk/weather/feeds/rss'),(4,'http://incubator.apache.org/wookie');
+INSERT INTO Whitelist VALUES (1,'http://127.0.0.1'),(2,'http://localhost'),(3,'http://incubator.apache.org/wookie');
 INSERT INTO ApiKey VALUES (1,'TEST','test@127.0.0.1')
\ No newline at end of file

Modified: incubator/wookie/trunk/scripts/mysql/widgetdb.sql
URL: http://svn.apache.org/viewvc/incubator/wookie/trunk/scripts/mysql/widgetdb.sql?rev=915501&r1=915500&r2=915501&view=diff
==============================================================================
--- incubator/wookie/trunk/scripts/mysql/widgetdb.sql (original)
+++ incubator/wookie/trunk/scripts/mysql/widgetdb.sql Tue Feb 23 20:26:50 2010
@@ -51,6 +51,17 @@
   CONSTRAINT `FKwidgetnamewidgetc` FOREIGN KEY (`widget_id`) REFERENCES `Widget` (`id`)
 );
 
+CREATE TABLE `AccessRequest` (
+  `id` int(11) NOT NULL auto_increment,
+  `origin` varchar(2048) default NULL,
+  `subdomains` varchar(1) default NULL,
+  `granted` varchar(1) default NULL,
+  `widget_id` int(11) NOT NULL,
+  PRIMARY KEY  (`id`),
+  KEY `FKwidgetaccesswidget` (`widget_id`),
+  CONSTRAINT `FKwidgetaccesswidgetc` FOREIGN KEY (`widget_id`) REFERENCES `Widget` (`id`)
+);
+
 CREATE TABLE `Description` (
   `id` int(11) NOT NULL auto_increment,
   `content` longtext default NULL,
@@ -235,5 +246,5 @@
 INSERT INTO `WidgetService` VALUES (1,'unsupported'),(2,'chat'),(3,'games'),(4,'voting'),(5,'weather');
 INSERT INTO `WidgetType` VALUES (1,1,'unsupported');
 INSERT INTO `WidgetIcon` VALUES (1,'/wookie/shared/images/defaultwidget.png',80,80,'en',1);
-INSERT INTO `Whitelist` VALUES (1,'http://127.0.0.1'),(2,'http://localhost'),(3,'http://feeds.bbc.co.uk/weather/feeds/rss'),(4,'http://incubator.apache.org/wookie');
+INSERT INTO `Whitelist` VALUES (1,'http://127.0.0.1'),(2,'http://localhost'),(3,'http://incubator.apache.org/wookie');
 INSERT INTO `ApiKey` VALUES (1,'TEST','test@127.0.0.1');
\ No newline at end of file

Added: incubator/wookie/trunk/src-tests/org/apache/wookie/tests/AccessRequestTest.java
URL: http://svn.apache.org/viewvc/incubator/wookie/trunk/src-tests/org/apache/wookie/tests/AccessRequestTest.java?rev=915501&view=auto
==============================================================================
--- incubator/wookie/trunk/src-tests/org/apache/wookie/tests/AccessRequestTest.java (added)
+++ incubator/wookie/trunk/src-tests/org/apache/wookie/tests/AccessRequestTest.java Tue Feb 23 20:26:50 2010
@@ -0,0 +1,74 @@
+/*
+ *  Licensed 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.wookie.tests;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.net.URI;
+
+import org.apache.wookie.beans.AccessRequest;
+import org.junit.Test;
+
+
+public class AccessRequestTest {
+
+	@Test
+	public void wildcardTest() throws Exception{
+		AccessRequest ar = new AccessRequest();
+		ar.setOrigin("*");
+		assertTrue(ar.isAllowed(new URI("http://incubator.apache.org")));
+	}
+	
+	@Test
+	public void basicTest() throws Exception{
+		AccessRequest ar = new AccessRequest();
+		ar.setOrigin("http://incubator.apache.org");
+		assertTrue(ar.isAllowed(new URI("http://incubator.apache.org")));
+	}
+	
+	@Test
+	public void pathsTest() throws Exception{
+		AccessRequest ar = new AccessRequest();
+		ar.setOrigin("http://incubator.apache.org");
+		assertTrue(ar.isAllowed(new URI("http://incubator.apache.org/test")));
+	}
+	
+	@Test
+	public void schemesTest() throws Exception{
+		AccessRequest ar = new AccessRequest();
+		ar.setOrigin("http://incubator.apache.org");
+		assertFalse(ar.isAllowed(new URI("https://incubator.apache.org/test")));
+	}
+	
+	@Test
+	public void subDomainsTest() throws Exception{
+		AccessRequest ar = new AccessRequest();
+		ar.setOrigin("http://apache.org");
+		ar.setSubdomains(true);
+		assertTrue(ar.isAllowed(new URI("http://incubator.apache.org")));
+		assertTrue(ar.isAllowed(new URI("http://www.apache.org")));
+		assertFalse(ar.isAllowed(new URI("http://apache.org.com")));
+	}
+	
+	@Test
+	public void noSubDomainsTest() throws Exception{
+		AccessRequest ar = new AccessRequest();
+		ar.setOrigin("http://apache.org");
+		ar.setSubdomains(false);
+		assertTrue(ar.isAllowed(new URI("http://apache.org")));
+		assertFalse(ar.isAllowed(new URI("http://incubator.apache.org")));
+		assertFalse(ar.isAllowed(new URI("http://www.apache.org")));
+	}
+}

Modified: incubator/wookie/trunk/src-tests/org/apache/wookie/tests/functional/AbstractControllerTest.java
URL: http://svn.apache.org/viewvc/incubator/wookie/trunk/src-tests/org/apache/wookie/tests/functional/AbstractControllerTest.java?rev=915501&r1=915500&r2=915501&view=diff
==============================================================================
--- incubator/wookie/trunk/src-tests/org/apache/wookie/tests/functional/AbstractControllerTest.java (original)
+++ incubator/wookie/trunk/src-tests/org/apache/wookie/tests/functional/AbstractControllerTest.java Tue Feb 23 20:26:50 2010
@@ -28,7 +28,7 @@
 		
 	protected static final String API_KEY_VALID = "TEST";
 	protected static final String API_KEY_INVALID = "rubbish";
-	protected static final String WIDGET_ID_VALID = "http://www.getwookie.org/widgets/natter";
+	protected static final String WIDGET_ID_VALID = "http://www.getwookie.org/widgets/weather";
 	protected static final String WIDGET_ID_INVALID = "http://www.getwookie.org/widgets/nosuchwidget";
 
 }

Modified: incubator/wookie/trunk/src-tests/org/apache/wookie/tests/functional/ProxyTest.java
URL: http://svn.apache.org/viewvc/incubator/wookie/trunk/src-tests/org/apache/wookie/tests/functional/ProxyTest.java?rev=915501&r1=915500&r2=915501&view=diff
==============================================================================
--- incubator/wookie/trunk/src-tests/org/apache/wookie/tests/functional/ProxyTest.java (original)
+++ incubator/wookie/trunk/src-tests/org/apache/wookie/tests/functional/ProxyTest.java Tue Feb 23 20:26:50 2010
@@ -34,11 +34,15 @@
 public class ProxyTest extends AbstractControllerTest {
 
 	private static String instance_id_key;
+	private static String other_instance_id_key;
+	private static final String OTHER_WIDGET_ID = "http://www.getwookie.org/widgets/natter";
 	private static final String PROXY_URL = "http://localhost:8080/wookie/proxy";
 	private static final String VALID_SITE_URL = "http://incubator.apache.org/wookie/";
 	private static final String VALID_SITE_XML_URL = "http://localhost:8080/wookie/widgets?all=true";
 	private static final String INVALID_SITE_URL = "DFASFAFEQ3FQ32145235123452";
 	private static final String BLOCKED_SITE_URL = "http://very.bad.place";
+	private static final String POLICY_ALLOWED_SITE_URL = "http://www.bbc.co.uk/weather/feeds/rss.shtml?world=11";
+	private static final String POLICY_DISALLOWED_SITE_URL = "http://news.bbc.co.uk";
 	private static final String PROTECTED_SITE_URL = "http://localhost:8080/wookie/admin/";
 
 	/**
@@ -59,6 +63,19 @@
 			e.printStackTrace();
 			fail("post failed");
 		}
+		try {
+			HttpClient client = new HttpClient();
+			PostMethod post = new PostMethod(TEST_INSTANCES_SERVICE_URL_VALID);
+			post.setQueryString("api_key="+API_KEY_VALID+"&widgetid="+OTHER_WIDGET_ID+"&userid=test&shareddatakey=proxytest");
+			client.executeMethod(post);
+			String response = post.getResponseBodyAsString();
+			other_instance_id_key = response.substring(response.indexOf("<identifier>")+12, response.indexOf("</identifier>"));
+			post.releaseConnection();
+		}
+		catch (Exception e) {
+			e.printStackTrace();
+			fail("post failed");
+		}
 	}
 
 	@Test
@@ -69,6 +86,28 @@
 	}
 	
 	@Test
+	public void getAllowedSite(){
+		String url = PROXY_URL+"?instanceid_key="+instance_id_key+"&url="+POLICY_ALLOWED_SITE_URL;
+		assertEquals(200,send(url,"GET"));
+		assertEquals(200,send(url,"POST"));
+	}
+	
+	@Test
+	public void getDisallowedSite(){
+		String url = PROXY_URL+"?instanceid_key="+instance_id_key+"&url="+POLICY_DISALLOWED_SITE_URL;
+		assertEquals(403,send(url,"GET"));
+		assertEquals(403,send(url,"POST")); // This URL doesn't support POST
+	}
+	
+	// Test trying to get to a site allowed for a different widget, but not this one
+	@Test
+	public void getAllowedSiteWrongInstance(){
+		String url = PROXY_URL+"?instanceid_key="+other_instance_id_key+"&url="+POLICY_ALLOWED_SITE_URL;
+		assertEquals(403,send(url,"GET"));
+		assertEquals(403,send(url,"POST"));
+	}
+	
+	@Test
 	public void getValidSiteAndValidXMLContentType() throws Exception{
 		String url = PROXY_URL+"?instanceid_key="+instance_id_key+"&url="+VALID_SITE_XML_URL;
 		HttpClient client = new HttpClient();

Added: incubator/wookie/trunk/src/org/apache/wookie/beans/AccessRequest.java
URL: http://svn.apache.org/viewvc/incubator/wookie/trunk/src/org/apache/wookie/beans/AccessRequest.java?rev=915501&view=auto
==============================================================================
--- incubator/wookie/trunk/src/org/apache/wookie/beans/AccessRequest.java (added)
+++ incubator/wookie/trunk/src/org/apache/wookie/beans/AccessRequest.java Tue Feb 23 20:26:50 2010
@@ -0,0 +1,114 @@
+/*
+ *  Licensed 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.wookie.beans;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.Map;
+
+public class AccessRequest extends AbstractKeyBean<AccessRequest> {
+	
+	private static final long serialVersionUID = -1205834267479594166L;
+	
+	private String origin;
+	private boolean subdomains;
+	private Widget widget;
+	private boolean granted;
+	
+	public boolean isGranted() {
+		return granted;
+	}
+	public void setGranted(boolean granted) {
+		this.granted = granted;
+	}
+	public String getOrigin() {
+		return origin;
+	}
+	public void setOrigin(String origin) {
+		this.origin = origin;
+	}
+	public boolean isSubdomains() {
+		return subdomains;
+	}
+	public void setSubdomains(boolean subdomains) {
+		this.subdomains = subdomains;
+	}
+	public Widget getWidget() {
+		return widget;
+	}
+	public void setWidget(Widget widget) {
+		this.widget = widget;
+	}
+	
+	/// Active record methods
+	public static AccessRequest findById(Object id){
+		return (AccessRequest) findById(AccessRequest.class, id);
+	}
+
+	public static AccessRequest[] findByValue(String key, Object value) {
+		return (AccessRequest[]) findByValue(AccessRequest.class, key, value);
+	}
+
+	@SuppressWarnings("unchecked")
+	public static AccessRequest[] findByValues(Map map) {
+		return (AccessRequest[]) findByValues(AccessRequest.class, map);
+	}
+	
+	public static AccessRequest[] findAll(){
+		return (AccessRequest[]) findAll(AccessRequest.class);
+	}
+
+	//// Special Queries
+	public static AccessRequest[] findAllApplicable(Widget widget){
+		HashMap<String, Object> map = new HashMap<String, Object>();
+		map.put("widget", widget);
+		map.put("granted", true);
+		return findByValues(map);
+	}
+	
+	private URI getOriginAsURI(){
+		try {
+			return new URI(origin);
+		} catch (URISyntaxException e) {
+			// origins other than "*" MUST be valid URIs
+			e.printStackTrace();
+			return null;
+		}
+	}
+	
+	/**
+	 * Implementation of the W3C WARP algorithm for a single access request
+	 * @param requestedUri the URI requested
+	 * @return true if this access request grants access, otherwise false
+	 */
+	public boolean isAllowed(URI requestedUri){
+		if (origin.equals("*")) return true;
+		URI accessUri = getOriginAsURI();
+		// Schemes must match
+		if (!accessUri.getScheme().equalsIgnoreCase(requestedUri.getScheme())) return false;
+		if (isSubdomains()){
+			// Host must match or match with subdomains
+			if (!accessUri.getHost().equalsIgnoreCase(requestedUri.getHost()) &&
+					!requestedUri.getHost().endsWith("."+accessUri.getHost())) return false;
+		} else {
+			// Hosts must match
+			if (!accessUri.getHost().equalsIgnoreCase(requestedUri.getHost())) return false;
+		}
+		// Ports must match
+		if (accessUri.getPort()==requestedUri.getPort()) return true;
+		return false;
+	}
+
+}

Modified: incubator/wookie/trunk/src/org/apache/wookie/beans/schema.hbm.xml
URL: http://svn.apache.org/viewvc/incubator/wookie/trunk/src/org/apache/wookie/beans/schema.hbm.xml?rev=915501&r1=915500&r2=915501&view=diff
==============================================================================
--- incubator/wookie/trunk/src/org/apache/wookie/beans/schema.hbm.xml (original)
+++ incubator/wookie/trunk/src/org/apache/wookie/beans/schema.hbm.xml Tue Feb 23 20:26:50 2010
@@ -23,6 +23,16 @@
 		</set>
 		<property name="version" column="widget_version" type="string" />
 	</class>
+
+	<class name="AccessRequest" table="AccessRequest">
+		<id name="id" column="id">
+			<generator class="increment" />
+		</id>
+		<many-to-one name="widget" class="Widget" column="widget_id" not-null="true" />
+		<property name="origin" column="origin" type="string" />
+		<property name="subdomains" column="subdomains" type="true_false" />
+		<property name="granted" column="granted" type="true_false" />
+	</class>
 	
 	<class name="WidgetType" table="WidgetType">
 		<id name="id" column="id">

Modified: incubator/wookie/trunk/src/org/apache/wookie/manager/IWidgetAdminManager.java
URL: http://svn.apache.org/viewvc/incubator/wookie/trunk/src/org/apache/wookie/manager/IWidgetAdminManager.java?rev=915501&r1=915500&r2=915501&view=diff
==============================================================================
--- incubator/wookie/trunk/src/org/apache/wookie/manager/IWidgetAdminManager.java (original)
+++ incubator/wookie/trunk/src/org/apache/wookie/manager/IWidgetAdminManager.java Tue Feb 23 20:26:50 2010
@@ -26,15 +26,27 @@
 public interface IWidgetAdminManager {
 
 	/**
-	 * Add a new widget to the system
-	 * @param widgetName - the name of this widget
-	 * @param url - the url which it resides
-	 * @param height - the height at which it is supposed to be displayed
-	 * @param width - the width at which it is supposed to be displayed
-	 * @param widgetTypes - a string array containing the types this widget can perform as
-	 * @return - the new key created for this widget
+	 * Adds a new widget
+	 * @param model the model of the widget to add
+	 * @param widgetTypes the types to allocate the widget to
+	 * @return true if successfully added, otherwise false
 	 */
 	int addNewWidget(IManifestModel model, String[] widgetTypes);
+	
+	/**
+	 * Adds a new widget
+	 * @param model the model of the widget to add
+	 * @return true if successfully added, otherwise false
+	 */
+	int addNewWidget(IManifestModel model);
+	
+	/**
+	 * Adds a new widget
+	 * @param model the model of the widget to add
+	 * @param grantAccessRequests whether to automatically grant access requests for the widget
+	 * @return true if successfully added, otherwise false
+	 */
+	int addNewWidget(IManifestModel model, boolean grantAccessRequests);
 
 	/**
 	 * Add a new whitelist entry

Modified: incubator/wookie/trunk/src/org/apache/wookie/manager/impl/WidgetAdminManager.java
URL: http://svn.apache.org/viewvc/incubator/wookie/trunk/src/org/apache/wookie/manager/impl/WidgetAdminManager.java?rev=915501&r1=915500&r2=915501&view=diff
==============================================================================
--- incubator/wookie/trunk/src/org/apache/wookie/manager/impl/WidgetAdminManager.java (original)
+++ incubator/wookie/trunk/src/org/apache/wookie/manager/impl/WidgetAdminManager.java Tue Feb 23 20:26:50 2010
@@ -20,6 +20,7 @@
 
 import org.apache.log4j.Logger;
 import org.apache.wookie.Messages;
+import org.apache.wookie.beans.AccessRequest;
 import org.apache.wookie.beans.Description;
 import org.apache.wookie.beans.Feature;
 import org.apache.wookie.beans.License;
@@ -37,6 +38,7 @@
 import org.apache.wookie.beans.WidgetInstance;
 import org.apache.wookie.beans.WidgetType;
 import org.apache.wookie.manager.IWidgetAdminManager;
+import org.apache.wookie.manifestmodel.IAccessEntity;
 import org.apache.wookie.manifestmodel.IContentEntity;
 import org.apache.wookie.manifestmodel.IDescriptionEntity;
 import org.apache.wookie.manifestmodel.IFeatureEntity;
@@ -65,11 +67,20 @@
 		this.localizedMessages = localizedMessages;	
 	}
 	
-	/* (non-Javadoc)
-	 * @see org.apache.wookie.manager.IWidgetAdminManager#addNewWidget(java.lang.String, java.lang.String, java.lang.String, int, int, java.lang.String[])
-	 */
+	public int addNewWidget(IManifestModel model, boolean grantAccessRequests) {
+		return addNewWidget(model,null, grantAccessRequests);
+	}
+
+	public int addNewWidget(IManifestModel model) {
+		return addNewWidget(model,null,false);
+	}
+	
+	public int addNewWidget(IManifestModel model,String[] widgetTypes) {
+		return addNewWidget(model,widgetTypes,false);
+	}	
+
 	@SuppressWarnings("unchecked")
-	public int addNewWidget(IManifestModel model, String[] widgetTypes) {
+	public int addNewWidget(IManifestModel model, String[] widgetTypes, boolean grantAccessRequests) {
 		// NOTE: we pass the whole model here, so that we can create all the DB hooks more easily.
 		int newWidgetIdx = -1;			
 		Widget widget;
@@ -163,6 +174,19 @@
 				param.save();
 			}
 		}
+		
+		// Save Access Requests
+		for(IAccessEntity accessEntity:model.getAccessList()){
+			AccessRequest acc = new AccessRequest();
+			acc.setOrigin(accessEntity.getOrigin());
+			acc.setSubdomains(accessEntity.hasSubDomains());
+			acc.setWidget(widget);
+			acc.setGranted(grantAccessRequests);
+			if (grantAccessRequests){
+				_logger.info("access policy granted for "+widget.getWidgetTitle("en")+" to access "+acc.getOrigin());
+			}
+			acc.save();
+		}
 
 		return newWidgetIdx;	       
 	}

Modified: incubator/wookie/trunk/src/org/apache/wookie/proxy/ProxyServlet.java
URL: http://svn.apache.org/viewvc/incubator/wookie/trunk/src/org/apache/wookie/proxy/ProxyServlet.java?rev=915501&r1=915500&r2=915501&view=diff
==============================================================================
--- incubator/wookie/trunk/src/org/apache/wookie/proxy/ProxyServlet.java (original)
+++ incubator/wookie/trunk/src/org/apache/wookie/proxy/ProxyServlet.java Tue Feb 23 20:26:50 2010
@@ -18,24 +18,23 @@
 import java.io.PrintWriter;
 import java.io.UnsupportedEncodingException;
 import java.net.MalformedURLException;
+import java.net.URI;
 import java.net.URL;
 import java.net.URLDecoder;
-import java.util.Locale;
 
 import javax.servlet.Servlet;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
 
 import org.apache.commons.configuration.Configuration;
 import org.apache.commons.httpclient.auth.AuthenticationException;
 import org.apache.log4j.Logger;
-import org.apache.wookie.Messages;
+import org.apache.wookie.beans.AccessRequest;
 import org.apache.wookie.beans.Whitelist;
+import org.apache.wookie.beans.Widget;
 import org.apache.wookie.beans.WidgetInstance;
-import org.apache.wookie.server.LocaleHandler;
 
 /**
  * A web proxy servlet which will translate calls for content and return them as if they came from
@@ -48,11 +47,6 @@
 
 	static Logger fLogger = Logger.getLogger(ProxyServlet.class.getName());
 
-	public void init(){}
-
-	/* (non-Java-doc)
-	 * @see javax.servlet.http.HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
-	 */
 	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 		dealWithRequest(request, response, "post");	
 	}  
@@ -72,11 +66,20 @@
 		try {
 			Configuration properties = (Configuration) request.getSession().getServletContext().getAttribute("properties");
 
-			if(!isValidUser(request, properties.getBoolean("widget.proxy.checkdomain"))){
+			// Check that the request is coming from the same domain (i.e. from a widget served by this server)
+			if (properties.getBoolean("widget.proxy.checkdomain") && !isSameDomain(request)){
+				response.sendError(HttpServletResponse.SC_FORBIDDEN,"<error>"+UNAUTHORISED_MESSAGE+"</error>");	
+				return;				
+			}
+
+			// Check that the request is coming from a valid widget
+			WidgetInstance instance = WidgetInstance.findByIdKey(request.getParameter("instanceid_key"));	
+			if(instance == null && !isDefaultGadget(request)){
 				response.sendError(HttpServletResponse.SC_FORBIDDEN,"<error>"+UNAUTHORISED_MESSAGE+"</error>");	
 				return;
 			}
 
+			// Create the proxy bean for the request
 			ProxyURLBean bean;
 			try {
 				bean = new ProxyURLBean(request);
@@ -86,9 +89,9 @@
 			}		
 
 			// should we filter urls?
-			if (properties.getBoolean("widget.proxy.usewhitelist") && !isAllowed(bean.getNewUrl().toExternalForm())){
+			if (properties.getBoolean("widget.proxy.usewhitelist") && !isAllowed(bean.getNewUrl().toURI(), instance)){
 				response.sendError(HttpServletResponse.SC_FORBIDDEN,"<error>URL Blocked</error>");
-				fLogger.warn("URL" + bean.getNewUrl().toExternalForm() + "Blocked");
+				fLogger.warn("URL " + bean.getNewUrl().toExternalForm() + " Blocked");
 				return;
 			}	
 
@@ -112,7 +115,6 @@
 					response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ex.getMessage());
 				}
 				fLogger.error(ex.getMessage());
-				throw new ServletException(ex);
 			} catch (IOException e) {
 				// give up!
 				fLogger.error(ex.getMessage());	
@@ -137,47 +139,26 @@
 		return xml;
 	}
 
-	private boolean isValidUser(HttpServletRequest request, boolean checkDomain){
-		return isSameDomain(request, checkDomain) && isValidWidgetInstance(request);
-	}
-
-	private boolean isSameDomain(HttpServletRequest request, boolean checkDomain){
-		if(!checkDomain) return true;
+	/**
+	 * Checks that the request is from the same domain as this service
+	 * @param request
+	 * @param checkDomain
+	 * @return
+	 */
+	private boolean isSameDomain(HttpServletRequest request){
 		String remoteHost = request.getRemoteHost();
 		String serverHost = request.getServerName();
-		fLogger.debug("remote host:"+remoteHost);
-		fLogger.debug("server host:"+ serverHost);
-		if(remoteHost.equals(serverHost)){
-			return true;
-		}
+		if(remoteHost.equals(serverHost)) return true;
 		return false;
 	}
 
-	private boolean isValidWidgetInstance(HttpServletRequest request){
-		HttpSession session = request.getSession(true);						
-		Messages localizedMessages = (Messages)session.getAttribute(Messages.class.getName());
-		if(localizedMessages == null){
-			Locale locale = request.getLocale();
-			localizedMessages = LocaleHandler.getInstance().getResourceBundle(locale);
-			session.setAttribute(Messages.class.getName(), localizedMessages);			
-		}
+	private boolean isDefaultGadget(HttpServletRequest request){
 		String instanceId = request.getParameter("instanceid_key");
-		if(instanceId == null) return false;
-		// check if instance is valid
-		WidgetInstance widgetInstance = WidgetInstance.findByIdKey(instanceId);			
-		if(widgetInstance!=null){
+		// check  if the default Shindig gadget key is being used
+		Configuration properties = (Configuration) request.getSession().getServletContext().getAttribute("opensocial");
+		if (properties.getBoolean("opensocial.enable") && properties.getString("opensocial.proxy.id").equals(instanceId))
 			return true;
-		}
-		else{
-			// check  if the default Shindig gadget key is being used
-			Configuration properties = (Configuration) request.getSession().getServletContext().getAttribute("opensocial");
-			if (properties.getBoolean("opensocial.enable") && properties.getString("opensocial.proxy.id").equals(instanceId)) {
-				return true;
-			} else {
-				return false;
-			}
-		}
-
+		return false;
 	}
 
 	/**
@@ -185,16 +166,34 @@
 	 * @param aUrl
 	 * @return
 	 */
-	public boolean isAllowed(String aUrl){					
+	public boolean isAllowed(URI requestedUri, WidgetInstance instance){
+		// Check global whitelist
 		for (Whitelist whiteList : Whitelist.findAll()){
 			// TODO - make this better then just comparing the beginning...
-			if(aUrl.toLowerCase().startsWith(whiteList.getfUrl().toLowerCase()))			
+			if(requestedUri.toString().toLowerCase().startsWith(whiteList.getfUrl().toLowerCase()))			
 				return true;
 		}
+
+		// Check widget-specific policies using W3C WARP
+		if (instance != null && isAllowedByPolicy(requestedUri, instance.getWidget())) return true;
+
 		return false;		
 	}
 
 	/**
+	 * Check widget-specific policies using W3C WARP
+	 * @param requestedUri the URI requested
+	 * @param widget the Widget requesting access to the URI
+	 * @return true if a policy grants access to the requested URI
+	 */
+	private boolean isAllowedByPolicy(URI requestedUri, Widget widget){
+		for (AccessRequest policy: AccessRequest.findAllApplicable(widget))
+			if (policy.isAllowed(requestedUri)) return true;
+		fLogger.warn("No policy grants widget "+widget.getWidgetTitle("en")+" access to: "+requestedUri.toString());
+		return false;
+	}
+
+	/**
 	 * 
 	 * A class used to model a url both with and without a proxy address attached to it
 	 *
@@ -233,11 +232,11 @@
 			// try to locate a POST form parameter instead
 			if (endPointURL == null)	
 				endPointURL=request.getParameter("url");
-			
+
 			// the request didn't contain any params, so throw an exception
 			if (endPointURL == null)	
 				throw new MalformedURLException("Unable to obtain url from args");
-			
+
 			try {
 				// try decoding the URL
 				fNewUrl = new URL(URLDecoder.decode(endPointURL, "UTF-8"));

Modified: incubator/wookie/trunk/src/org/apache/wookie/server/ContextListener.java
URL: http://svn.apache.org/viewvc/incubator/wookie/trunk/src/org/apache/wookie/server/ContextListener.java?rev=915501&r1=915500&r2=915501&view=diff
==============================================================================
--- incubator/wookie/trunk/src/org/apache/wookie/server/ContextListener.java (original)
+++ incubator/wookie/trunk/src/org/apache/wookie/server/ContextListener.java Tue Feb 23 20:26:50 2010
@@ -163,7 +163,7 @@
 	 						IManifestModel model = WidgetPackageUtils.processWidgetPackage(upload, localWidgetFolderPath, WIDGETFOLDER, UPLOADFOLDER, locales);
 	 						WidgetAdminManager manager = new WidgetAdminManager(null);
 	 						if(!Widget.exists(model.getIdentifier())) {
-	 							manager.addNewWidget(model, null);	
+	 							manager.addNewWidget(model, true);	
 	 							_logger.info(model.getLocalName("en") +"' - " + localizedMessages.getString("WidgetAdminServlet.19"));
 	 						} else {
 	 							_logger.info(model.getLocalName("en") +"' - " + localizedMessages.getString("WidgetAdminServlet.20"));