From a502d96a860456ec5e8c96761db70f7cabb74751 Mon Sep 17 00:00:00 2001 From: Paul Martin <paul@paulsputer.com> Date: Sat, 30 Apr 2016 04:19:14 -0400 Subject: [PATCH] Merge pull request #1073 from gitblit/1062-DocEditorUpdates --- src/main/java/com/gitblit/servlet/AccessRestrictionFilter.java | 63 ++++++++++++++++++++++++++----- 1 files changed, 52 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/gitblit/servlet/AccessRestrictionFilter.java b/src/main/java/com/gitblit/servlet/AccessRestrictionFilter.java index 6d2efa4..e1d76db 100644 --- a/src/main/java/com/gitblit/servlet/AccessRestrictionFilter.java +++ b/src/main/java/com/gitblit/servlet/AccessRestrictionFilter.java @@ -17,6 +17,8 @@ import java.io.IOException; import java.text.MessageFormat; +import java.util.Collections; +import java.util.Iterator; import javax.servlet.FilterChain; import javax.servlet.ServletException; @@ -84,16 +86,17 @@ * * @return true if the filter allows repository creation */ - protected abstract boolean isCreationAllowed(); + protected abstract boolean isCreationAllowed(String action); /** * Determine if the action may be executed on the repository. * * @param repository * @param action + * @param method * @return true if the action may be performed */ - protected abstract boolean isActionAllowed(RepositoryModel repository, String action); + protected abstract boolean isActionAllowed(RepositoryModel repository, String action, String method); /** * Determine if the repository requires authentication. @@ -102,7 +105,7 @@ * @param action * @return true if authentication required */ - protected abstract boolean requiresAuthentication(RepositoryModel repository, String action); + protected abstract boolean requiresAuthentication(RepositoryModel repository, String action, String method); /** * Determine if the user can access the repository and perform the specified @@ -126,7 +129,27 @@ protected RepositoryModel createRepository(UserModel user, String repository, String action) { return null; } - + + /** + * Allows authentication header to be altered based on the action requested + * Default is WWW-Authenticate + * @param httpRequest + * @param action + * @return authentication type header + */ + protected String getAuthenticationHeader(HttpServletRequest httpRequest, String action) { + return "WWW-Authenticate"; + } + + /** + * Allows request headers to be used as part of filtering + * @param request + * @return true (default) if headers are valid, false otherwise + */ + protected boolean hasValidRequestHeader(String action, HttpServletRequest request) { + return true; + } + /** * doFilter does the actual work of preprocessing the request to ensure that * the user may proceed. @@ -143,6 +166,10 @@ String fullUrl = getFullUrl(httpRequest); String repository = extractRepositoryName(fullUrl); + if (StringUtils.isEmpty(repository)) { + httpResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST); + return; + } if (repositoryManager.isCollectingGarbage(repository)) { logger.info(MessageFormat.format("ARF: Rejecting request for {0}, busy collecting garbage!", repository)); @@ -159,13 +186,14 @@ // Load the repository model RepositoryModel model = repositoryManager.getRepositoryModel(repository); if (model == null) { - if (isCreationAllowed()) { + if (isCreationAllowed(urlRequestType)) { if (user == null) { // challenge client to provide credentials for creation. send 401. if (runtimeManager.isDebugMode()) { logger.info(MessageFormat.format("ARF: CREATE CHALLENGE {0}", fullUrl)); } - httpResponse.setHeader("WWW-Authenticate", CHALLENGE); + + httpResponse.setHeader(getAuthenticationHeader(httpRequest, urlRequestType), CHALLENGE); httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED); return; } else { @@ -184,7 +212,7 @@ } // Confirm that the action may be executed on the repository - if (!isActionAllowed(model, urlRequestType)) { + if (!isActionAllowed(model, urlRequestType, httpRequest.getMethod())) { logger.info(MessageFormat.format("ARF: action {0} on {1} forbidden ({2})", urlRequestType, model, HttpServletResponse.SC_FORBIDDEN)); httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN); @@ -206,13 +234,13 @@ } // BASIC authentication challenge and response processing - if (!StringUtils.isEmpty(urlRequestType) && requiresAuthentication(model, urlRequestType)) { + if (!StringUtils.isEmpty(urlRequestType) && requiresAuthentication(model, urlRequestType, httpRequest.getMethod())) { if (user == null) { // challenge client to provide credentials. send 401. if (runtimeManager.isDebugMode()) { logger.info(MessageFormat.format("ARF: CHALLENGE {0}", fullUrl)); } - httpResponse.setHeader("WWW-Authenticate", CHALLENGE); + httpResponse.setHeader(getAuthenticationHeader(httpRequest, urlRequestType), CHALLENGE); httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED); return; } else { @@ -221,8 +249,8 @@ // authenticated request permitted. // pass processing to the restricted servlet. newSession(authenticatedRequest, httpResponse); - logger.info(MessageFormat.format("ARF: {0} ({1}) authenticated", fullUrl, - HttpServletResponse.SC_CONTINUE)); + logger.info(MessageFormat.format("ARF: authenticated {0} to {1} ({2})", user.username, + fullUrl, HttpServletResponse.SC_CONTINUE)); chain.doFilter(authenticatedRequest, httpResponse); return; } @@ -244,4 +272,17 @@ // pass processing to the restricted servlet. chain.doFilter(authenticatedRequest, httpResponse); } + + public static boolean hasContentInRequestHeader(HttpServletRequest request, String headerName, String content) + { + Iterator<String> headerItr = Collections.list(request.getHeaders(headerName)).iterator(); + + while (headerItr.hasNext()) { + if (headerItr.next().contains(content)) { + return true; + } + } + + return false; + } } \ No newline at end of file -- Gitblit v1.9.1