mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-06-01 05:11:34 +02:00
Better javadoc, improve handling of submodules
This commit is contained in:
@@ -678,7 +678,7 @@ public class Bridge {
|
||||
private void makeCommitsFromSnapshots(
|
||||
ProjectRepo repo,
|
||||
Collection<Snapshot> snapshots
|
||||
) throws IOException, SizeLimitExceededException {
|
||||
) throws IOException, GitUserException {
|
||||
String name = repo.getProjectName();
|
||||
for (Snapshot snapshot : snapshots) {
|
||||
Map<String, RawFile> fileTable = repo.getFiles();
|
||||
|
||||
@@ -9,6 +9,7 @@ import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
|
||||
import uk.ac.ic.wlgitbridge.data.filestore.GitDirectoryContents;
|
||||
import uk.ac.ic.wlgitbridge.data.filestore.RawFile;
|
||||
import uk.ac.ic.wlgitbridge.git.exception.GitUserException;
|
||||
import uk.ac.ic.wlgitbridge.git.exception.SizeLimitExceededException;
|
||||
import uk.ac.ic.wlgitbridge.git.util.RepositoryObjectTreeWalker;
|
||||
import uk.ac.ic.wlgitbridge.util.Log;
|
||||
@@ -62,7 +63,7 @@ public class GitProjectRepo implements ProjectRepo {
|
||||
|
||||
@Override
|
||||
public Map<String, RawFile> getFiles()
|
||||
throws IOException, SizeLimitExceededException {
|
||||
throws IOException, GitUserException {
|
||||
Preconditions.checkState(repository.isPresent());
|
||||
return new RepositoryObjectTreeWalker(
|
||||
repository.get()
|
||||
|
||||
@@ -2,6 +2,7 @@ package uk.ac.ic.wlgitbridge.bridge.repo;
|
||||
|
||||
import uk.ac.ic.wlgitbridge.data.filestore.GitDirectoryContents;
|
||||
import uk.ac.ic.wlgitbridge.data.filestore.RawFile;
|
||||
import uk.ac.ic.wlgitbridge.git.exception.GitUserException;
|
||||
import uk.ac.ic.wlgitbridge.git.exception.SizeLimitExceededException;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -24,7 +25,7 @@ public interface ProjectRepo {
|
||||
) throws IOException;
|
||||
|
||||
Map<String, RawFile> getFiles(
|
||||
) throws IOException, SizeLimitExceededException;
|
||||
) throws IOException, GitUserException;
|
||||
|
||||
Collection<String> commitAndGetMissing(
|
||||
GitDirectoryContents gitDirectoryContents
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package uk.ac.ic.wlgitbridge.git.exception;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class InvalidGitRepository extends GitUserException {
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return "invalid git repo";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getDescriptionLines() {
|
||||
return Arrays.asList(
|
||||
"Your Git repository is invalid.",
|
||||
"If your project contains a Git submodule,",
|
||||
"please remove it and try again."
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -74,7 +74,7 @@ public class WriteLatexPutHook implements PreReceiveHook {
|
||||
);
|
||||
} catch (OutOfDateException e) {
|
||||
receiveCommand.setResult(Result.REJECTED_NONFASTFORWARD);
|
||||
} catch (SnapshotPostException e) {
|
||||
} catch (GitUserException e) {
|
||||
handleSnapshotPostException(receivePack, receiveCommand, e);
|
||||
} catch (Throwable t) {
|
||||
Log.warn("Throwable on pre receive: ", t);
|
||||
@@ -90,7 +90,7 @@ public class WriteLatexPutHook implements PreReceiveHook {
|
||||
private void handleSnapshotPostException(
|
||||
ReceivePack receivePack,
|
||||
ReceiveCommand receiveCommand,
|
||||
SnapshotPostException e
|
||||
GitUserException e
|
||||
) {
|
||||
String message = e.getMessage();
|
||||
receivePack.sendError(message);
|
||||
|
||||
@@ -8,6 +8,7 @@ import org.eclipse.jgit.treewalk.TreeWalk;
|
||||
import uk.ac.ic.wlgitbridge.data.filestore.RawDirectory;
|
||||
import uk.ac.ic.wlgitbridge.data.filestore.RawFile;
|
||||
import uk.ac.ic.wlgitbridge.data.filestore.RepositoryFile;
|
||||
import uk.ac.ic.wlgitbridge.git.exception.InvalidGitRepository;
|
||||
import uk.ac.ic.wlgitbridge.git.exception.SizeLimitExceededException;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -44,7 +45,7 @@ public class RepositoryObjectTreeWalker {
|
||||
}
|
||||
|
||||
public RawDirectory getDirectoryContents(
|
||||
) throws IOException, SizeLimitExceededException {
|
||||
) throws IOException, SizeLimitExceededException, InvalidGitRepository {
|
||||
return new RawDirectory(walkGitObjectTree());
|
||||
}
|
||||
|
||||
@@ -63,7 +64,7 @@ public class RepositoryObjectTreeWalker {
|
||||
}
|
||||
|
||||
private Map<String, RawFile> walkGitObjectTree(
|
||||
) throws IOException, SizeLimitExceededException {
|
||||
) throws IOException, SizeLimitExceededException, InvalidGitRepository {
|
||||
Map<String, RawFile> fileContentsTable = new HashMap<>();
|
||||
if (treeWalk == null) {
|
||||
return fileContentsTable;
|
||||
@@ -71,9 +72,13 @@ public class RepositoryObjectTreeWalker {
|
||||
while (treeWalk.next()) {
|
||||
String path = treeWalk.getPathString();
|
||||
|
||||
ObjectId objectId = treeWalk.getObjectId(0);
|
||||
if (!repository.hasObject(objectId)) {
|
||||
throw new InvalidGitRepository();
|
||||
}
|
||||
try {
|
||||
byte[] content = repository.open(
|
||||
treeWalk.getObjectId(0)
|
||||
objectId
|
||||
).getBytes();
|
||||
fileContentsTable.put(path, new RepositoryFile(path, content));
|
||||
} catch (LargeObjectException e) {
|
||||
|
||||
@@ -8,6 +8,7 @@ import uk.ac.ic.wlgitbridge.application.config.Oauth2;
|
||||
import uk.ac.ic.wlgitbridge.snapshot.base.ForbiddenException;
|
||||
import uk.ac.ic.wlgitbridge.snapshot.getdoc.GetDocRequest;
|
||||
import uk.ac.ic.wlgitbridge.util.Instance;
|
||||
import uk.ac.ic.wlgitbridge.util.Log;
|
||||
import uk.ac.ic.wlgitbridge.util.Util;
|
||||
|
||||
import javax.servlet.*;
|
||||
@@ -34,6 +35,17 @@ public class Oauth2Filter implements Filter {
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) {}
|
||||
|
||||
/**
|
||||
* The original request from git will not contain the Authorization header.
|
||||
*
|
||||
* So, for projects that need auth, we return 401. Git will swallow this
|
||||
* and prompt the user for user/pass, and then make a brand new request.
|
||||
* @param servletRequest
|
||||
* @param servletResponse
|
||||
* @param filterChain
|
||||
* @throws IOException
|
||||
* @throws ServletException
|
||||
*/
|
||||
@Override
|
||||
public void doFilter(
|
||||
ServletRequest servletRequest,
|
||||
@@ -44,24 +56,29 @@ public class Oauth2Filter implements Filter {
|
||||
((Request) servletRequest).getRequestURI().split("/")[1],
|
||||
".git"
|
||||
);
|
||||
Log.info("[{}] Checking if auth needed", project);
|
||||
GetDocRequest doc = new GetDocRequest(project);
|
||||
doc.request();
|
||||
try {
|
||||
doc.getResult();
|
||||
} catch (ForbiddenException e) {
|
||||
Log.info("[{}] Auth needed", project);
|
||||
getAndInjectCredentials(
|
||||
project,
|
||||
servletRequest,
|
||||
servletResponse,
|
||||
filterChain
|
||||
);
|
||||
return;
|
||||
}
|
||||
Log.info("[{}] Auth not needed");
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
}
|
||||
|
||||
// TODO: this is ridiculous. Check for error cases first, then return/throw
|
||||
// TODO: also, use an Optional credential, since we treat it as optional
|
||||
private void getAndInjectCredentials(
|
||||
String projectName,
|
||||
ServletRequest servletRequest,
|
||||
ServletResponse servletResponse,
|
||||
FilterChain filterChain
|
||||
@@ -71,6 +88,7 @@ public class Oauth2Filter implements Filter {
|
||||
|
||||
String authHeader = request.getHeader("Authorization");
|
||||
if (authHeader != null) {
|
||||
Log.info("[{}] Authorization header present");
|
||||
StringTokenizer st = new StringTokenizer(authHeader);
|
||||
if (st.hasMoreTokens()) {
|
||||
String basic = st.nextToken();
|
||||
@@ -100,10 +118,9 @@ public class Oauth2Filter implements Filter {
|
||||
oauth2.getOauth2ClientID(),
|
||||
oauth2.getOauth2ClientSecret()
|
||||
)
|
||||
)
|
||||
.execute().getAccessToken();
|
||||
).execute().getAccessToken();
|
||||
} catch (TokenResponseException e) {
|
||||
unauthorized(response);
|
||||
unauthorized(projectName, response);
|
||||
return;
|
||||
}
|
||||
final Credential cred = new Credential.Builder(
|
||||
@@ -118,7 +135,7 @@ public class Oauth2Filter implements Filter {
|
||||
servletResponse
|
||||
);
|
||||
} else {
|
||||
unauthorized(response);
|
||||
unauthorized(projectName, response);
|
||||
}
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new Error("Couldn't retrieve authentication", e);
|
||||
@@ -126,7 +143,7 @@ public class Oauth2Filter implements Filter {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unauthorized(response);
|
||||
unauthorized(projectName, response);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,8 +151,10 @@ public class Oauth2Filter implements Filter {
|
||||
public void destroy() {}
|
||||
|
||||
private void unauthorized(
|
||||
String projectName,
|
||||
ServletResponse servletResponse
|
||||
) throws IOException {
|
||||
Log.info("[{}] Unauthorized", projectName);
|
||||
HttpServletResponse response = (HttpServletResponse) servletResponse;
|
||||
response.setContentType("text/plain");
|
||||
response.setHeader("WWW-Authenticate", "Basic realm=\"Git Bridge\"");
|
||||
|
||||
@@ -39,6 +39,13 @@ public abstract class SnapshotAPIRequest<T extends Result> extends Request<T> {
|
||||
).intercept(request1);
|
||||
oauth2.intercept(request1);
|
||||
});
|
||||
} else {
|
||||
request.setInterceptor(request1 -> {
|
||||
new BasicAuthentication(
|
||||
USERNAME,
|
||||
PASSWORD
|
||||
).intercept(request1);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user