示例#1
0
  @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));
      }
    }
  }
示例#3
0
  @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;
   }
 }
示例#6
0
  @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"));
  }
示例#7
0
 /** 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;
 }
示例#8
0
 @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;
 }
示例#11
0
  /**
   * 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);
   }
 }
示例#13
0
  @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("/"));
    }
  }
示例#14
0
 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;
  }
示例#16
0
  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));
  }
示例#17
0
 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;
 }
示例#19
0
  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));
  }