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/wicket/pages/RootPage.java |  312 +++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 260 insertions(+), 52 deletions(-)

diff --git a/src/com/gitblit/wicket/pages/RootPage.java b/src/com/gitblit/wicket/pages/RootPage.java
index a907c73..adcd7b1 100644
--- a/src/com/gitblit/wicket/pages/RootPage.java
+++ b/src/com/gitblit/wicket/pages/RootPage.java
@@ -17,12 +17,21 @@
 
 import java.text.MessageFormat;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.regex.Pattern;
 
 import org.apache.wicket.PageParameters;
 import org.apache.wicket.markup.html.form.PasswordTextField;
-import org.apache.wicket.markup.html.form.StatelessForm;
 import org.apache.wicket.markup.html.form.TextField;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.Model;
@@ -37,6 +46,8 @@
 import com.gitblit.utils.StringUtils;
 import com.gitblit.wicket.GitBlitWebSession;
 import com.gitblit.wicket.PageRegistration;
+import com.gitblit.wicket.PageRegistration.DropDownMenuItem;
+import com.gitblit.wicket.SessionlessForm;
 import com.gitblit.wicket.WicketUtils;
 import com.gitblit.wicket.panels.NavigationPanel;
 
@@ -53,6 +64,7 @@
 
 	IModel<String> username = new Model<String>("");
 	IModel<String> password = new Model<String>("");
