/plugin/src/main/java/com/atlassian/labs/speakeasy/rest/PluginsResource.java
Java | 352 lines | 317 code | 32 blank | 3 comment | 8 complexity | a3bcc3950101280558a301a58e44072e MD5 | raw file
- package com.atlassian.labs.speakeasy.rest;
- import com.atlassian.labs.speakeasy.external.PluginType;
- import com.atlassian.labs.speakeasy.external.SpeakeasyService;
- import com.atlassian.labs.speakeasy.external.UnauthorizedAccessException;
- import com.atlassian.labs.speakeasy.manager.PluginOperationFailedException;
- import com.atlassian.labs.speakeasy.model.*;
- import com.atlassian.plugins.rest.common.json.JaxbJsonMarshaller;
- import com.atlassian.plugins.rest.common.security.RequiresXsrfCheck;
- import com.atlassian.sal.api.user.UserManager;
- import com.atlassian.sal.api.xsrf.XsrfTokenValidator;
- import org.apache.commons.fileupload.FileItem;
- import org.apache.commons.fileupload.FileUploadException;
- import org.apache.commons.fileupload.disk.DiskFileItemFactory;
- import org.apache.commons.fileupload.servlet.ServletFileUpload;
- import org.json.JSONException;
- import org.json.JSONObject;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import javax.servlet.http.HttpServletRequest;
- import javax.ws.rs.Consumes;
- import javax.ws.rs.DELETE;
- import javax.ws.rs.FormParam;
- import javax.ws.rs.GET;
- import javax.ws.rs.POST;
- import javax.ws.rs.PUT;
- import javax.ws.rs.Path;
- import javax.ws.rs.PathParam;
- import javax.ws.rs.Produces;
- import javax.ws.rs.QueryParam;
- import javax.ws.rs.core.Context;
- import javax.ws.rs.core.Response;
- import java.io.File;
- import java.net.URI;
- import java.net.URISyntaxException;
- import java.util.List;
- import static com.atlassian.labs.speakeasy.util.KeyExtractor.createExtractableTempFile;
- import static com.atlassian.labs.speakeasy.util.KeyExtractor.extractFromFilename;
- /**
- *
- */
- @Path("/plugins")
- public class PluginsResource
- {
- private final SpeakeasyService speakeasyService;
- private final UserManager userManager;
- private final JaxbJsonMarshaller jaxbJsonMarshaller;
- private final XsrfTokenValidator xsrfTokenValidator;
- private static final Logger log = LoggerFactory.getLogger(PluginsResource.class);
- public PluginsResource(UserManager userManager, JaxbJsonMarshaller jaxbJsonMarshaller, SpeakeasyService speakeasyService, XsrfTokenValidator xsrfTokenValidator)
- {
- this.userManager = userManager;
- this.jaxbJsonMarshaller = jaxbJsonMarshaller;
- this.speakeasyService = speakeasyService;
- this.xsrfTokenValidator = xsrfTokenValidator;
- }
- @GET
- @Path("atom")
- @Produces("application/atom+xml")
- public Response atom() throws UnauthorizedAccessException
- {
- String user = userManager.getRemoteUsername();
- return Response.ok().entity(speakeasyService.getPluginFeed(user)).build();
- }
- @DELETE
- @Path("plugin/{pluginKey}")
- @Produces("application/json")
- public Response uninstallPlugin(@PathParam("pluginKey") String pluginKey) throws UnauthorizedAccessException
- {
- String user = userManager.getRemoteUsername();
- UserPlugins entity = speakeasyService.uninstallPlugin(pluginKey, user);
- return Response.ok().entity(entity).build();
- }
- @GET
- @Path("download/project/{pluginKey}-project.zip")
- @Produces("application/octet-stream")
- public Response getAsAmpsProject(@PathParam("pluginKey") String pluginKey) throws UnauthorizedAccessException
- {
- String user = userManager.getRemoteUsername();
- File file = speakeasyService.getPluginAsProject(pluginKey, user);
- return Response.ok().entity(file).build();
- }
- @GET
- @Path("screenshot/{pluginKey}.png")
- @Produces("image/png")
- public Response getScreenshot(@PathParam("pluginKey") String pluginKey) throws UnauthorizedAccessException, URISyntaxException
- {
- String user = userManager.getRemoteUsername();
- String url = speakeasyService.getScreenshotUrl(pluginKey, user);
- return Response.status(301).location(new URI(url)).build();
- }
- @GET
- @Path("download/extension/{pluginKeyAndExtension}")
- @Produces("application/octet-stream")
- public Response getAsExtension(@PathParam("pluginKeyAndExtension") String pluginKeyAndExtension) throws UnauthorizedAccessException
- {
- String user = userManager.getRemoteUsername();
- int pos = pluginKeyAndExtension.lastIndexOf('.');
- if (pos > 0)
- {
- File file = speakeasyService.getPluginArtifact(pluginKeyAndExtension.substring(0, pos), user);
- return Response.ok().entity(file).build();
- }
- else
- {
- throw new PluginOperationFailedException("Missing extension on '" + pluginKeyAndExtension, null);
- }
- }
- @POST
- @Path("search")
- @Produces("application/json")
- @RequiresXsrfCheck
- public Response search(@FormParam("q") String searchQuery) throws UnauthorizedAccessException
- {
- SearchResults entity = speakeasyService.search(searchQuery, userManager.getRemoteUsername());
- return Response.ok().entity(entity).build();
- }
- @POST
- @Path("fork/{pluginKey}")
- @Produces("application/json")
- @RequiresXsrfCheck
- public Response fork(@PathParam("pluginKey") String pluginKey, @FormParam("description") String description) throws UnauthorizedAccessException
- {
- UserPlugins entity = speakeasyService.fork(pluginKey, userManager.getRemoteUsername(), description);
- return Response.ok().entity(entity).build();
- }
- @POST
- @Path("feedback/{pluginKey}")
- @Produces("application/json")
- @RequiresXsrfCheck
- public Response feedback(@PathParam("pluginKey") String pluginKey, Feedback feedback) throws UnauthorizedAccessException
- {
- speakeasyService.sendFeedback(pluginKey, feedback, userManager.getRemoteUsername());
- return Response.ok().build();
- }
- @POST
- @Path("broken/{pluginKey}")
- @Produces("application/json")
- @RequiresXsrfCheck
- public Response broken(@PathParam("pluginKey") String pluginKey, Feedback feedback) throws UnauthorizedAccessException
- {
- speakeasyService.reportBroken(pluginKey, feedback, userManager.getRemoteUsername());
- return Response.ok().build();
- }
- @POST
- @Path("favorite/{pluginKey}")
- @Produces("application/json")
- @RequiresXsrfCheck
- public Response favorite(@PathParam("pluginKey") String pluginKey) throws UnauthorizedAccessException
- {
- UserPlugins entity = speakeasyService.favorite(pluginKey, userManager.getRemoteUsername());
- return Response.ok().entity(entity).build();
- }
- @DELETE
- @Path("favorite/{pluginKey}")
- @Produces("application/json")
- public Response unfavorite(@PathParam("pluginKey") String pluginKey) throws UnauthorizedAccessException
- {
- UserPlugins entity = speakeasyService.unfavorite(pluginKey, userManager.getRemoteUsername());
- return Response.ok().entity(entity).build();
- }
- @POST
- @Path("create/{pluginKey}")
- @Produces("application/json")
- @RequiresXsrfCheck
- public Response create(@PathParam("pluginKey") String pluginKey, @FormParam("description") String description, @FormParam("name") String name) throws UnauthorizedAccessException
- {
- UserPlugins entity = speakeasyService.createExtension(pluginKey, PluginType.ZIP, userManager.getRemoteUsername(), description, name);
- return Response.ok().entity(entity).build();
- }
- @DELETE
- @Path("global/{pluginKey}")
- @Produces("application/json")
- public Response disableGlobally(@PathParam("pluginKey") String pluginKey) throws UnauthorizedAccessException
- {
- UserPlugins entity = speakeasyService.disableGlobally(pluginKey, userManager.getRemoteUsername());
- return Response.ok().entity(entity).build();
- }
- @PUT
- @Path("global/{pluginKey}")
- @Produces("application/json")
- @RequiresXsrfCheck
- public Response enableGlobally(@PathParam("pluginKey") String pluginKey) throws UnauthorizedAccessException
- {
- UserPlugins entity = speakeasyService.enableGlobally(pluginKey, userManager.getRemoteUsername());
- return Response.ok().entity(entity).build();
- }
- @GET
- @Path("plugin/{pluginKey}/index")
- @Produces("application/json")
- public Response getIndex(@PathParam("pluginKey") String pluginKey) throws UnauthorizedAccessException
- {
- String user = userManager.getRemoteUsername();
- PluginIndex index = new PluginIndex();
- index.setFiles(speakeasyService.getPluginFileNames(pluginKey, user));
- return Response.ok().entity(index).build();
- }
- @GET
- @Path("plugin/{pluginKey}/file")
- @Produces("text/plain")
- public Response getFileText(@PathParam("pluginKey") String pluginKey, @QueryParam("path") String fileName) throws UnauthorizedAccessException
- {
- String user = userManager.getRemoteUsername();
- Object pluginFile = speakeasyService.getPluginFile(pluginKey, fileName, user);
- return Response.ok().entity(pluginFile).build();
- }
- @GET
- @Path("plugin/{pluginKey}/binary")
- @Produces("application/octet-stream")
- public Response getFileBinary(@PathParam("pluginKey") String pluginKey, @QueryParam("path") String fileName) throws UnauthorizedAccessException
- {
- String user = userManager.getRemoteUsername();
- Object pluginFile = speakeasyService.getPluginFile(pluginKey, fileName, user);
- return Response.ok().entity(pluginFile).build();
- }
- @PUT
- @Path("plugin/{pluginKey}/file")
- @Consumes("text/plain")
- @Produces("application/json")
- public Response saveAndRebuild(@PathParam("pluginKey") String pluginKey, @QueryParam("path") String fileName, String contents) throws UnauthorizedAccessException
- {
- String user = userManager.getRemoteUsername();
- final UserExtension extension = speakeasyService.saveAndRebuild(pluginKey, fileName, contents, user);
- return Response.ok().entity(extension).build();
- }
- @POST
- @Produces("text/html")
- public Response uploadPlugin(@Context HttpServletRequest request)
- {
- String user = userManager.getRemoteUsername(request);
- try
- {
- xsrfTokenValidator.validateFormEncodedToken(request);
- File uploadedFile = extractPluginFile(request);
- UserPlugins plugins = speakeasyService.installPlugin(uploadedFile, user);
- return Response.ok().entity(wrapBodyInTextArea(jaxbJsonMarshaller.marshal(plugins))).build();
- }
- catch (PluginOperationFailedException e)
- {
- log.error(e.getError(), e.getCause());
- return Response.ok().entity(wrapBodyInTextArea(createErrorJson(user, e))).build();
- }
- catch (UnauthorizedAccessException e)
- {
- return Response.ok().entity(wrapBodyInTextArea(createErrorJson(user, e))).build();
- }
- catch (RuntimeException e)
- {
- log.error(e.getMessage(), e);
- return Response.ok().entity(wrapBodyInTextArea(createErrorJson(user, e))).build();
- }
- }
- private String createErrorJson(String user, Exception e)
- {
- JSONObject obj = new JSONObject();
- try
- {
- obj.put("error", e.toString());
- obj.put("plugins", new JSONObject(jaxbJsonMarshaller.marshal(speakeasyService.getRemotePluginList(user))));
- }
- catch (JSONException e1)
- {
- throw new PluginOperationFailedException("Unable to serialize error", e1, null);
- }
- catch (UnauthorizedAccessException e1)
- {
- throw new PluginOperationFailedException("Unauthorized access", e1, null);
- }
- return obj.toString();
- }
- private File extractPluginFile(HttpServletRequest request)
- {
- if (!ServletFileUpload.isMultipartContent(request))
- {
- return null;
- }
- DiskFileItemFactory factory = new DiskFileItemFactory();
- factory.setSizeThreshold(1024 * 1024);
- ServletFileUpload upload = new ServletFileUpload(factory);
- upload.setFileSizeMax(1024 * 1024 * 10);
- List<FileItem> items = null;
- try
- {
- items = upload.parseRequest(request);
- }
- catch (FileUploadException e)
- {
- throw new RuntimeException(e);
- }
- File pluginFile = null;
- if (items != null)
- {
- for (FileItem item : items)
- {
- if (!item.isFormField() && item.getSize() > 0 && "plugin-file".equals(item.getFieldName()))
- {
- try
- {
- String fileName = processFileName(item.getName());
- String key = extractFromFilename(fileName);
- pluginFile = createExtractableTempFile(key, fileName);
- item.write(pluginFile);
- }
- catch (Exception e)
- {
- throw new RuntimeException(e);
- }
- }
- }
- }
- return pluginFile;
- }
- private String wrapBodyInTextArea(String body)
- {
- return "JSON_MARKER||" + body + "||";
- }
- private String processFileName(String fileNameInput)
- {
- return fileNameInput.substring(fileNameInput.lastIndexOf("\\") + 1, fileNameInput.length());
- }
- }