From cb285cbfddfc0b633d6b8cdb4dc0d2bd2b8b51ef Mon Sep 17 00:00:00 2001
From: James Moger <james.moger@gitblit.com>
Date: Thu, 05 Jan 2012 17:34:05 -0500
Subject: [PATCH] Fixed bug in receive hook for repositories in subfolders

---
 src/com/gitblit/client/EditUserDialog.java |  161 +++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 125 insertions(+), 36 deletions(-)

diff --git a/src/com/gitblit/client/EditUserDialog.java b/src/com/gitblit/client/EditUserDialog.java
index c60b2b2..3f1b929 100644
--- a/src/com/gitblit/client/EditUserDialog.java
+++ b/src/com/gitblit/client/EditUserDialog.java
@@ -23,9 +23,10 @@
 import java.awt.Insets;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
 import java.text.MessageFormat;
 import java.util.ArrayList;
-import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -39,12 +40,16 @@
 import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JPasswordField;
+import javax.swing.JRootPane;
+import javax.swing.JTabbedPane;
 import javax.swing.JTextField;
+import javax.swing.KeyStroke;
 
 import com.gitblit.Constants.AccessRestrictionType;
-import com.gitblit.IStoredSettings;
 import com.gitblit.Keys;
 import com.gitblit.models.RepositoryModel;
+import com.gitblit.models.ServerSettings;
+import com.gitblit.models.TeamModel;
 import com.gitblit.models.UserModel;
 import com.gitblit.utils.StringUtils;
 
@@ -52,12 +57,14 @@
 
 	private static final long serialVersionUID = 1L;
 
+	private final String username;
+
 	private final UserModel user;
 
-	private final IStoredSettings settings;
+	private final ServerSettings settings;
 
 	private boolean isCreate;
-	
+
 	private boolean canceled = true;
 
 	private JTextField usernameField;
@@ -71,28 +78,43 @@
 	private JCheckBox notFederatedCheckbox;
 
 	private JPalette<String> repositoryPalette;
+	
+	private JPalette<TeamModel> teamsPalette;
 
 	private Set<String> usernames;
 
