From 2492c95c0b75b4d1a90874875c36d1e9a91fd395 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Fri, 24 May 2019 16:31:52 +0100 Subject: [PATCH] Handle a 409 response with code=projectHasDotGit --- .../ic/wlgitbridge/snapshot/base/Request.java | 26 +++++++++++++++++-- .../WLGitBridgeIntegrationTest.java | 21 +++++++++++++++ .../state/state.json | 19 ++++++++++++++ 3 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/cannotCloneAHasDotGitProject/state/state.json diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/Request.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/Request.java index eeb40c8f35..648e24a0ba 100644 --- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/Request.java +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/Request.java @@ -11,6 +11,7 @@ import uk.ac.ic.wlgitbridge.util.Log; import javax.servlet.http.HttpServletResponse; import java.io.IOException; +import java.util.Arrays; import java.util.concurrent.*; /** @@ -73,9 +74,30 @@ public abstract class Request { if (cause instanceof HttpResponseException) { HttpResponseException httpCause = (HttpResponseException) cause; int sc = httpCause.getStatusCode(); - if (sc == HttpServletResponse.SC_UNAUTHORIZED || sc == HttpServletResponse.SC_FORBIDDEN) { + if (sc == HttpServletResponse.SC_UNAUTHORIZED || sc == HttpServletResponse.SC_FORBIDDEN) { // 401, 403 throw new ForbiddenException(); - } else if (sc == HttpServletResponse.SC_NOT_FOUND) { + } else if (sc == HttpServletResponse.SC_CONFLICT) { // 409 + try { + JsonObject json = Instance.gson.fromJson(httpCause.getContent(), JsonObject.class); + String code = json.get("code").getAsString(); + if ("projectHasDotGit".equals(code)) { + throw new MissingRepositoryException(Arrays.asList( + "This project contains a '.git' entity at the top level, indicating that it is", + "already a git repository. The Overleaf git-bridge cannot work with this project", + "due to a known problem with handling these '.git' folders.", + "", + "If this is unexpected, please contact us at support@overleaf.com, or", + "see https://www.overleaf.com/help/342 for more information." + )); + } else { + throw new MissingRepositoryException(Arrays.asList("Conflict: 409")); + } + } catch (IllegalStateException + | ClassCastException + | NullPointerException _e) { // json parse errors + throw new MissingRepositoryException(Arrays.asList("Conflict: 409")); + } + } else if (sc == HttpServletResponse.SC_NOT_FOUND) { // 404 try { JsonObject json = Instance.gson.fromJson(httpCause.getContent(), JsonObject.class); String message = json.get("message").getAsString(); diff --git a/services/git-bridge/src/test/java/uk/ac/ic/wlgitbridge/application/WLGitBridgeIntegrationTest.java b/services/git-bridge/src/test/java/uk/ac/ic/wlgitbridge/application/WLGitBridgeIntegrationTest.java index e0f0ddeffb..4ffa9dda67 100644 --- a/services/git-bridge/src/test/java/uk/ac/ic/wlgitbridge/application/WLGitBridgeIntegrationTest.java +++ b/services/git-bridge/src/test/java/uk/ac/ic/wlgitbridge/application/WLGitBridgeIntegrationTest.java @@ -129,6 +129,9 @@ public class WLGitBridgeIntegrationTest { put("rejectV1Repository", new HashMap() {{ put("state", new SnapshotAPIStateBuilder(getResourceAsStream("/rejectV1Repository/state/state.json")).build()); }}); + put("cannotCloneAHasDotGitProject", new HashMap() {{ + put("state", new SnapshotAPIStateBuilder(getResourceAsStream("/cannotCloneAHasDotGitProject/state/state.json")).build()); + }}); }}; @Rule @@ -868,6 +871,24 @@ public class WLGitBridgeIntegrationTest { assertNotEquals(0, gitProcess.waitFor()); } + @Test + public void cannotCloneAHasDotGitProject() throws IOException, GitAPIException, InterruptedException { + int gitBridgePort = 33885; + int mockServerPort = 3885; + + MockSnapshotServer server = new MockSnapshotServer(mockServerPort, getResource("/cannotCloneAHasDotGitProject").toFile()); + server.start(); + server.setState(states.get("cannotCloneAHasDotGitProject").get("state")); + GitBridgeApp wlgb = new GitBridgeApp(new String[] { + makeConfigFile(gitBridgePort, mockServerPort) + }); + + wlgb.run(); + Process gitProcess = runtime.exec("git clone http://127.0.0.1:" + gitBridgePort + "/conflict.git", null, dir); + assertNotEquals(0, gitProcess.waitFor()); + wlgb.stop(); + } + private String makeConfigFile( int port, int apiPort diff --git a/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/cannotCloneAHasDotGitProject/state/state.json b/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/cannotCloneAHasDotGitProject/state/state.json new file mode 100644 index 0000000000..23bf520b29 --- /dev/null +++ b/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/cannotCloneAHasDotGitProject/state/state.json @@ -0,0 +1,19 @@ +[ + { + "project": "conflict", + "getDoc": { + "error": 409, + "code": "projectHasDotGit", + "versionID": 1, + "createdAt": "2018-02-05T15:30:00Z", + "email": "michael.walker@overleaf.com", + "name": "msw" + }, + "getSavedVers": [], + "getForVers": [], + "push": "success", + "postback": { + "type": "outOfDate" + } + } +]