From 27ae9095639bb228a1b7ff86a3ebe4264abf05be Mon Sep 17 00:00:00 2001
From: mschaefers <mschaefers@scoop-gmbh.de>
Date: Thu, 29 Nov 2012 12:33:09 -0500
Subject: [PATCH] feature: when using LdapUserService one can configure Gitblit to fetch all users from ldap that can possibly login. This allows to see newly generated LDAP users instantly in Gitblit. By now an LDAP user had to log in once to appear in GitBlit.

---
 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