From 8b4c29ec836042fd50bc7a589f7e938efe59e420 Mon Sep 17 00:00:00 2001 From: Michael Walker Date: Mon, 5 Feb 2018 12:16:09 +0000 Subject: [PATCH 01/16] Throw an exception if the API returns 410 --- .../uk/ac/ic/wlgitbridge/bridge/Bridge.java | 7 ++++-- .../bridge/snapshot/SnapshotApi.java | 6 +++-- .../bridge/snapshot/SnapshotApiFacade.java | 3 ++- .../ic/wlgitbridge/server/Oauth2Filter.java | 4 ++++ .../base/DisabledRepositoryException.java | 24 +++++++++++++++++++ .../ic/wlgitbridge/snapshot/base/Request.java | 20 ++++++++++------ 6 files changed, 52 insertions(+), 12 deletions(-) create mode 100644 services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/DisabledRepositoryException.java diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/Bridge.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/Bridge.java index c7c27564f2..bf7316ae55 100644 --- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/Bridge.java +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/Bridge.java @@ -35,6 +35,7 @@ import uk.ac.ic.wlgitbridge.git.handler.hook.WriteLatexPutHook; import uk.ac.ic.wlgitbridge.server.FileHandler; import uk.ac.ic.wlgitbridge.server.PostbackContents; import uk.ac.ic.wlgitbridge.server.PostbackHandler; +import uk.ac.ic.wlgitbridge.snapshot.base.DisabledRepositoryException; import uk.ac.ic.wlgitbridge.snapshot.base.ForbiddenException; import uk.ac.ic.wlgitbridge.snapshot.getforversion.SnapshotAttachment; import uk.ac.ic.wlgitbridge.snapshot.push.PostbackManager; @@ -383,6 +384,7 @@ public class Bridge { * @param hostname * @throws SnapshotPostException * @throws IOException + * @throws DisabledRepositoryException * @throws ForbiddenException */ public void push( @@ -391,7 +393,7 @@ public class Bridge { RawDirectory directoryContents, RawDirectory oldDirectoryContents, String hostname - ) throws SnapshotPostException, IOException, ForbiddenException { + ) throws SnapshotPostException, IOException, DisabledRepositoryException, ForbiddenException { try (LockGuard __ = lock.lockGuard(projectName)) { pushCritical( oauth2, @@ -460,6 +462,7 @@ public class Bridge { * @param directoryContents * @param oldDirectoryContents * @throws IOException + * @throws DisabledRepositoryException * @throws ForbiddenException * @throws SnapshotPostException */ @@ -468,7 +471,7 @@ public class Bridge { String projectName, RawDirectory directoryContents, RawDirectory oldDirectoryContents - ) throws IOException, ForbiddenException, SnapshotPostException { + ) throws IOException, DisabledRepositoryException, ForbiddenException, SnapshotPostException { Log.info("[{}] Pushing", projectName); String postbackKey = postbackManager.makeKeyForProject(projectName); Log.info( diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/snapshot/SnapshotApi.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/snapshot/SnapshotApi.java index d4edf22189..7b842779dd 100644 --- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/snapshot/SnapshotApi.java +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/snapshot/SnapshotApi.java @@ -2,6 +2,7 @@ package uk.ac.ic.wlgitbridge.bridge.snapshot; import com.google.api.client.auth.oauth2.Credential; import uk.ac.ic.wlgitbridge.data.CandidateSnapshot; +import uk.ac.ic.wlgitbridge.snapshot.base.DisabledRepositoryException; import uk.ac.ic.wlgitbridge.snapshot.base.ForbiddenException; import uk.ac.ic.wlgitbridge.snapshot.exception.FailedConnectionException; import uk.ac.ic.wlgitbridge.snapshot.getdoc.GetDocResult; @@ -33,13 +34,14 @@ public interface SnapshotApi { String postbackKey); static T getResult(CompletableFuture result) - throws FailedConnectionException, ForbiddenException { + throws DisabledRepositoryException, FailedConnectionException, ForbiddenException { try { return result.join(); } catch (CompletionException e) { try { throw e.getCause(); - } catch (FailedConnectionException + } catch (DisabledRepositoryException + | FailedConnectionException | ForbiddenException | RuntimeException r) { throw r; diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/snapshot/SnapshotApiFacade.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/snapshot/SnapshotApiFacade.java index ea4d388101..69a7d0a317 100644 --- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/snapshot/SnapshotApiFacade.java +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/snapshot/SnapshotApiFacade.java @@ -4,6 +4,7 @@ import com.google.api.client.auth.oauth2.Credential; import uk.ac.ic.wlgitbridge.data.CandidateSnapshot; import uk.ac.ic.wlgitbridge.data.model.Snapshot; import uk.ac.ic.wlgitbridge.git.exception.GitUserException; +import uk.ac.ic.wlgitbridge.snapshot.base.DisabledRepositoryException; import uk.ac.ic.wlgitbridge.snapshot.base.ForbiddenException; import uk.ac.ic.wlgitbridge.snapshot.exception.FailedConnectionException; import uk.ac.ic.wlgitbridge.snapshot.getdoc.GetDocResult; @@ -65,7 +66,7 @@ public class SnapshotApiFacade { Optional oauth2, CandidateSnapshot candidateSnapshot, String postbackKey - ) throws FailedConnectionException, ForbiddenException { + ) throws DisabledRepositoryException, FailedConnectionException, ForbiddenException { return SnapshotApi.getResult(api.push( oauth2, candidateSnapshot, postbackKey)); } diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/server/Oauth2Filter.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/server/Oauth2Filter.java index e33294f75e..54f5754ace 100644 --- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/server/Oauth2Filter.java +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/server/Oauth2Filter.java @@ -6,6 +6,7 @@ import org.apache.commons.codec.binary.Base64; import org.eclipse.jetty.server.Request; import uk.ac.ic.wlgitbridge.application.config.Oauth2; import uk.ac.ic.wlgitbridge.bridge.snapshot.SnapshotApi; +import uk.ac.ic.wlgitbridge.snapshot.base.DisabledRepositoryException; import uk.ac.ic.wlgitbridge.snapshot.base.ForbiddenException; import uk.ac.ic.wlgitbridge.snapshot.getdoc.GetDocRequest; import uk.ac.ic.wlgitbridge.util.Instance; @@ -76,6 +77,9 @@ public class Oauth2Filter implements Filter { filterChain ); return; + } catch (DisabledRepositoryException e) { + Log.info("[{}] Git access disabled", project); + throw new ServletException(e); } Log.info("[{}] Auth not needed", project); filterChain.doFilter(servletRequest, servletResponse); diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/DisabledRepositoryException.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/DisabledRepositoryException.java new file mode 100644 index 0000000000..3a2640d6be --- /dev/null +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/DisabledRepositoryException.java @@ -0,0 +1,24 @@ +package uk.ac.ic.wlgitbridge.snapshot.base; + +import com.google.gson.JsonElement; +import uk.ac.ic.wlgitbridge.git.exception.SnapshotAPIException; + +import java.util.Arrays; +import java.util.List; + +public class DisabledRepositoryException extends SnapshotAPIException { + + @Override + public void fromJSON(JsonElement json) {} + + @Override + public String getMessage() { + return "project not accessible over git"; + } + + @Override + public List getDescriptionLines() { + return Arrays.asList(getMessage()); + } + +} 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 58491fb736..ee0849493e 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 @@ -50,7 +50,7 @@ public abstract class Request { return ret; } - private T getResult() throws FailedConnectionException, ForbiddenException { + private T getResult() throws DisabledRepositoryException, FailedConnectionException, ForbiddenException { try { HttpResponse response = future.get(); Log.info( @@ -68,12 +68,18 @@ public abstract class Request { throw new FailedConnectionException(); } catch (ExecutionException e) { Throwable cause = e.getCause(); - if (cause instanceof HttpResponseException && - (((HttpResponseException) cause).getStatusCode() == - HttpServletResponse.SC_UNAUTHORIZED || - ((HttpResponseException) cause).getStatusCode() == - HttpServletResponse.SC_FORBIDDEN)) { - throw new ForbiddenException(); + if (cause instanceof HttpResponseException) { + HttpResponseException httpCause = (HttpResponseException) cause; + switch (httpCause.getStatusCode()) { + case HttpServletResponse.SC_UNAUTHORIZED: + case HttpServletResponse.SC_FORBIDDEN: + throw new ForbiddenException(); + case HttpServletResponse.SC_GONE: + throw new DisabledRepositoryException(); + default: + break; + } + throw new FailedConnectionException(cause); } else { throw new FailedConnectionException(cause); } From 20a748f14e361843374dff379b3bca9cf40f0ff9 Mon Sep 17 00:00:00 2001 From: Michael Walker Date: Mon, 5 Feb 2018 13:35:58 +0000 Subject: [PATCH 02/16] Explain to the user that their project is inaccessible --- .../ic/wlgitbridge/server/Oauth2Filter.java | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/server/Oauth2Filter.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/server/Oauth2Filter.java index 54f5754ace..c0277f66ee 100644 --- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/server/Oauth2Filter.java +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/server/Oauth2Filter.java @@ -78,8 +78,7 @@ public class Oauth2Filter implements Filter { ); return; } catch (DisabledRepositoryException e) { - Log.info("[{}] Git access disabled", project); - throw new ServletException(e); + disabled(project, (HttpServletResponse) servletResponse); } Log.info("[{}] Auth not needed", project); filterChain.doFilter(servletRequest, servletResponse); @@ -204,4 +203,22 @@ public class Oauth2Filter implements Filter { w.close(); } + private void disabled( + String projectName, + HttpServletResponse response + ) throws IOException { + Log.info("[{}] Git access to project disabled.", projectName); + + response.setContentType("text/plain"); + + // git special-cases 404 to give "repository '%s' not found", + // rather than displaying the raw status code. + response.setStatus(404); + + PrintWriter w = response.getWriter(); + w.println("This project is not accessible over Git."); + w.println(); + w.println("If you think this is an error, contact support at support@overleaf.com."); + w.close(); + } } From 5e08f6f5c6a6208c1c21917a98b839c0f7961d43 Mon Sep 17 00:00:00 2001 From: Michael Walker Date: Mon, 5 Feb 2018 15:32:01 +0000 Subject: [PATCH 03/16] Add a test for cloning disabled projects --- .../WLGitBridgeIntegrationTest.java | 21 +++++++++++++++++++ .../state/state.json | 18 ++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/cannotCloneADisabledProject/state/state.json 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 20b1fb85ed..59a4406130 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 @@ -45,6 +45,9 @@ public class WLGitBridgeIntegrationTest { put("cannotCloneAProtectedProject", new HashMap() {{ put("state", new SnapshotAPIStateBuilder(getResourceAsStream("/cannotCloneAProtectedProject/state/state.json")).build()); }}); + put("cannotCloneADisabledProject", new HashMap() {{ + put("state", new SnapshotAPIStateBuilder(getResourceAsStream("/cannotCloneADisabledProject/state/state.json")).build()); + }}); put("canPullAModifiedTexFile", new HashMap() {{ put("base", new SnapshotAPIStateBuilder(getResourceAsStream("/canPullAModifiedTexFile/base/state.json")).build()); put("withModifiedTexFile", new SnapshotAPIStateBuilder(getResourceAsStream("/canPullAModifiedTexFile/withModifiedTexFile/state.json")).build()); @@ -727,6 +730,24 @@ public class WLGitBridgeIntegrationTest { wlgb.stop(); } + @Test + public void cannotCloneADisabledProject() throws IOException, GitAPIException, InterruptedException { + int gitBridgePort = 33879; + int mockServerPort = 3879; + + MockSnapshotServer server = new MockSnapshotServer(mockServerPort, getResource("/cannotCloneADisabledProject").toFile()); + server.start(); + server.setState(states.get("cannotCloneADisabledProject").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 + "/testproj.git", null, dir); + wlgb.stop(); + assertNotEquals(0, gitProcess.waitFor()); + } + private String makeConfigFile( int port, int apiPort diff --git a/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/cannotCloneADisabledProject/state/state.json b/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/cannotCloneADisabledProject/state/state.json new file mode 100644 index 0000000000..05fa040b14 --- /dev/null +++ b/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/cannotCloneADisabledProject/state/state.json @@ -0,0 +1,18 @@ +[ + { + "project": "disabled", + "getDoc": { + "error": 410, + "versionID": 1, + "createdAt": "2018-02-05T15:30:00Z", + "email": "michael.walker@overleaf.com", + "name": "msw" + }, + "getSavedVers": [], + "getForVers": [], + "push": "success", + "postback": { + "type": "outOfDate" + } + } +] From 6ae6acd8263b01b50010dde8ea2912a6e75e8aa2 Mon Sep 17 00:00:00 2001 From: Michael Walker Date: Tue, 6 Feb 2018 13:24:41 +0000 Subject: [PATCH 04/16] Rename DisabledRepositoryException to MissingRepositoryException --- .../main/java/uk/ac/ic/wlgitbridge/bridge/Bridge.java | 10 +++++----- .../ac/ic/wlgitbridge/bridge/snapshot/SnapshotApi.java | 6 +++--- .../wlgitbridge/bridge/snapshot/SnapshotApiFacade.java | 4 ++-- .../java/uk/ac/ic/wlgitbridge/server/Oauth2Filter.java | 10 +++++----- ...yException.java => MissingRepositoryException.java} | 2 +- .../uk/ac/ic/wlgitbridge/snapshot/base/Request.java | 4 ++-- 6 files changed, 18 insertions(+), 18 deletions(-) rename services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/{DisabledRepositoryException.java => MissingRepositoryException.java} (86%) diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/Bridge.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/Bridge.java index bf7316ae55..d9448ab0bb 100644 --- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/Bridge.java +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/Bridge.java @@ -35,7 +35,7 @@ import uk.ac.ic.wlgitbridge.git.handler.hook.WriteLatexPutHook; import uk.ac.ic.wlgitbridge.server.FileHandler; import uk.ac.ic.wlgitbridge.server.PostbackContents; import uk.ac.ic.wlgitbridge.server.PostbackHandler; -import uk.ac.ic.wlgitbridge.snapshot.base.DisabledRepositoryException; +import uk.ac.ic.wlgitbridge.snapshot.base.MissingRepositoryException; import uk.ac.ic.wlgitbridge.snapshot.base.ForbiddenException; import uk.ac.ic.wlgitbridge.snapshot.getforversion.SnapshotAttachment; import uk.ac.ic.wlgitbridge.snapshot.push.PostbackManager; @@ -384,7 +384,7 @@ public class Bridge { * @param hostname * @throws SnapshotPostException * @throws IOException - * @throws DisabledRepositoryException + * @throws MissingRepositoryException * @throws ForbiddenException */ public void push( @@ -393,7 +393,7 @@ public class Bridge { RawDirectory directoryContents, RawDirectory oldDirectoryContents, String hostname - ) throws SnapshotPostException, IOException, DisabledRepositoryException, ForbiddenException { + ) throws SnapshotPostException, IOException, MissingRepositoryException, ForbiddenException { try (LockGuard __ = lock.lockGuard(projectName)) { pushCritical( oauth2, @@ -462,7 +462,7 @@ public class Bridge { * @param directoryContents * @param oldDirectoryContents * @throws IOException - * @throws DisabledRepositoryException + * @throws MissingRepositoryException * @throws ForbiddenException * @throws SnapshotPostException */ @@ -471,7 +471,7 @@ public class Bridge { String projectName, RawDirectory directoryContents, RawDirectory oldDirectoryContents - ) throws IOException, DisabledRepositoryException, ForbiddenException, SnapshotPostException { + ) throws IOException, MissingRepositoryException, ForbiddenException, SnapshotPostException { Log.info("[{}] Pushing", projectName); String postbackKey = postbackManager.makeKeyForProject(projectName); Log.info( diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/snapshot/SnapshotApi.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/snapshot/SnapshotApi.java index 7b842779dd..0358db7834 100644 --- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/snapshot/SnapshotApi.java +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/snapshot/SnapshotApi.java @@ -2,7 +2,7 @@ package uk.ac.ic.wlgitbridge.bridge.snapshot; import com.google.api.client.auth.oauth2.Credential; import uk.ac.ic.wlgitbridge.data.CandidateSnapshot; -import uk.ac.ic.wlgitbridge.snapshot.base.DisabledRepositoryException; +import uk.ac.ic.wlgitbridge.snapshot.base.MissingRepositoryException; import uk.ac.ic.wlgitbridge.snapshot.base.ForbiddenException; import uk.ac.ic.wlgitbridge.snapshot.exception.FailedConnectionException; import uk.ac.ic.wlgitbridge.snapshot.getdoc.GetDocResult; @@ -34,13 +34,13 @@ public interface SnapshotApi { String postbackKey); static T getResult(CompletableFuture result) - throws DisabledRepositoryException, FailedConnectionException, ForbiddenException { + throws MissingRepositoryException, FailedConnectionException, ForbiddenException { try { return result.join(); } catch (CompletionException e) { try { throw e.getCause(); - } catch (DisabledRepositoryException + } catch (MissingRepositoryException | FailedConnectionException | ForbiddenException | RuntimeException r) { diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/snapshot/SnapshotApiFacade.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/snapshot/SnapshotApiFacade.java index 69a7d0a317..f9085febcb 100644 --- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/snapshot/SnapshotApiFacade.java +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/snapshot/SnapshotApiFacade.java @@ -4,7 +4,7 @@ import com.google.api.client.auth.oauth2.Credential; import uk.ac.ic.wlgitbridge.data.CandidateSnapshot; import uk.ac.ic.wlgitbridge.data.model.Snapshot; import uk.ac.ic.wlgitbridge.git.exception.GitUserException; -import uk.ac.ic.wlgitbridge.snapshot.base.DisabledRepositoryException; +import uk.ac.ic.wlgitbridge.snapshot.base.MissingRepositoryException; import uk.ac.ic.wlgitbridge.snapshot.base.ForbiddenException; import uk.ac.ic.wlgitbridge.snapshot.exception.FailedConnectionException; import uk.ac.ic.wlgitbridge.snapshot.getdoc.GetDocResult; @@ -66,7 +66,7 @@ public class SnapshotApiFacade { Optional oauth2, CandidateSnapshot candidateSnapshot, String postbackKey - ) throws DisabledRepositoryException, FailedConnectionException, ForbiddenException { + ) throws MissingRepositoryException, FailedConnectionException, ForbiddenException { return SnapshotApi.getResult(api.push( oauth2, candidateSnapshot, postbackKey)); } diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/server/Oauth2Filter.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/server/Oauth2Filter.java index c0277f66ee..9cba5255f9 100644 --- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/server/Oauth2Filter.java +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/server/Oauth2Filter.java @@ -6,7 +6,7 @@ import org.apache.commons.codec.binary.Base64; import org.eclipse.jetty.server.Request; import uk.ac.ic.wlgitbridge.application.config.Oauth2; import uk.ac.ic.wlgitbridge.bridge.snapshot.SnapshotApi; -import uk.ac.ic.wlgitbridge.snapshot.base.DisabledRepositoryException; +import uk.ac.ic.wlgitbridge.snapshot.base.MissingRepositoryException; import uk.ac.ic.wlgitbridge.snapshot.base.ForbiddenException; import uk.ac.ic.wlgitbridge.snapshot.getdoc.GetDocRequest; import uk.ac.ic.wlgitbridge.util.Instance; @@ -77,8 +77,8 @@ public class Oauth2Filter implements Filter { filterChain ); return; - } catch (DisabledRepositoryException e) { - disabled(project, (HttpServletResponse) servletResponse); + } catch (MissingRepositoryException e) { + missing(project, (HttpServletResponse) servletResponse); } Log.info("[{}] Auth not needed", project); filterChain.doFilter(servletRequest, servletResponse); @@ -203,11 +203,11 @@ public class Oauth2Filter implements Filter { w.close(); } - private void disabled( + private void missing( String projectName, HttpServletResponse response ) throws IOException { - Log.info("[{}] Git access to project disabled.", projectName); + Log.info("[{}] Project missing.", projectName); response.setContentType("text/plain"); diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/DisabledRepositoryException.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/MissingRepositoryException.java similarity index 86% rename from services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/DisabledRepositoryException.java rename to services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/MissingRepositoryException.java index 3a2640d6be..c0723d63ca 100644 --- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/DisabledRepositoryException.java +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/MissingRepositoryException.java @@ -6,7 +6,7 @@ import uk.ac.ic.wlgitbridge.git.exception.SnapshotAPIException; import java.util.Arrays; import java.util.List; -public class DisabledRepositoryException extends SnapshotAPIException { +public class MissingRepositoryException extends SnapshotAPIException { @Override public void fromJSON(JsonElement 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 ee0849493e..9cf58227f9 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 @@ -50,7 +50,7 @@ public abstract class Request { return ret; } - private T getResult() throws DisabledRepositoryException, FailedConnectionException, ForbiddenException { + private T getResult() throws MissingRepositoryException, FailedConnectionException, ForbiddenException { try { HttpResponse response = future.get(); Log.info( @@ -75,7 +75,7 @@ public abstract class Request { case HttpServletResponse.SC_FORBIDDEN: throw new ForbiddenException(); case HttpServletResponse.SC_GONE: - throw new DisabledRepositoryException(); + throw new MissingRepositoryException(); default: break; } From 82c0873743482be94268b83582181a0c9767adc6 Mon Sep 17 00:00:00 2001 From: Michael Walker Date: Tue, 6 Feb 2018 13:30:30 +0000 Subject: [PATCH 05/16] Report all 4xx from write-latex API as MissingRepositoryException --- .../ic/wlgitbridge/snapshot/base/Request.java | 14 ++++++------- .../WLGitBridgeIntegrationTest.java | 21 +++++++++++++++++++ .../state/state.json | 18 ++++++++++++++++ 3 files changed, 45 insertions(+), 8 deletions(-) create mode 100644 services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/cannotCloneAMissingProject/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 9cf58227f9..f587288e77 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 @@ -70,14 +70,12 @@ public abstract class Request { Throwable cause = e.getCause(); if (cause instanceof HttpResponseException) { HttpResponseException httpCause = (HttpResponseException) cause; - switch (httpCause.getStatusCode()) { - case HttpServletResponse.SC_UNAUTHORIZED: - case HttpServletResponse.SC_FORBIDDEN: - throw new ForbiddenException(); - case HttpServletResponse.SC_GONE: - throw new MissingRepositoryException(); - default: - break; + int sc = httpCause.getStatusCode(); + if (sc == HttpServletResponse.SC_UNAUTHORIZED || sc == HttpServletResponse.SC_FORBIDDEN) { + throw new ForbiddenException(); + } + if (sc >= 400 && sc < 500) { + throw new MissingRepositoryException(); } throw new FailedConnectionException(cause); } else { 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 59a4406130..1afb80b8cb 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 @@ -48,6 +48,9 @@ public class WLGitBridgeIntegrationTest { put("cannotCloneADisabledProject", new HashMap() {{ put("state", new SnapshotAPIStateBuilder(getResourceAsStream("/cannotCloneADisabledProject/state/state.json")).build()); }}); + put("cannotCloneAMissingProject", new HashMap() {{ + put("state", new SnapshotAPIStateBuilder(getResourceAsStream("/cannotCloneAMissingProject/state/state.json")).build()); + }}); put("canPullAModifiedTexFile", new HashMap() {{ put("base", new SnapshotAPIStateBuilder(getResourceAsStream("/canPullAModifiedTexFile/base/state.json")).build()); put("withModifiedTexFile", new SnapshotAPIStateBuilder(getResourceAsStream("/canPullAModifiedTexFile/withModifiedTexFile/state.json")).build()); @@ -748,6 +751,24 @@ public class WLGitBridgeIntegrationTest { assertNotEquals(0, gitProcess.waitFor()); } + @Test + public void cannotCloneAMissingProject() throws IOException, GitAPIException, InterruptedException { + int gitBridgePort = 33880; + int mockServerPort = 3880; + + MockSnapshotServer server = new MockSnapshotServer(mockServerPort, getResource("/cannotCloneAMissingProject").toFile()); + server.start(); + server.setState(states.get("cannotCloneAMissingProject").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 + "/testproj.git", null, dir); + wlgb.stop(); + assertNotEquals(0, gitProcess.waitFor()); + } + private String makeConfigFile( int port, int apiPort diff --git a/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/cannotCloneAMissingProject/state/state.json b/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/cannotCloneAMissingProject/state/state.json new file mode 100644 index 0000000000..1db62b00b7 --- /dev/null +++ b/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/cannotCloneAMissingProject/state/state.json @@ -0,0 +1,18 @@ +[ + { + "project": "missing", + "getDoc": { + "error": 404, + "versionID": 1, + "createdAt": "2018-02-06T13:29:00Z", + "email": "michael.walker@overleaf.com", + "name": "msw" + }, + "getSavedVers": [], + "getForVers": [], + "push": "success", + "postback": { + "type": "outOfDate" + } + } +] From 3a374e0ba71a4f8e4a5db8f8bc298c98ff37bd0d Mon Sep 17 00:00:00 2001 From: Michael Walker Date: Tue, 6 Feb 2018 14:11:28 +0000 Subject: [PATCH 06/16] Send the MissingRepositoryException message to the client --- .../uk/ac/ic/wlgitbridge/server/Oauth2Filter.java | 9 +++++---- .../snapshot/base/MissingRepositoryException.java | 11 ++++++++++- .../uk/ac/ic/wlgitbridge/snapshot/base/Request.java | 9 +++++++-- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/server/Oauth2Filter.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/server/Oauth2Filter.java index 9cba5255f9..f4c2c4d67d 100644 --- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/server/Oauth2Filter.java +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/server/Oauth2Filter.java @@ -78,7 +78,7 @@ public class Oauth2Filter implements Filter { ); return; } catch (MissingRepositoryException e) { - missing(project, (HttpServletResponse) servletResponse); + missing(project, e, (HttpServletResponse) servletResponse); } Log.info("[{}] Auth not needed", project); filterChain.doFilter(servletRequest, servletResponse); @@ -205,6 +205,7 @@ public class Oauth2Filter implements Filter { private void missing( String projectName, + MissingRepositoryException e, HttpServletResponse response ) throws IOException { Log.info("[{}] Project missing.", projectName); @@ -216,9 +217,9 @@ public class Oauth2Filter implements Filter { response.setStatus(404); PrintWriter w = response.getWriter(); - w.println("This project is not accessible over Git."); - w.println(); - w.println("If you think this is an error, contact support at support@overleaf.com."); + for (String line : e.getDescriptionLines()) { + w.println(line); + } w.close(); } } diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/MissingRepositoryException.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/MissingRepositoryException.java index c0723d63ca..5fc74f4af3 100644 --- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/MissingRepositoryException.java +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/MissingRepositoryException.java @@ -8,12 +8,21 @@ import java.util.List; public class MissingRepositoryException extends SnapshotAPIException { + private String message = ""; + + public MissingRepositoryException() { + } + + public MissingRepositoryException(String message) { + this.message = message; + } + @Override public void fromJSON(JsonElement json) {} @Override public String getMessage() { - return "project not accessible over git"; + return message; } @Override 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 f587288e77..d010123c4d 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 @@ -73,9 +73,14 @@ public abstract class Request { int sc = httpCause.getStatusCode(); if (sc == HttpServletResponse.SC_UNAUTHORIZED || sc == HttpServletResponse.SC_FORBIDDEN) { throw new ForbiddenException(); - } - if (sc >= 400 && sc < 500) { + } else if (sc == HttpServletResponse.SC_NOT_FOUND) { throw new MissingRepositoryException(); + } else if (sc >= 400 && sc < 500) { + throw new MissingRepositoryException( + "This project is currently inaccessible over Git.\n" + + "\n" + + "If you think this is an error, contact support at support@overleaf.com." + ); } throw new FailedConnectionException(cause); } else { From 44d3ddd9aadde02442b3ac81dff2a26ec7462ed2 Mon Sep 17 00:00:00 2001 From: Michael Walker Date: Tue, 6 Feb 2018 14:59:55 +0000 Subject: [PATCH 07/16] Display a more specific message for v2 projects --- .../base/MissingRepositoryException.java | 10 ++++++++++ .../ic/wlgitbridge/snapshot/base/Request.java | 20 ++++++++++++++----- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/MissingRepositoryException.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/MissingRepositoryException.java index 5fc74f4af3..7bdd07938c 100644 --- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/MissingRepositoryException.java +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/MissingRepositoryException.java @@ -8,6 +8,16 @@ import java.util.List; public class MissingRepositoryException extends SnapshotAPIException { + public static final String GENERIC_REASON = + "This Overleaf project currently has no git access.\n" + + "\n" + + "If you think this is an error, contact support at support@overleaf.com."; + + public static final String EXPORTED_TO_V2 = + "This Overleaf project has been moved to Overleaf v2, and git access is temporarily unsupported.\n" + + "\n" + + "See https://www.overleaf.com/help/342 for more information."; + private String message = ""; public MissingRepositoryException() { 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 d010123c4d..9316eb667b 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 @@ -2,6 +2,7 @@ package uk.ac.ic.wlgitbridge.snapshot.base; import com.google.api.client.http.*; import com.google.gson.JsonElement; +import com.google.gson.JsonObject; import com.ning.http.client.AsyncHttpClient; import uk.ac.ic.wlgitbridge.snapshot.exception.FailedConnectionException; import uk.ac.ic.wlgitbridge.util.Instance; @@ -74,13 +75,22 @@ public abstract class Request { if (sc == HttpServletResponse.SC_UNAUTHORIZED || sc == HttpServletResponse.SC_FORBIDDEN) { throw new ForbiddenException(); } else if (sc == HttpServletResponse.SC_NOT_FOUND) { + try { + JsonObject json = Instance.gson.fromJson(httpCause.getContent(), JsonObject.class); + String message = json.get("message").getAsString(); + + if ("Exported to v2".equals(message)) { + throw new MissingRepositoryException(MissingRepositoryException.EXPORTED_TO_V2); + } + } catch (IllegalStateException + | ClassCastException + | NullPointerException _) { + // disregard any errors that arose while handling the JSON + } + throw new MissingRepositoryException(); } else if (sc >= 400 && sc < 500) { - throw new MissingRepositoryException( - "This project is currently inaccessible over Git.\n" + - "\n" + - "If you think this is an error, contact support at support@overleaf.com." - ); + throw new MissingRepositoryException(MissingRepositoryException.GENERIC_REASON); } throw new FailedConnectionException(cause); } else { From f13324134f281f71abb82e0df8ed4b3bc8c3416e Mon Sep 17 00:00:00 2001 From: Michael Walker Date: Wed, 7 Feb 2018 09:39:35 +0000 Subject: [PATCH 08/16] Give 'unauthorized' and 'missing' better names --- .../uk/ac/ic/wlgitbridge/server/Oauth2Filter.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/server/Oauth2Filter.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/server/Oauth2Filter.java index f4c2c4d67d..5478d68e43 100644 --- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/server/Oauth2Filter.java +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/server/Oauth2Filter.java @@ -78,7 +78,7 @@ public class Oauth2Filter implements Filter { ); return; } catch (MissingRepositoryException e) { - missing(project, e, (HttpServletResponse) servletResponse); + handleMissingRepository(project, e, (HttpServletResponse) servletResponse); } Log.info("[{}] Auth not needed", project); filterChain.doFilter(servletRequest, servletResponse); @@ -133,7 +133,7 @@ public class Oauth2Filter implements Filter { ) ).execute().getAccessToken(); } catch (TokenResponseException e) { - unauthorized(projectName, capturedUsername, e.getStatusCode(), request, response); + handleNeedAuthorization(projectName, capturedUsername, e.getStatusCode(), request, response); return; } final Credential cred = new Credential.Builder( @@ -148,7 +148,7 @@ public class Oauth2Filter implements Filter { servletResponse ); } else { - unauthorized(projectName, capturedUsername, 0, request, response); + handleNeedAuthorization(projectName, capturedUsername, 0, request, response); } } catch (UnsupportedEncodingException e) { throw new Error("Couldn't retrieve authentication", e); @@ -156,14 +156,14 @@ public class Oauth2Filter implements Filter { } } } else { - unauthorized(projectName, capturedUsername, 0, request, response); + handleNeedAuthorization(projectName, capturedUsername, 0, request, response); } } @Override public void destroy() {} - private void unauthorized( + private void handleNeedAuthorization( String projectName, String userName, int statusCode, @@ -203,7 +203,7 @@ public class Oauth2Filter implements Filter { w.close(); } - private void missing( + private void handleMissingRepository( String projectName, MissingRepositoryException e, HttpServletResponse response From bd8e8688c3351e4a775f0c676021d5f16b0098c1 Mon Sep 17 00:00:00 2001 From: Michael Walker Date: Wed, 7 Feb 2018 10:06:28 +0000 Subject: [PATCH 09/16] Make GENERIC_REASON consistent with web messages. --- .../wlgitbridge/snapshot/base/MissingRepositoryException.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/MissingRepositoryException.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/MissingRepositoryException.java index 7bdd07938c..7c5258bf82 100644 --- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/MissingRepositoryException.java +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/MissingRepositoryException.java @@ -11,7 +11,7 @@ public class MissingRepositoryException extends SnapshotAPIException { public static final String GENERIC_REASON = "This Overleaf project currently has no git access.\n" + "\n" + - "If you think this is an error, contact support at support@overleaf.com."; + "If this problem persists, please contact us."; public static final String EXPORTED_TO_V2 = "This Overleaf project has been moved to Overleaf v2, and git access is temporarily unsupported.\n" + From 994ad9a933b467bc0991b3f2ce7b84bfd624dc2b Mon Sep 17 00:00:00 2001 From: Michael Walker Date: Wed, 7 Feb 2018 10:10:09 +0000 Subject: [PATCH 10/16] 410 is no longer "disabled" --- .../cannotCloneADisabledProject/state/state.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/cannotCloneADisabledProject/state/state.json b/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/cannotCloneADisabledProject/state/state.json index 05fa040b14..f8c76c1dec 100644 --- a/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/cannotCloneADisabledProject/state/state.json +++ b/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/cannotCloneADisabledProject/state/state.json @@ -1,6 +1,6 @@ [ { - "project": "disabled", + "project": "gone", "getDoc": { "error": 410, "versionID": 1, From 63e28fede1a926999d7b212ee2c9baa8b8912d11 Mon Sep 17 00:00:00 2001 From: Michael Walker Date: Wed, 7 Feb 2018 10:10:16 +0000 Subject: [PATCH 11/16] Enable the "cannot clone a protected project" test --- .../WLGitBridgeIntegrationTest.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) 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 1afb80b8cb..15cdd5d5af 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 @@ -733,6 +733,24 @@ public class WLGitBridgeIntegrationTest { wlgb.stop(); } + @Test + public void cannotCloneAProtectedProject() throws IOException, GitAPIException, InterruptedException { + int gitBridgePort = 33883; + int mockServerPort = 3883; + + MockSnapshotServer server = new MockSnapshotServer(mockServerPort, getResource("/cannotCloneAProtectedProject").toFile()); + server.start(); + server.setState(states.get("cannotCloneAProtectedProject").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 + "/testproj.git", null, dir); + wlgb.stop(); + assertNotEquals(0, gitProcess.waitFor()); + } + @Test public void cannotCloneADisabledProject() throws IOException, GitAPIException, InterruptedException { int gitBridgePort = 33879; From 647cf24bb6bde5696ee0424fceb0d35d396eb39a Mon Sep 17 00:00:00 2001 From: Michael Walker Date: Wed, 7 Feb 2018 10:39:26 +0000 Subject: [PATCH 12/16] Use a List rather than hard-coding newlines --- .../base/MissingRepositoryException.java | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/MissingRepositoryException.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/MissingRepositoryException.java index 7c5258bf82..a39dbd4dfc 100644 --- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/MissingRepositoryException.java +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/MissingRepositoryException.java @@ -4,27 +4,35 @@ import com.google.gson.JsonElement; import uk.ac.ic.wlgitbridge.git.exception.SnapshotAPIException; import java.util.Arrays; +import java.util.ArrayList; import java.util.List; public class MissingRepositoryException extends SnapshotAPIException { - public static final String GENERIC_REASON = - "This Overleaf project currently has no git access.\n" + - "\n" + - "If this problem persists, please contact us."; + public static final List GENERIC_REASON = Arrays.asList( + "This Overleaf project currently has no git access.", + "", + "If this problem persists, please contact us." + ); - public static final String EXPORTED_TO_V2 = - "This Overleaf project has been moved to Overleaf v2, and git access is temporarily unsupported.\n" + - "\n" + - "See https://www.overleaf.com/help/342 for more information."; + public static final List EXPORTED_TO_V2 = Arrays.asList( + "This Overleaf project has been moved to Overleaf v2, and git access is temporarily unsupported.", + "", + "See https://www.overleaf.com/help/342 for more information." + ); - private String message = ""; + private List descriptionLines; public MissingRepositoryException() { + descriptionLines = new ArrayList(); } public MissingRepositoryException(String message) { - this.message = message; + this.descriptionLines = Arrays.asList(message); + } + + public MissingRepositoryException(List descriptionLines) { + this.descriptionLines = descriptionLines; } @Override @@ -32,12 +40,12 @@ public class MissingRepositoryException extends SnapshotAPIException { @Override public String getMessage() { - return message; + return String.join("\n", this.descriptionLines); } @Override public List getDescriptionLines() { - return Arrays.asList(getMessage()); + return this.descriptionLines; } } From 77e3bc0d3ba58d49a0f7f531dcdaab07c6d5b4aa Mon Sep 17 00:00:00 2001 From: Michael Walker Date: Wed, 7 Feb 2018 13:01:41 +0000 Subject: [PATCH 13/16] Remove unused constructor --- .../wlgitbridge/snapshot/base/MissingRepositoryException.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/MissingRepositoryException.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/MissingRepositoryException.java index a39dbd4dfc..b671a84d9c 100644 --- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/MissingRepositoryException.java +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/MissingRepositoryException.java @@ -27,10 +27,6 @@ public class MissingRepositoryException extends SnapshotAPIException { descriptionLines = new ArrayList(); } - public MissingRepositoryException(String message) { - this.descriptionLines = Arrays.asList(message); - } - public MissingRepositoryException(List descriptionLines) { this.descriptionLines = descriptionLines; } From 25ccfe28fea738f9dfc53f0d8ad8391522f093ec Mon Sep 17 00:00:00 2001 From: Michael Walker Date: Wed, 7 Feb 2018 13:27:19 +0000 Subject: [PATCH 14/16] Rename protected project test --- .../application/WLGitBridgeIntegrationTest.java | 10 +++++----- .../state/state.json | 0 2 files changed, 5 insertions(+), 5 deletions(-) rename services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/{cannotCloneAProtectedProject => cannotCloneAProtectedProjectWithoutAuthentication}/state/state.json (100%) 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 15cdd5d5af..6ed5b62d40 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 @@ -42,8 +42,8 @@ public class WLGitBridgeIntegrationTest { put("canCloneMultipleRepositories", new HashMap() {{ put("state", new SnapshotAPIStateBuilder(getResourceAsStream("/canCloneMultipleRepositories/state/state.json")).build()); }}); - put("cannotCloneAProtectedProject", new HashMap() {{ - put("state", new SnapshotAPIStateBuilder(getResourceAsStream("/cannotCloneAProtectedProject/state/state.json")).build()); + put("cannotCloneAProtectedProjectWithoutAuthentication", new HashMap() {{ + put("state", new SnapshotAPIStateBuilder(getResourceAsStream("/cannotCloneAProtectedProjectWithoutAuthentication/state/state.json")).build()); }}); put("cannotCloneADisabledProject", new HashMap() {{ put("state", new SnapshotAPIStateBuilder(getResourceAsStream("/cannotCloneADisabledProject/state/state.json")).build()); @@ -734,13 +734,13 @@ public class WLGitBridgeIntegrationTest { } @Test - public void cannotCloneAProtectedProject() throws IOException, GitAPIException, InterruptedException { + public void cannotCloneAProtectedProjectWithoutAuthentication() throws IOException, GitAPIException, InterruptedException { int gitBridgePort = 33883; int mockServerPort = 3883; - MockSnapshotServer server = new MockSnapshotServer(mockServerPort, getResource("/cannotCloneAProtectedProject").toFile()); + MockSnapshotServer server = new MockSnapshotServer(mockServerPort, getResource("/cannotCloneAProtectedProjectWithoutAuthentication").toFile()); server.start(); - server.setState(states.get("cannotCloneAProtectedProject").get("state")); + server.setState(states.get("cannotCloneAProtectedProjectWithoutAuthentication").get("state")); GitBridgeApp wlgb = new GitBridgeApp(new String[] { makeConfigFile(gitBridgePort, mockServerPort) }); diff --git a/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/cannotCloneAProtectedProject/state/state.json b/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/cannotCloneAProtectedProjectWithoutAuthentication/state/state.json similarity index 100% rename from services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/cannotCloneAProtectedProject/state/state.json rename to services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/cannotCloneAProtectedProjectWithoutAuthentication/state/state.json From 4c237e84f5e37eb157be657f3642c08e61ca8541 Mon Sep 17 00:00:00 2001 From: Michael Walker Date: Wed, 7 Feb 2018 13:27:31 +0000 Subject: [PATCH 15/16] Rename disabled project test --- .../application/WLGitBridgeIntegrationTest.java | 10 +++++----- .../state/state.json | 0 2 files changed, 5 insertions(+), 5 deletions(-) rename services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/{cannotCloneADisabledProject => cannotCloneA4xxProject}/state/state.json (100%) 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 6ed5b62d40..cd103fca5b 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 @@ -45,8 +45,8 @@ public class WLGitBridgeIntegrationTest { put("cannotCloneAProtectedProjectWithoutAuthentication", new HashMap() {{ put("state", new SnapshotAPIStateBuilder(getResourceAsStream("/cannotCloneAProtectedProjectWithoutAuthentication/state/state.json")).build()); }}); - put("cannotCloneADisabledProject", new HashMap() {{ - put("state", new SnapshotAPIStateBuilder(getResourceAsStream("/cannotCloneADisabledProject/state/state.json")).build()); + put("cannotCloneA4xxProject", new HashMap() {{ + put("state", new SnapshotAPIStateBuilder(getResourceAsStream("/cannotCloneA4xxProject/state/state.json")).build()); }}); put("cannotCloneAMissingProject", new HashMap() {{ put("state", new SnapshotAPIStateBuilder(getResourceAsStream("/cannotCloneAMissingProject/state/state.json")).build()); @@ -752,13 +752,13 @@ public class WLGitBridgeIntegrationTest { } @Test - public void cannotCloneADisabledProject() throws IOException, GitAPIException, InterruptedException { + public void cannotCloneA4xxProject() throws IOException, GitAPIException, InterruptedException { int gitBridgePort = 33879; int mockServerPort = 3879; - MockSnapshotServer server = new MockSnapshotServer(mockServerPort, getResource("/cannotCloneADisabledProject").toFile()); + MockSnapshotServer server = new MockSnapshotServer(mockServerPort, getResource("/cannotCloneA4xxProject").toFile()); server.start(); - server.setState(states.get("cannotCloneADisabledProject").get("state")); + server.setState(states.get("cannotCloneA4xxProject").get("state")); GitBridgeApp wlgb = new GitBridgeApp(new String[] { makeConfigFile(gitBridgePort, mockServerPort) }); diff --git a/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/cannotCloneADisabledProject/state/state.json b/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/cannotCloneA4xxProject/state/state.json similarity index 100% rename from services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/cannotCloneADisabledProject/state/state.json rename to services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/cannotCloneA4xxProject/state/state.json From 1ca63e1ba165f7f5a66f9ea898719a2ddbba2494 Mon Sep 17 00:00:00 2001 From: Michael Walker Date: Wed, 7 Feb 2018 14:25:04 +0000 Subject: [PATCH 16/16] Return a generic summary from MissingRepositoryException.getMessage --- .../wlgitbridge/snapshot/base/MissingRepositoryException.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/MissingRepositoryException.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/MissingRepositoryException.java index b671a84d9c..c39f6c2481 100644 --- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/MissingRepositoryException.java +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/base/MissingRepositoryException.java @@ -36,7 +36,7 @@ public class MissingRepositoryException extends SnapshotAPIException { @Override public String getMessage() { - return String.join("\n", this.descriptionLines); + return "no git access"; } @Override