-	public EditUserDialog(IStoredSettings settings) {
-		this(new UserModel(""), settings);
+	public EditUserDialog(int protocolVersion, ServerSettings settings) {
+		this(protocolVersion, new UserModel(""), settings);
 		this.isCreate = true;
-		setTitle(Translation.get("gb.newUser"));		
+		setTitle(Translation.get("gb.newUser"));
 	}
 
-	public EditUserDialog(UserModel anUser, IStoredSettings settings) {
+	public EditUserDialog(int protocolVersion, UserModel anUser, ServerSettings settings) {
 		super();
+		this.username = anUser.username;
 		this.user = new UserModel("");
 		this.settings = settings;
 		this.usernames = new HashSet<String>();
 		this.isCreate = false;
-		initialize(anUser);
+		initialize(protocolVersion, anUser);
 		setModal(true);
 		setTitle(Translation.get("gb.edit") + ": " + anUser.username);
 		setIconImage(new ImageIcon(getClass().getResource("/gitblt-favicon.png")).getImage());
 	}
 
-	private void initialize(UserModel anUser) {
+	@Override
+	protected JRootPane createRootPane() {
+		KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
+		JRootPane rootPane = new JRootPane();
+		rootPane.registerKeyboardAction(new ActionListener() {
+			public void actionPerformed(ActionEvent actionEvent) {
+				setVisible(false);
+			}
+		}, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW);
+		return rootPane;
+	}
+
+	private void initialize(int protocolVersion, UserModel anUser) {
 		usernameField = new JTextField(anUser.username == null ? "" : anUser.username, 25);
 		passwordField = new JPasswordField(anUser.password == null ? "" : anUser.password, 25);
 		confirmPasswordField = new JPasswordField(anUser.password == null ? "" : anUser.password,
@@ -110,11 +132,40 @@
 		fieldsPanel.add(newFieldPanel(Translation.get("gb.excludeFromFederation"),
 				notFederatedCheckbox));
 
+		final Insets _insets = new Insets(5, 5, 5, 5);
 		repositoryPalette = new JPalette<String>();
-		JPanel panel = new JPanel(new BorderLayout());
-		panel.add(fieldsPanel, BorderLayout.NORTH);
-		panel.add(newFieldPanel(Translation.get("gb.restrictedRepositories"), repositoryPalette),
-				BorderLayout.CENTER);
+		teamsPalette = new JPalette<TeamModel>();
+		
+		JPanel fieldsPanelTop = new JPanel(new BorderLayout());
+		fieldsPanelTop.add(fieldsPanel, BorderLayout.NORTH);
+		
+		JPanel repositoriesPanel = new JPanel(new BorderLayout()) {
+
+			private static final long serialVersionUID = 1L;
+
+			public Insets getInsets() {
+				return _insets;
+			}
+		};
+		repositoriesPanel.add(repositoryPalette, BorderLayout.CENTER);
+
+		JPanel teamsPanel = new JPanel(new BorderLayout()) {
+
+			private static final long serialVersionUID = 1L;
+
+			public Insets getInsets() {
+				return _insets;
+			}
+		};
+		teamsPanel.add(teamsPalette, BorderLayout.CENTER);
+
+		JTabbedPane panel = new JTabbedPane(JTabbedPane.TOP);
+		panel.addTab(Translation.get("gb.general"), fieldsPanelTop);
+		if (protocolVersion > 1) {
+			panel.addTab(Translation.get("gb.teamMemberships"), teamsPanel);
+		}
+		panel.addTab(Translation.get("gb.restrictedRepositories"), repositoriesPanel);
+
 
 		JButton createButton = new JButton(Translation.get("gb.save"));
 		createButton.addActionListener(new ActionListener() {
@@ -137,8 +188,7 @@
 		JPanel controls = new JPanel();
 		controls.add(cancelButton);
 		controls.add(createButton);
-
-		final Insets _insets = new Insets(5, 5, 5, 5);
+		
 		JPanel centerPanel = new JPanel(new BorderLayout(5, 5)) {
 
 			private static final long serialVersionUID = 1L;
@@ -154,7 +204,6 @@
 		getContentPane().setLayout(new BorderLayout(5, 5));
 		getContentPane().add(centerPanel, BorderLayout.CENTER);
 		pack();
-		setLocationRelativeTo(null);
 	}
 
 	private JPanel newFieldPanel(String label, JComponent comp) {
@@ -174,46 +223,78 @@
 			return false;
 		}
 
+		boolean rename = false;
 		// verify username uniqueness on create
 		if (isCreate) {
 			if (usernames.contains(uname.toLowerCase())) {
 				error(MessageFormat.format("Username ''{0}'' is unavailable.", uname));
 				return false;
 			}
+		} else {
+			// check rename collision
+			rename = !StringUtils.isEmpty(username) && !username.equalsIgnoreCase(uname);
+			if (rename) {
+				if (usernames.contains(uname.toLowerCase())) {
+					error(MessageFormat.format(
+							"Failed to rename ''{0}'' because ''{1}'' already exists.", username,
+							uname));
+					return false;
+				}
+			}
 		}
+		user.username = uname;
 
-		int minLength = settings.getInteger(Keys.realm.minPasswordLength, 5);
+		int minLength = settings.get(Keys.realm.minPasswordLength).getInteger(5);
 		if (minLength < 4) {
 			minLength = 4;
 		}
-		char[] pw = passwordField.getPassword();
-		if (pw == null || pw.length < minLength) {
-			error(MessageFormat.format(
-					"Password is too short. Minimum length is {0} characters.", minLength));
+
+		String password = new String(passwordField.getPassword());
+		if (StringUtils.isEmpty(password) || password.length() < minLength) {
+			error(MessageFormat.format("Password is too short. Minimum length is {0} characters.",
+					minLength));
 			return false;
 		}
-		char[] cpw = confirmPasswordField.getPassword();
-		if (cpw == null || cpw.length != pw.length) {
-			error("Please confirm the password!");
+		if (!password.toUpperCase().startsWith(StringUtils.MD5_TYPE)
+				&& !password.toUpperCase().startsWith(StringUtils.COMBINED_MD5_TYPE)) {
+			String cpw = new String(confirmPasswordField.getPassword());
+			if (cpw == null || cpw.length() != password.length()) {
+				error("Please confirm the password!");
+				return false;
+			}
+			if (!password.equals(cpw)) {
+				error("Passwords do not match!");
+				return false;
+			}
+
+			String type = settings.get(Keys.realm.passwordStorage).getString("md5");
+			if (type.equalsIgnoreCase("md5")) {
+				// store MD5 digest of password
+				user.password = StringUtils.MD5_TYPE + StringUtils.getMD5(password);
+			} else if (type.equalsIgnoreCase("combined-md5")) {
+				// store MD5 digest of username+password
+				user.password = StringUtils.COMBINED_MD5_TYPE
+						+ StringUtils.getMD5(username.toLowerCase() + password);
+			} else {
+				// plain-text password
+				user.password = password;
+			}
+		} else if (rename && password.toUpperCase().startsWith(StringUtils.COMBINED_MD5_TYPE)) {
+			error("Gitblit is configured for combined-md5 password hashing. You must enter a new password on account rename.");
 			return false;
-		}
-		if (!Arrays.equals(pw, cpw)) {
-			error("Passwords do not match!");
-			return false;
-		}
-		user.username = uname;
-		String type = settings.getString(Keys.realm.passwordStorage, "md5");
-		if (type.equalsIgnoreCase("md5")) {
-			// store MD5 digest of password
-			user.password = StringUtils.MD5_TYPE + StringUtils.getMD5(new String(pw));
 		} else {
-			user.password = new String(pw);
+			// no change in password
+			user.password = password;
 		}
+
 		user.canAdmin = canAdminCheckbox.isSelected();
 		user.excludeFromFederation = notFederatedCheckbox.isSelected();
 
 		user.repositories.clear();
 		user.repositories.addAll(repositoryPalette.getSelections());
+		
+		user.teams.clear();
+		user.teams.addAll(teamsPalette.getSelections());
 		return true;
 	}
 
@@ -242,6 +323,14 @@
 		}
 		repositoryPalette.setObjects(restricted, selected);
 	}
+	
+	public void setTeams(List<TeamModel> teams, List<TeamModel> selected) {
+		Collections.sort(teams);
+		if (selected != null) {
+			Collections.sort(selected);
+		}
+		teamsPalette.setObjects(teams, selected);
+	}
 
 	public UserModel getUser() {
 		if (canceled) {

--
Gitblit v1.9.1