Author: scottbw
Date: Mon Aug 22 12:00:11 2011
New Revision: 1160225
URL: http://svn.apache.org/viewvc?rev=1160225&view=rev
Log:
Improved code comments for widget upload, and conduct checks for valid .wgt
files in the upload. Also added some basic functional tests (unauthorized
upload, valid upload, upload with wrong type of file). Note that POSTing URLs
rather than files (e.g. for Shindig gadgets) is not yet implemented.
Added:
incubator/wookie/trunk/src-tests/testdata/not_a_widget.zip (with props)
incubator/wookie/trunk/src-tests/testdata/notsupported.wgt (with props)
Modified:
incubator/wookie/trunk/src-tests/org/apache/wookie/tests/functional/WidgetsControllerTest.java
incubator/wookie/trunk/src/org/apache/wookie/controller/WidgetsController.java
Modified:
incubator/wookie/trunk/src-tests/org/apache/wookie/tests/functional/WidgetsControllerTest.java
URL:
http://svn.apache.org/viewvc/incubator/wookie/trunk/src-tests/org/apache/wookie/tests/functional/WidgetsControllerTest.java?rev=1160225&r1=1160224&r2=1160225&view=diff
==============================================================================
---
incubator/wookie/trunk/src-tests/org/apache/wookie/tests/functional/WidgetsControllerTest.java
(original)
+++
incubator/wookie/trunk/src-tests/org/apache/wookie/tests/functional/WidgetsControllerTest.java
Mon Aug 22 12:00:11 2011
@@ -16,11 +16,18 @@ package org.apache.wookie.tests.function
import static org.junit.Assert.*;
+import java.io.File;
import java.io.IOException;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
+import org.apache.commons.httpclient.UsernamePasswordCredentials;
+import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.methods.multipart.FilePart;
+import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
+import org.apache.commons.httpclient.methods.multipart.Part;
import org.junit.Test;
/**
@@ -129,4 +136,82 @@ public class WidgetsControllerTest exten
get.releaseConnection();
}
+ @Test
+ public void importWidget_unauthorized() throws HttpException,
IOException{
+ HttpClient client = new HttpClient();
+ PostMethod post = new PostMethod(TEST_WIDGETS_SERVICE_URL_VALID);
+ client.executeMethod(post);
+ int code = post.getStatusCode();
+ assertEquals(401,code);
+ post.releaseConnection();
+ }
+
+ @Test
+ public void importWidget() throws HttpException, IOException{
+ HttpClient client = new HttpClient();
+ //
+ // Use admin credentials
+ //
+ client.getState().setCredentials(
+ new AuthScope("localhost", 8080, "wookie"),
+ new UsernamePasswordCredentials("java", "java")
+ );
+ PostMethod post = new PostMethod(TEST_WIDGETS_SERVICE_URL_VALID);
+
+ //
+ // We'll use a copy of the unsupported widget widget for testing
+ //
+ File file = new File("src-tests/testdata/notsupported.wgt");
+ assertTrue(file.exists());
+
+ //
+ // Add test wgt file to POST
+ //
+ Part[] parts = { new FilePart(file.getName(), file) };
+ post.setRequestEntity(new MultipartRequestEntity(parts, post
+ .getParams()));
+
+ //
+ // POST the file to /widgets and check we get 201 (Created)
+ //
+ client.executeMethod(post);
+ int code = post.getStatusCode();
+ assertEquals(201,code);
+ post.releaseConnection();
+ }
+
+ @Test
+ public void importWrongFileType() throws HttpException, IOException{
+ HttpClient client = new HttpClient();
+ //
+ // Use admin credentials
+ //
+ client.getState().setCredentials(
+ new AuthScope("localhost", 8080, "wookie"),
+ new UsernamePasswordCredentials("java", "java")
+ );
+ PostMethod post = new PostMethod(TEST_WIDGETS_SERVICE_URL_VALID);
+
+ //
+ // We'll use a copy of the unsupported widget widget for testing
+ //
+ File file = new File("src-tests/testdata/not_a_widget.zip");
+ assertTrue(file.exists());
+
+ //
+ // Add test wgt file to POST
+ //
+ Part[] parts = { new FilePart(file.getName(), file) };
+ post.setRequestEntity(new MultipartRequestEntity(parts, post
+ .getParams()));
+
+ //
+ // POST the file to /widgets and check we get a 400
+ //
+ client.executeMethod(post);
+ int code = post.getStatusCode();
+ assertEquals(400,code);
+ post.releaseConnection();
+ }
+
}
Added: incubator/wookie/trunk/src-tests/testdata/not_a_widget.zip
URL:
http://svn.apache.org/viewvc/incubator/wookie/trunk/src-tests/testdata/not_a_widget.zip?rev=1160225&view=auto
==============================================================================
Binary file - no diff available.
Propchange: incubator/wookie/trunk/src-tests/testdata/not_a_widget.zip
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: incubator/wookie/trunk/src-tests/testdata/notsupported.wgt
URL:
http://svn.apache.org/viewvc/incubator/wookie/trunk/src-tests/testdata/notsupported.wgt?rev=1160225&view=auto
==============================================================================
Binary file - no diff available.
Propchange: incubator/wookie/trunk/src-tests/testdata/notsupported.wgt
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Modified:
incubator/wookie/trunk/src/org/apache/wookie/controller/WidgetsController.java
URL:
http://svn.apache.org/viewvc/incubator/wookie/trunk/src/org/apache/wookie/controller/WidgetsController.java?rev=1160225&r1=1160224&r2=1160225&view=diff
==============================================================================
---
incubator/wookie/trunk/src/org/apache/wookie/controller/WidgetsController.java
(original)
+++
incubator/wookie/trunk/src/org/apache/wookie/controller/WidgetsController.java
Mon Aug 22 12:00:11 2011
@@ -49,6 +49,7 @@ import org.apache.wookie.helpers.WidgetH
* <li>GET widgets - index </li>
* <li>GET widgets/{id} - show widget</li>
* <li>GET widgets/{category} - index widgets for category</li>
+ * <li>POST widgets {.wgt file} - import a widget</li>
* </ul>
* @author scott
*
@@ -150,33 +151,83 @@ public class WidgetsController extends C
/**
* Install a new Widget by saving it in the deploy folder
* Note: a Widget must have a .wgt extension!
+ * FIXME: Support POSTing references to OpenSocial gadgets, remote
widget files
*/
@Override
protected boolean create(String resourceId, HttpServletRequest request)
throws ResourceDuplicationException,
InvalidParametersException,
UnauthorizedAccessException {
-
+
+ //
+ // Check for a "url" parameter in the request, indicating this is a remote
widget or opensocial gadget xml file
+ // FIXME implement this
+ //
+ String url = request.getParameter("url");
+ if (url != null && url.trim().length() != 0){
+ _logger.info("POSTing URLs instead of files it not yet supported");
+ throw new InvalidParametersException();
+ }
+
+ //
+ // Get the path for the deploy folder
+ //
Configuration properties = (Configuration)
request.getSession().getServletContext().getAttribute("properties");
//$NON-NLS-1$
final String DEPLOY_FOLDER =
getServletContext().getRealPath(properties.getString("widget.deployfolder"));//$NON-NLS-1$
+
+ //
+ // Create factory for processing POSTed files
+ //
FileItemFactory factory = new DiskFileItemFactory();
+
+ //
// Create a new file upload handler
+ //
ServletFileUpload upload = new ServletFileUpload(factory);
+ //
+ // Create a flag we'll use to check if we got any .wgt files in
the POST
+ //
+ boolean requestContainedWgtFile = false;
+
+ //
+ // Save file in the deploy folder
+ //
try {
@SuppressWarnings("unchecked")
List <FileItem> items = upload.parseRequest(request);
+ //
+ // Only save .wgt files and ignore any others in the
POST
+ //
for (FileItem item: items){
- File saveFile = new File(DEPLOY_FOLDER + "/" +
item.getName());
- item.write(saveFile);
+ if (item.getName().endsWith(".wgt")){
+ File saveFile = new File(DEPLOY_FOLDER + "/" +
item.getName());
+ item.write(saveFile);
+ requestContainedWgtFile = true;
+ }
}
} catch (FileUploadException e) {
throw new InvalidParametersException();
} catch (Exception e) {
- e.printStackTrace();
- return false;
+ //
+ // Catch any other exceptions thrown by the save file
operation
+ // and throw a basic 400 response to the client, though really
+ // this is more like a 500. At least we can log the details.
+ //
+ _logger.error(e.getMessage(), e);
+ throw new InvalidParametersException();
}
+
+ //
+ // If there are no .wgt files in the POST, throw an exception
+ // We have to check for this here as other exceptions are
caught in
+ // the code above, e.g. generic file system errors
+ //
+ if (requestContainedWgtFile == false){
+ throw new InvalidParametersException();
+ }
+
return true;
}
}