From bd0e83e350fc703bcae72a28c41b09d9a9cec594 Mon Sep 17 00:00:00 2001
From: Paul Martin <paul@paulsputer.com>
Date: Sat, 10 Oct 2015 07:50:00 -0400
Subject: [PATCH] Git-LFS support

---
 src/main/java/com/gitblit/servlet/AccessRestrictionFilter.java |   54 +++++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 45 insertions(+), 9 deletions(-)

diff --git a/src/main/java/com/gitblit/servlet/AccessRestrictionFilter.java b/src/main/java/com/gitblit/servlet/AccessRestrictionFilter.java
index ee4a91a..bfbc089 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,26 @@
 	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 action
+	 * @return authentication type header
+	 */
+	protected String getAuthenticationHeader(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.
@@ -163,13 +185,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(urlRequestType), CHALLENGE);
 					httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED);
 					return;
 				} else {
@@ -188,7 +211,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);
@@ -210,13 +233,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(urlRequestType), CHALLENGE);
 				httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED);
 				return;
 			} else {
@@ -248,4 +271,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