From 413e9b486b1a84960d4c8ddac130e87280f64c6a Mon Sep 17 00:00:00 2001 From: James Moger Date: Sun, 30 Mar 2014 14:21:19 -0400 Subject: [PATCH] Split administration commands into a plugin, enhance plugin manager --- build.xml | 42 +- .../com/gitblit/manager/GitblitManager.java | 52 ++ .../com/gitblit/manager/IPluginManager.java | 23 +- .../com/gitblit/manager/PluginManager.java | 32 +- .../gitblit/transport/ssh/WelcomeShell.java | 2 +- .../ssh/commands/PluginDispatcher.java | 293 +++++++++ .../ssh/commands/RootDispatcher.java | 6 +- .../{gitblit => commands}/VersionCommand.java | 4 +- .../transport/ssh/gitblit/ConfigCommand.java | 174 ----- .../ssh/gitblit/GitblitDispatcher.java | 40 -- .../transport/ssh/gitblit/ListDispatcher.java | 58 -- .../ssh/gitblit/ProjectsDispatcher.java | 94 --- .../ssh/gitblit/RepositoriesDispatcher.java | 532 ---------------- .../transport/ssh/gitblit/ReviewCommand.java | 89 --- .../ssh/gitblit/TeamsDispatcher.java | 507 --------------- .../ssh/gitblit/TicketsDispatcher.java | 157 ----- .../ssh/gitblit/UsersDispatcher.java | 592 ------------------ .../ssh/{gitblit => keys}/BaseKeyCommand.java | 2 +- .../ssh/{gitblit => keys}/KeysDispatcher.java | 2 +- src/site/setup_transport_ssh.mkd | 22 +- .../java/com/gitblit/tests/SshDaemonTest.java | 2 +- 21 files changed, 433 insertions(+), 2292 deletions(-) create mode 100644 src/main/java/com/gitblit/transport/ssh/commands/PluginDispatcher.java rename src/main/java/com/gitblit/transport/ssh/{gitblit => commands}/VersionCommand.java (84%) delete mode 100644 src/main/java/com/gitblit/transport/ssh/gitblit/ConfigCommand.java delete mode 100644 src/main/java/com/gitblit/transport/ssh/gitblit/GitblitDispatcher.java delete mode 100644 src/main/java/com/gitblit/transport/ssh/gitblit/ListDispatcher.java delete mode 100644 src/main/java/com/gitblit/transport/ssh/gitblit/ProjectsDispatcher.java delete mode 100644 src/main/java/com/gitblit/transport/ssh/gitblit/RepositoriesDispatcher.java delete mode 100644 src/main/java/com/gitblit/transport/ssh/gitblit/ReviewCommand.java delete mode 100644 src/main/java/com/gitblit/transport/ssh/gitblit/TeamsDispatcher.java delete mode 100644 src/main/java/com/gitblit/transport/ssh/gitblit/TicketsDispatcher.java delete mode 100644 src/main/java/com/gitblit/transport/ssh/gitblit/UsersDispatcher.java rename src/main/java/com/gitblit/transport/ssh/{gitblit => keys}/BaseKeyCommand.java (97%) rename src/main/java/com/gitblit/transport/ssh/{gitblit => keys}/KeysDispatcher.java (99%) diff --git a/build.xml b/build.xml index a802c827..0baf090e 100644 --- a/build.xml +++ b/build.xml @@ -569,14 +569,14 @@ - - - - + + + + - - - + + + @@ -888,14 +888,14 @@ - - - - - + + + + + - - + + @@ -1046,5 +1046,19 @@ + + + + + + + + + + diff --git a/src/main/java/com/gitblit/manager/GitblitManager.java b/src/main/java/com/gitblit/manager/GitblitManager.java index 0001706c..6b1cc8a5 100644 --- a/src/main/java/com/gitblit/manager/GitblitManager.java +++ b/src/main/java/com/gitblit/manager/GitblitManager.java @@ -42,7 +42,9 @@ import org.eclipse.jgit.transport.RefSpec; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import ro.fortsoft.pf4j.PluginClassLoader; import ro.fortsoft.pf4j.PluginWrapper; +import ro.fortsoft.pf4j.RuntimeMode; import com.gitblit.Constants; import com.gitblit.Constants.AccessPermission; @@ -1187,4 +1189,54 @@ public class GitblitManager implements IGitblit { public PluginWrapper whichPlugin(Class clazz) { return pluginManager.whichPlugin(clazz); } + + @Override + public boolean deletePlugin(PluginWrapper wrapper) { + return pluginManager.deletePlugin(wrapper); + } + + @Override + public List getPlugins() { + return pluginManager.getPlugins(); + } + + @Override + public List getResolvedPlugins() { + return pluginManager.getResolvedPlugins(); + } + + @Override + public List getUnresolvedPlugins() { + return pluginManager.getUnresolvedPlugins(); + } + + @Override + public List getStartedPlugins() { + return pluginManager.getStartedPlugins(); + } + + @Override + public void loadPlugins() { + pluginManager.loadPlugins(); + } + + @Override + public void startPlugins() { + pluginManager.startPlugins(); + } + + @Override + public void stopPlugins() { + pluginManager.stopPlugins(); + } + + @Override + public PluginClassLoader getPluginClassLoader(String pluginId) { + return pluginManager.getPluginClassLoader(pluginId); + } + + @Override + public RuntimeMode getRuntimeMode() { + return pluginManager.getRuntimeMode(); + } } diff --git a/src/main/java/com/gitblit/manager/IPluginManager.java b/src/main/java/com/gitblit/manager/IPluginManager.java index 670e9769..11b81ea3 100644 --- a/src/main/java/com/gitblit/manager/IPluginManager.java +++ b/src/main/java/com/gitblit/manager/IPluginManager.java @@ -15,19 +15,10 @@ */ package com.gitblit.manager; -import java.util.List; - +import ro.fortsoft.pf4j.PluginManager; import ro.fortsoft.pf4j.PluginWrapper; -public interface IPluginManager extends IManager { - - /** - * Retrieves the extension for given class 'clazz'. - * - * @param clazz extension point class to retrieve extension for - * @return list of extensions - */ - public List getExtensions(Class clazz); +public interface IPluginManager extends IManager, PluginManager { /** * Retrieves the {@link PluginWrapper} that loaded the given class 'clazz'. @@ -35,5 +26,13 @@ public interface IPluginManager extends IManager { * @param clazz extension point class to retrieve extension for * @return PluginWrapper that loaded the given class */ - public PluginWrapper whichPlugin(Class clazz); + PluginWrapper whichPlugin(Class clazz); + + /** + * Delete the plugin represented by {@link PluginWrapper}. + * + * @param wrapper + * @return true if successful + */ + boolean deletePlugin(PluginWrapper wrapper); } diff --git a/src/main/java/com/gitblit/manager/PluginManager.java b/src/main/java/com/gitblit/manager/PluginManager.java index 5eb00e92..e23aaec0 100644 --- a/src/main/java/com/gitblit/manager/PluginManager.java +++ b/src/main/java/com/gitblit/manager/PluginManager.java @@ -15,12 +15,16 @@ */ package com.gitblit.manager; +import java.io.File; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ro.fortsoft.pf4j.DefaultPluginManager; +import ro.fortsoft.pf4j.PluginWrapper; import com.gitblit.Keys; +import com.gitblit.utils.FileUtils; /** * The plugin manager maintains the lifecycle of plugins. It is exposed as @@ -30,27 +34,45 @@ import com.gitblit.Keys; * @author David Ostrovsky * */ -public class PluginManager extends DefaultPluginManager implements - IPluginManager { +public class PluginManager extends DefaultPluginManager implements IPluginManager { private final Logger logger = LoggerFactory.getLogger(getClass()); + + private final IRuntimeManager runtimeManager; public PluginManager(IRuntimeManager runtimeManager) { - super(runtimeManager.getFileOrFolder(Keys.plugins.folder, - "${baseFolder}/plugins")); + super(runtimeManager.getFileOrFolder(Keys.plugins.folder, "${baseFolder}/plugins")); + this.runtimeManager = runtimeManager; } @Override public PluginManager start() { - logger.info("Plugin manager started"); + logger.info("Loading plugins..."); loadPlugins(); + logger.info("Starting loaded plugins..."); startPlugins(); return this; } @Override public PluginManager stop() { + logger.info("Stopping loaded plugins..."); stopPlugins(); return null; } + + @Override + public boolean deletePlugin(PluginWrapper pw) { + File folder = runtimeManager.getFileOrFolder(Keys.plugins.folder, "${baseFolder}/plugins"); + File pluginFolder = new File(folder, pw.getPluginPath()); + File pluginZip = new File(folder, pw.getPluginPath() + ".zip"); + + if (pluginFolder.exists()) { + FileUtils.delete(pluginFolder); + } + if (pluginZip.exists()) { + FileUtils.delete(pluginZip); + } + return true; + } } diff --git a/src/main/java/com/gitblit/transport/ssh/WelcomeShell.java b/src/main/java/com/gitblit/transport/ssh/WelcomeShell.java index 6809ba62..4341a3ea 100644 --- a/src/main/java/com/gitblit/transport/ssh/WelcomeShell.java +++ b/src/main/java/com/gitblit/transport/ssh/WelcomeShell.java @@ -165,7 +165,7 @@ public class WelcomeShell implements Factory { msg.append(nl); msg.append(nl); - msg.append(String.format(" cat ~/.ssh/id_rsa.pub | ssh -l %s -p %d %s gitblit keys add", user.username, port, hostname)); + msg.append(String.format(" cat ~/.ssh/id_rsa.pub | ssh -l %s -p %d %s keys add", user.username, port, hostname)); msg.append(nl); msg.append(nl); diff --git a/src/main/java/com/gitblit/transport/ssh/commands/PluginDispatcher.java b/src/main/java/com/gitblit/transport/ssh/commands/PluginDispatcher.java new file mode 100644 index 00000000..5c413db2 --- /dev/null +++ b/src/main/java/com/gitblit/transport/ssh/commands/PluginDispatcher.java @@ -0,0 +1,293 @@ +/* + * Copyright 2014 gitblit.com. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitblit.transport.ssh.commands; + +import java.util.ArrayList; +import java.util.List; + +import org.kohsuke.args4j.Argument; + +import ro.fortsoft.pf4j.PluginDependency; +import ro.fortsoft.pf4j.PluginDescriptor; +import ro.fortsoft.pf4j.PluginState; +import ro.fortsoft.pf4j.PluginWrapper; + +import com.gitblit.manager.IGitblit; +import com.gitblit.models.UserModel; +import com.gitblit.utils.FlipTable; +import com.gitblit.utils.FlipTable.Borders; + +/** + * The plugin dispatcher and commands for runtime plugin management. + * + * @author James Moger + * + */ +@CommandMetaData(name = "plugin", description = "Plugin management commands", admin = true) +public class PluginDispatcher extends DispatchCommand { + + @Override + protected void setup(UserModel user) { + register(user, ListPlugins.class); + register(user, StartPlugin.class); + register(user, StopPlugin.class); + register(user, ShowPlugin.class); + register(user, RemovePlugin.class); + register(user, UploadPlugin.class); + } + + @CommandMetaData(name = "list", aliases = { "ls" }, description = "List the loaded plugins") + public static class ListPlugins extends ListCommand { + + @Override + protected List getItems() throws UnloggedFailure { + IGitblit gitblit = getContext().getGitblit(); + List list = gitblit.getPlugins(); + return list; + } + + @Override + protected void asTable(List list) { + String[] headers; + if (verbose) { + String [] h = { "#", "Id", "Version", "State", "Mode", "Path", "Provider"}; + headers = h; + } else { + String [] h = { "#", "Id", "Version", "State", "Path"}; + headers = h; + } + Object[][] data = new Object[list.size()][]; + for (int i = 0; i < list.size(); i++) { + PluginWrapper p = list.get(i); + PluginDescriptor d = p.getDescriptor(); + if (verbose) { + data[i] = new Object[] { "" + (i + 1), d.getPluginId(), d.getVersion(), p.getPluginState(), p.getRuntimeMode(), p.getPluginPath(), d.getProvider() }; + } else { + data[i] = new Object[] { "" + (i + 1), d.getPluginId(), d.getVersion(), p.getPluginState(), p.getPluginPath() }; + } + } + + stdout.println(FlipTable.of(headers, data, Borders.BODY_HCOLS)); + } + + @Override + protected void asTabbed(List list) { + for (PluginWrapper pw : list) { + PluginDescriptor d = pw.getDescriptor(); + if (verbose) { + outTabbed(d.getPluginId(), d.getVersion(), pw.getPluginState(), pw.getRuntimeMode(), pw.getPluginPath(), d.getProvider()); + } else { + outTabbed(d.getPluginId(), d.getVersion(), pw.getPluginState(), pw.getPluginPath()); + } + } + } + } + + @CommandMetaData(name = "start", description = "Start a plugin") + public static class StartPlugin extends SshCommand { + + @Argument(index = 0, required = true, metaVar = "ALL|", usage = "the plugin to start") + protected String plugin; + + @Override + public void run() throws UnloggedFailure { + IGitblit gitblit = getContext().getGitblit(); + if (plugin.equalsIgnoreCase("ALL")) { + gitblit.startPlugins(); + stdout.println("All plugins started"); + } else { + try { + int index = Integer.parseInt(plugin); + List plugins = gitblit.getPlugins(); + if (index > plugins.size()) { + throw new UnloggedFailure(1, "Invalid plugin index specified!"); + } + PluginWrapper pw = plugins.get(index - 1); + start(pw); + } catch (NumberFormatException n) { + for (PluginWrapper pw : gitblit.getPlugins()) { + PluginDescriptor pd = pw.getDescriptor(); + if (pd.getPluginId().equalsIgnoreCase(plugin)) { + start(pw); + break; + } + } + } + } + } + + protected void start(PluginWrapper pw) throws UnloggedFailure { + String id = pw.getDescriptor().getPluginId(); + if (pw.getPluginState() == PluginState.STARTED) { + throw new UnloggedFailure(1, String.format("%s is already started.", id)); + } + try { + pw.getPlugin().start(); +// pw.setPluginState(PluginState.STARTED); + stdout.println(String.format("%s started", id)); + } catch (Exception pe) { + throw new UnloggedFailure(1, String.format("Failed to start %s", id), pe); + } + } + } + + + @CommandMetaData(name = "stop", description = "Stop a plugin") + public static class StopPlugin extends SshCommand { + + @Argument(index = 0, required = true, metaVar = "ALL|", usage = "the plugin to stop") + protected String plugin; + + @Override + public void run() throws UnloggedFailure { + IGitblit gitblit = getContext().getGitblit(); + if (plugin.equalsIgnoreCase("ALL")) { + gitblit.stopPlugins(); + stdout.println("All plugins stopped"); + } else { + try { + int index = Integer.parseInt(plugin); + List plugins = gitblit.getPlugins(); + if (index > plugins.size()) { + throw new UnloggedFailure(1, "Invalid plugin index specified!"); + } + PluginWrapper pw = plugins.get(index - 1); + stop(pw); + } catch (NumberFormatException n) { + for (PluginWrapper pw : gitblit.getPlugins()) { + PluginDescriptor pd = pw.getDescriptor(); + if (pd.getPluginId().equalsIgnoreCase(plugin)) { + stop(pw); + break; + } + } + } + } + } + + protected void stop(PluginWrapper pw) throws UnloggedFailure { + String id = pw.getDescriptor().getPluginId(); + if (pw.getPluginState() == PluginState.STOPPED) { + throw new UnloggedFailure(1, String.format("%s is already stopped.", id)); + } + try { + pw.getPlugin().stop(); +// pw.setPluginState(PluginState.STOPPED); + stdout.println(String.format("%s stopped", id)); + } catch (Exception pe) { + throw new UnloggedFailure(1, String.format("Failed to stop %s", id), pe); + } + } + } + + @CommandMetaData(name = "show", description = "Show the details of a plugin") + public static class ShowPlugin extends SshCommand { + + @Argument(index = 0, required = true, metaVar = "", usage = "the plugin to stop") + protected int index; + + @Override + public void run() throws UnloggedFailure { + IGitblit gitblit = getContext().getGitblit(); + List plugins = gitblit.getPlugins(); + if (index > plugins.size()) { + throw new UnloggedFailure(1, "Invalid plugin index specified!"); + } + PluginWrapper pw = plugins.get(index - 1); + PluginDescriptor d = pw.getDescriptor(); + + // FIELDS + StringBuilder sb = new StringBuilder(); + sb.append("Version : ").append(d.getVersion()).append('\n'); + sb.append("Provider : ").append(d.getProvider()).append('\n'); + sb.append("Path : ").append(pw.getPluginPath()).append('\n'); + sb.append("State : ").append(pw.getPluginState()).append('\n'); + final String fields = sb.toString(); + + // TODO EXTENSIONS + sb.setLength(0); + List exts = new ArrayList(); + String extensions; + if (exts.isEmpty()) { + extensions = FlipTable.EMPTY; + } else { + String[] headers = { "Id", "Version" }; + Object[][] data = new Object[exts.size()][]; + for (int i = 0; i < exts.size(); i++) { + String ext = exts.get(i); + data[0] = new Object[] { ext.toString(), ext.toString() }; + } + extensions = FlipTable.of(headers, data, Borders.COLS); + } + + // DEPENDENCIES + sb.setLength(0); + List deps = d.getDependencies(); + String dependencies; + if (deps.isEmpty()) { + dependencies = FlipTable.EMPTY; + } else { + String[] headers = { "Id", "Version" }; + Object[][] data = new Object[deps.size()][]; + for (int i = 0; i < deps.size(); i++) { + PluginDependency dep = deps.get(i); + data[0] = new Object[] { dep.getPluginId(), dep.getPluginVersion() }; + } + dependencies = FlipTable.of(headers, data, Borders.COLS); + } + + String[] headers = { d.getPluginId() }; + Object[][] data = new Object[5][]; + data[0] = new Object[] { fields }; + data[1] = new Object[] { "EXTENSIONS" }; + data[2] = new Object[] { extensions }; + data[3] = new Object[] { "DEPENDENCIES" }; + data[4] = new Object[] { dependencies }; + stdout.println(FlipTable.of(headers, data)); + } + } + + @CommandMetaData(name = "remove", aliases= { "rm", "del" }, description = "Remove a plugin", hidden = true) + public static class RemovePlugin extends SshCommand { + + @Argument(index = 0, required = true, metaVar = "", usage = "the plugin to stop") + protected int index; + + @Override + public void run() throws UnloggedFailure { + IGitblit gitblit = getContext().getGitblit(); + List plugins = gitblit.getPlugins(); + if (index > plugins.size()) { + throw new UnloggedFailure(1, "Invalid plugin index specified!"); + } + PluginWrapper pw = plugins.get(index - 1); + PluginDescriptor d = pw.getDescriptor(); + if (gitblit.deletePlugin(pw)) { + stdout.println(String.format("Deleted %s %s", d.getPluginId(), d.getVersion())); + } else { + throw new UnloggedFailure(1, String.format("Failed to delete %s %s", d.getPluginId(), d.getVersion())); + } + } + } + + @CommandMetaData(name = "receive", aliases= { "upload" }, description = "Upload a plugin to the server", hidden = true) + public static class UploadPlugin extends SshCommand { + + @Override + public void run() throws UnloggedFailure { + } + } +} diff --git a/src/main/java/com/gitblit/transport/ssh/commands/RootDispatcher.java b/src/main/java/com/gitblit/transport/ssh/commands/RootDispatcher.java index 8a871ebb..3c378669 100644 --- a/src/main/java/com/gitblit/transport/ssh/commands/RootDispatcher.java +++ b/src/main/java/com/gitblit/transport/ssh/commands/RootDispatcher.java @@ -24,7 +24,7 @@ import com.gitblit.manager.IGitblit; import com.gitblit.models.UserModel; import com.gitblit.transport.ssh.SshDaemonClient; import com.gitblit.transport.ssh.git.GitDispatcher; -import com.gitblit.transport.ssh.gitblit.GitblitDispatcher; +import com.gitblit.transport.ssh.keys.KeysDispatcher; /** * The root dispatcher is the dispatch command that handles registering all @@ -41,8 +41,10 @@ class RootDispatcher extends DispatchCommand { setContext(new SshCommandContext(gitblit, client, cmdLine)); UserModel user = client.getUser(); - register(user, GitblitDispatcher.class); + register(user, VersionCommand.class); register(user, GitDispatcher.class); + register(user, KeysDispatcher.class); + register(user, PluginDispatcher.class); List exts = gitblit.getExtensions(DispatchCommand.class); for (DispatchCommand ext : exts) { diff --git a/src/main/java/com/gitblit/transport/ssh/gitblit/VersionCommand.java b/src/main/java/com/gitblit/transport/ssh/commands/VersionCommand.java similarity index 84% rename from src/main/java/com/gitblit/transport/ssh/gitblit/VersionCommand.java rename to src/main/java/com/gitblit/transport/ssh/commands/VersionCommand.java index 384c6ce4..3a2fd5e2 100644 --- a/src/main/java/com/gitblit/transport/ssh/gitblit/VersionCommand.java +++ b/src/main/java/com/gitblit/transport/ssh/commands/VersionCommand.java @@ -14,11 +14,9 @@ * limitations under the License. */ -package com.gitblit.transport.ssh.gitblit; +package com.gitblit.transport.ssh.commands; import com.gitblit.Constants; -import com.gitblit.transport.ssh.commands.CommandMetaData; -import com.gitblit.transport.ssh.commands.SshCommand; @CommandMetaData(name="version", description = "Display the Gitblit version") public class VersionCommand extends SshCommand { diff --git a/src/main/java/com/gitblit/transport/ssh/gitblit/ConfigCommand.java b/src/main/java/com/gitblit/transport/ssh/gitblit/ConfigCommand.java deleted file mode 100644 index f6740349..00000000 --- a/src/main/java/com/gitblit/transport/ssh/gitblit/ConfigCommand.java +++ /dev/null @@ -1,174 +0,0 @@ -package com.gitblit.transport.ssh.gitblit; - -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import org.kohsuke.args4j.Argument; -import org.kohsuke.args4j.Option; -import org.parboiled.common.StringUtils; - -import com.gitblit.manager.IGitblit; -import com.gitblit.models.ServerSettings; -import com.gitblit.models.SettingModel; -import com.gitblit.transport.ssh.commands.CommandMetaData; -import com.gitblit.transport.ssh.commands.SshCommand; -import com.gitblit.transport.ssh.commands.UsageExample; -import com.gitblit.transport.ssh.commands.UsageExamples; -import com.google.common.collect.Maps; - -@CommandMetaData(name = "config", description = "Administer Gitblit settings", admin = true) -@UsageExamples(examples = { - @UsageExample(syntax = "${cmd} --list", description = "List all settings"), - @UsageExample(syntax = "${cmd} git.sshPort", description = "Describe the git.sshPort setting"), - @UsageExample(syntax = "${cmd} git.sshPort 29418", description = "Set git.sshPort to 29418"), - @UsageExample(syntax = "${cmd} git.sshPort --reset", description = "Reset git.sshPort to it's default value"), -}) -public class ConfigCommand extends SshCommand { - - @Argument(index = 0, metaVar = "KEY", usage = "The setting to describe or update") - protected String setting; - - @Argument(index = 1, metaVar = "VALUE", usage = "The new value for the setting") - protected String value; - - @Option(name = "--list", aliases = { "-l" }, usage = "List all settings") - private boolean listAll; - - @Option(name = "--modified", aliases = { "-m" }, usage = "List modified settings") - private boolean listModified; - - @Option(name = "--reset", usage = "Reset a setting to it's default value") - private boolean reset; - - @Override - public void run() throws UnloggedFailure { - IGitblit gitblit = getContext().getGitblit(); - ServerSettings settings = gitblit.getSettingsModel(); - - if (listAll || listModified) { - /* - * List settings - */ - List list = new ArrayList(); - int maxLen = 0; - for (String key : settings.getKeys()) { - SettingModel model = settings.get(key); - if (listModified) { - if (!model.isDefaultValue()) { - list.add(model); - } else { - continue; - } - } else { - list.add(model); - } - - if (key.length() > maxLen) { - maxLen = key.length(); - } - } - String pattern = MessageFormat.format("%s%-{0,number,0}s : %s", maxLen); - for (SettingModel model : list) { - stdout.println(String.format(pattern, - model.isDefaultValue() ? " " : "*", - model.name, - model.currentValue)); - } - } else if (!StringUtils.isEmpty(setting) && value == null && !reset) { - /* - * Describe a setting - */ - SettingModel model = settings.get(setting); - if (model == null) { - // unknown setting - String value = gitblit.getSettings().getString(setting, null); - if (value == null) { - // setting does not exist, can not describe - stdout.println(String.format("\"%s\" is not a valid setting.", setting)); - return; - } - - model = new SettingModel(); - model.defaultValue = ""; - model.currentValue = value; - } - stdout.println(); - stdout.println(model.name); - if (!StringUtils.isEmpty(model.since)) { - stdout.println(SettingModel.SINCE + " " + model.since); - } - if (model.restartRequired) { - stdout.println(SettingModel.RESTART_REQUIRED); - } - if (model.spaceDelimited) { - stdout.println(SettingModel.SPACE_DELIMITED); - } - if (!StringUtils.isEmpty(model.description)) { - stdout.println(); - stdout.println(model.description); - } - stdout.println(); - if (model.defaultValue != null) { - stdout.println("default: " + model.defaultValue); - } - if (!model.isDefaultValue()) { - stdout.println("current: " + model.currentValue); - } else { - stdout.println("current: "); - } - stdout.println(); - } else if (!StringUtils.isEmpty(setting) && value == null && reset) { - /* - * Reset a setting - */ - SettingModel model = settings.get(setting); - if (model == null) { - stdout.println(String.format("\"%s\" is not a valid setting.", setting)); - return; - } - - if (model.defaultValue == null || model.defaultValue.equals("null")) { - // no default value, remove setting - gitblit.getSettings().removeSetting(setting); - gitblit.getSettings().saveSettings(); - settings.remove(setting); - - stdout.println(String.format("%s removed.", setting)); - } else { - // reset to default value - Map updates = Maps.newHashMap(); - updates.put(setting, model.defaultValue == null ? "" : model.defaultValue); - gitblit.getSettings().saveSettings(updates); - - // confirm reset - String newValue = gitblit.getSettings().getString(setting, null); - if (model.defaultValue.equals(newValue)) { - stdout.println(String.format("%s reset to the default value.", setting)); - } else { - stdout.println(String.format("failed to reset %s!", setting)); - } - } - - } else if (!StringUtils.isEmpty(setting) && value != null) { - /* - * Update a setting - */ - Map updates = Maps.newHashMap(); - updates.put(setting, value); - gitblit.getSettings().saveSettings(updates); - - // confirm update - String newValue = gitblit.getSettings().getString(setting, null); - if (value.equals(newValue)) { - stdout.println(String.format("%s updated.", setting)); - } else { - stdout.println(String.format("failed to update %s!", setting)); - } - } else { - // Display usage - showHelp(); - } - } -} \ No newline at end of file diff --git a/src/main/java/com/gitblit/transport/ssh/gitblit/GitblitDispatcher.java b/src/main/java/com/gitblit/transport/ssh/gitblit/GitblitDispatcher.java deleted file mode 100644 index 67fedeaa..00000000 --- a/src/main/java/com/gitblit/transport/ssh/gitblit/GitblitDispatcher.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2014 gitblit.com. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.gitblit.transport.ssh.gitblit; - -import com.gitblit.models.UserModel; -import com.gitblit.transport.ssh.commands.CommandMetaData; -import com.gitblit.transport.ssh.commands.DispatchCommand; - -@CommandMetaData(name = "gitblit", description = "Gitblit server commands") -public class GitblitDispatcher extends DispatchCommand { - - @Override - protected void setup(UserModel user) { - // commands in this dispatcher - register(user, VersionCommand.class); - register(user, ConfigCommand.class); - - // nested dispatchers - register(user, ListDispatcher.class); - register(user, KeysDispatcher.class); - register(user, TicketsDispatcher.class); - register(user, UsersDispatcher.class); - register(user, TeamsDispatcher.class); - register(user, ProjectsDispatcher.class); - register(user, RepositoriesDispatcher.class); - } -} diff --git a/src/main/java/com/gitblit/transport/ssh/gitblit/ListDispatcher.java b/src/main/java/com/gitblit/transport/ssh/gitblit/ListDispatcher.java deleted file mode 100644 index 343e59aa..00000000 --- a/src/main/java/com/gitblit/transport/ssh/gitblit/ListDispatcher.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2014 gitblit.com. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.gitblit.transport.ssh.gitblit; - -import com.gitblit.models.UserModel; -import com.gitblit.transport.ssh.commands.CommandMetaData; -import com.gitblit.transport.ssh.commands.DispatchCommand; - -/** - * The dispatcher and it's commands for Gitblit object listing. - * - * @author James Moger - * - */ -@CommandMetaData(name = "list", aliases = { "ls" }, description = "Gitblit object list commands") -public class ListDispatcher extends DispatchCommand { - - @Override - protected void setup(UserModel user) { - register(user, ListRepositories.class); - register(user, ListProjects.class); - register(user, ListUsers.class); - register(user, ListKeys.class); - } - - /* List SSH public keys */ - @CommandMetaData(name = "keys", description = "List your public keys") - public static class ListKeys extends KeysDispatcher.ListKeys { - } - - /* List repositories */ - @CommandMetaData(name = "repositories", aliases = { "repos" }, description = "List repositories") - public static class ListRepositories extends RepositoriesDispatcher.ListRepositories { - } - - /* List projects */ - @CommandMetaData(name = "projects", description = "List projects") - public static class ListProjects extends ProjectsDispatcher.ListProjects { - } - - /* List users */ - @CommandMetaData(name = "users", description = "List users", admin = true) - public static class ListUsers extends UsersDispatcher.ListUsers { - } -} diff --git a/src/main/java/com/gitblit/transport/ssh/gitblit/ProjectsDispatcher.java b/src/main/java/com/gitblit/transport/ssh/gitblit/ProjectsDispatcher.java deleted file mode 100644 index 97076adf..00000000 --- a/src/main/java/com/gitblit/transport/ssh/gitblit/ProjectsDispatcher.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2014 gitblit.com. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.gitblit.transport.ssh.gitblit; - -import java.util.List; - -import com.gitblit.manager.IGitblit; -import com.gitblit.models.ProjectModel; -import com.gitblit.models.UserModel; -import com.gitblit.transport.ssh.commands.CommandMetaData; -import com.gitblit.transport.ssh.commands.DispatchCommand; -import com.gitblit.transport.ssh.commands.ListFilterCommand; -import com.gitblit.utils.FlipTable; -import com.gitblit.utils.FlipTable.Borders; - -@CommandMetaData(name = "projects", description = "Project management commands") -public class ProjectsDispatcher extends DispatchCommand { - - @Override - protected void setup(UserModel user) { - register(user, ListProjects.class); - } - - /* List projects */ - @CommandMetaData(name = "list", aliases= { "ls" }, description = "List projects") - public static class ListProjects extends ListFilterCommand { - - @Override - protected List getItems() { - IGitblit gitblit = getContext().getGitblit(); - UserModel user = getContext().getClient().getUser(); - - List projects = gitblit.getProjectModels(user, false); - return projects; - } - - @Override - protected boolean matches(String filter, ProjectModel p) { - return p.name.matches(filter); - } - - @Override - protected void asTable(List list) { - String[] headers; - if (verbose) { - String[] h = { "Name", "Description", "Last Modified", "# Repos" }; - headers = h; - } else { - String[] h = { "Name", "Last Modified", "# Repos" }; - headers = h; - } - - Object[][] data = new Object[list.size()][]; - for (int i = 0; i < list.size(); i++) { - ProjectModel p = list.get(i); - - if (verbose) { - data[i] = new Object[] { p.name, p.description, formatDate(p.lastChange), p.repositories.size() }; - } else { - data[i] = new Object[] { p.name, formatDate(p.lastChange), p.repositories.size() }; - } - } - stdout.println(FlipTable.of(headers, data, Borders.BODY_HCOLS)); - } - - @Override - protected void asTabbed(List list) { - if (verbose) { - for (ProjectModel project : list) { - outTabbed(project.name, - project.description == null ? "" : project.description, - formatDate(project.lastChange)); - } - } else { - for (ProjectModel project : list) { - outTabbed(project.name); - } - } - } - } -} \ No newline at end of file diff --git a/src/main/java/com/gitblit/transport/ssh/gitblit/RepositoriesDispatcher.java b/src/main/java/com/gitblit/transport/ssh/gitblit/RepositoriesDispatcher.java deleted file mode 100644 index 292c2126..00000000 --- a/src/main/java/com/gitblit/transport/ssh/gitblit/RepositoriesDispatcher.java +++ /dev/null @@ -1,532 +0,0 @@ -/* - * Copyright 2014 gitblit.com. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.gitblit.transport.ssh.gitblit; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.kohsuke.args4j.Argument; - -import com.gitblit.GitBlitException; -import com.gitblit.Keys; -import com.gitblit.Constants.AccessRestrictionType; -import com.gitblit.Constants.AuthorizationControl; -import com.gitblit.manager.IGitblit; -import com.gitblit.models.RegistrantAccessPermission; -import com.gitblit.models.RepositoryModel; -import com.gitblit.models.UserModel; -import com.gitblit.transport.ssh.commands.CommandMetaData; -import com.gitblit.transport.ssh.commands.DispatchCommand; -import com.gitblit.transport.ssh.commands.ListFilterCommand; -import com.gitblit.transport.ssh.commands.SshCommand; -import com.gitblit.transport.ssh.commands.UsageExample; -import com.gitblit.utils.ArrayUtils; -import com.gitblit.utils.FlipTable; -import com.gitblit.utils.FlipTable.Borders; -import com.gitblit.utils.StringUtils; -import com.google.common.base.Joiner; - -@CommandMetaData(name = "repositories", aliases = { "repos" }, description = "Repository management commands") -public class RepositoriesDispatcher extends DispatchCommand { - - @Override - protected void setup(UserModel user) { - // primary commands - register(user, NewRepository.class); - register(user, RenameRepository.class); - register(user, RemoveRepository.class); - register(user, ShowRepository.class); - register(user, ListRepositories.class); - - // repository-specific commands - register(user, SetField.class); - } - - public static abstract class RepositoryCommand extends SshCommand { - @Argument(index = 0, required = true, metaVar = "REPOSITORY", usage = "repository") - protected String repository; - - protected RepositoryModel getRepository(boolean requireRepository) throws UnloggedFailure { - IGitblit gitblit = getContext().getGitblit(); - RepositoryModel repo = gitblit.getRepositoryModel(repository); - if (requireRepository && repo == null) { - throw new UnloggedFailure(1, String.format("Repository %s does not exist!", repository)); - } - return repo; - } - - protected String sanitize(String name) throws UnloggedFailure { - // automatically convert backslashes to forward slashes - name = name.replace('\\', '/'); - // Automatically replace // with / - name = name.replace("//", "/"); - - // prohibit folder paths - if (name.startsWith("/")) { - throw new UnloggedFailure(1, "Illegal leading slash"); - } - if (name.startsWith("../")) { - throw new UnloggedFailure(1, "Illegal relative slash"); - } - if (name.contains("/../")) { - throw new UnloggedFailure(1, "Illegal relative slash"); - } - if (name.endsWith("/")) { - name = name.substring(0, name.length() - 1); - } - return name; - } - } - - @CommandMetaData(name = "new", aliases = { "add" }, description = "Create a new repository") - @UsageExample(syntax = "${cmd} myRepo") - public static class NewRepository extends RepositoryCommand { - - @Override - public void run() throws UnloggedFailure { - - UserModel user = getContext().getClient().getUser(); - - String name = sanitize(repository); - - if (!user.canCreate(name)) { - // try to prepend personal path - String path = StringUtils.getFirstPathElement(name); - if ("".equals(path)) { - name = user.getPersonalPath() + "/" + name; - } - } - - if (getRepository(false) != null) { - throw new UnloggedFailure(1, String.format("Repository %s already exists!", name)); - } - - if (!user.canCreate(name)) { - throw new UnloggedFailure(1, String.format("Sorry, you do not have permission to create %s", name)); - } - - IGitblit gitblit = getContext().getGitblit(); - - RepositoryModel repo = new RepositoryModel(); - repo.name = name; - repo.projectPath = StringUtils.getFirstPathElement(name); - String restriction = gitblit.getSettings().getString(Keys.git.defaultAccessRestriction, "PUSH"); - repo.accessRestriction = AccessRestrictionType.fromName(restriction); - String authorization = gitblit.getSettings().getString(Keys.git.defaultAuthorizationControl, null); - repo.authorizationControl = AuthorizationControl.fromName(authorization); - - if (user.isMyPersonalRepository(name)) { - // personal repositories are private by default - repo.addOwner(user.username); - repo.accessRestriction = AccessRestrictionType.VIEW; - repo.authorizationControl = AuthorizationControl.NAMED; - } - - try { - gitblit.updateRepositoryModel(repository, repo, true); - stdout.println(String.format("%s created.", repo.name)); - } catch (GitBlitException e) { - log.error("Failed to add " + repository, e); - throw new UnloggedFailure(1, e.getMessage()); - } - } - } - - @CommandMetaData(name = "rename", aliases = { "mv" }, description = "Rename a repository") - @UsageExample(syntax = "${cmd} myRepo.git otherRepo.git", description = "Rename the repository from myRepo.git to otherRepo.git") - public static class RenameRepository extends RepositoryCommand { - @Argument(index = 1, required = true, metaVar = "NEWNAME", usage = "the new repository name") - protected String newRepositoryName; - - @Override - public void run() throws UnloggedFailure { - RepositoryModel repo = getRepository(true); - IGitblit gitblit = getContext().getGitblit(); - UserModel user = getContext().getClient().getUser(); - - String name = sanitize(newRepositoryName); - if (!user.canCreate(name)) { - // try to prepend personal path - String path = StringUtils.getFirstPathElement(name); - if ("".equals(path)) { - name = user.getPersonalPath() + "/" + name; - } - } - - if (null != gitblit.getRepositoryModel(name)) { - throw new UnloggedFailure(1, String.format("Repository %s already exists!", name)); - } - - if (repo.name.equalsIgnoreCase(name)) { - throw new UnloggedFailure(1, "Repository names are identical"); - } - - if (!user.canAdmin(repo)) { - throw new UnloggedFailure(1, String.format("Sorry, you do not have permission to rename %s", repository)); - } - - if (!user.canCreate(name)) { - throw new UnloggedFailure(1, String.format("Sorry, you don't have permission to move %s to %s/", repository, name)); - } - - // set the new name - repo.name = name; - - try { - gitblit.updateRepositoryModel(repository, repo, false); - stdout.println(String.format("Renamed repository %s to %s.", repository, name)); - } catch (GitBlitException e) { - String msg = String.format("Failed to rename repository from %s to %s", repository, name); - log.error(msg, e); - throw new UnloggedFailure(1, msg); - } - } - } - - @CommandMetaData(name = "set", description = "Set the specified field of a repository") - @UsageExample(syntax = "${cmd} myRepo description John's personal projects", description = "Set the description of a repository") - public static class SetField extends RepositoryCommand { - - @Argument(index = 1, required = true, metaVar = "FIELD", usage = "the field to update") - protected String fieldName; - - @Argument(index = 2, required = true, metaVar = "VALUE", usage = "the new value") - protected List fieldValues = new ArrayList(); - - protected enum Field { - description; - - static Field fromString(String name) { - for (Field field : values()) { - if (field.name().equalsIgnoreCase(name)) { - return field; - } - } - return null; - } - } - - @Override - protected String getUsageText() { - String fields = Joiner.on(", ").join(Field.values()); - StringBuilder sb = new StringBuilder(); - sb.append("Valid fields are:\n ").append(fields); - return sb.toString(); - } - - @Override - public void run() throws UnloggedFailure { - RepositoryModel repo = getRepository(true); - - Field field = Field.fromString(fieldName); - if (field == null) { - throw new UnloggedFailure(1, String.format("Unknown field %s", fieldName)); - } - - if (!getContext().getClient().getUser().canAdmin(repo)) { - throw new UnloggedFailure(1, String.format("Sorry, you do not have permission to administer %s", repository)); - } - - String value = Joiner.on(" ").join(fieldValues).trim(); - IGitblit gitblit = getContext().getGitblit(); - - switch(field) { - case description: - repo.description = value; - break; - default: - throw new UnloggedFailure(1, String.format("Field %s was not properly handled by the set command.", fieldName)); - } - - try { - gitblit.updateRepositoryModel(repo.name, repo, false); - stdout.println(String.format("Set %s.%s = %s", repo.name, fieldName, value)); - } catch (GitBlitException e) { - String msg = String.format("Failed to set %s.%s = %s", repo.name, fieldName, value); - log.error(msg, e); - throw new UnloggedFailure(1, msg); - } - } - - protected boolean toBool(String value) throws UnloggedFailure { - String v = value.toLowerCase(); - if (v.equals("t") - || v.equals("true") - || v.equals("yes") - || v.equals("on") - || v.equals("y") - || v.equals("1")) { - return true; - } else if (v.equals("f") - || v.equals("false") - || v.equals("no") - || v.equals("off") - || v.equals("n") - || v.equals("0")) { - return false; - } - throw new UnloggedFailure(1, String.format("Invalid boolean value %s", value)); - } - } - - @CommandMetaData(name = "remove", aliases = { "rm" }, description = "Remove a repository") - @UsageExample(syntax = "${cmd} myRepo.git", description = "Delete myRepo.git") - public static class RemoveRepository extends RepositoryCommand { - - @Override - public void run() throws UnloggedFailure { - - RepositoryModel repo = getRepository(true); - - if (!getContext().getClient().getUser().canAdmin(repo)) { - throw new UnloggedFailure(1, String.format("Sorry, you do not have permission to delete %s", repository)); - } - - IGitblit gitblit = getContext().getGitblit(); - if (gitblit.deleteRepositoryModel(repo)) { - stdout.println(String.format("%s has been deleted.", repository)); - } else { - throw new UnloggedFailure(1, String.format("Failed to delete %s!", repository)); - } - } - } - - @CommandMetaData(name = "show", description = "Show the details of a repository") - @UsageExample(syntax = "${cmd} myRepo.git", description = "Display myRepo.git") - public static class ShowRepository extends RepositoryCommand { - - @Override - public void run() throws UnloggedFailure { - - RepositoryModel r = getRepository(true); - - if (!getContext().getClient().getUser().canAdmin(r)) { - throw new UnloggedFailure(1, String.format("Sorry, you do not have permission to see the %s settings.", repository)); - } - - IGitblit gitblit = getContext().getGitblit(); - - // fields - StringBuilder fb = new StringBuilder(); - fb.append("Description : ").append(toString(r.description)).append('\n'); - fb.append("Origin : ").append(toString(r.origin)).append('\n'); - fb.append("Default Branch : ").append(toString(r.HEAD)).append('\n'); - fb.append('\n'); - fb.append("GC Period : ").append(r.gcPeriod).append('\n'); - fb.append("GC Threshold : ").append(r.gcThreshold).append('\n'); - fb.append('\n'); - fb.append("Accept Tickets : ").append(toString(r.acceptNewTickets)).append('\n'); - fb.append("Accept Patchsets : ").append(toString(r.acceptNewPatchsets)).append('\n'); - fb.append("Require Approval : ").append(toString(r.requireApproval)).append('\n'); - fb.append("Merge To : ").append(toString(r.mergeTo)).append('\n'); - fb.append('\n'); - fb.append("Incremental push tags : ").append(toString(r.useIncrementalPushTags)).append('\n'); - fb.append("Show remote branches : ").append(toString(r.showRemoteBranches)).append('\n'); - fb.append("Skip size calculations : ").append(toString(r.skipSizeCalculation)).append('\n'); - fb.append("Skip summary metrics : ").append(toString(r.skipSummaryMetrics)).append('\n'); - fb.append("Max activity commits : ").append(r.maxActivityCommits).append('\n'); - fb.append("Author metric exclusions : ").append(toString(r.metricAuthorExclusions)).append('\n'); - fb.append("Commit Message Renderer : ").append(r.commitMessageRenderer).append('\n'); - fb.append("Mailing Lists : ").append(toString(r.mailingLists)).append('\n'); - fb.append('\n'); - fb.append("Access Restriction : ").append(r.accessRestriction).append('\n'); - fb.append("Authorization Control : ").append(r.authorizationControl).append('\n'); - fb.append('\n'); - fb.append("Is Frozen : ").append(toString(r.isFrozen)).append('\n'); - fb.append("Allow Forks : ").append(toString(r.allowForks)).append('\n'); - fb.append("Verify Committer : ").append(toString(r.verifyCommitter)).append('\n'); - fb.append('\n'); - fb.append("Federation Strategy : ").append(r.federationStrategy).append('\n'); - fb.append("Federation Sets : ").append(toString(r.federationSets)).append('\n'); - fb.append('\n'); - fb.append("Indexed Branches : ").append(toString(r.indexedBranches)).append('\n'); - fb.append('\n'); - fb.append("Pre-Receive Scripts : ").append(toString(r.preReceiveScripts)).append('\n'); - fb.append(" inherited : ").append(toString(gitblit.getPreReceiveScriptsInherited(r))).append('\n'); - fb.append("Post-Receive Scripts : ").append(toString(r.postReceiveScripts)).append('\n'); - fb.append(" inherited : ").append(toString(gitblit.getPostReceiveScriptsInherited(r))).append('\n'); - String fields = fb.toString(); - - // owners - String owners; - if (r.owners.isEmpty()) { - owners = FlipTable.EMPTY; - } else { - String[] pheaders = { "Account", "Name" }; - Object [][] pdata = new Object[r.owners.size()][]; - for (int i = 0; i < r.owners.size(); i++) { - String owner = r.owners.get(i); - UserModel u = gitblit.getUserModel(owner); - pdata[i] = new Object[] { owner, u == null ? "" : u.getDisplayName() }; - } - owners = FlipTable.of(pheaders, pdata, Borders.COLS); - } - - // team permissions - List tperms = gitblit.getTeamAccessPermissions(r); - String tpermissions; - if (tperms.isEmpty()) { - tpermissions = FlipTable.EMPTY; - } else { - String[] pheaders = { "Team", "Permission", "Type" }; - Object [][] pdata = new Object[tperms.size()][]; - for (int i = 0; i < tperms.size(); i++) { - RegistrantAccessPermission ap = tperms.get(i); - pdata[i] = new Object[] { ap.registrant, ap.permission, ap.permissionType }; - } - tpermissions = FlipTable.of(pheaders, pdata, Borders.COLS); - } - - // user permissions - List uperms = gitblit.getUserAccessPermissions(r); - String upermissions; - if (uperms.isEmpty()) { - upermissions = FlipTable.EMPTY; - } else { - String[] pheaders = { "Account", "Name", "Permission", "Type", "Source", "Mutable" }; - Object [][] pdata = new Object[uperms.size()][]; - for (int i = 0; i < uperms.size(); i++) { - RegistrantAccessPermission ap = uperms.get(i); - String name = ""; - try { - String dn = gitblit.getUserModel(ap.registrant).displayName; - if (dn != null) { - name = dn; - } - } catch (Exception e) { - } - pdata[i] = new Object[] { ap.registrant, name, ap.permission, ap.permissionType, ap.source, ap.mutable ? "Y":"" }; - } - upermissions = FlipTable.of(pheaders, pdata, Borders.COLS); - } - - // assemble table - String title = r.name; - String [] headers = new String[] { title }; - String[][] data = new String[8][]; - data[0] = new String [] { "FIELDS" }; - data[1] = new String [] {fields }; - data[2] = new String [] { "OWNERS" }; - data[3] = new String [] { owners }; - data[4] = new String [] { "TEAM PERMISSIONS" }; - data[5] = new String [] { tpermissions }; - data[6] = new String [] { "USER PERMISSIONS" }; - data[7] = new String [] { upermissions }; - stdout.println(FlipTable.of(headers, data)); - } - - protected String toString(String val) { - if (val == null) { - return ""; - } - return val; - } - - protected String toString(Collection collection) { - if (collection == null) { - return ""; - } - return Joiner.on(", ").join(collection); - } - - protected String toString(boolean val) { - if (val) { - return "Y"; - } - return ""; - } - - } - - /* List repositories */ - @CommandMetaData(name = "list", aliases = { "ls" }, description = "List repositories") - @UsageExample(syntax = "${cmd} mirror/.* -v", description = "Verbose list of all repositories in the 'mirror' directory") - public static class ListRepositories extends ListFilterCommand { - - @Override - protected List getItems() { - IGitblit gitblit = getContext().getGitblit(); - UserModel user = getContext().getClient().getUser(); - List repositories = gitblit.getRepositoryModels(user); - return repositories; - } - - @Override - protected boolean matches(String filter, RepositoryModel r) { - return r.name.matches(filter); - } - - @Override - protected void asTable(List list) { - String[] headers; - if (verbose) { - String[] h = { "Name", "Description", "Owners", "Last Modified", "Size" }; - headers = h; - } else { - String[] h = { "Name", "Last Modified", "Size" }; - headers = h; - } - - Object[][] data = new Object[list.size()][]; - for (int i = 0; i < list.size(); i++) { - RepositoryModel r = list.get(i); - - String lm = formatDate(r.lastChange); - String size = r.size; - if (!r.hasCommits) { - lm = ""; - size = FlipTable.EMPTY; - } - if (verbose) { - String owners = ""; - if (!ArrayUtils.isEmpty(r.owners)) { - owners = Joiner.on(",").join(r.owners); - } - data[i] = new Object[] { r.name, r.description, owners, lm, size }; - } else { - data[i] = new Object[] { r.name, lm, size }; - } - } - stdout.println(FlipTable.of(headers, data, Borders.BODY_HCOLS)); - } - - @Override - protected void asTabbed(List list) { - if (verbose) { - for (RepositoryModel r : list) { - String lm = formatDate(r.lastChange); - String owners = ""; - if (!ArrayUtils.isEmpty(r.owners)) { - owners = Joiner.on(",").join(r.owners); - } - String size = r.size; - if (!r.hasCommits) { - lm = ""; - size = "(empty)"; - } - - outTabbed(r.name, r.description == null ? "" : r.description, - owners, lm, size); - } - } else { - for (RepositoryModel r : list) { - outTabbed(r.name); - } - } - } - } -} \ No newline at end of file diff --git a/src/main/java/com/gitblit/transport/ssh/gitblit/ReviewCommand.java b/src/main/java/com/gitblit/transport/ssh/gitblit/ReviewCommand.java deleted file mode 100644 index b3691cbb..00000000 --- a/src/main/java/com/gitblit/transport/ssh/gitblit/ReviewCommand.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2014 gitblit.com. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.gitblit.transport.ssh.gitblit; - -import java.util.HashSet; -import java.util.Set; - -import org.kohsuke.args4j.Argument; -import org.kohsuke.args4j.Option; - -import com.gitblit.models.TicketModel.Change; -import com.gitblit.models.TicketModel.Patchset; -import com.gitblit.models.TicketModel.Score; -import com.gitblit.models.UserModel; -import com.gitblit.transport.ssh.commands.CommandMetaData; -import com.gitblit.transport.ssh.commands.SshCommand; -import com.gitblit.wicket.GitBlitWebSession; - -@CommandMetaData(name = "review", description = "Verify, approve and/or submit one or more patch sets", hidden = true) -public class ReviewCommand extends SshCommand { - - private final static short REV_ID_LEN = 40; - private final Set patchSets = new HashSet(); - - @Argument(index = 0, required = true, multiValued = true, metaVar = "{COMMIT | CHANGE,PATCHSET}", usage = "list of commits or patch sets to review") - void addPatchSetId(final String token) { - try { - patchSets.add(parsePatchSet(token)); - } catch (UnloggedFailure e) { - throw new IllegalArgumentException(e.getMessage(), e); - } - } - - @Option(name = "--project", required = true, aliases = "-p", usage = "project containing the specified patch set(s)") - private String project; - - @Option(name = "--message", aliases = "-m", usage = "cover message to publish on change(s)", metaVar = "MESSAGE") - private String changeComment; - - @Option(name = "--vote", aliases = "-v", usage = "vote on this patch set", metaVar = "VOTE") - private int vote; - - @Option(name = "--submit", aliases = "-s", usage = "submit the specified patch set(s)") - private boolean submitChange; - - @Override - public void run() throws UnloggedFailure { - UserModel user = GitBlitWebSession.get().getUser(); - // TODO ensure user has permission to score +2/-2 - for (Patchset ps : patchSets) { - // review - Change change = new Change(user.username); - change.review(ps, Score.fromScore(vote), false); - // TODO(davido): add patchset comment - if (submitChange) { - // TODO(davido): merge (when desired and the change is mergeable) - } - } - } - - private Patchset parsePatchSet(String ps) throws UnloggedFailure { - // By commit? - // - if (ps.matches("^([0-9a-fA-F]{4," + REV_ID_LEN + "})$")) { - // TODO; parse - } - - // By older style change,patchset? - // - if (ps.matches("^[1-9][0-9]*,[1-9][0-9]*$")) { - // TODO: parse - } - - throw new UnloggedFailure(1, "fatal: Cannot parse patchset: " + ps); - } -} diff --git a/src/main/java/com/gitblit/transport/ssh/gitblit/TeamsDispatcher.java b/src/main/java/com/gitblit/transport/ssh/gitblit/TeamsDispatcher.java deleted file mode 100644 index d0ec58f0..00000000 --- a/src/main/java/com/gitblit/transport/ssh/gitblit/TeamsDispatcher.java +++ /dev/null @@ -1,507 +0,0 @@ -/* - * Copyright 2014 gitblit.com. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.gitblit.transport.ssh.gitblit; - -import java.util.ArrayList; -import java.util.List; - -import org.kohsuke.args4j.Argument; -import org.kohsuke.args4j.Option; - -import com.gitblit.Constants.AccessPermission; -import com.gitblit.GitBlitException; -import com.gitblit.manager.IGitblit; -import com.gitblit.models.RegistrantAccessPermission; -import com.gitblit.models.RepositoryModel; -import com.gitblit.models.TeamModel; -import com.gitblit.models.UserModel; -import com.gitblit.transport.ssh.commands.CommandMetaData; -import com.gitblit.transport.ssh.commands.DispatchCommand; -import com.gitblit.transport.ssh.commands.ListFilterCommand; -import com.gitblit.transport.ssh.commands.SshCommand; -import com.gitblit.transport.ssh.commands.UsageExample; -import com.gitblit.transport.ssh.commands.UsageExamples; -import com.gitblit.utils.ArrayUtils; -import com.gitblit.utils.FlipTable; -import com.gitblit.utils.FlipTable.Borders; -import com.gitblit.utils.StringUtils; -import com.google.common.base.Joiner; - -@CommandMetaData(name = "teams", description = "Team management commands", admin = true) -public class TeamsDispatcher extends DispatchCommand { - - @Override - protected void setup(UserModel user) { - // primary team commands - register(user, NewTeam.class); - register(user, RenameTeam.class); - register(user, RemoveTeam.class); - register(user, ShowTeam.class); - register(user, ListTeams.class); - - // team-specific commands - register(user, SetField.class); - register(user, Permissions.class); - register(user, Members.class); - } - - public static abstract class TeamCommand extends SshCommand { - @Argument(index = 0, required = true, metaVar = "TEAM", usage = "team name") - protected String teamname; - - protected TeamModel getTeam(boolean requireTeam) throws UnloggedFailure { - IGitblit gitblit = getContext().getGitblit(); - TeamModel team = gitblit.getTeamModel(teamname); - if (requireTeam && team == null) { - throw new UnloggedFailure(1, String.format("Team %s does not exist!", teamname)); - } - return team; - } - } - - @CommandMetaData(name = "new", aliases = { "add" }, description = "Create a new team") - @UsageExample(syntax = "${cmd} contributors --canFork --canCreate") - public static class NewTeam extends TeamCommand { - - @Option(name = "--canAdmin", usage = "can administer the server") - protected boolean canAdmin; - - @Option(name = "--canFork", usage = "can fork repositories") - protected boolean canFork; - - @Option(name = "--canCreate", usage = "can create personal repositories") - protected boolean canCreate; - - @Override - public void run() throws UnloggedFailure { - - if (getTeam(false) != null) { - throw new UnloggedFailure(1, String.format("Team %s already exists!", teamname)); - } - - TeamModel team = new TeamModel(teamname); - team.canAdmin = canAdmin; - team.canFork = canFork; - team.canCreate = canCreate; - - IGitblit gitblit = getContext().getGitblit(); - try { - gitblit.addTeam(team); - stdout.println(String.format("%s created.", teamname)); - } catch (GitBlitException e) { - String msg = String.format("Failed to create %s!", teamname); - log.error(msg, e); - throw new UnloggedFailure(1, msg); - } - } - } - - @CommandMetaData(name = "rename", aliases = { "mv" }, description = "Rename a team") - @UsageExample(syntax = "${cmd} contributors friends", description = "Rename the contributors team to the friends team") - public static class RenameTeam extends TeamCommand { - @Argument(index = 1, required = true, metaVar = "NEWNAME", usage = "the new team name") - protected String newTeamName; - - @Override - public void run() throws UnloggedFailure { - TeamModel team = getTeam(true); - IGitblit gitblit = getContext().getGitblit(); - if (null != gitblit.getTeamModel(newTeamName)) { - throw new UnloggedFailure(1, String.format("Team %s already exists!", newTeamName)); - } - - // set the new team name - team.name = newTeamName; - - try { - gitblit.reviseTeam(teamname, team); - stdout.println(String.format("Renamed team %s to %s.", teamname, newTeamName)); - } catch (GitBlitException e) { - String msg = String.format("Failed to rename team from %s to %s", teamname, newTeamName); - log.error(msg, e); - throw new UnloggedFailure(1, msg); - } - } - } - - @CommandMetaData(name = "set", description = "Set the specified field of a team") - @UsageExample(syntax = "${cmd} contributors canFork true", description = "Allow the contributors team to fork repositories") - public static class SetField extends TeamCommand { - - @Argument(index = 1, required = true, metaVar = "FIELD", usage = "the field to update") - protected String fieldName; - - @Argument(index = 2, required = true, metaVar = "VALUE", usage = "the new value") - protected List fieldValues = new ArrayList(); - - protected enum Field { - mailingList, preReceive, postReceive, canAdmin, canFork, canCreate; - - static Field fromString(String name) { - for (Field field : values()) { - if (field.name().equalsIgnoreCase(name)) { - return field; - } - } - return null; - } - } - - @Override - protected String getUsageText() { - String fields = Joiner.on(", ").join(Field.values()); - StringBuilder sb = new StringBuilder(); - sb.append("Valid fields are:\n ").append(fields); - return sb.toString(); - } - - @Override - public void run() throws UnloggedFailure { - TeamModel team = getTeam(true); - - Field field = Field.fromString(fieldName); - if (field == null) { - throw new UnloggedFailure(1, String.format("Unknown field %s", fieldName)); - } - - String value = Joiner.on(" ").join(fieldValues); - IGitblit gitblit = getContext().getGitblit(); - - switch(field) { - case mailingList: - team.mailingLists.clear(); - team.mailingLists.addAll(fieldValues); - break; - case preReceive: - team.preReceiveScripts.clear(); - team.preReceiveScripts.addAll(fieldValues); - break; - case postReceive: - team.postReceiveScripts.clear(); - team.postReceiveScripts.addAll(fieldValues); - break; - case canAdmin: - team.canAdmin = toBool(value); - break; - case canFork: - team.canFork = toBool(value); - break; - case canCreate: - team.canCreate = toBool(value); - break; - default: - throw new UnloggedFailure(1, String.format("Field %s was not properly handled by the set command.", fieldName)); - } - - try { - gitblit.reviseTeam(teamname, team); - stdout.println(String.format("Set %s.%s = %s", teamname, fieldName, value)); - } catch (GitBlitException e) { - String msg = String.format("Failed to set %s.%s = %s", teamname, fieldName, value); - log.error(msg, e); - throw new UnloggedFailure(1, msg); - } - } - - protected boolean toBool(String value) throws UnloggedFailure { - String v = value.toLowerCase(); - if (v.equals("t") - || v.equals("true") - || v.equals("yes") - || v.equals("on") - || v.equals("y") - || v.equals("1")) { - return true; - } else if (v.equals("f") - || v.equals("false") - || v.equals("no") - || v.equals("off") - || v.equals("n") - || v.equals("0")) { - return false; - } - throw new UnloggedFailure(1, String.format("Invalid boolean value %s", value)); - } - } - - @CommandMetaData(name = "permissions", aliases = { "perms" }, description = "Add or remove permissions from a team") - @UsageExample(syntax = "${cmd} contributors RW:alpha/repo.git RWC:alpha/repo2.git", description = "Add or set permissions for contributors") - public static class Permissions extends TeamCommand { - - @Argument(index = 1, multiValued = true, metaVar = "[PERMISSION:]REPOSITORY", usage = "a repository expression") - protected List permissions; - - @Option(name = "--remove", aliases = { "-r" }, metaVar = "REPOSITORY|ALL", usage = "remove a repository permission") - protected List removals; - - @Override - public void run() throws UnloggedFailure { - IGitblit gitblit = getContext().getGitblit(); - TeamModel team = getTeam(true); - - boolean modified = false; - if (!ArrayUtils.isEmpty(removals)) { - if (removals.contains("ALL")) { - team.permissions.clear(); - } else { - for (String repo : removals) { - team.removeRepositoryPermission(repo); - log.info(String.format("Removing permission for %s from %s", repo, teamname)); - } - } - modified = true; - } - - if (!ArrayUtils.isEmpty(permissions)) { - for (String perm : permissions) { - String repo = AccessPermission.repositoryFromRole(perm); - if (StringUtils.findInvalidCharacter(repo) == null) { - // explicit permision, confirm repository - RepositoryModel r = gitblit.getRepositoryModel(repo); - if (r == null) { - throw new UnloggedFailure(1, String.format("Repository %s does not exist!", repo)); - } - } - AccessPermission ap = AccessPermission.permissionFromRole(perm); - team.setRepositoryPermission(repo, ap); - log.info(String.format("Setting %s:%s for %s", ap.name(), repo, teamname)); - } - modified = true; - } - - if (modified && gitblit.updateTeamModel(teamname, team)) { - // reload & display new permissions - team = gitblit.getTeamModel(teamname); - } - - showPermissions(team); - } - - protected void showPermissions(TeamModel team) { - List perms = team.getRepositoryPermissions(); - String[] pheaders = { "Repository", "Permission", "Type" }; - Object [][] pdata = new Object[perms.size()][]; - for (int i = 0; i < perms.size(); i++) { - RegistrantAccessPermission ap = perms.get(i); - pdata[i] = new Object[] { ap.registrant, ap.permission, ap.permissionType }; - } - stdout.println(FlipTable.of(pheaders, pdata, Borders.BODY_HCOLS)); - } - } - - @CommandMetaData(name = "members", aliases = { "users" }, description = "Add or remove team members") - @UsageExample(syntax = "${cmd} contributors RW:alpha/repo.git RWC:alpha/repo2.git", description = "Add or set permissions for contributors") - public static class Members extends TeamCommand { - - @Argument(index = 1, multiValued = true, metaVar = "USERNAME", usage = "a username") - protected List members; - - @Option(name = "--remove", aliases = { "-r" }, metaVar = "USERNAME|ALL", usage = "remove a team member") - protected List removals; - - @Override - public void run() throws UnloggedFailure { - IGitblit gitblit = getContext().getGitblit(); - TeamModel team = getTeam(true); - - boolean canEditMemberships = gitblit.supportsTeamMembershipChanges(team); - if (!canEditMemberships) { - String msg = String.format("Team %s (%s) does not permit membership changes!", team.name, team.accountType); - throw new UnloggedFailure(1, msg); - } - - boolean modified = false; - if (!ArrayUtils.isEmpty(removals)) { - if (removals.contains("ALL")) { - team.users.clear(); - } else { - for (String member : removals) { - team.removeUser(member); - log.info(String.format("Removing member %s from %s", member, teamname)); - } - } - modified = true; - } - - if (!ArrayUtils.isEmpty(members)) { - for (String username : members) { - UserModel u = gitblit.getUserModel(username); - if (u == null) { - throw new UnloggedFailure(1, String.format("Unknown user %s", username)); - } - boolean canEditTeams = gitblit.supportsTeamMembershipChanges(u); - if (!canEditTeams) { - String msg = String.format("User %s (%s) does not allow team membership changes ", u.username, u.accountType); - throw new UnloggedFailure(1, msg); - } - team.addUser(username); - } - modified = true; - } - - if (modified && gitblit.updateTeamModel(teamname, team)) { - // reload & display new permissions - team = gitblit.getTeamModel(teamname); - } - - String[] headers = { "Username", "Display Name" }; - Object [][] data = new Object[team.users.size()][]; - int i = 0; - for (String username : team.users) { - UserModel u = gitblit.getUserModel(username); - data[i] = new Object[] { username, u.displayName }; - i++; - } - stdout.println(FlipTable.of(headers, data, Borders.BODY_HCOLS)); - } - } - - @CommandMetaData(name = "remove", aliases = { "rm" }, description = "Remove a team") - @UsageExample(syntax = "${cmd} contributors", description = "Delete the contributors team") - public static class RemoveTeam extends TeamCommand { - - @Override - public void run() throws UnloggedFailure { - - TeamModel team = getTeam(true); - IGitblit gitblit = getContext().getGitblit(); - if (gitblit.deleteTeamModel(team)) { - stdout.println(String.format("%s has been deleted.", teamname)); - } else { - throw new UnloggedFailure(1, String.format("Failed to delete %s!", teamname)); - } - } - } - - @CommandMetaData(name = "show", description = "Show the details of a team") - @UsageExample(syntax = "${cmd} contributors", description = "Display the 'contributors' team") - public static class ShowTeam extends TeamCommand { - - @Override - public void run() throws UnloggedFailure { - - TeamModel t = getTeam(true); - - // fields - StringBuilder fb = new StringBuilder(); - fb.append("Mailing Lists : ").append(Joiner.on(", ").join(t.mailingLists)).append('\n'); - fb.append("Type : ").append(t.accountType).append('\n'); - fb.append("Can Admin : ").append(t.canAdmin ? "Y":"").append('\n'); - fb.append("Can Fork : ").append(t.canFork ? "Y":"").append('\n'); - fb.append("Can Create : ").append(t.canCreate ? "Y":"").append('\n'); - fb.append("Pre-Receive : ").append(Joiner.on(", ").join(t.preReceiveScripts)).append('\n'); - fb.append("Post-Receive : ").append(Joiner.on(", ").join(t.postReceiveScripts)).append('\n'); - String fields = fb.toString(); - - // members - String members; - if (t.users.size() == 0) { - members = FlipTable.EMPTY; - } else { - IGitblit gitblit = getContext().getGitblit(); - String[] headers = { "Username", "Display Name" }; - Object [][] data = new Object[t.users.size()][]; - int i = 0; - for (String username : t.users) { - UserModel u = gitblit.getUserModel(username); - data[i] = new Object[] { username, u == null ? null : u.displayName }; - i++; - } - members = FlipTable.of(headers, data, Borders.COLS); - } - - // permissions - List perms = t.getRepositoryPermissions(); - String permissions; - if (perms.isEmpty()) { - permissions = FlipTable.EMPTY; - } else { - String[] pheaders = { "Repository", "Permission", "Type" }; - Object [][] pdata = new Object[perms.size()][]; - for (int i = 0; i < perms.size(); i++) { - RegistrantAccessPermission ap = perms.get(i); - pdata[i] = new Object[] { ap.registrant, ap.permission, ap.permissionType }; - } - permissions = FlipTable.of(pheaders, pdata, Borders.COLS); - } - - // assemble team table - String [] headers = new String[] { t.name }; - String[][] data = new String[6][]; - data[0] = new String [] { "FIELDS" }; - data[1] = new String [] { fields }; - data[2] = new String [] { "MEMBERS" }; - data[3] = new String [] { members }; - data[4] = new String [] { "PERMISSIONS" }; - data[5] = new String [] { permissions }; - stdout.println(FlipTable.of(headers, data)); - } - } - - @CommandMetaData(name = "list", aliases= { "ls" }, description = "List teams") - @UsageExamples(examples = { - @UsageExample(syntax = "${cmd}", description = "List teams as a table"), - @UsageExample(syntax = "${cmd} j.*", description = "List all teams that start with 'j'"), - }) - public static class ListTeams extends ListFilterCommand { - - @Override - protected List getItems() { - IGitblit gitblit = getContext().getGitblit(); - List teams = gitblit.getAllTeams(); - return teams; - } - - @Override - protected boolean matches(String filter, TeamModel t) { - return t.name.matches(filter); - } - - @Override - protected void asTable(List list) { - String[] headers = { "Name", "Members", "Type", "Create?", "Fork?"}; - Object[][] data = new Object[list.size()][]; - for (int i = 0; i < list.size(); i++) { - TeamModel t = list.get(i); - data[i] = new Object[] { - (t.canAdmin ? "*" : " ") + t.name, - t.users.isEmpty() ? "" : t.users.size(), - t.accountType + (t.canAdmin ? ",admin":""), - (t.canAdmin || t.canCreate) ? "Y":"", - (t.canAdmin || t.canFork) ? "Y" : ""}; - } - stdout.println(FlipTable.of(headers, data, Borders.BODY_HCOLS)); - } - - @Override - protected void asTabbed(List teams) { - if (verbose) { - for (TeamModel t : teams) { - outTabbed( - t.name, - t.users.isEmpty() ? "" : t.users.size(), - t.accountType + (t.canAdmin ? ",admin":""), - (t.canAdmin || t.canCreate) ? "Y":"", - (t.canAdmin || t.canFork) ? "Y" : ""); - } - } else { - for (TeamModel u : teams) { - outTabbed((u.canAdmin ? "*" : " ") + u.name); - } - } - } - } -} \ No newline at end of file diff --git a/src/main/java/com/gitblit/transport/ssh/gitblit/TicketsDispatcher.java b/src/main/java/com/gitblit/transport/ssh/gitblit/TicketsDispatcher.java deleted file mode 100644 index dd29b6ac..00000000 --- a/src/main/java/com/gitblit/transport/ssh/gitblit/TicketsDispatcher.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright 2014 gitblit.com. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.gitblit.transport.ssh.gitblit; - -import java.util.List; - -import org.kohsuke.args4j.Argument; - -import com.gitblit.manager.IGitblit; -import com.gitblit.models.RepositoryModel; -import com.gitblit.models.TicketModel.Status; -import com.gitblit.models.UserModel; -import com.gitblit.tickets.ITicketService; -import com.gitblit.tickets.QueryBuilder; -import com.gitblit.tickets.QueryResult; -import com.gitblit.tickets.TicketIndexer.Lucene; -import com.gitblit.transport.ssh.commands.CommandMetaData; -import com.gitblit.transport.ssh.commands.DispatchCommand; -import com.gitblit.transport.ssh.commands.ListCommand; -import com.gitblit.utils.ArrayUtils; -import com.gitblit.utils.FlipTable; -import com.gitblit.utils.FlipTable.Borders; -import com.gitblit.utils.StringUtils; - -@CommandMetaData(name = "tickets", description = "Ticket commands", hidden = true) -public class TicketsDispatcher extends DispatchCommand { - - @Override - protected void setup(UserModel user) { - register(user, ReviewCommand.class); - register(user, ListTickets.class); - } - - /* List tickets */ - @CommandMetaData(name = "list", aliases = { "ls" }, description = "List tickets") - public static class ListTickets extends ListCommand { - - private final String ALL = "ALL"; - - @Argument(index = 0, metaVar = "ALL|REPOSITORY", usage = "the repository or ALL") - protected String repository; - - @Argument(index = 1, multiValued = true, metaVar="CONDITION", usage = "query condition") - protected List query; - - protected String userQuery; - - @Override - protected List getItems() throws UnloggedFailure { - IGitblit gitblit = getContext().getGitblit(); - ITicketService tickets = gitblit.getTicketService(); - - QueryBuilder sb = new QueryBuilder(); - if (ArrayUtils.isEmpty(query)) { - sb.and(Lucene.status.matches(Status.New.toString())).or(Lucene.status.matches(Status.Open.toString())); - } else { - StringBuilder b = new StringBuilder(); - for (String q : query) { - b.append(q).append(' '); - } - b.setLength(b.length() - 1); - sb.and(b.toString()); - } - - QueryBuilder qb; - if (StringUtils.isEmpty(repository) || ALL.equalsIgnoreCase(repository)) { - qb = sb; - userQuery = sb.build(); - } else { - qb = new QueryBuilder(); - RepositoryModel r = gitblit.getRepositoryModel(repository); - if (r == null) { - throw new UnloggedFailure(1, String.format("%s is not a repository!", repository)); - } - qb.and(Lucene.rid.matches(r.getRID())); - qb.and(sb.toSubquery().toString()); - userQuery = sb.build(); - } - - String query = qb.build(); - List list = tickets.queryFor(query, 0, 0, null, true); - return list; - } - - @Override - protected void asTable(List list) { - boolean forRepo = !StringUtils.isEmpty(repository) && !ALL.equalsIgnoreCase(repository); - String[] headers; - if (verbose) { - if (forRepo) { - String[] h = { "ID", "Title", "Status", "Last Modified", "Votes", "Commits" }; - headers = h; - } else { - String[] h = { "Repository", "ID", "Title", "Status", "Last Modified", "Votes", "Commits" }; - headers = h; - } - } else { - if (forRepo) { - String[] h = { "ID", "Title", "Status", "Last Modifed" }; - headers = h; - } else { - String[] h = { "Repository", "ID", "Title", "Status", "Last Modified" }; - headers = h; - } - } - - Object[][] data = new Object[list.size()][]; - for (int i = 0; i < list.size(); i++) { - QueryResult q = list.get(i); - - if (verbose) { - if (forRepo) { - data[i] = new Object[] { q.number, q.title, q.status, formatDate(q.getDate()), q.votesCount, q.patchset == null ? "": q.patchset.commits }; - } else { - data[i] = new Object[] { q.repository, q.number, q.title, q.status, formatDate(q.getDate()), q.votesCount, q.patchset == null ? "": q.patchset.commits }; - } - } else { - if (forRepo) { - data[i] = new Object[] { q.number, q.title, q.status, formatDate(q.getDate()) }; - } else { - data[i] = new Object[] { q.repository, q.number, q.title, q.status, formatDate(q.getDate()) }; - } - } - } - stdout.print(FlipTable.of(headers, data, Borders.BODY_HCOLS)); - stdout.println(" " + repository + ": " + userQuery); - stdout.println(); - } - - @Override - protected void asTabbed(List list) { - if (verbose) { - for (QueryResult q : list) { - outTabbed(q.repository, q.number, q.title, q.status.toString(), - formatDate(q.getDate())); - } - } else { - for (QueryResult q : list) { - outTabbed(q.repository, q.number, q.title); - } - } - } - } -} diff --git a/src/main/java/com/gitblit/transport/ssh/gitblit/UsersDispatcher.java b/src/main/java/com/gitblit/transport/ssh/gitblit/UsersDispatcher.java deleted file mode 100644 index 1a6dee46..00000000 --- a/src/main/java/com/gitblit/transport/ssh/gitblit/UsersDispatcher.java +++ /dev/null @@ -1,592 +0,0 @@ -/* - * Copyright 2014 gitblit.com. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.gitblit.transport.ssh.gitblit; - -import java.util.ArrayList; -import java.util.List; - -import org.kohsuke.args4j.Argument; -import org.kohsuke.args4j.Option; - -import com.gitblit.Constants.AccessPermission; -import com.gitblit.GitBlitException; -import com.gitblit.Keys; -import com.gitblit.manager.IGitblit; -import com.gitblit.models.RegistrantAccessPermission; -import com.gitblit.models.RepositoryModel; -import com.gitblit.models.UserModel; -import com.gitblit.transport.ssh.SshKey; -import com.gitblit.transport.ssh.commands.CommandMetaData; -import com.gitblit.transport.ssh.commands.DispatchCommand; -import com.gitblit.transport.ssh.commands.ListFilterCommand; -import com.gitblit.transport.ssh.commands.SshCommand; -import com.gitblit.transport.ssh.commands.UsageExample; -import com.gitblit.transport.ssh.commands.UsageExamples; -import com.gitblit.utils.ArrayUtils; -import com.gitblit.utils.FlipTable; -import com.gitblit.utils.FlipTable.Borders; -import com.gitblit.utils.StringUtils; -import com.google.common.base.Joiner; - -@CommandMetaData(name = "users", description = "User management commands", admin = true) -public class UsersDispatcher extends DispatchCommand { - - @Override - protected void setup(UserModel user) { - // primary user commands - register(user, NewUser.class); - register(user, RenameUser.class); - register(user, RemoveUser.class); - register(user, ShowUser.class); - register(user, ListUsers.class); - - // user-specific commands - register(user, SetField.class); - register(user, Permissions.class); - register(user, DisableUser.class); - register(user, EnableUser.class); - } - - public static abstract class UserCommand extends SshCommand { - @Argument(index = 0, required = true, metaVar = "USERNAME", usage = "username") - protected String username; - - protected UserModel getUser(boolean requireUser) throws UnloggedFailure { - IGitblit gitblit = getContext().getGitblit(); - UserModel user = gitblit.getUserModel(username); - if (requireUser && user == null) { - throw new UnloggedFailure(1, String.format("User %s does not exist!", username)); - } - return user; - } - } - - @CommandMetaData(name = "new", aliases = { "add" }, description = "Create a new user account") - @UsageExample(syntax = "${cmd} john 12345 --email john@smith.com --canFork --canCreate") - public static class NewUser extends UserCommand { - - @Argument(index = 1, required = true, metaVar = "PASSWORD", usage = "password") - protected String password; - - @Option(name = "--email", metaVar = "ADDRESS", usage = "email address") - protected String email; - - @Option(name = "--canAdmin", usage = "can administer the server") - protected boolean canAdmin; - - @Option(name = "--canFork", usage = "can fork repositories") - protected boolean canFork; - - @Option(name = "--canCreate", usage = "can create personal repositories") - protected boolean canCreate; - - @Option(name = "--disabled", usage = "create a disabled user account") - protected boolean disabled; - - @Override - public void run() throws UnloggedFailure { - - if (getUser(false) != null) { - throw new UnloggedFailure(1, String.format("User %s already exists!", username)); - } - - UserModel user = new UserModel(username); - user.password = password; - - if (email != null) { - user.emailAddress = email; - } - - user.canAdmin = canAdmin; - user.canFork = canFork; - user.canCreate = canCreate; - user.disabled = disabled; - - IGitblit gitblit = getContext().getGitblit(); - try { - gitblit.addUser(user); - stdout.println(String.format("%s created.", username)); - } catch (GitBlitException e) { - log.error("Failed to add " + username, e); - throw new UnloggedFailure(1, e.getMessage()); - } - } - } - - @CommandMetaData(name = "rename", aliases = { "mv" }, description = "Rename an account") - @UsageExample(syntax = "${cmd} john frank", description = "Rename the account from john to frank") - public static class RenameUser extends UserCommand { - @Argument(index = 1, required = true, metaVar = "NEWNAME", usage = "the new account name") - protected String newUserName; - - @Override - public void run() throws UnloggedFailure { - UserModel user = getUser(true); - IGitblit gitblit = getContext().getGitblit(); - if (null != gitblit.getTeamModel(newUserName)) { - throw new UnloggedFailure(1, String.format("Team %s already exists!", newUserName)); - } - - // set the new name - user.username = newUserName; - - try { - gitblit.reviseUser(username, user); - stdout.println(String.format("Renamed user %s to %s.", username, newUserName)); - } catch (GitBlitException e) { - String msg = String.format("Failed to rename user from %s to %s", username, newUserName); - log.error(msg, e); - throw new UnloggedFailure(1, msg); - } - } - } - - @CommandMetaData(name = "set", description = "Set the specified field of an account") - @UsageExample(syntax = "${cmd} john name John Smith", description = "Set the display name to \"John Smith\" for john's account") - public static class SetField extends UserCommand { - - @Argument(index = 1, required = true, metaVar = "FIELD", usage = "the field to update") - protected String fieldName; - - @Argument(index = 2, required = true, metaVar = "VALUE", usage = "the new value") - protected List fieldValues = new ArrayList(); - - protected enum Field { - name, displayName, email, password, canAdmin, canFork, canCreate, disabled; - - static Field fromString(String name) { - for (Field field : values()) { - if (field.name().equalsIgnoreCase(name)) { - return field; - } - } - return null; - } - } - - @Override - protected String getUsageText() { - String fields = Joiner.on(", ").join(Field.values()); - StringBuilder sb = new StringBuilder(); - sb.append("Valid fields are:\n ").append(fields); - return sb.toString(); - } - - @Override - public void run() throws UnloggedFailure { - UserModel user = getUser(true); - - Field field = Field.fromString(fieldName); - if (field == null) { - throw new UnloggedFailure(1, String.format("Unknown field %s", fieldName)); - } - - String value = Joiner.on(" ").join(fieldValues).trim(); - IGitblit gitblit = getContext().getGitblit(); - - boolean editCredentials = gitblit.supportsCredentialChanges(user); - boolean editDisplayName = gitblit.supportsDisplayNameChanges(user); - boolean editEmailAddress = gitblit.supportsEmailAddressChanges(user); - - String m = String.format("Can not edit %s for %s (%s)", field, user.username, user.accountType); - - switch(field) { - case name: - case displayName: - if (!editDisplayName) { - throw new UnloggedFailure(1, m); - } - user.displayName = value; - break; - case email: - if (!editEmailAddress) { - throw new UnloggedFailure(1, m); - } - user.emailAddress = value; - break; - case password: - if (!editCredentials) { - throw new UnloggedFailure(1, m); - } - int minLength = gitblit.getSettings().getInteger(Keys.realm.minPasswordLength, 5); - if (minLength < 4) { - minLength = 4; - } - if (value.trim().length() < minLength) { - throw new UnloggedFailure(1, "Password is too short."); - } - - // Optionally store the password MD5 digest. - String type = gitblit.getSettings().getString(Keys.realm.passwordStorage, "md5"); - if (type.equalsIgnoreCase("md5")) { - // store MD5 digest of password - user.password = StringUtils.MD5_TYPE + StringUtils.getMD5(value); - } else if (type.equalsIgnoreCase("combined-md5")) { - // store MD5 digest of username+password - user.password = StringUtils.COMBINED_MD5_TYPE + StringUtils.getMD5(username + value); - } else { - user.password = value; - } - - // reset the cookie - user.cookie = StringUtils.getSHA1(user.username + value); - break; - case canAdmin: - user.canAdmin = toBool(value); - break; - case canFork: - user.canFork = toBool(value); - break; - case canCreate: - user.canCreate = toBool(value); - break; - case disabled: - user.disabled = toBool(value); - break; - default: - throw new UnloggedFailure(1, String.format("Field %s was not properly handled by the set command.", fieldName)); - } - - try { - gitblit.reviseUser(username, user); - stdout.println(String.format("Set %s.%s = %s", username, fieldName, value)); - } catch (GitBlitException e) { - String msg = String.format("Failed to set %s.%s = %s", username, fieldName, value); - log.error(msg, e); - throw new UnloggedFailure(1, msg); - } - } - - protected boolean toBool(String value) throws UnloggedFailure { - String v = value.toLowerCase(); - if (v.equals("t") - || v.equals("true") - || v.equals("yes") - || v.equals("on") - || v.equals("y") - || v.equals("1")) { - return true; - } else if (v.equals("f") - || v.equals("false") - || v.equals("no") - || v.equals("off") - || v.equals("n") - || v.equals("0")) { - return false; - } - throw new UnloggedFailure(1, String.format("Invalid boolean value %s", value)); - } - } - - @CommandMetaData(name = "disable", description = "Prohibit an account from authenticating") - @UsageExample(syntax = "${cmd} john", description = "Prevent John from authenticating") - public static class DisableUser extends UserCommand { - - @Override - public void run() throws UnloggedFailure { - - UserModel user = getUser(true); - user.disabled = true; - - IGitblit gitblit = getContext().getGitblit(); - if (gitblit.updateUserModel(username, user)) { - stdout.println(String.format("%s is not allowed to authenticate.", username)); - } else { - throw new UnloggedFailure(1, String.format("Failed to disable %s!", username)); - } - } - } - - @CommandMetaData(name = "enable", description = "Allow an account to authenticate") - @UsageExample(syntax = "${cmd} john", description = "Allow John to authenticate") - public static class EnableUser extends UserCommand { - - @Override - public void run() throws UnloggedFailure { - - UserModel user = getUser(true); - user.disabled = false; - - IGitblit gitblit = getContext().getGitblit(); - if (gitblit.updateUserModel(username, user)) { - stdout.println(String.format("%s may now authenticate.", username)); - } else { - throw new UnloggedFailure(1, String.format("Failed to enable %s!", username)); - } - } - } - - @CommandMetaData(name = "permissions", aliases = { "perms" }, description = "Add or remove permissions from an account") - @UsageExample(syntax = "${cmd} john RW:alpha/repo.git RWC:alpha/repo2.git", description = "Add or set permissions for John") - public static class Permissions extends UserCommand { - - @Argument(index = 1, multiValued = true, metaVar = "[PERMISSION:]REPOSITORY", usage = "a repository expression") - protected List permissions; - - @Option(name = "--remove", aliases = { "-r" }, metaVar = "REPOSITORY|ALL", usage = "remove a repository permission") - protected List removals; - - @Override - public void run() throws UnloggedFailure { - IGitblit gitblit = getContext().getGitblit(); - UserModel user = getUser(true); - - boolean modified = false; - if (!ArrayUtils.isEmpty(removals)) { - if (removals.contains("ALL")) { - user.permissions.clear(); - } else { - for (String repo : removals) { - user.removeRepositoryPermission(repo); - log.info(String.format("Removing permission for %s from %s", repo, username)); - } - } - modified = true; - } - - if (!ArrayUtils.isEmpty(permissions)) { - for (String perm : permissions) { - String repo = AccessPermission.repositoryFromRole(perm); - if (StringUtils.findInvalidCharacter(repo) == null) { - // explicit permision, confirm repository - RepositoryModel r = gitblit.getRepositoryModel(repo); - if (r == null) { - throw new UnloggedFailure(1, String.format("Repository %s does not exist!", repo)); - } - } - AccessPermission ap = AccessPermission.permissionFromRole(perm); - user.setRepositoryPermission(repo, ap); - log.info(String.format("Setting %s:%s for %s", ap.name(), repo, username)); - } - modified = true; - } - - if (modified && gitblit.updateUserModel(username, user)) { - // reload & display new permissions - user = gitblit.getUserModel(username); - } - - showPermissions(user); - } - - protected void showPermissions(UserModel user) { - List perms = user.getRepositoryPermissions(); - String[] pheaders = { "Repository", "Permission", "Type", "Source", "Mutable" }; - Object [][] pdata = new Object[perms.size()][]; - for (int i = 0; i < perms.size(); i++) { - RegistrantAccessPermission ap = perms.get(i); - pdata[i] = new Object[] { ap.registrant, ap.permission, ap.permissionType, ap.source, ap.mutable ? "Y":"" }; - } - stdout.println(FlipTable.of(pheaders, pdata, Borders.BODY_HCOLS)); - } - } - - @CommandMetaData(name = "remove", aliases = { "rm" }, description = "Remove a user account") - @UsageExample(syntax = "${cmd} john", description = "Delete john's account") - public static class RemoveUser extends UserCommand { - - @Override - public void run() throws UnloggedFailure { - - UserModel user = getUser(true); - IGitblit gitblit = getContext().getGitblit(); - if (gitblit.deleteUserModel(user)) { - stdout.println(String.format("%s has been deleted.", username)); - } else { - throw new UnloggedFailure(1, String.format("Failed to delete %s!", username)); - } - } - } - - @CommandMetaData(name = "show", description = "Show the details of an account") - @UsageExample(syntax = "${cmd} john", description = "Display john's account") - public static class ShowUser extends UserCommand { - - @Override - public void run() throws UnloggedFailure { - - UserModel u = getUser(true); - - // fields - StringBuilder fb = new StringBuilder(); - fb.append("Email : ").append(u.emailAddress == null ? "": u.emailAddress).append('\n'); - fb.append("Type : ").append(u.accountType).append('\n'); - fb.append("Can Admin : ").append(u.canAdmin() ? "Y":"").append('\n'); - fb.append("Can Fork : ").append(u.canFork() ? "Y":"").append('\n'); - fb.append("Can Create : ").append(u.canCreate() ? "Y":"").append('\n'); - String fields = fb.toString(); - - // teams - String teams; - if (u.teams.size() == 0) { - teams = FlipTable.EMPTY; - } else { - teams = Joiner.on(", ").join(u.teams); - } - - // owned repositories - String ownedTable; - List owned = new ArrayList(); - for (RepositoryModel repository : getContext().getGitblit().getRepositoryModels(u)) { - if (repository.isOwner(u.username)) { - owned.add(repository); - } - } - if (owned.isEmpty()) { - ownedTable = FlipTable.EMPTY; - } else { - String [] theaders = new String [] { "Repository", "Description" }; - Object [][] tdata = new Object[owned.size()][]; - int i = 0; - for (RepositoryModel r : owned) { - tdata[i] = new Object [] { r.name, r.description }; - i++; - } - ownedTable = FlipTable.of(theaders, tdata, Borders.COLS); - } - - // permissions - List perms = u.getRepositoryPermissions(); - String permissions; - if (perms.isEmpty()) { - permissions = FlipTable.EMPTY; - } else { - String[] pheaders = { "Repository", "Permission", "Type", "Source", "Mutable" }; - Object [][] pdata = new Object[perms.size()][]; - for (int i = 0; i < perms.size(); i++) { - RegistrantAccessPermission ap = perms.get(i); - pdata[i] = new Object[] { ap.registrant, ap.permission, ap.permissionType, ap.source, ap.mutable ? "Y":"" }; - } - permissions = FlipTable.of(pheaders, pdata, Borders.COLS); - } - - // keys - String keyTable; - List keys = getContext().getGitblit().getPublicKeyManager().getKeys(u.username); - if (ArrayUtils.isEmpty(keys)) { - keyTable = FlipTable.EMPTY; - } else { - String[] headers = { "#", "Fingerprint", "Comment", "Type" }; - int len = keys == null ? 0 : keys.size(); - Object[][] data = new Object[len][]; - for (int i = 0; i < len; i++) { - // show 1-based index numbers with the fingerprint - // this is useful for comparing with "ssh-add -l" - SshKey k = keys.get(i); - data[i] = new Object[] { (i + 1), k.getFingerprint(), k.getComment(), k.getAlgorithm() }; - } - keyTable = FlipTable.of(headers, data, Borders.COLS); - } - - // assemble user table - String userTitle = u.getDisplayName() + (u.username.equals(u.getDisplayName()) ? "" : (" (" + u.username + ")")); - if (u.disabled) { - userTitle += " [DISABLED]"; - } - String [] headers = new String[] { userTitle }; - String[][] data = new String[8][]; - data[0] = new String [] { "FIELDS" }; - data[1] = new String [] { fields }; - data[2] = new String [] { "TEAMS" }; - data[3] = new String [] { teams }; - data[4] = new String [] { "OWNED REPOSITORIES" }; - data[5] = new String [] { ownedTable }; - data[4] = new String [] { "PERMISSIONS" }; - data[5] = new String [] { permissions }; - data[6] = new String [] { "SSH PUBLIC KEYS" }; - data[7] = new String [] { keyTable }; - stdout.println(FlipTable.of(headers, data)); - } - } - - @CommandMetaData(name = "list", aliases= { "ls" }, description = "List accounts") - @UsageExamples(examples = { - @UsageExample(syntax = "${cmd}", description = "List accounts as a table"), - @UsageExample(syntax = "${cmd} j.*", description = "List all accounts that start with 'j'"), - }) - public static class ListUsers extends ListFilterCommand { - - @Override - protected List getItems() { - IGitblit gitblit = getContext().getGitblit(); - List users = gitblit.getAllUsers(); - return users; - } - - @Override - protected boolean matches(String filter, UserModel u) { - return u.username.matches(filter); - } - - @Override - protected void asTable(List list) { - String[] headers; - if (verbose) { - String[] h = { "Name", "Display name", "Email", "Type", "Teams", "Create?", "Fork?"}; - headers = h; - } else { - String[] h = { "Name", "Display name", "Email", "Type"}; - headers = h; - } - - Object[][] data = new Object[list.size()][]; - for (int i = 0; i < list.size(); i++) { - UserModel u = list.get(i); - - String name = (u.disabled ? "-" : ((u.canAdmin() ? "*" : " "))) + u.username; - if (verbose) { - data[i] = new Object[] { - name, - u.displayName, - u.emailAddress, - u.accountType + (u.canAdmin() ? ",admin":""), - u.teams.isEmpty() ? "" : u.teams.size(), - (u.canAdmin() || u.canCreate()) ? "Y":"", - (u.canAdmin() || u.canFork()) ? "Y" : ""}; - } else { - data[i] = new Object[] { - name, - u.displayName, - u.emailAddress, - u.accountType + (u.canAdmin() ? ",admin":"")}; - } - } - stdout.print(FlipTable.of(headers, data, Borders.BODY_HCOLS)); - stdout.println(" * = admin account, - = disabled account"); - stdout.println(); - } - - @Override - protected void asTabbed(List users) { - if (verbose) { - for (UserModel u : users) { - outTabbed( - u.disabled ? "-" : ((u.canAdmin() ? "*" : " ")) + u.username, - u.getDisplayName(), - u.emailAddress == null ? "" : u.emailAddress, - u.accountType + (u.canAdmin() ? ",admin":""), - u.teams.isEmpty() ? "" : u.teams.size(), - (u.canAdmin() || u.canCreate()) ? "Y":"", - (u.canAdmin() || u.canFork()) ? "Y" : ""); - } - } else { - for (UserModel u : users) { - outTabbed(u.disabled ? "-" : ((u.canAdmin() ? "*" : " ")) + u.username); - } - } - } - } -} \ No newline at end of file diff --git a/src/main/java/com/gitblit/transport/ssh/gitblit/BaseKeyCommand.java b/src/main/java/com/gitblit/transport/ssh/keys/BaseKeyCommand.java similarity index 97% rename from src/main/java/com/gitblit/transport/ssh/gitblit/BaseKeyCommand.java rename to src/main/java/com/gitblit/transport/ssh/keys/BaseKeyCommand.java index 930c058f..588770f4 100644 --- a/src/main/java/com/gitblit/transport/ssh/gitblit/BaseKeyCommand.java +++ b/src/main/java/com/gitblit/transport/ssh/keys/BaseKeyCommand.java @@ -13,7 +13,7 @@ * License for the specific language governing permissions and limitations under * the License. */ -package com.gitblit.transport.ssh.gitblit; +package com.gitblit.transport.ssh.keys; import java.io.BufferedReader; import java.io.IOException; diff --git a/src/main/java/com/gitblit/transport/ssh/gitblit/KeysDispatcher.java b/src/main/java/com/gitblit/transport/ssh/keys/KeysDispatcher.java similarity index 99% rename from src/main/java/com/gitblit/transport/ssh/gitblit/KeysDispatcher.java rename to src/main/java/com/gitblit/transport/ssh/keys/KeysDispatcher.java index 9bb60003..ad373060 100644 --- a/src/main/java/com/gitblit/transport/ssh/gitblit/KeysDispatcher.java +++ b/src/main/java/com/gitblit/transport/ssh/keys/KeysDispatcher.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.gitblit.transport.ssh.gitblit; +package com.gitblit.transport.ssh.keys; import java.io.IOException; import java.util.ArrayList; diff --git a/src/site/setup_transport_ssh.mkd b/src/site/setup_transport_ssh.mkd index 0f09910e..a671e5af 100644 --- a/src/site/setup_transport_ssh.mkd +++ b/src/site/setup_transport_ssh.mkd @@ -23,8 +23,8 @@ First you'll need to create an SSH key pair, if you don't already have one or if Then you can upload your *public* key right from the command-line. - cat ~/.ssh/id_rsa.pub | ssh -l -p 29418 gitblit keys add - cat c:\\.ssh\id_rsa.pub | ssh -l -p 29418 gitblit keys add + cat ~/.ssh/id_rsa.pub | ssh -l -p 29418 keys add + cat c:\\.ssh\id_rsa.pub | ssh -l -p 29418 keys add **NOTE:** It is important to note that *ssh-keygen* generates a public/private keypair (e.g. id_rsa and id_rsa.pub). You want to upload the *public* key, which is denoted by the *.pub* file extension. @@ -36,7 +36,7 @@ Once you've done both of those steps you should be able to execute the following Typing the following command syntax all the time gets to be rather tedious. - ssh -l -p 29418 gitblit version + ssh -l -p 29418 You can define an alias for your server which will reduce your command syntax to something like this. @@ -54,29 +54,33 @@ Create or modify your `~/.ssh/config` file and add a host entry. If you are on Gitblit supports SSH command plugins and provides several commands out-of-the-box. -#### gitblit +#### keys -The *gitblit* command has many subcommands for interacting with Gitblit. +The *keys* command dispatcher allows you to manage your public ssh keys. You can list keys, add keys, remove keys, and identify the key in-use for the active session. ##### keys add Add an SSH public key to your account. This command accepts a public key piped to stdin. - cat ~/.ssh/id_rsa.pub | ssh -l -p 29418 gitblit keys add + cat ~/.ssh/id_rsa.pub | ssh -l -p 29418 keys add ##### keys list Show the SSH public keys you have added to your account. - ssh -l -p 29418 gitblit keys list + ssh -l -p 29418 keys list ##### keys remove Remove an SSH public key from your account. This command accepts several input values, the most useful one is an index number which matches the index number displayed in the `list` command. - ssh -l -p 29418 gitblit keys remove 2 + ssh -l -p 29418 keys remove 2 You can also remove all your public keys from your account. - ssh -l -p 29418 gitblit keys remove ALL + ssh -l -p 29418 keys remove ALL + +### SSH Command Plugins + +Gitblit supports loading custom SSH command plugins. diff --git a/src/test/java/com/gitblit/tests/SshDaemonTest.java b/src/test/java/com/gitblit/tests/SshDaemonTest.java index dbd1d868..620190ef 100644 --- a/src/test/java/com/gitblit/tests/SshDaemonTest.java +++ b/src/test/java/com/gitblit/tests/SshDaemonTest.java @@ -93,7 +93,7 @@ public class SshDaemonTest extends GitblitUnitTest { pair.getPublic().getEncoded(); assertTrue(session.authPublicKey("admin", pair).await().isSuccess()); - ClientChannel channel = session.createChannel(ClientChannel.CHANNEL_EXEC, "gitblit version"); + ClientChannel channel = session.createChannel(ClientChannel.CHANNEL_EXEC, "version"); ByteArrayOutputStream baos = new ByteArrayOutputStream(); Writer w = new OutputStreamWriter(baos); w.close(); -- 2.39.5