From 13331ae61c7f08b4a202a531e005915147467bd8 Mon Sep 17 00:00:00 2001
From: James Moger <james.moger@gitblit.com>
Date: Thu, 10 Apr 2014 18:58:09 -0400
Subject: [PATCH] Exclude SSH repository urls from anonymous users

---
 src/main/java/com/gitblit/transport/ssh/commands/DispatchCommand.java |   95 +++++++++++++++++++++++------------------------
 1 files changed, 47 insertions(+), 48 deletions(-)

diff --git a/src/main/java/com/gitblit/transport/ssh/commands/DispatchCommand.java b/src/main/java/com/gitblit/transport/ssh/commands/DispatchCommand.java
index 38f1a48..00b79ff 100644
--- a/src/main/java/com/gitblit/transport/ssh/commands/DispatchCommand.java
+++ b/src/main/java/com/gitblit/transport/ssh/commands/DispatchCommand.java
@@ -30,17 +30,16 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import ro.fortsoft.pf4j.ExtensionPoint;
+
 import com.gitblit.models.UserModel;
-import com.gitblit.transport.ssh.CommandMetaData;
-import com.gitblit.transport.ssh.CachingPublicKeyAuthenticator;
-import com.gitblit.transport.ssh.gitblit.BaseKeyCommand;
 import com.gitblit.utils.StringUtils;
 import com.gitblit.utils.cli.SubcommandHandler;
 import com.google.common.base.Charsets;
 import com.google.common.base.Strings;
 import com.google.common.collect.Maps;
 
