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/client/EditUserDialog.java |  136 +++++++++++++++++++++++++++++++++++++--------
 1 files changed, 111 insertions(+), 25 deletions(-)

diff --git a/src/com/gitblit/client/EditUserDialog.java b/src/com/gitblit/client/EditUserDialog.java
index 3f1b929..e954fed 100644
--- a/src/com/gitblit/client/EditUserDialog.java
+++ b/src/com/gitblit/client/EditUserDialog.java
@@ -27,8 +27,10 @@
 import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import javax.swing.ImageIcon;
@@ -46,7 +48,11 @@
 import javax.swing.KeyStroke;
 
 import com.gitblit.Constants.AccessRestrictionType;
+import com.gitblit.Constants.AuthorizationControl;
+import com.gitblit.Constants.PermissionType;
+import com.gitblit.Constants.RegistrantType;
 import com.gitblit.Keys;
+import com.gitblit.models.RegistrantAccessPermission;
 import com.gitblit.models.RepositoryModel;
 import com.gitblit.models.ServerSettings;
 import com.gitblit.models.TeamModel;
@@ -72,13 +78,21 @@
 	private JPasswordField passwordField;
 
 	private JPasswordField confirmPasswordField;
+	
+	private JTextField displayNameField;
+	
+	private JTextField emailAddressField;
 
 	private JCheckBox canAdminCheckbox;
+	
+	private JCheckBox canForkCheckbox;
+	
+	private JCheckBox canCreateCheckbox;
 
 	private JCheckBox notFederatedCheckbox;
 
-	private JPalette<String> repositoryPalette;
-	
+	private RegistrantPermissionsPanel repositoryPalette;
+
 	private JPalette<TeamModel> teamsPalette;
 
 	private Set<String> usernames;
@@ -119,26 +133,43 @@
 		passwordField = new JPasswordField(anUser.password == null ? "" : anUser.password, 25);
 		confirmPasswordField = new JPasswordField(anUser.password == null ? "" : anUser.password,
 				25);
-		canAdminCheckbox = new JCheckBox(Translation.get("gb.canAdminDescription"), anUser.canAdmin);
+		displayNameField = new JTextField(anUser.displayName == null ? "" : anUser.displayName, 25);
+		emailAddressField = new JTextField(anUser.emailAddress == null ? "" : anUser.emailAddress, 25);
+		canAdminCheckbox = new JCheckBox(Translation.get("gb.canAdminDescription"), anUser.canAdmin);		
+		canForkCheckbox = new JCheckBox(Translation.get("gb.canForkDescription"), anUser.canFork);
+		canCreateCheckbox = new JCheckBox(Translation.get("gb.canCreateDescription"), anUser.canCreate);
 		notFederatedCheckbox = new JCheckBox(
 				Translation.get("gb.excludeFromFederationDescription"),
 				anUser.excludeFromFederation);
+		
+		// credentials are optionally controlled by 3rd-party authentication
+		usernameField.setEnabled(settings.supportsCredentialChanges);
+		passwordField.setEnabled(settings.supportsCredentialChanges);
+		confirmPasswordField.setEnabled(settings.supportsCredentialChanges);
+
+		displayNameField.setEnabled(settings.supportsDisplayNameChanges);
+		emailAddressField.setEnabled(settings.supportsEmailAddressChanges);
 
 		JPanel fieldsPanel = new JPanel(new GridLayout(0, 1));
 		fieldsPanel.add(newFieldPanel(Translation.get("gb.username"), usernameField));
 		fieldsPanel.add(newFieldPanel(Translation.get("gb.password"), passwordField));
 		fieldsPanel.add(newFieldPanel(Translation.get("gb.confirmPassword"), confirmPasswordField));
+		fieldsPanel.add(newFieldPanel(Translation.get("gb.displayName"), displayNameField));
+		fieldsPanel.add(newFieldPanel(Translation.get("gb.emailAddress"), emailAddressField));
 		fieldsPanel.add(newFieldPanel(Translation.get("gb.canAdmin"), canAdminCheckbox));
+		fieldsPanel.add(newFieldPanel(Translation.get("gb.canFork"), canForkCheckbox));
+		fieldsPanel.add(newFieldPanel(Translation.get("gb.canCreate"), canCreateCheckbox));
 		fieldsPanel.add(newFieldPanel(Translation.get("gb.excludeFromFederation"),
 				notFederatedCheckbox));
 
 		final Insets _insets = new Insets(5, 5, 5, 5);
-		repositoryPalette = new JPalette<String>();
+		repositoryPalette = new RegistrantPermissionsPanel(RegistrantType.REPOSITORY);
 		teamsPalette = new JPalette<TeamModel>();
-		
+		teamsPalette.setEnabled(settings.supportsTeamMembershipChanges);
+
 		JPanel fieldsPanelTop = new JPanel(new BorderLayout());
 		fieldsPanelTop.add(fieldsPanel, BorderLayout.NORTH);
-		
+
 		JPanel repositoriesPanel = new JPanel(new BorderLayout()) {
 
 			private static final long serialVersionUID = 1L;
@@ -166,7 +197,6 @@
 		}
 		panel.addTab(Translation.get("gb.restrictedRepositories"), repositoriesPanel);
 