+	List<RepositoryModel> repositoryModels = new ArrayList<RepositoryModel>();
 
 	public RootPage() {
 		super();
@@ -64,14 +76,17 @@
 
 	@Override
 	protected void setupPage(String repositoryName, String pageName) {
-		if (GitBlit.getBoolean(Keys.web.authenticateAdminPages, true)) {
-			boolean allowAdmin = GitBlit.getBoolean(Keys.web.allowAdministration, false);
+		boolean authenticateView = GitBlit.getBoolean(Keys.web.authenticateViewPages, false);
+		boolean authenticateAdmin = GitBlit.getBoolean(Keys.web.authenticateAdminPages, true);
+		boolean allowAdmin = GitBlit.getBoolean(Keys.web.allowAdministration, true);
+
+		if (authenticateAdmin) {
 			showAdmin = allowAdmin && GitBlitWebSession.get().canAdmin();
 			// authentication requires state and session
 			setStatelessHint(false);
 		} else {
-			showAdmin = GitBlit.getBoolean(Keys.web.allowAdministration, false);
-			if (GitBlit.getBoolean(Keys.web.authenticateViewPages, false)) {
+			showAdmin = allowAdmin;
+			if (authenticateView) {
 				// authentication requires state and session
 				setStatelessHint(false);
 			} else {
@@ -84,19 +99,28 @@
 
 		// navigation links
 		List<PageRegistration> pages = new ArrayList<PageRegistration>();
-		pages.add(new PageRegistration("gb.repositories", RepositoriesPage.class));
-		pages.add(new PageRegistration("gb.activity", ActivityPage.class));
+		pages.add(new PageRegistration("gb.repositories", RepositoriesPage.class,
+				getRootPageParameters()));
+		pages.add(new PageRegistration("gb.activity", ActivityPage.class, getRootPageParameters()));
+		if (GitBlit.getBoolean(Keys.web.allowLuceneIndexing, true)) {
+			pages.add(new PageRegistration("gb.search", LuceneSearchPage.class));
+		}
 		if (showAdmin) {
 			pages.add(new PageRegistration("gb.users", UsersPage.class));
 		}
 		if (showAdmin || showRegistrations) {
 			pages.add(new PageRegistration("gb.federation", FederationPage.class));
 		}
+
+		if (!authenticateView || (authenticateView && GitBlitWebSession.get().isLoggedIn())) {
+			addDropDownMenus(pages);
+		}
+
 		NavigationPanel navPanel = new NavigationPanel("navPanel", getClass(), pages);
 		add(navPanel);
 
 		// login form
-		StatelessForm<Void> loginForm = new StatelessForm<Void>("loginForm") {
+		SessionlessForm<Void> loginForm = new SessionlessForm<Void>("loginForm", getClass(), getPageParameters()) {
 
 			private static final long serialVersionUID = 1L;
 
@@ -107,11 +131,11 @@
 
 				UserModel user = GitBlit.self().authenticate(username, password);
 				if (user == null) {
-					error("Invalid username or password!");
+					error(getString("gb.invalidUsernameOrPassword"));
 				} else if (user.username.equals(Constants.FEDERATION_USER)) {
 					// disallow the federation user from logging in via the
 					// web ui
-					error("Invalid username or password!");
+					error(getString("gb.invalidUsernameOrPassword"));
 					user = null;
 				} else {
 					loginUser(user);
@@ -125,8 +149,8 @@
 		WicketUtils.setInputPlaceholder(pwField, getString("gb.password"));
 		loginForm.add(pwField);
 		add(loginForm);
-		if (GitBlit.getBoolean(Keys.web.authenticateViewPages, true)
-				|| GitBlit.getBoolean(Keys.web.authenticateAdminPages, true)) {
+
+		if (authenticateView || authenticateAdmin) {
 			loginForm.setVisible(!GitBlitWebSession.get().isLoggedIn());
 		} else {
 			loginForm.setVisible(false);
@@ -139,9 +163,9 @@
 		} else if (showAdmin) {
 			int pendingProposals = GitBlit.self().getPendingFederationProposals().size();
 			if (pendingProposals == 1) {
-				info("There is 1 federation proposal awaiting review.");
+				info(getString("gb.OneProposalToReview"));
 			} else if (pendingProposals > 1) {
-				info(MessageFormat.format("There are {0} federation proposals awaiting review.",
+				info(MessageFormat.format(getString("gb.nFederationProposalsToReview"),
 						pendingProposals));
 			}
 		}
@@ -149,10 +173,42 @@
 		super.setupPage(repositoryName, pageName);
 	}
 
+	private PageParameters getRootPageParameters() {
+		if (reusePageParameters()) {
+			PageParameters pp = getPageParameters();
+			if (pp != null) {
+				PageParameters params = new PageParameters(pp);
+				// remove named project parameter
+				params.remove("p");
+
+				// remove named repository parameter
+				params.remove("r");
+
+				// remove named user parameter
+				params.remove("user");
+
+				// remove days back parameter if it is the default value
+				if (params.containsKey("db")
+						&& params.getInt("db") == GitBlit.getInteger(Keys.web.activityDuration, 14)) {
+					params.remove("db");
+				}
+				return params;
+			}			
+		}
+		return null;
+	}
+
+	protected boolean reusePageParameters() {
+		return false;
+	}
+
 	private void loginUser(UserModel user) {
 		if (user != null) {
 			// Set the user into the session
-			GitBlitWebSession.get().setUser(user);
+			GitBlitWebSession session = GitBlitWebSession.get();
+			// issue 62: fix session fixation vulnerability
+			session.replaceSession();
+			session.setUser(user);
 
 			// Set Cookie
 			if (GitBlit.getBoolean(Keys.web.allowCookieAuthentication, false)) {
@@ -160,87 +216,239 @@
 				GitBlit.self().setCookie(response, user);
 			}
 
-			if (!continueToOriginalDestination()) {
-				// Redirect to home page
-				setResponsePage(getApplication().getHomePage());
+			if (!session.continueRequest()) {
+				PageParameters params = getPageParameters();
+				if (params == null) {
+					// redirect to this page
+					setResponsePage(getClass());
+				} else {
+					// Strip username and password and redirect to this page
+					params.remove("username");
+					params.remove("password");
+					setResponsePage(getClass(), params);
+				}
 			}
 		}
 	}
+	
+	protected List<RepositoryModel> getRepositoryModels() {
+		if (repositoryModels.isEmpty()) {
+			final UserModel user = GitBlitWebSession.get().getUser();
+			List<RepositoryModel> repositories = GitBlit.self().getRepositoryModels(user);
+			repositoryModels.addAll(repositories);
+			Collections.sort(repositoryModels);
+		}
+		return repositoryModels;
+	}
 
-	protected List<RepositoryModel> getRepositories(PageParameters params) {
+	protected void addDropDownMenus(List<PageRegistration> pages) {
+
+	}
+
+	protected List<DropDownMenuItem> getRepositoryFilterItems(PageParameters params) {
 		final UserModel user = GitBlitWebSession.get().getUser();
-		if (params == null) {
-			return GitBlit.self().getRepositoryModels(user);
+		Set<DropDownMenuItem> filters = new LinkedHashSet<DropDownMenuItem>();
+		List<RepositoryModel> repositories = getRepositoryModels();
+
+		// accessible repositories by federation set
+		Map<String, AtomicInteger> setMap = new HashMap<String, AtomicInteger>();
+		for (RepositoryModel repository : repositories) {
+			for (String set : repository.federationSets) {
+				String key = set.toLowerCase();
+				if (setMap.containsKey(key)) {
+					setMap.get(key).incrementAndGet();
+				} else {
+					setMap.put(key, new AtomicInteger(1));
+				}
+			}
+		}
+		if (setMap.size() > 0) {
+			List<String> sets = new ArrayList<String>(setMap.keySet());
+			Collections.sort(sets);
+			for (String set : sets) {
+				filters.add(new DropDownMenuItem(MessageFormat.format("{0} ({1})", set,
+						setMap.get(set).get()), "set", set, params));
+			}
+			// divider
+			filters.add(new DropDownMenuItem());
 		}
 
+		// user's team memberships
+		if (user != null && user.teams.size() > 0) {
+			List<TeamModel> teams = new ArrayList<TeamModel>(user.teams);
+			Collections.sort(teams);
+			for (TeamModel team : teams) {
+				filters.add(new DropDownMenuItem(MessageFormat.format("{0} ({1})", team.name,
+						team.repositories.size()), "team", team.name, params));
+			}
+			// divider
+			filters.add(new DropDownMenuItem());
+		}
+
+		// custom filters
+		String customFilters = GitBlit.getString(Keys.web.customFilters, null);
+		if (!StringUtils.isEmpty(customFilters)) {
+			boolean addedExpression = false;
+			List<String> expressions = StringUtils.getStringsFromValue(customFilters, "!!!");
+			for (String expression : expressions) {
+				if (!StringUtils.isEmpty(expression)) {
+					addedExpression = true;
+					filters.add(new DropDownMenuItem(null, "x", expression, params));
+				}
+			}
+			// if we added any custom expressions, add a divider
+			if (addedExpression) {
+				filters.add(new DropDownMenuItem());
+			}
+		}
+		return new ArrayList<DropDownMenuItem>(filters);
+	}
+
+	protected List<DropDownMenuItem> getTimeFilterItems(PageParameters params) {
+		// days back choices - additive parameters
+		int daysBack = GitBlit.getInteger(Keys.web.activityDuration, 14);
+		if (daysBack < 1) {
+			daysBack = 14;
+		}
+		List<DropDownMenuItem> items = new ArrayList<DropDownMenuItem>();
+		Set<Integer> choicesSet = new HashSet<Integer>(Arrays.asList(daysBack, 14, 28, 60, 90, 180));
+		List<Integer> choices = new ArrayList<Integer>(choicesSet);
+		Collections.sort(choices);
+		String lastDaysPattern = getString("gb.lastNDays");
+		for (Integer db : choices) {
+			String txt = MessageFormat.format(lastDaysPattern, db);
+			items.add(new DropDownMenuItem(txt, "db", db.toString(), params));
+		}
+		items.add(new DropDownMenuItem());
+		return items;
+	}
+
+	protected List<RepositoryModel> getRepositories(PageParameters params) {
+		if (params == null) {
+			return getRepositoryModels();
+		}
+
+		boolean hasParameter = false;
+		String projectName = WicketUtils.getProjectName(params);
+		String userName = WicketUtils.getUsername(params);
+		if (StringUtils.isEmpty(projectName)) {
+			if (!StringUtils.isEmpty(userName)) {
+				projectName = "~" + userName;
+			}
+		}
 		String repositoryName = WicketUtils.getRepositoryName(params);
 		String set = WicketUtils.getSet(params);
 		String regex = WicketUtils.getRegEx(params);
 		String team = WicketUtils.getTeam(params);
+		int daysBack = params.getInt("db", 0);
 
-		List<RepositoryModel> models = null;
+		List<RepositoryModel> availableModels = getRepositoryModels();
+		Set<RepositoryModel> models = new HashSet<RepositoryModel>();
 
 		if (!StringUtils.isEmpty(repositoryName)) {
 			// try named repository
-			models = new ArrayList<RepositoryModel>();
-			RepositoryModel model = GitBlit.self().getRepositoryModel(repositoryName);
-			if (user.canAccessRepository(model)) {
-				models.add(model);
+			hasParameter = true;
+			for (RepositoryModel model : availableModels) {
+				if (model.name.equalsIgnoreCase(repositoryName)) {
+					models.add(model);
+					break;
+				}
 			}
 		}
 
-		// get all user accessible repositories
-		if (models == null) {
-			models = GitBlit.self().getRepositoryModels(user);
+		if (!StringUtils.isEmpty(projectName)) {
+			// try named project
+			hasParameter = true;			
+			if (projectName.equalsIgnoreCase(GitBlit.getString(Keys.web.repositoryRootGroupName, "main"))) {
+				// root project/group
+				for (RepositoryModel model : availableModels) {
+					if (model.name.indexOf('/') == -1) {
+						models.add(model);
+					}
+				}
+			} else {
+				// named project/group
+				String group = projectName.toLowerCase() + "/";
+				for (RepositoryModel model : availableModels) {
+					if (model.name.toLowerCase().startsWith(group)) {
+						models.add(model);
+					}
+				}
+			}
 		}
 
 		if (!StringUtils.isEmpty(regex)) {
 			// filter the repositories by the regex
-			List<RepositoryModel> accessible = GitBlit.self().getRepositoryModels(user);
-			List<RepositoryModel> matchingModels = new ArrayList<RepositoryModel>();
+			hasParameter = true;
 			Pattern pattern = Pattern.compile(regex);
-			for (RepositoryModel aModel : accessible) {
-				if (pattern.matcher(aModel.name).find()) {
-					matchingModels.add(aModel);
+			for (RepositoryModel model : availableModels) {
+				if (pattern.matcher(model.name).find()) {
+					models.add(model);
 				}
 			}
-			models = matchingModels;
-		} else if (!StringUtils.isEmpty(set)) {
+		}
+
+		if (!StringUtils.isEmpty(set)) {
 			// filter the repositories by the specified sets
+			hasParameter = true;
 			List<String> sets = StringUtils.getStringsFromValue(set, ",");
-			List<RepositoryModel> matchingModels = new ArrayList<RepositoryModel>();
-			for (RepositoryModel model : models) {
+			for (RepositoryModel model : availableModels) {
 				for (String curr : sets) {
 					if (model.federationSets.contains(curr)) {
-						matchingModels.add(model);
+						models.add(model);
 					}
 				}
 			}
-			models = matchingModels;
-		} else if (!StringUtils.isEmpty(team)) {
+		}
+
+		if (!StringUtils.isEmpty(team)) {
 			// filter the repositories by the specified teams
+			hasParameter = true;
 			List<String> teams = StringUtils.getStringsFromValue(team, ",");
-			
+
 			// need TeamModels first
 			List<TeamModel> teamModels = new ArrayList<TeamModel>();
 			for (String name : teams) {
-				TeamModel model = GitBlit.self().getTeamModel(name);
-				if (model != null) {
-					teamModels.add(model);
+				TeamModel teamModel = GitBlit.self().getTeamModel(name);
+				if (teamModel != null) {
+					teamModels.add(teamModel);
 				}
 			}
-			
+
 			// brute-force our way through finding the matching models
-			List<RepositoryModel> matchingModels = new ArrayList<RepositoryModel>();
-			for (RepositoryModel repositoryModel : models) {
+			for (RepositoryModel repositoryModel : availableModels) {
 				for (TeamModel teamModel : teamModels) {
-					if (teamModel.hasRepository(repositoryModel.name)) {
-						matchingModels.add(repositoryModel);
+					if (teamModel.hasRepositoryPermission(repositoryModel.name)) {
+						models.add(repositoryModel);
 					}
 				}
 			}
-			models = matchingModels;
 		}
-		return models;
+
+		if (!hasParameter) {
+			models.addAll(availableModels);
+		}
+
+		// time-filter the list
+		if (daysBack > 0) {
+			Calendar cal = Calendar.getInstance();
+			cal.set(Calendar.HOUR_OF_DAY, 0);
+			cal.set(Calendar.MINUTE, 0);
+			cal.set(Calendar.SECOND, 0);
+			cal.set(Calendar.MILLISECOND, 0);
+			cal.add(Calendar.DATE, -1 * daysBack);
+			Date threshold = cal.getTime();
+			Set<RepositoryModel> timeFiltered = new HashSet<RepositoryModel>();
+			for (RepositoryModel model : models) {
+				if (model.lastChange.after(threshold)) {
+					timeFiltered.add(model);
+				}
+			}
+			models = timeFiltered;
+		}
+		
+		List<RepositoryModel> list = new ArrayList<RepositoryModel>(models);
+		Collections.sort(list);
+		return list;
 	}
 }

--
Gitblit v1.9.1