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 |  262 ++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 203 insertions(+), 59 deletions(-)

diff --git a/src/com/gitblit/wicket/pages/RootPage.java b/src/com/gitblit/wicket/pages/RootPage.java
index 74122bc..adcd7b1 100644
--- a/src/com/gitblit/wicket/pages/RootPage.java
+++ b/src/com/gitblit/wicket/pages/RootPage.java
@@ -17,14 +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;
@@ -40,6 +47,7 @@
 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;
 
@@ -56,6 +64,7 @@
 
 	IModel<String> username = new Model<String>("");
 	IModel<String> password = new Model<String>("");
+	List<RepositoryModel> repositoryModels = new ArrayList<RepositoryModel>();
 
 	public RootPage() {
 		super();
@@ -70,8 +79,8 @@
 		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) {			
+
+		if (authenticateAdmin) {
 			showAdmin = allowAdmin && GitBlitWebSession.get().canAdmin();
 			// authentication requires state and session
 			setStatelessHint(false);
@@ -90,8 +99,12 @@
 
 		// 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));
 		}
@@ -107,7 +120,7 @@
 		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;
 
@@ -118,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);
@@ -136,7 +149,7 @@
 		WicketUtils.setInputPlaceholder(pwField, getString("gb.password"));
 		loginForm.add(pwField);
 		add(loginForm);
-		
+
 		if (authenticateView || authenticateAdmin) {
 			loginForm.setVisible(!GitBlitWebSession.get().isLoggedIn());
 		} else {
@@ -150,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));
 			}
 		}
@@ -160,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)) {
@@ -171,36 +216,70 @@
 				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 void addDropDownMenus(List<PageRegistration> pages) {
 
 	}
 
-	protected List<DropDownMenuItem> getFilterMenuItems() {
+	protected List<DropDownMenuItem> getRepositoryFilterItems(PageParameters params) {
 		final UserModel user = GitBlitWebSession.get().getUser();
 		Set<DropDownMenuItem> filters = new LinkedHashSet<DropDownMenuItem>();
+		List<RepositoryModel> repositories = getRepositoryModels();
 
 		// accessible repositories by federation set
-		for (RepositoryModel repository : GitBlit.self().getRepositoryModels(user)) {
+		Map<String, AtomicInteger> setMap = new HashMap<String, AtomicInteger>();
+		for (RepositoryModel repository : repositories) {
 			for (String set : repository.federationSets) {
-				filters.add(new DropDownMenuItem(set, "set", set));
+				String key = set.toLowerCase();
+				if (setMap.containsKey(key)) {
+					setMap.get(key).incrementAndGet();
+				} else {
+					setMap.put(key, new AtomicInteger(1));
+				}
 			}
 		}
-		if (filters.size() > 0) {
+		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) {
-			for (TeamModel team : user.teams) {
-				filters.add(new DropDownMenuItem(team.name, "team", team.name));
+			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());
@@ -214,7 +293,7 @@
 			for (String expression : expressions) {
 				if (!StringUtils.isEmpty(expression)) {
 					addedExpression = true;
-					filters.add(new DropDownMenuItem(null, "x", expression));
+					filters.add(new DropDownMenuItem(null, "x", expression, params));
 				}
 			}
 			// if we added any custom expressions, add a divider
@@ -222,89 +301,154 @@
 				filters.add(new DropDownMenuItem());
 			}
 		}
-
-		if (filters.size() > 0) {
-			// add All Repositories
-			filters.add(new DropDownMenuItem("All Repositories", null, null));
-		}
-
 		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) {
-		final UserModel user = GitBlitWebSession.get().getUser();
 		if (params == null) {
-			return GitBlit.self().getRepositoryModels(user);
+			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