-
 		JButton createButton = new JButton(Translation.get("gb.save"));
 		createButton.addActionListener(new ActionListener() {
 			public void actionPerformed(ActionEvent event) {
@@ -188,7 +218,7 @@
 		JPanel controls = new JPanel();
 		controls.add(cancelButton);
 		controls.add(createButton);
-		
+
 		JPanel centerPanel = new JPanel(new BorderLayout(5, 5)) {
 
 			private static final long serialVersionUID = 1L;
@@ -217,16 +247,15 @@
 	}
 
 	private boolean validateFields() {
-		String uname = usernameField.getText();
-		if (StringUtils.isEmpty(uname)) {
+		if (StringUtils.isEmpty(usernameField.getText())) {
 			error("Please enter a username!");
 			return false;
 		}
-
+		String uname = usernameField.getText().toLowerCase();
 		boolean rename = false;
 		// verify username uniqueness on create
 		if (isCreate) {
-			if (usernames.contains(uname.toLowerCase())) {
+			if (usernames.contains(uname)) {
 				error(MessageFormat.format("Username ''{0}'' is unavailable.", uname));
 				return false;
 			}
@@ -234,7 +263,7 @@
 			// check rename collision
 			rename = !StringUtils.isEmpty(username) && !username.equalsIgnoreCase(uname);
 			if (rename) {
-				if (usernames.contains(uname.toLowerCase())) {
+				if (usernames.contains(uname)) {
 					error(MessageFormat.format(
 							"Failed to rename ''{0}'' because ''{1}'' already exists.", username,
 							uname));
@@ -274,7 +303,7 @@
 			} else if (type.equalsIgnoreCase("combined-md5")) {
 				// store MD5 digest of username+password
 				user.password = StringUtils.COMBINED_MD5_TYPE
-						+ StringUtils.getMD5(username.toLowerCase() + password);
+						+ StringUtils.getMD5(user.username + password);
 			} else {
 				// plain-text password
 				user.password = password;
@@ -286,13 +315,19 @@
 			// no change in password
 			user.password = password;
 		}
+		
+		user.displayName = displayNameField.getText().trim();
+		user.emailAddress = emailAddressField.getText().trim();
 
 		user.canAdmin = canAdminCheckbox.isSelected();
+		user.canFork = canForkCheckbox.isSelected();
+		user.canCreate = canCreateCheckbox.isSelected();
 		user.excludeFromFederation = notFederatedCheckbox.isSelected();
 
-		user.repositories.clear();
-		user.repositories.addAll(repositoryPalette.getSelections());
-		
+		for (RegistrantAccessPermission rp : repositoryPalette.getPermissions()) {
+			user.setRepositoryPermission(rp.registrant, rp.permission);
+		}
+
 		user.teams.clear();
 		user.teams.addAll(teamsPalette.getSelections());
 		return true;
@@ -310,20 +345,71 @@
 		}
 	}
 
-	public void setRepositories(List<RepositoryModel> repositories, List<String> selected) {
+	public void setRepositories(List<RepositoryModel> repositories, List<RegistrantAccessPermission> permissions) {
+		Map<String, RepositoryModel> repoMap = new HashMap<String, RepositoryModel>();
 		List<String> restricted = new ArrayList<String>();
 		for (RepositoryModel repo : repositories) {
-			if (repo.accessRestriction.exceeds(AccessRestrictionType.NONE)) {
-				restricted.add(repo.name);
+			// exclude Owner or personal repositories
+			if (!repo.isOwner(username) && !repo.isUsersPersonalRepository(username)) {
+				if (repo.accessRestriction.exceeds(AccessRestrictionType.NONE)
+						&& repo.authorizationControl.equals(AuthorizationControl.NAMED)) {
+					restricted.add(repo.name);
+				}				
 			}
+			repoMap.put(repo.name.toLowerCase(), repo);
 		}
 		StringUtils.sortRepositorynames(restricted);
-		if (selected != null) {
-			StringUtils.sortRepositorynames(selected);
+		
+		List<String> list = new ArrayList<String>();
+		// repositories
+		list.add(".*");
+		// all repositories excluding personal repositories
+		list.add("[^~].*");
+		String lastProject = null;
+		for (String repo : restricted) {
+			String projectPath = StringUtils.getFirstPathElement(repo).toLowerCase();
+			if (lastProject == null || !lastProject.equalsIgnoreCase(projectPath)) {
+				lastProject = projectPath;
+				if (!StringUtils.isEmpty(projectPath)) {
+					// regex for all repositories within a project
+					list.add(projectPath + "/.*");
+				}
+			}
+			list.add(repo);
 		}
-		repositoryPalette.setObjects(restricted, selected);
+
+		// remove repositories for which user already has a permission
+		if (permissions == null) {
+			permissions = new ArrayList<RegistrantAccessPermission>();
+		} else {
+			for (RegistrantAccessPermission rp : permissions) {
+				list.remove(rp.registrant.toLowerCase());
+			}
+		}
+		
+		// update owner and missing permissions for editing
+		for (RegistrantAccessPermission permission : permissions) {
+			if (permission.mutable && PermissionType.EXPLICIT.equals(permission.permissionType)) {
+				// Ensure this is NOT an owner permission - which is non-editable
+				// We don't know this from within the usermodel, ownership is a
+				// property of a repository.
+				RepositoryModel rm = repoMap.get(permission.registrant.toLowerCase());
+				if (rm == null) {
+					permission.permissionType = PermissionType.MISSING;
+					permission.mutable = false;
+					continue;
+				}
+				boolean isOwner = rm.isOwner(username);
+				if (isOwner) {
+					permission.permissionType = PermissionType.OWNER;
+					permission.mutable = false;
+				}
+			}
+		}
+
+		repositoryPalette.setObjects(list, permissions);
 	}
-	
+
 	public void setTeams(List<TeamModel> teams, List<TeamModel> selected) {
 		Collections.sort(teams);
 		if (selected != null) {
@@ -331,7 +417,7 @@
 		}
 		teamsPalette.setObjects(teams, selected);
 	}
-
+	
 	public UserModel getUser() {
 		if (canceled) {
 			return null;

--
Gitblit v1.9.1