-public abstract class DispatchCommand extends BaseCommand {
+public abstract class DispatchCommand extends BaseCommand implements ExtensionPoint {
 
 	private Logger log = LoggerFactory.getLogger(getClass());
 
@@ -50,31 +49,55 @@
 	@Argument(index = 1, multiValued = true, metaVar = "ARG")
 	private List<String> args = new ArrayList<String>();
 
-	private Set<Class<? extends BaseCommand>> commands;
+	private final Set<Class<? extends BaseCommand>> commands;
+	private final Map<String, DispatchCommand> dispatchers;
+	private final List<BaseCommand> instantiated;
 	private Map<String, Class<? extends BaseCommand>> map;
-	private Map<String, BaseCommand> dispatchers;
 
-	public DispatchCommand() {
+	protected DispatchCommand() {
 		commands = new HashSet<Class<? extends BaseCommand>>();
+		dispatchers = Maps.newHashMap();
+		instantiated = new ArrayList<BaseCommand>();
 	}
 
-	public void registerDispatcher(UserModel user, Class<? extends DispatchCommand> cmd) {
-		if (!cmd.isAnnotationPresent(CommandMetaData.class)) {
-			throw new RuntimeException(MessageFormat.format("{0} must be annotated with {1}!", cmd.getName(),
+	@Override
+	public void destroy() {
+		super.destroy();
+		commands.clear();
+		map = null;
+
+		for (BaseCommand command : instantiated) {
+			command.destroy();
+		}
+		for (DispatchCommand dispatcher : dispatchers.values()) {
+			dispatcher.destroy();
+		}
+	}
+
+	protected void registerDispatcher(UserModel user, Class<? extends DispatchCommand> cmd) {
+		try {
+			DispatchCommand dispatcher = cmd.newInstance();
+			registerDispatcher(user, dispatcher);
+		} catch (Exception e) {
+			log.error("failed to instantiate {}", cmd.getName());
+		}
+	}
+
+	protected void registerDispatcher(UserModel user, DispatchCommand dispatcher) {
+		Class<? extends DispatchCommand> dispatcherClass = dispatcher.getClass();
+		if (!dispatcherClass.isAnnotationPresent(CommandMetaData.class)) {
+			throw new RuntimeException(MessageFormat.format("{0} must be annotated with {1}!", dispatcher.getName(),
 					CommandMetaData.class.getName()));
 		}
-		if (dispatchers == null) {
-			dispatchers = Maps.newHashMap();
-		}
 
-		CommandMetaData meta = cmd.getAnnotation(CommandMetaData.class);
+		CommandMetaData meta = dispatcherClass.getAnnotation(CommandMetaData.class);
 		if (meta.admin() && !user.canAdmin()) {
-			log.debug(MessageFormat.format("excluding admin dispatch command {0} for {1}", meta.name(), user.username));
+			log.debug(MessageFormat.format("excluding admin dispatcher {0} for {1}", meta.name(), user.username));
 			return;
 		}
 
+		log.debug("registering {} dispatcher", meta.name());
 		try {
-			DispatchCommand dispatcher = cmd.newInstance();
 			dispatcher.registerCommands(user);
 			dispatchers.put(meta.name(), dispatcher);
 		} catch (Exception e) {
@@ -82,9 +105,8 @@
 		}
 	}
 
-	protected void registerCommands(UserModel user) {
-	}
 
+	protected abstract void registerCommands(UserModel user);
 
 	/**
 	 * Registers a command as long as the user is permitted to execute it.
@@ -92,7 +114,7 @@
 	 * @param user
 	 * @param cmd
 	 */
-	public void registerCommand(UserModel user, Class<? extends BaseCommand> cmd) {
+	protected void registerCommand(UserModel user, Class<? extends BaseCommand> cmd) {
 		if (!cmd.isAnnotationPresent(CommandMetaData.class)) {
 			throw new RuntimeException(MessageFormat.format("{0} must be annotated with {1}!", cmd.getName(),
 					CommandMetaData.class.getName()));
@@ -112,10 +134,9 @@
 				CommandMetaData meta = cmd.getAnnotation(CommandMetaData.class);
 				map.put(meta.name(), cmd);
 			}
-			if (dispatchers != null) {
-				for (Map.Entry<String, BaseCommand> entry : dispatchers.entrySet()) {
-					map.put(entry.getKey(), entry.getValue().getClass());
-				}
+
+			for (Map.Entry<String, DispatchCommand> entry : dispatchers.entrySet()) {
+				map.put(entry.getKey(), entry.getValue().getClass());
 			}
 		}
 		return map;
@@ -167,6 +188,7 @@
 		BaseCommand cmd = null;
 		try {
 			cmd = c.newInstance();
+			instantiated.add(cmd);
 		} catch (Exception e) {
 			throw new UnloggedFailure(1, MessageFormat.format("Failed to instantiate {0} command", commandName));
 		}
@@ -182,10 +204,8 @@
 		for (String name : m.keySet()) {
 			Class<? extends BaseCommand> c = m.get(name);
 			CommandMetaData meta = c.getAnnotation(CommandMetaData.class);
-			if (meta != null) {
-				if (meta.hidden()) {
-					continue;
-				}
+			if (meta.hidden()) {
+				continue;
 			}
 
 			maxLength = Math.max(maxLength, name.length());
@@ -242,26 +262,5 @@
 		usage.append("COMMAND --help' for more information.\n");
 		usage.append("\n");
 		return usage.toString();
-	}
-
-	protected void provideStateTo(final BaseCommand cmd) {
-		if (cmd instanceof BaseCommand) {
-			cmd.setContext(ctx);
-		}
-		cmd.setInputStream(in);
-		cmd.setOutputStream(out);
-		cmd.setErrorStream(err);
-		cmd.setExitCallback(exit);
-
-		if (cmd instanceof BaseKeyCommand) {
-			BaseKeyCommand k = (BaseKeyCommand) cmd;
-			k.setAuthenticator(authenticator);
-		}
-	}
-
-	private CachingPublicKeyAuthenticator authenticator;
-
-	public void setAuthenticator(CachingPublicKeyAuthenticator authenticator) {
-		this.authenticator = authenticator;
 	}
 }

--
Gitblit v1.9.1