From 13417cf9c6eec555b51da49742e47939d2f5715b Mon Sep 17 00:00:00 2001 From: James Moger <james.moger@gitblit.com> Date: Fri, 19 Oct 2012 22:47:33 -0400 Subject: [PATCH] Exclude submodules from zip downloads (issue 151) --- src/com/gitblit/GitFilter.java | 147 ++++++++++++++++++++++++++++++++++++------------ 1 files changed, 109 insertions(+), 38 deletions(-) diff --git a/src/com/gitblit/GitFilter.java b/src/com/gitblit/GitFilter.java index b310442..cfe4fe3 100644 --- a/src/com/gitblit/GitFilter.java +++ b/src/com/gitblit/GitFilter.java @@ -22,18 +22,32 @@ import com.gitblit.models.UserModel; import com.gitblit.utils.StringUtils; +/** + * The GitFilter is an AccessRestrictionFilter which ensures that Git client + * requests for push, clone, or view restricted repositories are authenticated + * and authorized. + * + * @author James Moger + * + */ public class GitFilter extends AccessRestrictionFilter { - protected final String gitReceivePack = "/git-receive-pack"; + protected static final String gitReceivePack = "/git-receive-pack"; - protected final String gitUploadPack = "/git-upload-pack"; + protected static final String gitUploadPack = "/git-upload-pack"; - protected final String[] suffixes = { gitReceivePack, gitUploadPack, "/info/refs", "/HEAD", + protected static final String[] suffixes = { gitReceivePack, gitUploadPack, "/info/refs", "/HEAD", "/objects" }; - @Override - protected String extractRepositoryName(String url) { - String repository = url; + /** + * Extract the repository name from the url. + * + * @param url + * @return repository name + */ + public static String getRepositoryName(String value) { + String repository = value; + // get the repository name from the url by finding a known url suffix for (String urlSuffix : suffixes) { if (repository.indexOf(urlSuffix) > -1) { repository = repository.substring(0, repository.indexOf(urlSuffix)); @@ -42,8 +56,26 @@ return repository; } + /** + * Extract the repository name from the url. + * + * @param url + * @return repository name + */ @Override - protected String getUrlRequestType(String suffix) { + protected String extractRepositoryName(String url) { + return GitFilter.getRepositoryName(url); + } + + /** + * Analyze the url and returns the action of the request. Return values are + * either "/git-receive-pack" or "/git-upload-pack". + * + * @param serverUrl + * @return action of the request + */ + @Override + protected String getUrlRequestAction(String suffix) { if (!StringUtils.isEmpty(suffix)) { if (suffix.startsWith(gitReceivePack)) { return gitReceivePack; @@ -53,48 +85,87 @@ return gitReceivePack; } else if (suffix.contains("?service=git-upload-pack")) { return gitUploadPack; + } else { + return gitUploadPack; } } return null; } - + + /** + * Determine if the repository can receive pushes. + * + * @param repository + * @param action + * @return true if the action may be performed + */ @Override - protected boolean requiresAuthentication(RepositoryModel repository) { - return repository.accessRestriction.atLeast(AccessRestrictionType.PUSH); + protected boolean isActionAllowed(RepositoryModel repository, String action) { + if (!StringUtils.isEmpty(action)) { + if (action.equals(gitReceivePack)) { + // Push request + if (!repository.isBare) { + logger.warn("Gitblit does not allow pushes to repositories with a working copy"); + return false; + } + } + } + return true; } + /** + * Determine if the repository requires authentication. + * + * @param repository + * @param action + * @return true if authentication required + */ @Override - protected boolean canAccess(RepositoryModel repository, UserModel user, String urlRequestType) { + protected boolean requiresAuthentication(RepositoryModel repository, String action) { + if (gitUploadPack.equals(action)) { + // send to client + return repository.accessRestriction.atLeast(AccessRestrictionType.CLONE); + } else if (gitReceivePack.equals(action)) { + // receive from client + return repository.accessRestriction.atLeast(AccessRestrictionType.PUSH); + } + return false; + } + + /** + * Determine if the user can access the repository and perform the specified + * action. + * + * @param repository + * @param user + * @param action + * @return true if user may execute the action on the repository + */ + @Override + protected boolean canAccess(RepositoryModel repository, UserModel user, String action) { if (!GitBlit.getBoolean(Keys.git.enableGitServlet, true)) { // Git Servlet disabled return false; - } - if (repository.isFrozen || repository.accessRestriction.atLeast(AccessRestrictionType.PUSH)) { - boolean authorizedUser = user.canAccessRepository(repository.name); - if (urlRequestType.equals(gitReceivePack)) { - // Push request - if (!repository.isFrozen && authorizedUser) { - // clone-restricted or push-authorized - return true; - } else { - // user is unauthorized to push to this repository - logger.warn(MessageFormat.format("user {0} is not authorized to push to {1}", - user.username, repository)); - return false; - } - } else if (urlRequestType.equals(gitUploadPack)) { - // Clone request - boolean cloneRestricted = repository.accessRestriction - .atLeast(AccessRestrictionType.CLONE); - if (!cloneRestricted || (cloneRestricted && authorizedUser)) { - // push-restricted or clone-authorized - return true; - } else { - // user is unauthorized to clone this repository - logger.warn(MessageFormat.format("user {0} is not authorized to clone {1}", - user.username, repository)); - return false; - } + } + if (action.equals(gitReceivePack)) { + // Push request + if (user.canPush(repository)) { + return true; + } else { + // user is unauthorized to push to this repository + logger.warn(MessageFormat.format("user {0} is not authorized to push to {1}", + user.username, repository)); + return false; + } + } else if (action.equals(gitUploadPack)) { + // Clone request + if (user.canClone(repository)) { + return true; + } else { + // user is unauthorized to clone this repository + logger.warn(MessageFormat.format("user {0} is not authorized to clone {1}", + user.username, repository)); + return false; } } return true; -- Gitblit v1.9.1