/******************************************************************************* * Copyright (c) 2011, 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.server.git.servlets; import java.io.File; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; 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.jgit.api.CheckoutCommand; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.errors.CheckoutConflictException; import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.api.errors.NoHeadException; import org.eclipse.jgit.api.errors.NoMessageException; import org.eclipse.jgit.api.errors.RefNotFoundException; import org.eclipse.jgit.api.errors.WrongRepositoryStateException; import org.eclipse.jgit.dircache.DirCache; import org.eclipse.jgit.dircache.DirCacheEntry; import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.StoredConfig; import org.eclipse.jgit.storage.file.FileRepositoryBuilder; import org.eclipse.jgit.transport.URIish; import org.eclipse.jgit.util.FileUtils; import org.eclipse.orion.internal.server.servlets.ServletResourceHandler; import org.eclipse.orion.internal.server.servlets.task.TaskJobHandler; import org.eclipse.orion.internal.server.servlets.workspace.WorkspaceResourceHandler; import org.eclipse.orion.internal.server.servlets.workspace.authorization.AuthorizationService; import org.eclipse.orion.server.core.EncodingUtils; import org.eclipse.orion.server.core.LogHelper; 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.IMetaStore; 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.git.GitConstants; import org.eclipse.orion.server.git.GitCredentialsProvider; import org.eclipse.orion.server.git.jobs.CloneJob; import org.eclipse.orion.server.git.jobs.InitJob; import org.eclipse.orion.server.git.jobs.PullJob; import org.eclipse.orion.server.git.objects.Clone; import org.eclipse.orion.server.git.servlets.GitUtils.Traverse; import org.eclipse.orion.server.servlets.JsonURIUnqualificationStrategy; import org.eclipse.orion.server.servlets.OrionServlet; import org.eclipse.osgi.util.NLS; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; /** * A handler for Git Clone operation. */ public class GitCloneHandlerV1 extends ServletResourceHandler<String> { private ServletResourceHandler<IStatus> statusHandler; GitCloneHandlerV1(ServletResourceHandler<IStatus> statusHandler) { this.statusHandler = statusHandler; } @Override public boolean handleRequest(HttpServletRequest request, HttpServletResponse response, String path) throws ServletException { try { IPath filePath = new Path(path); if (filePath.segmentCount() > 0 && filePath.segment(0).equals("file") && !AuthorizationService.checkRights(request.getRemoteUser(), "/" + filePath.toString(), request.getMethod())) { response.sendError(HttpServletResponse.SC_FORBIDDEN); return true; } switch (getMethod(request)) { case GET: return handleGet(request, response, path); case PUT: return handlePut(request, response, path); case POST: return handlePost(request, response, path); case DELETE: return handleDelete(request, response, path); default: // we don't know how to handle this request return false; } } catch (Exception e) { String msg = NLS.bind("Failed to handle /git/clone request for {0}", EncodingUtils.encodeForHTML(path.toString())); ServerStatus status = new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, msg, e); LogHelper.log(status); return statusHandler.handleRequest(request, response, status); } } 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)) { GitCredentialsProvider cp = GitUtils.createGitCredentialsProvider(toAdd, request); 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 = ServletResourceHandler.toOrionLocation(request, toAdd.optString(ProtocolConstants.KEY_LOCATION, null)); // expected path /file/{workspaceId}/{projectName}[/{path}] String filePathString = ServletResourceHandler.toOrionLocation(request, 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 ProjectInfo project = null; boolean webProjectExists = false; if (filePath != null) { // path format is /file/{workspaceId}/{projectName}/[filePath] clone.setId(filePath.toString()); project = GitUtils.projectFromPath(filePath); // workspace path format needs to be used if project does not exist if (project == 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(project.getProjectStore().getFileStore(filePath.removeFirstSegments(3)).toURI()); if (cloneName == null) cloneName = filePath.segmentCount() > 2 ? filePath.lastSegment() : project.getFullName(); } 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 final IMetaStore metaStore = OrionConfiguration.getMetaStore(); WorkspaceInfo workspace = metaStore.readWorkspace(path.segment(1)); if (cloneName == null) cloneName = new URIish(url).getHumanishName(); cloneName = GitUtils.getUniqueProjectName(workspace, cloneName); webProjectExists = false; project = new ProjectInfo(); project.setFullName(cloneName); project.setWorkspaceId(workspace.getUniqueId()); try { // creating project in the backing store will assign a project id metaStore.createProject(project); } catch (CoreException e) { return statusHandler.handleRequest(request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Error persisting project state", e)); } try { WorkspaceResourceHandler.computeProjectLocation(request, project, null, false); metaStore.updateProject(project); } catch (CoreException e) { // delete the project so we don't end up with a project in a bad location try { metaStore.deleteProject(workspace.getUniqueId(), project.getFullName()); } catch (CoreException e1) { // swallow secondary error LogHelper.log(e1); } // we are unable to write in the platform location! String msg = NLS.bind("Failed to create project: {0}", project.getFullName()); return statusHandler.handleRequest(request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, msg, 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, project).toString()); clone.setContentLocation(project.getProjectStore().toURI()); } clone.setName(cloneName); clone.setBaseLocation(getURI(request)); JSONObject cloneObject = clone.toJSON(); String cloneLocation = cloneObject.getString(ProtocolConstants.KEY_LOCATION); String gitUserName = toAdd.optString(GitConstants.KEY_NAME, null); String gitUserMail = toAdd.optString(GitConstants.KEY_MAIL, null); Boolean initProject = toAdd.optBoolean(GitConstants.KEY_INIT_PROJECT, false); Boolean cloneSubmodules = toAdd.optBoolean(GitConstants.KEY_CLONE_SUBMODULES, true); if (initOnly) { // git init InitJob job = new InitJob(clone, TaskJobHandler.getUserId(request), request.getRemoteUser(), cloneLocation, gitUserName, gitUserMail); return TaskJobHandler.handleTaskJob(request, response, job, statusHandler, JsonURIUnqualificationStrategy.ALL_NO_GIT); } // git clone // prepare creds GitCredentialsProvider cp = GitUtils.createGitCredentialsProvider(toAdd, request); cp.setUri(new URIish(clone.getUrl())); // if all went well, clone // check for SSO token Object cookie = request.getAttribute(GitConstants.KEY_SSO_TOKEN); CloneJob job = new CloneJob(clone, TaskJobHandler.getUserId(request), cp, request.getRemoteUser(), cloneLocation, webProjectExists ? null : project /* used for cleaning up, so null when not needed */, gitUserName, gitUserMail, initProject, cloneSubmodules, cookie); return TaskJobHandler.handleTaskJob(request, response, job, statusHandler, JsonURIUnqualificationStrategy.ALL_NO_GIT); } public static void doConfigureClone(Git git, String user, String gitUserName, String gitUserMail) throws IOException, CoreException, JSONException { StoredConfig config = git.getRepository().getConfig(); if (gitUserName == null && gitUserMail == null) { JSONObject gitUserConfig = getUserGitConfig(user); if (gitUserConfig != null) { gitUserName = gitUserConfig.getString("GitName"); //$NON-NLS-1$ gitUserMail = gitUserConfig.getString("GitMail"); //$NON-NLS-1$ } } if (gitUserName != null) config.setString(ConfigConstants.CONFIG_USER_SECTION, null, ConfigConstants.CONFIG_KEY_NAME, gitUserName); if (gitUserMail != null) config.setString(ConfigConstants.CONFIG_USER_SECTION, null, ConfigConstants.CONFIG_KEY_EMAIL, gitUserMail); config.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null, ConfigConstants.CONFIG_KEY_FILEMODE, false); config.save(); } private static JSONObject getUserGitConfig(String user) throws CoreException { JSONObject userGitConfig = null; UserInfo userInfo = OrionConfiguration.getMetaStore().readUser(user); if (userInfo != null) { String gitUserInfo = userInfo.getProperty("git/config/userInfo"); //$NON-NLS-1$ if (gitUserInfo != null) { try { userGitConfig = new JSONObject(gitUserInfo); } catch (JSONException e) { // treat as no git options available } } } return userGitConfig; } 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 WorkspaceInfo workspace = OrionConfiguration.getMetaStore().readWorkspace(path.segment(1)); if (workspace != null) { JSONObject result = new JSONObject(); JSONArray children = new JSONArray(); for (String projectName : workspace.getProjectNames()) { ProjectInfo project = OrionConfiguration.getMetaStore().readProject(workspace.getUniqueId(), projectName); // this is the location of the project metadata if (project != null && isAccessAllowed(user, project)) { IPath projectPath = GitUtils.pathFromProject(workspace, project); Map<IPath, File> gitDirs = GitUtils.getGitDirs(projectPath, Traverse.GO_DOWN); for (Map.Entry<IPath, File> entry : gitDirs.entrySet()) { children.put(new Clone().toJSON(entry.getKey(), baseLocation, GitUtils.getCloneUrl(entry.getValue()))); } } } result.put(ProtocolConstants.KEY_TYPE, Clone.TYPE); result.put(ProtocolConstants.KEY_CHILDREN, children); OrionServlet.writeJSONResponse(request, response, result, JsonURIUnqualificationStrategy.ALL_NO_GIT); return true; } String msg = NLS.bind("Nothing found for the given ID: {0}", EncodingUtils.encodeForHTML(path.toString())); 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 ProjectInfo 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.getKey(), baseLocation, GitUtils.getCloneUrl(entry.getValue()))); } result.put(ProtocolConstants.KEY_TYPE, Clone.TYPE); result.put(ProtocolConstants.KEY_CHILDREN, children); OrionServlet.writeJSONResponse(request, response, result, JsonURIUnqualificationStrategy.ALL_NO_GIT); return true; } String msg = NLS.bind("Nothing found for the given ID: {0}", EncodingUtils.encodeForHTML(path.toString())); 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}", EncodingUtils.encodeForHTML(path.toString())); return statusHandler.handleRequest(request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, msg, null)); } 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 ProjectInfo 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}", EncodingUtils.encodeForHTML(path.toString())); 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)); } Repository db = null; try { db = FileRepositoryBuilder.create(gitDir); Git git = Git.wrap(db); 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); DirCacheEntry entry = getEntry(db, p); if (removeUntracked && entry ==null) toRemove.add(p); if (entry != null && entry.getFileMode().equals(FileMode.GITLINK) && !new File(db.getWorkTree(), p).exists()){ // when checkout removed submodule, remake directory if it doesn't exist new File(db.getWorkTree(), p).mkdir(); } else { checkout.addPath(p); } } checkout.call(); for (String p : toRemove) { File f = new File(git.getRepository().getWorkTree(), p); if (f.isDirectory()) { FileUtils.delete(f, FileUtils.RECURSIVE); } else { f.delete(); } } return true; } else if (tag != null && branch != null) { CheckoutCommand co = git.checkout(); try { if (branch.isEmpty()) { co.setName(tag).setStartPoint(tag).call(); } else { co.setName(branch).setStartPoint(tag).setCreateBranch(true).call(); } return true; } catch (RefNotFoundException e) { String msg = NLS.bind("Tag not found: {0}", EncodingUtils.encodeForHTML(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.", EncodingUtils.encodeForHTML(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}", EncodingUtils.encodeForHTML(branch)); return statusHandler.handleRequest(request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_FOUND, msg, e)); } // TODO: handle other exceptions } } finally { if (db != null) { db.close(); } } } else { String msg = NLS.bind("Nothing found for the given ID: {0}", EncodingUtils.encodeForHTML(path.toString())); 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 isLocalBranch(Git git, String branch) throws GitAPIException { List<Ref> branches = git.branchList().call(); for (Ref ref : branches) { if (Repository.shortenRefName(ref.getName()).equals(branch)) return true; } return false; } private DirCacheEntry getEntry(Repository db, String path) throws IOException { DirCache dc = DirCache.read(db.getIndexFile(), db.getFS()); return dc.getEntry(path); } private boolean handleDelete(HttpServletRequest request, HttpServletResponse response, String pathString) throws GitAPIException, CoreException, IOException, ServletException { IPath path = pathString == null ? Path.EMPTY : new Path(pathString); // expected path format is /file/{workspaceId}/{projectId}[/{directoryPath}] if (path.segment(0).equals("file") && path.segmentCount() > 2) { //$NON-NLS-1$ // make sure a clone is addressed ProjectInfo webProject = GitUtils.projectFromPath(path); if (webProject != null && isAccessAllowed(request.getRemoteUser(), webProject)) { File gitDir = GitUtils.getGitDirs(path, Traverse.CURRENT).values().iterator().next(); Repository repo = FileRepositoryBuilder.create(gitDir); repo.close(); FileUtils.delete(repo.getWorkTree(), FileUtils.RECURSIVE | FileUtils.RETRY); if (path.segmentCount() == 3) return statusHandler.handleRequest(request, response, removeProject(request.getRemoteUser(), webProject)); return true; } String msg = NLS.bind("Nothing found for the given ID: {0}", EncodingUtils.encodeForHTML(path.toString())); return statusHandler.handleRequest(request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_FOUND, msg, null)); } String msg = NLS.bind("Invalid delete request {0}", EncodingUtils.encodeForHTML(pathString)); return statusHandler.handleRequest(request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, msg, null)); } /** * Returns whether the user can access the given project */ private boolean isAccessAllowed(String userName, ProjectInfo webProject) { try { UserInfo user = OrionConfiguration.getMetaStore().readUser(userName); for (String workspaceId : user.getWorkspaceIds()) { WorkspaceInfo workspace = OrionConfiguration.getMetaStore().readWorkspace(workspaceId); if (workspace != null && workspace.getProjectNames().contains(webProject.getFullName())) return true; } } catch (Exception e) { // fall through and deny access LogHelper.log(e); } return false; } /** * Looks for the project in all workspaces of the user and removes it when found. * * @see WorkspaceResourceHandler#handleRemoveProject(HttpServletRequest, HttpServletResponse, WorkspaceInfo) * * @param userId * the user name * @param project * 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 userId, ProjectInfo project) { try { UserInfo user = OrionConfiguration.getMetaStore().readUser(userId); for (String workspaceId : user.getWorkspaceIds()) { WorkspaceInfo workspace = OrionConfiguration.getMetaStore().readWorkspace(workspaceId); if (workspace == null) continue; for (String projectName : workspace.getProjectNames()) { if (projectName.equals(project.getFullName())) { // If found, remove project from workspace try { WorkspaceResourceHandler.removeProject(userId, workspace, project); } catch (CoreException e) { // we are unable to write in the platform location! String msg = NLS.bind("Failed to remove project: {0}", project.getFullName()); return new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, msg, e); } return new ServerStatus(IStatus.OK, HttpServletResponse.SC_OK, null, null); } } } } catch (Exception e) { // ignore, no project will be harmed } // FIXME: not sure about this one return new ServerStatus(IStatus.OK, HttpServletResponse.SC_OK, null, null); } /** * Validates that the provided clone name is valid. Returns <code>true</code> if the clone name is valid, and <code>false</code> otherwise. This method * takes care of setting the error response when the clone name is not valid. */ private boolean validateCloneName(String name, HttpServletRequest request, HttpServletResponse response) throws ServletException { if (name == null) { return true; } if (name.trim().length() == 0) { statusHandler.handleRequest(request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, "Repository name cannot be empty", null)); return false; } if (name.contains("/")) { //$NON-NLS-1$ statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, NLS.bind("Invalid repository name: {0}", EncodingUtils.encodeForHTML(name)), null)); return false; } return true; } private boolean validateCloneUrl(String url, HttpServletRequest request, HttpServletResponse response) throws ServletException { if (url == null || url.trim().length() == 0) { statusHandler.handleRequest(request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, "Clone URL cannot be empty", null)); //$NON-NLS-1$ return false; } try { URIish uri = new URIish(url); if (GitUtils.isForbiddenGitUri(uri)) { statusHandler.handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, NLS.bind( "Clone URL {0} does not appear to be a git repository", EncodingUtils.encodeForHTML(uri.toString())), null)); //$NON-NLS-1$ return false; } } catch (URISyntaxException e) { statusHandler .handleRequest( request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, NLS.bind( "Invalid clone URL: {0}", EncodingUtils.encodeForHTML(url)), e)); //$NON-NLS-1$ return false; } return true; } private boolean pull(HttpServletRequest request, HttpServletResponse response, GitCredentialsProvider cp, String path, boolean force) throws URISyntaxException, JSONException, IOException, ServletException { Path p = new Path(path); // /{file}/{path} Object cookie = request.getAttribute(GitConstants.KEY_SSO_TOKEN); PullJob job = new PullJob(TaskJobHandler.getUserId(request), cp, p, force, cookie); return TaskJobHandler.handleTaskJob(request, response, job, statusHandler, JsonURIUnqualificationStrategy.ALL_NO_GIT); } }