/******************************************************************************* * Copyright (c) 2010, 2015 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.orion.internal.server.servlets.workspace; import java.io.IOException; import java.net.URI; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.orion.internal.server.servlets.Activator; import org.eclipse.orion.internal.server.servlets.ServletResourceHandler; import org.eclipse.orion.internal.server.servlets.workspace.authorization.AuthorizationService; import org.eclipse.orion.server.core.OrionConfiguration; import org.eclipse.orion.server.core.ProtocolConstants; import org.eclipse.orion.server.core.ServerStatus; import org.eclipse.orion.server.core.metastore.ProjectInfo; import org.eclipse.orion.server.core.metastore.UserInfo; import org.eclipse.orion.server.core.metastore.WorkspaceInfo; import org.eclipse.orion.server.servlets.OrionServlet; import org.json.JSONException; import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Servlet for accessing workspace metadata. */ public class WorkspaceServlet extends OrionServlet { /** * Version number of java serialization. */ private static final long serialVersionUID = 1L; private final Logger logger; private ServletResourceHandler<WorkspaceInfo> workspaceResourceHandler; public WorkspaceServlet() { workspaceResourceHandler = new WorkspaceResourceHandler(getStatusHandler()); this.logger = LoggerFactory.getLogger("org.eclipse.orion.server.workspace"); //$NON-NLS-1$ } /** * Verify that the user name is valid. Returns <code>true</code> if the name is valid and false otherwise. If invalid, this method will handle filling in * the servlet response. */ private boolean checkUser(String userId, HttpServletResponse response) throws ServletException { if (userId == null) { handleException(response, new Status(IStatus.ERROR, Activator.PI_SERVER_SERVLETS, "User name not specified"), HttpServletResponse.SC_FORBIDDEN); return false; } // if this is the first access for this user, log it if (logger != null && logger.isInfoEnabled()) logger.info("WorkspaceAccess: " + userId); //$NON-NLS-1$ return true; } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { traceRequest(req); String pathString = req.getPathInfo(); if (pathString == null || pathString.equals("/")) { //$NON-NLS-1$ doGetWorkspaces(req, resp); return; } IPath path = new Path(pathString); int segmentCount = path.segmentCount(); try { if (segmentCount > 0 && segmentCount < 3) { WorkspaceInfo workspace = OrionConfiguration.getMetaStore().readWorkspace(path.segment(0)); if (workspaceResourceHandler.handleRequest(req, resp, workspace)) return; } else if (segmentCount == 3) { // path format is /<wsId>/project/<projectName> WorkspaceInfo workspace = OrionConfiguration.getMetaStore().readWorkspace(path.segment(0)); ProjectInfo project = OrionConfiguration.getMetaStore().readProject(path.segment(0), path.segment(2)); // check if both workspace and project are present if (workspace == null || project == null) { String msg = workspace == null ? "Workspace not found" : "Project not found"; handleException(resp, msg, null, HttpServletResponse.SC_NOT_FOUND); return; } URI baseLocation = ServletResourceHandler.getURI(req); OrionServlet.writeJSONResponse(req, resp, ProjectInfoResourceHandler.toJSON(workspace, project, baseLocation)); return; } } catch (CoreException e) { handleException(resp, "Error reading workspace metadata", e); return; } super.doGet(req, resp); } @Override protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { traceRequest(req); String pathString = req.getPathInfo(); IPath path = new Path(pathString == null ? "" : pathString); //$NON-NLS-1$ if (path.segmentCount() > 0) { try { WorkspaceInfo workspace = OrionConfiguration.getMetaStore().readWorkspace(path.segment(0)); if (workspaceResourceHandler.handleRequest(req, resp, workspace)) return; } catch (CoreException e) { handleException(resp, "Error reading workspace metadata", e); return; } } super.doDelete(req, resp); } /** * Gets the list of all workspaces for this request's user. * * @return <code>true</code> if the request has handled (successful or otherwise), or <code>false</code> if the request could not be handled by this * servlet. */ private boolean doGetWorkspaces(HttpServletRequest req, HttpServletResponse resp) throws ServletException { String userId = getUserId(req); if (!checkUser(userId, resp)) return true; try { @SuppressWarnings("unused") Activator r = Activator.getDefault(); UserInfo user = OrionConfiguration.getMetaStore().readUser(userId); writeJSONResponse(req, resp, UserInfoResourceHandler.toJSON(user, ServletResourceHandler.getURI(req))); } catch (Exception e) { handleException(resp, "An error occurred while obtaining workspace data", e); } return true; } @Override protected synchronized void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { traceRequest(req); String pathString = req.getPathInfo(); if (pathString == null || pathString.equals("/")) {//$NON-NLS-1$ doCreateWorkspace(req, resp); return; } IPath path = new Path(pathString); if (path.segmentCount() == 1) { try { WorkspaceInfo workspace = OrionConfiguration.getMetaStore().readWorkspace(path.segment(0)); if (workspaceResourceHandler.handleRequest(req, resp, workspace)) return; } catch (CoreException e) { handleException(resp, "An error occurred while obtaining workspace data", e); return; } } super.doPost(req, resp); } private void doCreateWorkspace(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String userId = getUserId(req); if (!checkUser(userId, resp)) return; try { JSONObject data = OrionServlet.readJSONRequest(req); String id = data.optString(ProtocolConstants.KEY_ID, null); String workspaceName = data.optString(ProtocolConstants.KEY_NAME, null); if (workspaceName == null) { workspaceName = req.getHeader(ProtocolConstants.HEADER_SLUG); } if (workspaceName == null) { handleException(resp, "Workspace name not specified", null, HttpServletResponse.SC_BAD_REQUEST); return; } WorkspaceInfo workspace = new WorkspaceInfo(); workspace.setFullName(workspaceName); workspace.setUserId(userId); workspace.setUniqueId(id); OrionConfiguration.getMetaStore().createWorkspace(workspace); if (logger != null && logger.isInfoEnabled()) { logger.info("Workspace created for " + userId); //$NON-NLS-1$ } URI requestLocation = ServletResourceHandler.getURI(req); JSONObject result = WorkspaceResourceHandler.toJSON(workspace, requestLocation, requestLocation); writeJSONResponse(req, resp, result); String resultLocation = result.optString(ProtocolConstants.KEY_LOCATION); resp.setHeader(ProtocolConstants.KEY_LOCATION, resultLocation); // add user rights for the workspace String workspacePath = Activator.LOCATION_WORKSPACE_SERVLET + '/' + workspace.getUniqueId(); AuthorizationService.addUserRight(req.getRemoteUser(), workspacePath); AuthorizationService.addUserRight(req.getRemoteUser(), workspacePath + "/*"); //$NON-NLS-1$ // add user rights for file servlet location String filePath = Activator.LOCATION_FILE_SERVLET + '/' + workspace.getUniqueId(); AuthorizationService.addUserRight(req.getRemoteUser(), filePath); AuthorizationService.addUserRight(req.getRemoteUser(), filePath + "/*"); //$NON-NLS-1$ } catch (JSONException e) { handleException(resp, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, "Syntax error in request", e)); return; } catch (CoreException e) { handleException(resp, e.getStatus()); return; } } @Override protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { traceRequest(req); String pathString = req.getPathInfo(); if (pathString != null) { IPath path = new Path(pathString); if (path.segmentCount() == 1) { try { WorkspaceInfo workspace = OrionConfiguration.getMetaStore().readWorkspace(path.segment(0)); if (workspaceResourceHandler.handleRequest(req, resp, workspace)) return; } catch (CoreException e) { handleException(resp, "An error occurred while obtaining workspace data", e); return; } } } super.doPut(req, resp); } /** * Obtain and return the user name from the request headers. */ private String getUserId(HttpServletRequest req) { return req.getRemoteUser(); } }