@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; } }
/** 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 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("/")); } }
/** * 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); }
/** * 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; }
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); }
// 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; }