@Test public void testCopyFileOverwrite() throws Exception { String directoryPath = "/testCopyFile/directory/path" + System.currentTimeMillis(); String sourcePath = directoryPath + "/source.txt"; String destName = "destination.txt"; String destPath = directoryPath + "/" + destName; createDirectory(directoryPath); createFile(sourcePath, "This is the contents"); createFile(destPath, "Original file"); // with no-overwrite, copy should fail JSONObject requestObject = new JSONObject(); addSourceLocation(requestObject, sourcePath); WebRequest request = getPostFilesRequest(directoryPath, requestObject.toString(), "destination.txt"); request.setHeaderField("X-Create-Options", "copy,no-overwrite"); WebResponse response = webConversation.getResponse(request); assertEquals(HttpURLConnection.HTTP_PRECON_FAILED, response.getResponseCode()); // now omit no-overwrite and copy should succeed and return 200 instead of 201 request = getPostFilesRequest(directoryPath, requestObject.toString(), "destination.txt"); request.setHeaderField("X-Create-Options", "copy"); response = webConversation.getResponse(request); assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode()); JSONObject responseObject = new JSONObject(response.getText()); checkFileMetadata(responseObject, destName, null, null, null, null, null, null, null); assertTrue(checkFileExists(sourcePath)); assertTrue(checkFileExists(destPath)); }
private boolean handlePost(HttpServletRequest request, HttpServletResponse response, String path) throws IOException, JSONException, ServletException, URISyntaxException, CoreException { Path p = new Path(path); if (p.segment(0).equals("file")) { // $NON-NLS-1$ // handle adding new remote // expected path: /git/remote/file/{path} return addRemote(request, response, path); } else { JSONObject requestObject = OrionServlet.readJSONRequest(request); boolean fetch = Boolean.parseBoolean(requestObject.optString(GitConstants.KEY_FETCH, null)); String srcRef = requestObject.optString(GitConstants.KEY_PUSH_SRC_REF, null); boolean tags = requestObject.optBoolean(GitConstants.KEY_PUSH_TAGS, false); boolean force = requestObject.optBoolean(GitConstants.KEY_FORCE, false); // prepare creds GitCredentialsProvider cp = GitUtils.createGitCredentialsProvider(requestObject); // if all went well, continue with fetch or push if (fetch) { return fetch(request, response, cp, path, force); } else if (srcRef != null) { return push(request, response, path, cp, srcRef, tags, force); } else { return statusHandler.handleRequest( request, response, new ServerStatus( IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, "Only Fetch:true is currently supported.", null)); } } }
@Test public void testReadDirectoryChildren() throws CoreException, IOException, SAXException, JSONException { String dirName = "path" + System.currentTimeMillis(); String directoryPath = "sample/directory/" + dirName; createDirectory(directoryPath); String subDirectory = "subdirectory"; createDirectory(directoryPath + "/" + subDirectory); String subFile = "subfile.txt"; createFile(directoryPath + "/" + subFile, "Sample file"); WebRequest request = getGetFilesRequest(directoryPath + "?depth=1"); WebResponse response = webConversation.getResponse(request); assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode()); List<JSONObject> children = getDirectoryChildren(new JSONObject(response.getText())); assertEquals("Wrong number of directory children", 2, children.size()); for (JSONObject child : children) { if (child.getBoolean("Directory")) { checkDirectoryMetadata(child, subDirectory, null, null, null, null, null); } else { checkFileMetadata(child, subFile, null, null, null, null, null, null, null); } } }
/** Serializes a preference node as a JSON object. */ private JSONObject toJSON(HttpServletRequest req, IEclipsePreferences node) throws JSONException, BackingStoreException { JSONObject result = new JSONObject(); // TODO Do we need this extra information? // String nodePath = node.absolutePath(); // result.put("path", nodePath); // JSONObject children = new JSONObject(); // for (String child : node.childrenNames()) // children.put(child, createQuery(req, "/prefs" + nodePath + '/' + child)); // result.put("children", children); // JSONObject values = new JSONObject(); for (String key : node.keys()) { String valueString = node.get(key, null); Object value = null; if (valueString != null) { try { // value might be serialized JSON value = new JSONObject(valueString); } catch (JSONException e) { // value must be a string value = valueString; } } result.put(key, value); } return result; }
@SuppressWarnings("unchecked") @Override protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { traceRequest(req); IEclipsePreferences node = getNode(req, resp, true); if (node == null) return; String key = req.getParameter("key"); try { if (key != null) { node.put(key, req.getParameter("value")); } else { JSONObject newNode = new JSONObject(new JSONTokener(req.getReader())); node.clear(); for (Iterator<String> it = newNode.keys(); it.hasNext(); ) { key = it.next(); node.put(key, newNode.getString(key)); } } prefRoot.flush(); resp.setStatus(HttpServletResponse.SC_NO_CONTENT); } catch (Exception e) { handleException( resp, NLS.bind("Failed to store preferences for {0}", req.getRequestURL()), e); return; } }
@Test public void testCopyFileInvalidSource() throws Exception { String directoryPath = "/testCopyFile/directory/path" + System.currentTimeMillis(); createDirectory(directoryPath); JSONObject requestObject = new JSONObject(); requestObject.put("Location", "/this/does/not/exist/at/all"); WebRequest request = getPostFilesRequest(directoryPath, requestObject.toString(), "destination.txt"); request.setHeaderField("X-Create-Options", "copy"); WebResponse response = webConversation.getResponse(request); assertEquals(HttpURLConnection.HTTP_NOT_FOUND, response.getResponseCode()); JSONObject responseObject = new JSONObject(response.getText()); assertEquals("Error", responseObject.get("Severity")); }
/** Returns whether the user can access the given project */ private boolean isAccessAllowed(String userName, WebProject webProject) { try { WebUser webUser = WebUser.fromUserId(userName); JSONArray workspacesJSON = webUser.getWorkspacesJSON(); for (int i = 0; i < workspacesJSON.length(); i++) { JSONObject workspace = workspacesJSON.getJSONObject(i); String workspaceId = workspace.getString(ProtocolConstants.KEY_ID); WebWorkspace webWorkspace = WebWorkspace.fromId(workspaceId); JSONArray projectsJSON = webWorkspace.getProjectsJSON(); for (int j = 0; j < projectsJSON.length(); j++) { JSONObject project = projectsJSON.getJSONObject(j); String projectId = project.getString(ProtocolConstants.KEY_ID); if (projectId.equals(webProject.getId())) return true; } } } catch (JSONException e) { // ignore, deny access } return false; }
@Test public void testCopyFileNoOverwrite() throws Exception { String directoryPath = "/testCopyFile/directory/path" + System.currentTimeMillis(); String sourcePath = directoryPath + "/source.txt"; String destName = "destination.txt"; String destPath = directoryPath + "/" + destName; createDirectory(directoryPath); createFile(sourcePath, "This is the contents"); JSONObject requestObject = new JSONObject(); addSourceLocation(requestObject, sourcePath); WebRequest request = getPostFilesRequest(directoryPath, requestObject.toString(), "destination.txt"); request.setHeaderField("X-Create-Options", "copy"); WebResponse response = webConversation.getResponse(request); assertEquals(HttpURLConnection.HTTP_CREATED, response.getResponseCode()); JSONObject responseObject = new JSONObject(response.getText()); checkFileMetadata(responseObject, destName, null, null, null, null, null, null, null); assertTrue(checkFileExists(sourcePath)); assertTrue(checkFileExists(destPath)); }
/** * Computes the name of the resource to be created by a POST operation. Returns an empty string if * the name was not specified. */ private String computeName(HttpServletRequest request, JSONObject requestObject) { // get the slug first String name = request.getHeader(ProtocolConstants.HEADER_SLUG); // If the requestObject has a name then it must be used due to UTF-8 issues with names Bug // 376671 if (requestObject.has("Name")) { try { name = requestObject.getString("Name"); } catch (JSONException e) { } } // next comes the source location for a copy/move if (name == null || name.length() == 0) { String location = requestObject.optString(ProtocolConstants.KEY_LOCATION); int lastSlash = location.lastIndexOf('/'); if (lastSlash >= 0) name = location.substring(lastSlash + 1); } // finally use the name attribute from the request body if (name == null || name.length() == 0) name = requestObject.optString(ProtocolConstants.KEY_NAME); return name; }
/** * Performs the actual modification corresponding to a POST request. All preconditions are assumed * to be satisfied. * * @return <code>true</code> if the operation was successful, and <code>false</code> otherwise. */ private boolean performPost( HttpServletRequest request, HttpServletResponse response, JSONObject requestObject, IFileStore toCreate, int options) throws CoreException, IOException, ServletException { boolean isCopy = (options & CREATE_COPY) != 0; boolean isMove = (options & CREATE_MOVE) != 0; if (isCopy || isMove) return performCopyMove(request, response, requestObject, toCreate, isCopy, options); if (requestObject.optBoolean(ProtocolConstants.KEY_DIRECTORY)) toCreate.mkdir(EFS.NONE, null); else toCreate.openOutputStream(EFS.NONE, null).close(); return true; }
/** * Looks for the project in all workspaces of the user and removes it when found. * * @see WorkspaceResourceHandler#handleRemoveProject(HttpServletRequest, HttpServletResponse, * WebWorkspace) * @param userName the user name * @param webProject the project to remove * @return ServerStatus <code>OK</code> if the project has been found and successfully removed, * <code>ERROR</code> if an error occurred or the project couldn't be found */ public static ServerStatus removeProject(String userName, WebProject webProject) { try { WebUser webUser = WebUser.fromUserId(userName); JSONArray workspacesJSON = webUser.getWorkspacesJSON(); for (int i = 0; i < workspacesJSON.length(); i++) { JSONObject workspace = workspacesJSON.getJSONObject(i); String workspaceId = workspace.getString(ProtocolConstants.KEY_ID); WebWorkspace webWorkspace = WebWorkspace.fromId(workspaceId); JSONArray projectsJSON = webWorkspace.getProjectsJSON(); for (int j = 0; j < projectsJSON.length(); j++) { JSONObject project = projectsJSON.getJSONObject(j); String projectId = project.getString(ProtocolConstants.KEY_ID); if (projectId.equals(webProject.getId())) { // If found, remove project from workspace try { WorkspaceResourceHandler.removeProject(userName, webWorkspace, webProject); } catch (CoreException e) { // we are unable to write in the platform location! String msg = NLS.bind( "Server content location could not be written: {0}", Activator.getDefault().getRootLocationURI()); return new ServerStatus( IStatus.ERROR, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, msg, e); } return new ServerStatus(IStatus.OK, HttpServletResponse.SC_OK, null, null); } } } } catch (JSONException e) { // ignore, no project will be harmed } // FIXME: not sure about this one return new ServerStatus(IStatus.OK, HttpServletResponse.SC_OK, null, null); }
private void encodeChildren(IFileStore dir, URI location, JSONObject result, int depth) throws CoreException { if (depth <= 0) return; JSONArray children = new JSONArray(); IFileStore[] childStores = dir.childStores(EFS.NONE, null); for (IFileStore childStore : childStores) { IFileInfo childInfo = childStore.fetchInfo(); String name = childInfo.getName(); if (childInfo.isDirectory()) name += "/"; // $NON-NLS-1$ URI childLocation = URIUtil.append(location, name); JSONObject childResult = ServletFileStoreHandler.toJSON(childStore, childInfo, childLocation); if (childInfo.isDirectory()) encodeChildren(childStore, childLocation, childResult, depth - 1); children.put(childResult); } try { result.put(ProtocolConstants.KEY_CHILDREN, children); } catch (JSONException e) { // cannot happen throw new RuntimeException(e); } }
@Test public void testReadFileMetadata() throws Exception { String directoryPath = "sample/directory/path" + System.currentTimeMillis(); createDirectory(directoryPath); String fileName = "sampleFile" + System.currentTimeMillis() + ".txt"; String fileContent = "Sample File Cotnent " + System.currentTimeMillis(); createFile(directoryPath + "/" + fileName, fileContent); WebRequest request = getGetFilesRequest(directoryPath + "/" + fileName + "?parts=meta"); WebResponse response = webConversation.getResponse(request); assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode()); JSONObject result = new JSONObject(response.getText()); assertEquals(fileName, result.optString(ProtocolConstants.KEY_NAME)); JSONArray parents = result.optJSONArray(ProtocolConstants.KEY_PARENTS); assertNotNull(parents); assertEquals(3, parents.length()); IPath parentPath = new Path(directoryPath); // immediate parent JSONObject parent = parents.getJSONObject(0); assertEquals(parentPath.segment(2), parent.getString(ProtocolConstants.KEY_NAME)); // grandparent parent = parents.getJSONObject(1); assertEquals(parentPath.segment(1), parent.getString(ProtocolConstants.KEY_NAME)); // ensure all parent locations end with trailing slash for (int i = 0; i < parents.length(); i++) { parent = parents.getJSONObject(i); String location = parent.getString(ProtocolConstants.KEY_LOCATION); assertTrue(location.endsWith("/")); location = parent.getString(ProtocolConstants.KEY_CHILDREN_LOCATION); URI childrenLocation = new URI(location); assertTrue(childrenLocation.getPath().endsWith("/")); } }
private void addSourceLocation(JSONObject requestObject, String sourcePath) throws JSONException { requestObject.put( "Location", new Path(FileSystemTest.FILE_SERVLET_LOCATION).append(sourcePath)); }
// add new remote private boolean addRemote(HttpServletRequest request, HttpServletResponse response, String path) throws IOException, JSONException, ServletException, CoreException, URISyntaxException { // expected path: /git/remote/file/{path} Path p = new Path(path); JSONObject toPut = OrionServlet.readJSONRequest(request); String remoteName = toPut.optString(GitConstants.KEY_REMOTE_NAME, null); // remoteName is required if (remoteName == null || remoteName.isEmpty()) { return statusHandler.handleRequest( request, response, new ServerStatus( IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, "Remote name must be provided", null)); } String remoteURI = toPut.optString(GitConstants.KEY_REMOTE_URI, null); // remoteURI is required if (remoteURI == null || remoteURI.isEmpty()) { return statusHandler.handleRequest( request, response, new ServerStatus( IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, "Remote URI must be provided", null)); } String fetchRefSpec = toPut.optString(GitConstants.KEY_REMOTE_FETCH_REF, null); String remotePushURI = toPut.optString(GitConstants.KEY_REMOTE_PUSH_URI, null); String pushRefSpec = toPut.optString(GitConstants.KEY_REMOTE_PUSH_REF, null); File gitDir = GitUtils.getGitDir(p); Repository db = new FileRepository(gitDir); StoredConfig config = db.getConfig(); RemoteConfig rc = new RemoteConfig(config, remoteName); rc.addURI(new URIish(remoteURI)); // FetchRefSpec is required, but default version can be generated // if it isn't provided if (fetchRefSpec == null || fetchRefSpec.isEmpty()) { fetchRefSpec = String.format("+refs/heads/*:refs/remotes/%s/*", remoteName); // $NON-NLS-1$ } rc.addFetchRefSpec(new RefSpec(fetchRefSpec)); // pushURI is optional if (remotePushURI != null && !remotePushURI.isEmpty()) rc.addPushURI(new URIish(remotePushURI)); // PushRefSpec is optional if (pushRefSpec != null && !pushRefSpec.isEmpty()) rc.addPushRefSpec(new RefSpec(pushRefSpec)); rc.update(config); config.save(); URI cloneLocation = BaseToCloneConverter.getCloneLocation(getURI(request), BaseToCloneConverter.REMOTE_LIST); Remote remote = new Remote(cloneLocation, db, remoteName); JSONObject result = new JSONObject(); result.put(ProtocolConstants.KEY_LOCATION, remote.getLocation()); OrionServlet.writeJSONResponse(request, response, result); response.setHeader( ProtocolConstants.HEADER_LOCATION, result.getString(ProtocolConstants.KEY_LOCATION)); response.setStatus(HttpServletResponse.SC_CREATED); return true; }
private boolean handlePut( HttpServletRequest request, HttpServletResponse response, String pathString) throws GitAPIException, CoreException, IOException, JSONException, ServletException { IPath path = pathString == null ? Path.EMPTY : new Path(pathString); if (path.segment(0).equals("file") && path.segmentCount() > 1) { // $NON-NLS-1$ // make sure a clone is addressed WebProject webProject = GitUtils.projectFromPath(path); if (isAccessAllowed(request.getRemoteUser(), webProject)) { Map<IPath, File> gitDirs = GitUtils.getGitDirs(path, Traverse.CURRENT); if (gitDirs.isEmpty()) { String msg = NLS.bind("Request path is not a git repository: {0}", path); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, msg, null)); } File gitDir = gitDirs.values().iterator().next(); // make sure required fields are set JSONObject toCheckout = OrionServlet.readJSONRequest(request); JSONArray paths = toCheckout.optJSONArray(ProtocolConstants.KEY_PATH); String branch = toCheckout.optString(GitConstants.KEY_BRANCH_NAME, null); String tag = toCheckout.optString(GitConstants.KEY_TAG_NAME, null); boolean removeUntracked = toCheckout.optBoolean(GitConstants.KEY_REMOVE_UNTRACKED, false); if ((paths == null || paths.length() == 0) && branch == null && tag == null) { String msg = NLS.bind( "Either '{0}' or '{1}' or '{2}' should be provided, got: {3}", new Object[] { ProtocolConstants.KEY_PATH, GitConstants.KEY_BRANCH_NAME, GitConstants.KEY_TAG_NAME, toCheckout }); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, msg, null)); } Git git = new Git(new FileRepository(gitDir)); if (paths != null) { Set<String> toRemove = new HashSet<String>(); CheckoutCommand checkout = git.checkout(); for (int i = 0; i < paths.length(); i++) { String p = paths.getString(i); if (removeUntracked && !isInIndex(git.getRepository(), p)) toRemove.add(p); checkout.addPath(p); } checkout.call(); for (String p : toRemove) { File f = new File(git.getRepository().getWorkTree(), p); f.delete(); } return true; } else if (tag != null && branch != null) { CheckoutCommand co = git.checkout(); try { co.setName(branch).setStartPoint(tag).setCreateBranch(true).call(); return true; } catch (RefNotFoundException e) { String msg = NLS.bind("Tag not found: {0}", tag); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_FOUND, msg, e)); } catch (GitAPIException e) { if (org.eclipse.jgit.api.CheckoutResult.Status.CONFLICTS.equals( co.getResult().getStatus())) { return statusHandler.handleRequest( request, response, new ServerStatus( IStatus.ERROR, HttpServletResponse.SC_CONFLICT, "Checkout aborted.", e)); } // TODO: handle other exceptions } } else if (branch != null) { if (!isLocalBranch(git, branch)) { String msg = NLS.bind("{0} is not a branch.", branch); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_FOUND, msg, null)); } CheckoutCommand co = git.checkout(); try { co.setName(Constants.R_HEADS + branch).call(); return true; } catch (CheckoutConflictException e) { return statusHandler.handleRequest( request, response, new ServerStatus( IStatus.ERROR, HttpServletResponse.SC_CONFLICT, "Checkout aborted.", e)); } catch (RefNotFoundException e) { String msg = NLS.bind("Branch name not found: {0}", branch); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_FOUND, msg, e)); } // TODO: handle other exceptions } } else { String msg = NLS.bind("Nothing found for the given ID: {0}", path); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_FOUND, msg, null)); } } String msg = NLS.bind("Invalid checkout request {0}", pathString); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, msg, null)); }
private boolean handleGet( HttpServletRequest request, HttpServletResponse response, String pathString) throws IOException, JSONException, ServletException, URISyntaxException, CoreException { IPath path = pathString == null ? Path.EMPTY : new Path(pathString); URI baseLocation = getURI(request); String user = request.getRemoteUser(); // expected path format is 'workspace/{workspaceId}' or // 'file/{workspaceId}/{projectName}/{path}]' if ("workspace".equals(path.segment(0)) && path.segmentCount() == 2) { // $NON-NLS-1$ // all clones in the workspace if (WebWorkspace.exists(path.segment(1))) { WebWorkspace workspace = WebWorkspace.fromId(path.segment(1)); JSONObject result = new JSONObject(); JSONArray children = new JSONArray(); for (WebProject webProject : workspace.getProjects()) { // this is the location of the project metadata if (isAccessAllowed(user, webProject)) { IPath projectPath = GitUtils.pathFromProject(workspace, webProject); Map<IPath, File> gitDirs = GitUtils.getGitDirs(projectPath, Traverse.GO_DOWN); for (Map.Entry<IPath, File> entry : gitDirs.entrySet()) { children.put(new Clone().toJSON(entry, baseLocation)); } } } result.put(ProtocolConstants.KEY_TYPE, Clone.TYPE); result.put(ProtocolConstants.KEY_CHILDREN, children); OrionServlet.writeJSONResponse(request, response, result); return true; } String msg = NLS.bind("Nothing found for the given ID: {0}", path); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_FOUND, msg, null)); } else if ("file".equals(path.segment(0)) && path.segmentCount() > 1) { // $NON-NLS-1$ // clones under given path WebProject webProject = GitUtils.projectFromPath(path); IPath projectRelativePath = path.removeFirstSegments(3); if (webProject != null && isAccessAllowed(user, webProject) && webProject.getProjectStore().getFileStore(projectRelativePath).fetchInfo().exists()) { Map<IPath, File> gitDirs = GitUtils.getGitDirs(path, Traverse.GO_DOWN); JSONObject result = new JSONObject(); JSONArray children = new JSONArray(); for (Map.Entry<IPath, File> entry : gitDirs.entrySet()) { children.put(new Clone().toJSON(entry, baseLocation)); } result.put(ProtocolConstants.KEY_TYPE, Clone.TYPE); result.put(ProtocolConstants.KEY_CHILDREN, children); OrionServlet.writeJSONResponse(request, response, result); return true; } String msg = NLS.bind("Nothing found for the given ID: {0}", path); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_FOUND, msg, null)); } // else the request is malformed String msg = NLS.bind("Invalid clone request: {0}", path); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, msg, null)); }
/** * Perform a copy or move as specified by the request. * * @return <code>true</code> if the operation was successful, and <code>false</code> otherwise. */ private boolean performCopyMove( HttpServletRequest request, HttpServletResponse response, JSONObject requestObject, IFileStore toCreate, boolean isCopy, int options) throws ServletException, CoreException { String locationString = requestObject.optString(ProtocolConstants.KEY_LOCATION, null); if (locationString == null) { statusHandler.handleRequest( request, response, new ServerStatus( IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, "Copy or move request must specify source location", null)); return false; } try { IFileStore source = resolveSourceLocation(request, locationString); if (source == null) { statusHandler.handleRequest( request, response, new ServerStatus( IStatus.ERROR, HttpServletResponse.SC_NOT_FOUND, NLS.bind("Source does not exist: ", locationString), null)); return false; } boolean allowOverwrite = (options & CREATE_NO_OVERWRITE) == 0; int efsOptions = allowOverwrite ? EFS.OVERWRITE : EFS.NONE; try { if (isCopy) source.copy(toCreate, efsOptions, null); else source.move(toCreate, efsOptions, null); } catch (CoreException e) { if (!source.fetchInfo().exists()) { statusHandler.handleRequest( request, response, new ServerStatus( IStatus.ERROR, HttpServletResponse.SC_NOT_FOUND, NLS.bind("Source does not exist: ", locationString), e)); return false; } if (e.getStatus().getCode() == EFS.ERROR_EXISTS) { statusHandler.handleRequest( request, response, new ServerStatus( IStatus.ERROR, HttpServletResponse.SC_PRECONDITION_FAILED, "A file or folder with the same name already exists at this location", null)); return false; } // just rethrow if we can't do something more specific throw e; } } catch (URISyntaxException e) { statusHandler.handleRequest( request, response, new ServerStatus( IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, NLS.bind("Bad source location in request: ", locationString), e)); return false; } return true; }
private boolean handlePost( HttpServletRequest request, HttpServletResponse response, String pathString) throws IOException, JSONException, ServletException, URISyntaxException, CoreException, NoHeadException, NoMessageException, ConcurrentRefUpdateException, WrongRepositoryStateException { // make sure required fields are set JSONObject toAdd = OrionServlet.readJSONRequest(request); if (toAdd.optBoolean(GitConstants.KEY_PULL, false)) { GitUtils.createGitCredentialsProvider(toAdd); GitCredentialsProvider cp = GitUtils.createGitCredentialsProvider(toAdd); boolean force = toAdd.optBoolean(GitConstants.KEY_FORCE, false); return pull(request, response, cp, pathString, force); } Clone clone = new Clone(); String url = toAdd.optString(GitConstants.KEY_URL, null); // method handles repository clone or just repository init // decision is based on existence of GitUrl argument boolean initOnly; if (url == null || url.isEmpty()) initOnly = true; else { initOnly = false; if (!validateCloneUrl(url, request, response)) return true; clone.setUrl(new URIish(url)); } String cloneName = toAdd.optString(ProtocolConstants.KEY_NAME, null); if (cloneName == null) cloneName = request.getHeader(ProtocolConstants.HEADER_SLUG); // expected path /workspace/{workspaceId} String workspacePath = toAdd.optString(ProtocolConstants.KEY_LOCATION, null); // expected path /file/{workspaceId}/{projectName}[/{path}] String filePathString = toAdd.optString(ProtocolConstants.KEY_PATH, null); IPath filePath = filePathString == null ? null : new Path(filePathString); if (filePath != null && filePath.segmentCount() < 3) filePath = null; if (filePath == null && workspacePath == null) { String msg = NLS.bind( "Either {0} or {1} should be provided: {2}", new Object[] {ProtocolConstants.KEY_PATH, ProtocolConstants.KEY_LOCATION, toAdd}); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, msg, null)); } // only during init operation filePath or cloneName must be provided // during clone operation, name can be obtained from URL if (initOnly && filePath == null && cloneName == null) { String msg = NLS.bind( "Either {0} or {1} should be provided: {2}", new Object[] {ProtocolConstants.KEY_PATH, GitConstants.KEY_NAME, toAdd}); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, msg, null)); } if (!validateCloneName(cloneName, request, response)) return true; // prepare the WebClone object, create a new project if necessary WebProject webProject = null; boolean webProjectExists = false; if (filePath != null) { // path format is /file/{workspaceId}/{projectName}/[filePath] clone.setId(filePath.toString()); webProject = GitUtils.projectFromPath(filePath); // workspace path format needs to be used if project does not exist if (webProject == null) { String msg = NLS.bind("Specified project does not exist: {0}", filePath.segment(2)); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, msg, null)); } webProjectExists = true; clone.setContentLocation( webProject.getProjectStore().getFileStore(filePath.removeFirstSegments(3)).toURI()); if (cloneName == null) cloneName = filePath.segmentCount() > 2 ? filePath.lastSegment() : webProject.getName(); } else if (workspacePath != null) { IPath path = new Path(workspacePath); // TODO: move this to CloneJob // if so, modify init part to create a new project if necessary WebWorkspace workspace = WebWorkspace.fromId(path.segment(1)); String id = WebProject.nextProjectId(); if (cloneName == null) cloneName = new URIish(url).getHumanishName(); cloneName = getUniqueProjectName(workspace, cloneName); webProjectExists = false; webProject = WebProject.fromId(id); webProject.setName(cloneName); try { WorkspaceResourceHandler.computeProjectLocation(request, webProject, null, false); } catch (CoreException e) { // we are unable to write in the platform location! String msg = NLS.bind( "Server content location could not be written: {0}", Activator.getDefault().getRootLocationURI()); return statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, msg, e)); } catch (URISyntaxException e) { // should not happen, we do not allow linking at this point } try { // If all went well, add project to workspace WorkspaceResourceHandler.addProject(request.getRemoteUser(), workspace, webProject); } catch (CoreException e) { return statusHandler.handleRequest( request, response, new ServerStatus( IStatus.ERROR, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Error persisting project state", e)); } URI baseLocation = getURI(request); baseLocation = new URI( baseLocation.getScheme(), baseLocation.getUserInfo(), baseLocation.getHost(), baseLocation.getPort(), workspacePath, baseLocation.getQuery(), baseLocation.getFragment()); clone.setId(GitUtils.pathFromProject(workspace, webProject).toString()); clone.setContentLocation(webProject.getProjectStore().toURI()); } clone.setName(cloneName); clone.setBaseLocation(getURI(request)); JSONObject cloneObject = clone.toJSON(); String cloneLocation = cloneObject.getString(ProtocolConstants.KEY_LOCATION); if (initOnly) { // git init InitJob job = new InitJob( clone, TaskJobHandler.getUserId(request), request.getRemoteUser(), cloneLocation); return TaskJobHandler.handleTaskJob(request, response, job, statusHandler); } // git clone // prepare creds GitCredentialsProvider cp = GitUtils.createGitCredentialsProvider(toAdd); cp.setUri(new URIish(clone.getUrl())); // if all went well, clone CloneJob job = new CloneJob( clone, TaskJobHandler.getUserId(request), cp, request.getRemoteUser(), cloneLocation, webProjectExists ? null : webProject /* used for cleaning up, so null when not needed */); return TaskJobHandler.handleTaskJob(request, response, job, statusHandler); }
private boolean handleGet(HttpServletRequest request, HttpServletResponse response, String path) throws IOException, JSONException, ServletException, URISyntaxException, CoreException { Path p = new Path(path); // FIXME: what if a remote or branch is named "file"? if (p.segment(0).equals("file")) { // $NON-NLS-1$ // /git/remote/file/{path} File gitDir = GitUtils.getGitDir(p); Repository db = new FileRepository(gitDir); Set<String> configNames = db.getConfig().getSubsections(ConfigConstants.CONFIG_REMOTE_SECTION); JSONObject result = new JSONObject(); JSONArray children = new JSONArray(); URI cloneLocation = BaseToCloneConverter.getCloneLocation(getURI(request), BaseToCloneConverter.REMOTE_LIST); for (String configName : configNames) { Remote remote = new Remote(cloneLocation, db, configName); children.put(remote.toJSON(false, null)); } result.put(ProtocolConstants.KEY_CHILDREN, children); result.put(ProtocolConstants.KEY_TYPE, Remote.TYPE); OrionServlet.writeJSONResponse(request, response, result); return true; } else if (p.segment(1).equals("file")) { // $NON-NLS-1$ // /git/remote/{remote}/file/{path} RemoteDetailsJob job; String commits = request.getParameter(GitConstants.KEY_TAG_COMMITS); int commitsNumber = commits == null ? 0 : Integer.parseInt(commits); String page = request.getParameter("page"); if (page != null) { int pageNo = Integer.parseInt(page); int pageSize = request.getParameter("pageSize") == null ? PAGE_SIZE : Integer.parseInt(request.getParameter("pageSize")); job = new RemoteDetailsJob( TaskJobHandler.getUserId(request), p.segment(0), p.removeFirstSegments(1), BaseToCloneConverter.getCloneLocation(getURI(request), BaseToCloneConverter.REMOTE), commitsNumber, pageNo, pageSize, request.getRequestURI()); } else { job = new RemoteDetailsJob( TaskJobHandler.getUserId(request), p.segment(0), p.removeFirstSegments(1), BaseToCloneConverter.getCloneLocation(getURI(request), BaseToCloneConverter.REMOTE), commitsNumber); } return TaskJobHandler.handleTaskJob(request, response, job, statusHandler); } else if (p.segment(2).equals("file")) { // $NON-NLS-1$ // /git/remote/{remote}/{branch}/file/{path} File gitDir = GitUtils.getGitDir(p.removeFirstSegments(2)); Repository db = new FileRepository(gitDir); URI cloneLocation = BaseToCloneConverter.getCloneLocation( getURI(request), BaseToCloneConverter.REMOTE_BRANCH); Remote remote = new Remote(cloneLocation, db, p.segment(0)); RemoteBranch remoteBranch = new RemoteBranch(cloneLocation, db, remote, p.segment(1)); JSONObject result = remoteBranch.toJSON(); if (result != null) { OrionServlet.writeJSONResponse(request, response, result); return true; } JSONObject errorData = new JSONObject(); errorData.put(GitConstants.KEY_CLONE, cloneLocation); return statusHandler.handleRequest( request, response, new ServerStatus( new Status( IStatus.ERROR, GitActivator.PI_GIT, "No remote branch found: " + p.uptoSegment(2).removeTrailingSeparator()), HttpServletResponse.SC_NOT_FOUND, errorData)); } return statusHandler.handleRequest( request, response, new ServerStatus( IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, "Bad request, \"/git/remote/{remote}/{branch}/file/{path}\" expected", null)); }