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/GitblitManager.java |  242 +++++++++++++++++++++++++++++++-----------------
 1 files changed, 157 insertions(+), 85 deletions(-)

diff --git a/src/com/gitblit/client/GitblitManager.java b/src/com/gitblit/client/GitblitManager.java
index 43cdab3..dd0315f 100644
--- a/src/com/gitblit/client/GitblitManager.java
+++ b/src/com/gitblit/client/GitblitManager.java
@@ -19,22 +19,25 @@
 import java.awt.Cursor;
 import java.awt.Dimension;
 import java.awt.EventQueue;
-import java.awt.Font;
-import java.awt.GridLayout;
 import java.awt.Point;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.KeyEvent;
 import java.awt.event.WindowAdapter;
 import java.awt.event.WindowEvent;
+import java.io.BufferedReader;
 import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
 import java.io.IOException;
+import java.net.ConnectException;
 import java.text.MessageFormat;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Locale;
@@ -44,15 +47,12 @@
 
 import javax.swing.ImageIcon;
 import javax.swing.JFrame;
-import javax.swing.JLabel;
 import javax.swing.JMenu;
 import javax.swing.JMenuBar;
 import javax.swing.JMenuItem;
 import javax.swing.JOptionPane;
 import javax.swing.JPanel;
-import javax.swing.JPasswordField;
 import javax.swing.JTabbedPane;
-import javax.swing.JTextField;
 import javax.swing.KeyStroke;
 import javax.swing.SwingWorker;
 import javax.swing.UIManager;
@@ -60,10 +60,12 @@
 import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.lib.StoredConfig;
 import org.eclipse.jgit.storage.file.FileBasedConfig;
-import org.eclipse.jgit.util.Base64;
 import org.eclipse.jgit.util.FS;
 
 import com.gitblit.Constants;
