mirror of
https://github.com/overleaf/overleaf.git
synced 2025-04-13 03:54:26 +00:00
(fix #8) Add better error message for 403 protected projects with integration test and support.
This commit is contained in:
parent
d9f5644b7b
commit
ac50c26aef
10 changed files with 291 additions and 19 deletions
|
@ -1,5 +1,6 @@
|
|||
package uk.ac.ic.wlgitbridge.bridge;
|
||||
|
||||
import org.eclipse.jgit.transport.ServiceMayNotContinueException;
|
||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
|
||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.getdoc.exception.InvalidProjectException;
|
||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.push.exception.InvalidPostbackKeyException;
|
||||
|
@ -19,7 +20,7 @@ public interface WriteLatexDataSource {
|
|||
void unlockForProject(String projectName);
|
||||
|
||||
/* Called by request thread. */
|
||||
public boolean repositoryExists(String projectName) throws FailedConnectionException;
|
||||
public boolean repositoryExists(String projectName) throws ServiceMayNotContinueException;
|
||||
public List<WritableRepositoryContents> getWritableRepositories(String projectName) throws FailedConnectionException, InvalidProjectException;
|
||||
public void putDirectoryContentsToProjectWithName(String projectName, RawDirectoryContents directoryContents, String hostname) throws SnapshotPostException, IOException, FailedConnectionException;
|
||||
|
||||
|
|
|
@ -41,7 +41,6 @@ public class WLRepositoryResolver implements RepositoryResolver<HttpServletReque
|
|||
cannot occur
|
||||
*/
|
||||
} catch (ServiceMayNotContinueException e) { /* Such as FailedConnectionException */
|
||||
Util.printStackTrace(e);
|
||||
throw e;
|
||||
} catch (RuntimeException e) {
|
||||
Util.printStackTrace(e);
|
||||
|
|
|
@ -41,7 +41,7 @@ public class SnapshotAPIState {
|
|||
public SnapshotAPIState() {
|
||||
|
||||
getDoc = new HashMap<String, SnapshotGetDocResult>();
|
||||
getDoc.put("1826rqgsdb", new SnapshotGetDocResult(243, "2014-11-30T18:40:58Z", "jdleesmiller+1@gmail.com", "John+1"));
|
||||
getDoc.put("1826rqgsdb", new SnapshotGetDocResult(null, 243, "2014-11-30T18:40:58Z", "jdleesmiller+1@gmail.com", "John+1"));
|
||||
|
||||
getSavedVers = new HashMap<String, SnapshotGetSavedVersResult>();
|
||||
List<SnapshotInfo> savedVers = new LinkedList<SnapshotInfo>();
|
||||
|
|
|
@ -59,7 +59,8 @@ public class SnapshotAPIStateBuilder {
|
|||
|
||||
private void addGetDocForProject(String projectName, JsonObject jsonGetDoc) {
|
||||
getDoc.put(projectName,
|
||||
new SnapshotGetDocResult(jsonGetDoc.get("versionID").getAsInt(),
|
||||
new SnapshotGetDocResult(jsonGetDoc.get("error"),
|
||||
jsonGetDoc.get("versionID").getAsInt(),
|
||||
jsonGetDoc.get("createdAt").getAsString(),
|
||||
jsonGetDoc.get("email").getAsString(),
|
||||
jsonGetDoc.get("name").getAsString()));
|
||||
|
|
|
@ -10,6 +10,7 @@ import uk.ac.ic.wlgitbridge.writelatex.api.request.getforversion.SnapshotGetForV
|
|||
import uk.ac.ic.wlgitbridge.writelatex.api.request.getforversion.SnapshotGetForVersionResult;
|
||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.getsavedvers.SnapshotGetSavedVersRequest;
|
||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.getsavedvers.SnapshotInfo;
|
||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.push.exception.SnapshotPostException;
|
||||
import uk.ac.ic.wlgitbridge.writelatex.model.Snapshot;
|
||||
import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreAPI;
|
||||
import uk.ac.ic.wlgitbridge.writelatex.model.db.PersistentStoreSource;
|
||||
|
@ -93,7 +94,12 @@ public class SnapshotFetcher implements PersistentStoreSource {
|
|||
|
||||
private int putLatestDoc(SnapshotGetDocRequest getDoc, Set<Integer> fetchedIDs, Map<Integer, SnapshotInfo> fetchedSnapshotInfos) throws FailedConnectionException, InvalidProjectException {
|
||||
SnapshotGetDocResult result = getDoc.getResult();
|
||||
int latestVersionID = result.getVersionID();
|
||||
int latestVersionID = 0;
|
||||
try {
|
||||
latestVersionID = result.getVersionID();
|
||||
} catch (SnapshotPostException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
putFetchedResult(new SnapshotInfo(latestVersionID, result.getCreatedAt(), result.getName(), result.getEmail()), fetchedIDs, fetchedSnapshotInfos);
|
||||
return latestVersionID;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package uk.ac.ic.wlgitbridge.writelatex;
|
||||
|
||||
import org.eclipse.jgit.transport.ServiceMayNotContinueException;
|
||||
import uk.ac.ic.wlgitbridge.bridge.CandidateSnapshot;
|
||||
import uk.ac.ic.wlgitbridge.bridge.RawDirectoryContents;
|
||||
import uk.ac.ic.wlgitbridge.bridge.WritableRepositoryContents;
|
||||
|
@ -43,7 +44,7 @@ public class WriteLatexAPI implements WriteLatexDataSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean repositoryExists(String projectName) throws FailedConnectionException {
|
||||
public boolean repositoryExists(String projectName) throws ServiceMayNotContinueException {
|
||||
lockForProject(projectName);
|
||||
SnapshotGetDocRequest snapshotGetDocRequest = new SnapshotGetDocRequest(projectName);
|
||||
snapshotGetDocRequest.request();
|
||||
|
@ -53,6 +54,8 @@ public class WriteLatexAPI implements WriteLatexDataSource {
|
|||
return false;
|
||||
} catch (FailedConnectionException e) {
|
||||
throw e;
|
||||
} catch (SnapshotPostException e) {
|
||||
throw new ServiceMayNotContinueException(e.getMessage());
|
||||
} finally {
|
||||
unlockForProject(projectName);
|
||||
}
|
||||
|
|
|
@ -6,24 +6,32 @@ import uk.ac.ic.wlgitbridge.writelatex.api.request.base.Request;
|
|||
import uk.ac.ic.wlgitbridge.writelatex.api.request.base.Result;
|
||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
|
||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.getdoc.exception.InvalidProjectException;
|
||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.getdoc.exception.ProtectedProjectException;
|
||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.push.exception.SnapshotPostException;
|
||||
|
||||
/**
|
||||
* Created by Winston on 06/11/14.
|
||||
*/
|
||||
public class SnapshotGetDocResult extends Result {
|
||||
|
||||
private int error;
|
||||
private int versionID;
|
||||
private String createdAt;
|
||||
private String name;
|
||||
private String email;
|
||||
|
||||
private InvalidProjectException invalidProjectException;
|
||||
private SnapshotPostException exception;
|
||||
|
||||
public SnapshotGetDocResult(Request request, JsonElement json) throws FailedConnectionException {
|
||||
super(request, json);
|
||||
}
|
||||
|
||||
public SnapshotGetDocResult(int versionID, String createdAt, String email, String name) {
|
||||
public SnapshotGetDocResult(JsonElement error, int versionID, String createdAt, String email, String name) {
|
||||
if (error == null) {
|
||||
this.error = -1;
|
||||
} else {
|
||||
this.error = error.getAsInt();
|
||||
}
|
||||
this.versionID = versionID;
|
||||
this.createdAt = createdAt;
|
||||
this.name = name;
|
||||
|
@ -33,20 +41,40 @@ public class SnapshotGetDocResult extends Result {
|
|||
@Override
|
||||
public JsonElement toJson() {
|
||||
JsonObject jsonThis = new JsonObject();
|
||||
jsonThis.addProperty("latestVerId", versionID);
|
||||
jsonThis.addProperty("latestVerAt", createdAt);
|
||||
JsonObject latestVerBy = new JsonObject();
|
||||
latestVerBy.addProperty("email", email);
|
||||
latestVerBy.addProperty("name", name);
|
||||
jsonThis.add("latestVerBy", latestVerBy);
|
||||
if (error == -1) {
|
||||
jsonThis.addProperty("latestVerId", versionID);
|
||||
jsonThis.addProperty("latestVerAt", createdAt);
|
||||
JsonObject latestVerBy = new JsonObject();
|
||||
latestVerBy.addProperty("email", email);
|
||||
latestVerBy.addProperty("name", name);
|
||||
jsonThis.add("latestVerBy", latestVerBy);
|
||||
} else {
|
||||
jsonThis.addProperty("status", error);
|
||||
String message;
|
||||
if (error == 403) {
|
||||
message = "Forbidden";
|
||||
} else {
|
||||
message = "Not Found";
|
||||
}
|
||||
jsonThis.addProperty("message", message);
|
||||
}
|
||||
return jsonThis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromJSON(JsonElement json) {
|
||||
JsonObject jsonObject = json.getAsJsonObject();
|
||||
if (jsonObject.has("status") && jsonObject.get("status").getAsInt() == 404) {
|
||||
invalidProjectException = new InvalidProjectException();
|
||||
if (jsonObject.has("status")) {
|
||||
switch (jsonObject.get("status").getAsInt()) {
|
||||
case 403:
|
||||
exception = new ProtectedProjectException();
|
||||
break;
|
||||
case 404:
|
||||
exception = new InvalidProjectException();
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("unknown get doc error code");
|
||||
}
|
||||
} else {
|
||||
versionID = jsonObject.get("latestVerId").getAsInt();
|
||||
createdAt = jsonObject.get("latestVerAt").getAsString();
|
||||
|
@ -62,9 +90,9 @@ public class SnapshotGetDocResult extends Result {
|
|||
}
|
||||
}
|
||||
|
||||
public int getVersionID() throws InvalidProjectException {
|
||||
if (invalidProjectException != null) {
|
||||
throw invalidProjectException;
|
||||
public int getVersionID() throws SnapshotPostException {
|
||||
if (exception != null) {
|
||||
throw exception;
|
||||
}
|
||||
return versionID;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package uk.ac.ic.wlgitbridge.writelatex.api.request.getdoc.exception;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import uk.ac.ic.wlgitbridge.writelatex.api.request.push.exception.SnapshotPostException;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Winston on 20/02/15.
|
||||
*/
|
||||
public class ProtectedProjectException extends SnapshotPostException {
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return "Your project is protected, and can't be cloned (yet).";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getDescriptionLines() {
|
||||
return Arrays.asList("You can't currently clone a protected project.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromJSON(JsonElement json) {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -2,6 +2,7 @@ package uk.ac.ic.wlgitbridge;
|
|||
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.eclipse.jgit.api.errors.TransportException;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
@ -17,7 +18,9 @@ import java.nio.file.Paths;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* Created by Winston on 11/01/15.
|
||||
|
@ -40,6 +43,9 @@ public class WLGitBridgeIntegrationTest {
|
|||
put("base", new SnapshotAPIStateBuilder(getResourceAsStream("/canPullADeletedTexFile/base/state.json")).build());
|
||||
put("withDeletedTexFile", new SnapshotAPIStateBuilder(getResourceAsStream("/canPullADeletedTexFile/withDeletedTexFile/state.json")).build());
|
||||
}});
|
||||
put("cannotCloneAProtectedProject", new HashMap<String, SnapshotAPIState>() {{
|
||||
put("state", new SnapshotAPIStateBuilder(getResourceAsStream("/cannotCloneAProtectedProject/state/state.json")).build());
|
||||
}});
|
||||
}};
|
||||
|
||||
@Rule
|
||||
|
@ -138,6 +144,32 @@ public class WLGitBridgeIntegrationTest {
|
|||
assertTrue(FileUtil.gitDirectoriesAreEqual(getResource("/canPullADeletedTexFile/withDeletedTexFile/testproj"), git.toPath()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cannotCloneAProtectedProject() throws IOException, GitAPIException {
|
||||
MockSnapshotServer server = new MockSnapshotServer(3861, getResource("/cannotCloneAProtectedProject").toFile());
|
||||
server.start();
|
||||
server.setState(states.get("cannotCloneAProtectedProject").get("state"));
|
||||
WLGitBridgeApplication wlgb = new WLGitBridgeApplication(new String[] {
|
||||
makeConfigFile(33861, 3861)
|
||||
});
|
||||
wlgb.run();
|
||||
folder.create();
|
||||
File git = folder.newFolder();
|
||||
try {
|
||||
Git.cloneRepository()
|
||||
.setURI("http://127.0.0.1:33861/protected.git")
|
||||
.setDirectory(git)
|
||||
.call()
|
||||
.close();
|
||||
} catch (TransportException e) {
|
||||
assertEquals("http://127.0.0.1:33861/protected.git: Your project is protected, and can't be cloned (yet).", e.getMessage());
|
||||
return;
|
||||
} finally {
|
||||
wlgb.stop();
|
||||
}
|
||||
fail();
|
||||
}
|
||||
|
||||
private String makeConfigFile(int port, int apiPort) throws IOException {
|
||||
File wlgb = folder.newFolder();
|
||||
File config = folder.newFile();
|
||||
|
|
|
@ -0,0 +1,173 @@
|
|||
[
|
||||
{
|
||||
"project": "protected",
|
||||
"getDoc": {
|
||||
"error": 403,
|
||||
"versionID": 1,
|
||||
"createdAt": "2014-11-30T18:40:58Z",
|
||||
"email": "jdleesmiller+1@gmail.com",
|
||||
"name": "John+1"
|
||||
},
|
||||
"getSavedVers": [
|
||||
{
|
||||
"versionID": 1,
|
||||
"comment": "added more info on doc GET and error details",
|
||||
"email": "jdleesmiller+1@gmail.com",
|
||||
"name": "John+1",
|
||||
"createdAt": "2014-11-30T18:47:01Z"
|
||||
}
|
||||
],
|
||||
"getForVers": [
|
||||
{
|
||||
"versionID": 1,
|
||||
"srcs": [
|
||||
{
|
||||
"content": "contentchanged\n",
|
||||
"path": "main.tex"
|
||||
},
|
||||
{
|
||||
"content": "This text is from another file.",
|
||||
"path": "foo/bar/test.tex"
|
||||
}
|
||||
],
|
||||
"atts": []
|
||||
}
|
||||
],
|
||||
"push": "success",
|
||||
"postback": {
|
||||
"type": "outOfDate"
|
||||
}
|
||||
},
|
||||
{
|
||||
"project": "invalidFiles",
|
||||
"getDoc": {
|
||||
"versionID": 1,
|
||||
"createdAt": "2014-11-30T18:40:58Z",
|
||||
"email": "jdleesmiller+1@gmail.com",
|
||||
"name": "John+1"
|
||||
},
|
||||
"getSavedVers": [
|
||||
{
|
||||
"versionID": 1,
|
||||
"comment": "added more info on doc GET and error details",
|
||||
"email": "jdleesmiller+1@gmail.com",
|
||||
"name": "John+1",
|
||||
"createdAt": "2014-11-30T18:47:01Z"
|
||||
}
|
||||
],
|
||||
"getForVers": [
|
||||
{
|
||||
"versionID": 1,
|
||||
"srcs": [
|
||||
{
|
||||
"content": "changedñcontent\n",
|
||||
"path": "main.tex"
|
||||
},
|
||||
{
|
||||
"content": "This text is from another file.",
|
||||
"path": "foo/bar/test.tex"
|
||||
}
|
||||
],
|
||||
"atts": []
|
||||
}
|
||||
],
|
||||
"push": "success",
|
||||
"postback": {
|
||||
"type": "invalidFiles",
|
||||
"errors": [
|
||||
{
|
||||
"file": "file.invalid",
|
||||
"state": "error"
|
||||
},
|
||||
{
|
||||
"file": "virus.exe",
|
||||
"state": "disallowed"
|
||||
},
|
||||
{
|
||||
"file": "my image.jpg",
|
||||
"state": "unclean_name",
|
||||
"cleanFile": "my_image.jpg"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"project": "invalidProject",
|
||||
"getDoc": {
|
||||
"versionID": 1,
|
||||
"createdAt": "2014-11-30T18:40:58Z",
|
||||
"email": "jdleesmiller+1@gmail.com",
|
||||
"name": "John+1"
|
||||
},
|
||||
"getSavedVers": [
|
||||
{
|
||||
"versionID": 1,
|
||||
"comment": "added more info on doc GET and error details",
|
||||
"email": "jdleesmiller+1@gmail.com",
|
||||
"name": "John+1",
|
||||
"createdAt": "2014-11-30T18:47:01Z"
|
||||
}
|
||||
],
|
||||
"getForVers": [
|
||||
{
|
||||
"versionID": 1,
|
||||
"srcs": [
|
||||
{
|
||||
"content": "content\n",
|
||||
"path": "main.tex"
|
||||
},
|
||||
{
|
||||
"content": "This text is from another file.",
|
||||
"path": "foo/bar/test.tex"
|
||||
}
|
||||
],
|
||||
"atts": []
|
||||
}
|
||||
],
|
||||
"push": "success",
|
||||
"postback": {
|
||||
"type": "invalidProject",
|
||||
"errors": [
|
||||
"No main.tex file exists."
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"project": "error",
|
||||
"getDoc": {
|
||||
"versionID": 1,
|
||||
"createdAt": "2014-11-30T18:40:58Z",
|
||||
"email": "jdleesmiller+1@gmail.com",
|
||||
"name": "John+1"
|
||||
},
|
||||
"getSavedVers": [
|
||||
{
|
||||
"versionID": 1,
|
||||
"comment": "added more info on doc GET and error details",
|
||||
"email": "jdleesmiller+1@gmail.com",
|
||||
"name": "John+1",
|
||||
"createdAt": "2014-11-30T18:47:01Z"
|
||||
}
|
||||
],
|
||||
"getForVers": [
|
||||
{
|
||||
"versionID": 1,
|
||||
"srcs": [
|
||||
{
|
||||
"content": "content\n",
|
||||
"path": "main.tex"
|
||||
},
|
||||
{
|
||||
"content": "This text is from another file.",
|
||||
"path": "foo/bar/test.tex"
|
||||
}
|
||||
],
|
||||
"atts": []
|
||||
}
|
||||
],
|
||||
"push": "success",
|
||||
"postback": {
|
||||
"type": "error"
|
||||
}
|
||||
}
|
||||
]
|
Loading…
Add table
Reference in a new issue