From 9effe1630d97039b3e01cd9b58ed07e75be1d63c Mon Sep 17 00:00:00 2001 From: James Moger <james.moger@gitblit.com> Date: Mon, 25 Feb 2013 08:40:30 -0500 Subject: [PATCH] Merge pull request #75 from thefake/master --- src/com/gitblit/AccessRestrictionFilter.java | 77 ++++++++++++++++++++++++++++++++++---- 1 files changed, 69 insertions(+), 8 deletions(-) diff --git a/src/com/gitblit/AccessRestrictionFilter.java b/src/com/gitblit/AccessRestrictionFilter.java index a8d50b8..495d343 100644 --- a/src/com/gitblit/AccessRestrictionFilter.java +++ b/src/com/gitblit/AccessRestrictionFilter.java @@ -62,12 +62,29 @@ protected abstract String getUrlRequestAction(String url); /** + * Determine if a non-existing repository can be created using this filter. + * + * @return true if the filter allows repository creation + */ + protected abstract boolean isCreationAllowed(); + + /** + * Determine if the action may be executed on the repository. + * + * @param repository + * @param action + * @return true if the action may be performed + */ + protected abstract boolean isActionAllowed(RepositoryModel repository, String action); + + /** * Determine if the repository requires authentication. * * @param repository + * @param action * @return true if authentication required */ - protected abstract boolean requiresAuthentication(RepositoryModel repository); + protected abstract boolean requiresAuthentication(RepositoryModel repository, String action); /** * Determine if the user can access the repository and perform the specified @@ -80,6 +97,18 @@ */ protected abstract boolean canAccess(RepositoryModel repository, UserModel user, String action); + /** + * Allows a filter to create a repository, if one does not exist. + * + * @param user + * @param repository + * @param action + * @return the repository model, if it is created, null otherwise + */ + protected RepositoryModel createRepository(UserModel user, String repository, String action) { + return null; + } + /** * doFilter does the actual work of preprocessing the request to ensure that * the user may proceed. @@ -96,18 +125,51 @@ String fullUrl = getFullUrl(httpRequest); String repository = extractRepositoryName(fullUrl); + + if (GitBlit.self().isCollectingGarbage(repository)) { + logger.info(MessageFormat.format("ARF: Rejecting request for {0}, busy collecting garbage!", repository)); + httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN); + return; + } // Determine if the request URL is restricted String fullSuffix = fullUrl.substring(repository.length()); String urlRequestType = getUrlRequestAction(fullSuffix); + UserModel user = getUser(httpRequest); + // Load the repository model RepositoryModel model = GitBlit.self().getRepositoryModel(repository); if (model == null) { - // repository not found. send 404. - logger.info(MessageFormat.format("ARF: {0} ({1})", fullUrl, - HttpServletResponse.SC_NOT_FOUND)); - httpResponse.sendError(HttpServletResponse.SC_NOT_FOUND); + if (isCreationAllowed()) { + if (user == null) { + // challenge client to provide credentials for creation. send 401. + if (GitBlit.isDebugMode()) { + logger.info(MessageFormat.format("ARF: CREATE CHALLENGE {0}", fullUrl)); + } + httpResponse.setHeader("WWW-Authenticate", CHALLENGE); + httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED); + return; + } else { + // see if we can create a repository for this request + model = createRepository(user, repository, urlRequestType); + } + } + + if (model == null) { + // repository not found. send 404. + logger.info(MessageFormat.format("ARF: {0} ({1})", fullUrl, + HttpServletResponse.SC_NOT_FOUND)); + httpResponse.sendError(HttpServletResponse.SC_NOT_FOUND); + return; + } + } + + // Confirm that the action may be executed on the repository + if (!isActionAllowed(model, urlRequestType)) { + logger.info(MessageFormat.format("ARF: action {0} on {1} forbidden ({2})", + urlRequestType, model, HttpServletResponse.SC_FORBIDDEN)); + httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN); return; } @@ -121,13 +183,12 @@ // Gitblit must conditionally authenticate users per-repository so just // enabling http.receivepack is insufficient. AuthenticatedRequest authenticatedRequest = new AuthenticatedRequest(httpRequest); - UserModel user = getUser(httpRequest); if (user != null) { authenticatedRequest.setUser(user); } // BASIC authentication challenge and response processing - if (!StringUtils.isEmpty(urlRequestType) && requiresAuthentication(model)) { + if (!StringUtils.isEmpty(urlRequestType) && requiresAuthentication(model, urlRequestType)) { if (user == null) { // challenge client to provide credentials. send 401. if (GitBlit.isDebugMode()) { @@ -138,7 +199,7 @@ return; } else { // check user access for request - if (user.canAdmin || canAccess(model, user, urlRequestType)) { + if (user.canAdmin() || canAccess(model, user, urlRequestType)) { // authenticated request permitted. // pass processing to the restricted servlet. newSession(authenticatedRequest, httpResponse); -- Gitblit v1.9.1