+import com.gitblit.GitBlitException.ForbiddenException;
+import com.gitblit.models.FeedModel;
+import com.gitblit.utils.Base64;
 import com.gitblit.utils.StringUtils;
 
 /**
@@ -75,6 +77,8 @@
 public class GitblitManager extends JFrame implements RegistrationsDialog.RegistrationListener {
 
 	private static final long serialVersionUID = 1L;
+	private static final String SERVER = "server";
+	private static final String FEED = "feed";
 	private final SimpleDateFormat dateFormat;
 	private JTabbedPane serverTabs;
 	private File configFile = new File(System.getProperty("user.home"), ".gitblit/config");
@@ -98,6 +102,11 @@
 			@Override
 			public void windowClosing(WindowEvent event) {
 				saveSizeAndPosition();
+			}
+
+			@Override
+			public void windowOpened(WindowEvent event) {
+				manageRegistrations();
 			}
 		});
 
@@ -170,25 +179,7 @@
 		});
 		serversMenu.add(manage);
 
-		JMenuItem login = new JMenuItem(Translation.get("gb.login") + "...");
-		login.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_L, KeyEvent.CTRL_DOWN_MASK, false));
-		login.addActionListener(new ActionListener() {
-			public void actionPerformed(ActionEvent event) {
-				loginPrompt(GitblitRegistration.LOCALHOST);
-			}
-		});
-		serversMenu.add(login);
 		return menuBar;
-	}
-
-	private JPanel newLabelPanel(String text, JTextField field) {
-		JLabel label = new JLabel(text);
-		label.setFont(label.getFont().deriveFont(Font.BOLD));
-		label.setPreferredSize(new Dimension(75, 10));
-		JPanel jpanel = new JPanel(new BorderLayout());
-		jpanel.add(label, BorderLayout.WEST);
-		jpanel.add(field, BorderLayout.CENTER);
-		return jpanel;
 	}
 
 	private JPanel getCenterPanel() {
@@ -208,48 +199,28 @@
 	}
 
 	@Override
-	public void loginPrompt(GitblitRegistration reg) {
-		JTextField urlField = new JTextField(reg.url, 30);
-		JTextField nameField = new JTextField(reg.name);
-		JTextField accountField = new JTextField(reg.account);
-		JPasswordField passwordField = new JPasswordField(new String(reg.password));
-
-		JPanel panel = new JPanel(new GridLayout(0, 1, 5, 5));
-		panel.add(newLabelPanel(Translation.get("gb.name"), nameField));
-		panel.add(newLabelPanel(Translation.get("gb.url"), urlField));
-		panel.add(newLabelPanel(Translation.get("gb.username"), accountField));
-		panel.add(newLabelPanel(Translation.get("gb.password"), passwordField));
-
-		int result = JOptionPane.showConfirmDialog(GitblitManager.this, panel,
-				Translation.get("gb.login"), JOptionPane.OK_CANCEL_OPTION);
-		if (result != JOptionPane.OK_OPTION) {
-			return;
-		}
-		String url = urlField.getText();
-		if (StringUtils.isEmpty(url)) {
-			return;
-		}
-		String originalName = reg.name;
-		reg = new GitblitRegistration(nameField.getText(), url, accountField.getText(),
-				passwordField.getPassword());
-		if (!StringUtils.isEmpty(originalName) && !originalName.equals(reg.name)) {
-			// delete old registration
-			registrations.remove(originalName);
-			try {
-				StoredConfig config = getConfig();
-				config.unsetSection("servers", originalName);
-				config.save();
-			} catch (Throwable t) {
-				Utils.showException(GitblitManager.this, t);
+	public void login(GitblitRegistration reg) {
+		if (!reg.savePassword && (reg.password == null || reg.password.length == 0)) {
+			// prompt for password
+			EditRegistrationDialog dialog = new EditRegistrationDialog(this, reg, true);
+			dialog.setLocationRelativeTo(GitblitManager.this);
+			dialog.setVisible(true);
+			GitblitRegistration newReg = dialog.getRegistration();
+			if (newReg == null) {
+				// user canceled
+				return;
 			}
-		}
-		login(reg);
-	}
+			// preserve feeds
+			newReg.feeds.addAll(reg.feeds);
 
-	@Override
-	public void login(final GitblitRegistration reg) {
+			// use new reg
+			reg = newReg;
+		}
+
+		// login
 		setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
-		final GitblitPanel panel = new GitblitPanel(reg);
+		final GitblitRegistration registration = reg;
+		final GitblitPanel panel = new GitblitPanel(registration, this);
 		SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() {
 
 			@Override
@@ -262,17 +233,33 @@
 			protected void done() {
 				try {
 					boolean success = get();
-					serverTabs.addTab(reg.name, panel);
+					serverTabs.addTab(registration.name, panel);
 					int idx = serverTabs.getTabCount() - 1;
 					serverTabs.setSelectedIndex(idx);
-					serverTabs.setTabComponentAt(idx, new ClosableTabComponent(reg.name, null,
-							serverTabs, panel));
-					reg.lastLogin = new Date();
-					saveRegistration(reg);
-					registrations.put(reg.name, reg);
+					serverTabs.setTabComponentAt(idx, new ClosableTabComponent(registration.name,
+							null, serverTabs, panel));
+					registration.lastLogin = new Date();
+					saveRegistration(registration.name, registration);
+					registrations.put(registration.name, registration);
 					rebuildRecentMenu();
+					if (!registration.savePassword) {
+						// clear password
+						registration.password = null;
+					}
 				} catch (Throwable t) {
-					Utils.showException(GitblitManager.this, t);
+					Throwable cause = t.getCause();
+					if (cause instanceof ConnectException) {
+						JOptionPane.showMessageDialog(GitblitManager.this, cause.getMessage(),
+								Translation.get("gb.error"), JOptionPane.ERROR_MESSAGE);
+					} else if (cause instanceof ForbiddenException) {
+						JOptionPane
+								.showMessageDialog(
+										GitblitManager.this,
+										"This Gitblit server does not allow RPC Management or Administration",
+										Translation.get("gb.error"), JOptionPane.ERROR_MESSAGE);
+					} else {
+						Utils.showException(GitblitManager.this, t);
+					}
 				} finally {
 					setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
 				}
@@ -311,21 +298,39 @@
 	private void loadRegistrations() {
 		try {
 			StoredConfig config = getConfig();
-			Set<String> servers = config.getSubsections("servers");
+			Set<String> servers = config.getSubsections(SERVER);
 			for (String server : servers) {
-				Date lastLogin = dateFormat.parse(config.getString("servers", server, "lastLogin"));
-				String url = config.getString("servers", server, "url");
-				String account = config.getString("servers", server, "account");
+				Date lastLogin = new Date(0);
+				String date = config.getString(SERVER, server, "lastLogin");
+				if (!StringUtils.isEmpty(date)) {
+					lastLogin = dateFormat.parse(date);
+				}
+				String url = config.getString(SERVER, server, "url");
+				String account = config.getString(SERVER, server, "account");
 				char[] password;
-				String pw = config.getString("servers", server, "password");
+				String pw = config.getString(SERVER, server, "password");
 				if (StringUtils.isEmpty(pw)) {
 					password = new char[0];
 				} else {
-					// FIXME this is pretty lame
 					password = new String(Base64.decode(pw)).toCharArray();
 				}
-				GitblitRegistration reg = new GitblitRegistration(server, url, account, password);
+				GitblitRegistration reg = new GitblitRegistration(server, url, account, password) {
+					private static final long serialVersionUID = 1L;
+
+					protected void cacheFeeds() {
+						writeFeedCache(this);
+					}
+				};
+				String[] feeds = config.getStringList(SERVER, server, FEED);
+				if (feeds != null) {
+					// deserialize the field definitions
+					for (String definition : feeds) {
+						FeedModel feed = new FeedModel(definition);
+						reg.feeds.add(feed);
+					}
+				}
 				reg.lastLogin = lastLogin;
+				loadFeedCache(reg);
 				registrations.put(reg.name, reg);
 			}
 		} catch (Throwable t) {
@@ -333,27 +338,51 @@
 		}
 	}
 
-	private void saveRegistration(GitblitRegistration reg) {
+	@Override
+	public boolean saveRegistration(String name, GitblitRegistration reg) {
 		try {
 			StoredConfig config = getConfig();
-			config.setString("servers", reg.name, "url", reg.url);
-			config.setString("servers", reg.name, "account", reg.account);
-			// FIXME this is pretty lame			
-			config.setString("servers", reg.name, "password",
-					Base64.encodeBytes(new String(reg.password).getBytes("UTF-8")));
-			config.setString("servers", reg.name, "lastLogin", dateFormat.format(reg.lastLogin));
+			if (!StringUtils.isEmpty(name) && !name.equals(reg.name)) {
+				// delete old registration
+				registrations.remove(name);
+				config.unsetSection(SERVER, name);
+			}
+
+			// update registration
+			config.setString(SERVER, reg.name, "url", reg.url);
+			config.setString(SERVER, reg.name, "account", reg.account);
+			if (reg.savePassword) {
+				config.setString(SERVER, reg.name, "password",
+						Base64.encodeBytes(new String(reg.password).getBytes("UTF-8")));
+			} else {
+				config.setString(SERVER, reg.name, "password", "");
+			}
+			if (reg.lastLogin != null) {
+				config.setString(SERVER, reg.name, "lastLogin", dateFormat.format(reg.lastLogin));
+			}
+			// serialize the feed definitions
+			List<String> definitions = new ArrayList<String>();
+			for (FeedModel feed : reg.feeds) {
+				definitions.add(feed.toString());
+			}
+			if (definitions.size() > 0) {
+				config.setStringList(SERVER, reg.name, FEED, definitions);
+			}
 			config.save();
+			return true;
 		} catch (Throwable t) {
 			Utils.showException(GitblitManager.this, t);
 		}
+		return false;
 	}
 
+	@Override
 	public boolean deleteRegistrations(List<GitblitRegistration> list) {
 		boolean success = false;
 		try {
 			StoredConfig config = getConfig();
 			for (GitblitRegistration reg : list) {
-				config.unsetSection("servers", reg.name);
+				config.unsetSection(SERVER, reg.name);
 				registrations.remove(reg.name);
 			}
 			config.save();
@@ -370,6 +399,49 @@
 		return config;
 	}
 
+	private void loadFeedCache(GitblitRegistration reg) {
+		File feedCache = new File(configFile.getParentFile(), StringUtils.getSHA1(reg.toString())
+				+ ".cache");
+		if (!feedCache.exists()) {
+			// no cache for this registration
+			return;
+		}
+		try {
+			BufferedReader reader = new BufferedReader(new FileReader(feedCache));
+			Map<String, Date> cache = new HashMap<String, Date>();
+			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
+			String line = null;
+			while ((line = reader.readLine()) != null) {
+				String[] kvp = line.split("=");
+				cache.put(kvp[0], df.parse(kvp[1]));
+			}
+			reader.close();
+			for (FeedModel feed : reg.feeds) {
+				String name = feed.toString();
+				if (cache.containsKey(name)) {
+					feed.currentRefreshDate = cache.get(name);
+				}
+			}
+		} catch (Exception e) {
+			Utils.showException(GitblitManager.this, e);
+		}
+	}
+
+	private void writeFeedCache(GitblitRegistration reg) {
+		try {
+			File feedCache = new File(configFile.getParentFile(), StringUtils.getSHA1(reg
+					.toString()) + ".cache");
+			FileWriter writer = new FileWriter(feedCache);
+			for (FeedModel feed : reg.feeds) {
+				writer.append(MessageFormat.format("{0}={1,date,yyyy-MM-dd'T'HH:mm:ss}\n",
+						feed.toString(), feed.currentRefreshDate));
+			}
+			writer.close();
+		} catch (Exception e) {
+			Utils.showException(GitblitManager.this, e);
+		}
+	}
+
 	public static void main(String[] args) {
 		EventQueue.invokeLater(new Runnable() {
 			public void run() {

--
Gitblit v1.9.1