Browse Source

Improve command help with formatting and usage examples

tags/v1.5.0
James Moger 10 years ago
parent
commit
617909819c

+ 54
- 17
src/main/java/com/gitblit/transport/ssh/WelcomeShell.java View File

@@ -113,36 +113,71 @@ public class WelcomeShell implements Factory<Command> {
String getMessage() {
SshDaemonClient client = session.getAttribute(SshDaemonClient.KEY);
UserModel user = client.getUser();
String hostname = getHostname();
int port = settings.getInteger(Keys.git.sshPort, 0);

final String b1 = StringUtils.rightPad("", 72, '═');
final String b2 = StringUtils.rightPad("", 72, '─');
final String nl = "\r\n";

StringBuilder msg = new StringBuilder();
msg.append("\r\n");
msg.append("Hi ");
msg.append(nl);
msg.append(b1);
msg.append(nl);
msg.append(" ");
msg.append(com.gitblit.Constants.getGitBlitVersion());
msg.append(nl);
msg.append(b1);
msg.append(nl);
msg.append(nl);
msg.append(" Hi ");
msg.append(user.getDisplayName());
msg.append(", you have successfully connected to Gitblit over SSH");
msg.append("\r\n");
msg.append("with client: ");
msg.append(", you have successfully connected over SSH.");
msg.append(nl);
msg.append(nl);
msg.append(" client: ");
msg.append(session.getClientVersion());
msg.append("\r\n");
msg.append("\r\n");
msg.append(nl);
msg.append(nl);

msg.append("You may clone a repository with the following Git syntax:\r\n");
msg.append("\r\n");
msg.append(b2);
msg.append(nl);
msg.append(nl);
msg.append(" You may clone a repository with the following Git syntax:");
msg.append(nl);
msg.append(nl);

msg.append(" git clone ");
msg.append(formatUrl(user.username));
msg.append("\r\n");
msg.append("\r\n");
msg.append(formatUrl(hostname, port, user.username));
msg.append(nl);
msg.append(nl);

msg.append(b2);
msg.append(nl);
msg.append(nl);

msg.append(" You may upload an SSH public key with the following syntax:");
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(nl);
msg.append(nl);

msg.append(b2);
msg.append(nl);
msg.append(nl);

// display the core commands
SshCommandFactory cmdFactory = (SshCommandFactory) session.getFactoryManager().getCommandFactory();
DispatchCommand root = cmdFactory.createRootDispatcher(client, "");
String usage = root.usage().replace("\n", "\r\n");
String usage = root.usage().replace("\n", nl);
msg.append(usage);

return msg.toString();
}

private String formatUrl(String username) {
private String getHostname() {
String host = null;
String url = settings.getString(Keys.web.canonicalUrl, "https://localhost:8443");
if (url != null) {
@@ -154,15 +189,17 @@ public class WelcomeShell implements Factory<Command> {
if (StringUtils.isEmpty(host)) {
host = SystemReader.getInstance().getHostname();
}
return host;
}

int port = settings.getInteger(Keys.git.sshPort, 0);
private String formatUrl(String hostname, int port, String username) {
if (port == 22) {
// standard port
return MessageFormat.format("{0}@{1}/REPOSITORY.git", username, host);
return MessageFormat.format("{0}@{1}/REPOSITORY.git", username, hostname);
} else {
// non-standard port
return MessageFormat.format("ssh://{0}@{1}:{2,number,0}/REPOSITORY.git",
username, host, port);
username, hostname, port);
}
}
}

+ 58
- 2
src/main/java/com/gitblit/transport/ssh/commands/BaseCommand.java View File

@@ -37,7 +37,9 @@ import org.kohsuke.args4j.Option;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gitblit.Keys;
import com.gitblit.utils.IdGenerator;
import com.gitblit.utils.StringUtils;
import com.gitblit.utils.WorkQueue;
import com.gitblit.utils.WorkQueue.CancelableRunnable;
import com.gitblit.utils.cli.CmdLineParser;
@@ -200,9 +202,39 @@ public abstract class BaseCommand implements Command, SessionAware {
}

if (clp.wasHelpRequestedByOption()) {
CommandMetaData meta = getClass().getAnnotation(CommandMetaData.class);
String title = meta.name().toUpperCase() + ": " + meta.description();
String b = com.gitblit.utils.StringUtils.leftPad("", title.length() + 2, '═');
StringWriter msg = new StringWriter();
clp.printDetailedUsage(commandName, msg);
msg.write(usage());
msg.write('\n');
msg.write(b);
msg.write('\n');
msg.write(' ');
msg.write(title);
msg.write('\n');
msg.write(b);
msg.write("\n\n");
msg.write("USAGE\n");
msg.write("─────\n");
msg.write(' ');
msg.write(commandName);
msg.write('\n');
msg.write(' ');
clp.printSingleLineUsage(msg, null);
msg.write("\n\n");
msg.write("ARGUMENTS & OPTIONS\n");
msg.write("───────────────────\n");
clp.printUsage(msg, null);
msg.write('\n');
String examples = usage().trim();
if (!StringUtils.isEmpty(examples)) {
msg.write('\n');
msg.write("EXAMPLES\n");
msg.write("────────\n");
msg.write(examples);
msg.write('\n');
}

throw new UnloggedFailure(1, msg.toString());
}
}
@@ -213,9 +245,33 @@ public abstract class BaseCommand implements Command, SessionAware {
}

public String usage() {
Class<? extends BaseCommand> clazz = getClass();
if (clazz.isAnnotationPresent(UsageExamples.class)) {
return examples(clazz.getAnnotation(UsageExamples.class).examples());
} else if (clazz.isAnnotationPresent(UsageExample.class)) {
return examples(clazz.getAnnotation(UsageExample.class));
}
return "";
}

protected String examples(UsageExample... examples) {
int sshPort = getContext().getGitblit().getSettings().getInteger(Keys.git.sshPort, 29418);
String username = getContext().getClient().getUsername();
String hostname = "localhost";
String ssh = String.format("ssh -l %s -p %d %s", username, sshPort, hostname);

StringBuilder sb = new StringBuilder();
for (UsageExample example : examples) {
sb.append(example.description()).append("\n\n");
String syntax = example.syntax();
syntax = syntax.replace("${ssh}", ssh);
syntax = syntax.replace("${username}", username);
syntax = syntax.replace("${cmd}", commandName);
sb.append(" ").append(syntax).append("\n\n");
}
return sb.toString();
}

protected void showHelp() throws UnloggedFailure {
argv = new String [] { "--help" };
parseCommandLine();

+ 2
- 2
src/main/java/com/gitblit/transport/ssh/commands/DispatchCommand.java View File

@@ -332,9 +332,9 @@ public abstract class DispatchCommand extends BaseCommand implements ExtensionPo
continue;
}

String displayName = name;
String displayName = name + (meta.admin() ? "*" : "");
if (commandToAliases.containsKey(meta.name())) {
displayName = name + " (" + Joiner.on(',').join(commandToAliases.get(meta.name())) + ")";
displayName = name + (meta.admin() ? "*" : "")+ " (" + Joiner.on(',').join(commandToAliases.get(meta.name())) + ")";
}
displayNames.put(name, displayName);


+ 4
- 0
src/main/java/com/gitblit/transport/ssh/commands/SshCommand.java View File

@@ -18,8 +18,12 @@ import java.io.IOException;
import java.io.PrintWriter;

import org.apache.sshd.server.Environment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class SshCommand extends BaseCommand {

protected Logger log = LoggerFactory.getLogger(getClass());
protected PrintWriter stdout;
protected PrintWriter stderr;


+ 32
- 0
src/main/java/com/gitblit/transport/ssh/commands/UsageExample.java View File

@@ -0,0 +1,32 @@
/*
* 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 static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

/**
* Annotation tagged on a concrete Command to describe how to use it.
*/
@Target({ElementType.TYPE})
@Retention(RUNTIME)
public @interface UsageExample {
String syntax();
String description() default "";
}

+ 31
- 0
src/main/java/com/gitblit/transport/ssh/commands/UsageExamples.java View File

@@ -0,0 +1,31 @@
/*
* 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 static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

/**
* Annotation tagged on a concrete Command to describe how to use it.
*/
@Target({ElementType.TYPE})
@Retention(RUNTIME)
public @interface UsageExamples {
UsageExample [] examples() default {};
}

+ 2
- 0
src/main/java/com/gitblit/transport/ssh/git/GarbageCollectionCommand.java View File

@@ -25,8 +25,10 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gitblit.transport.ssh.commands.CommandMetaData;
import com.gitblit.transport.ssh.commands.UsageExample;

@CommandMetaData(name = "gc", description = "Cleanup unnecessary files and optimize the local repository", admin = true)
@UsageExample(syntax = "${cmd} test/myrepository.git", description = "Garbage collect \"test/myrepository.git\"")
public class GarbageCollectionCommand extends BaseGitCommand {

private static final Logger log = LoggerFactory.getLogger(GarbageCollectionCommand.class);

+ 1
- 1
src/main/java/com/gitblit/transport/ssh/gitblit/BaseKeyCommand.java View File

@@ -36,7 +36,7 @@ abstract class BaseKeyCommand extends SshCommand {
protected List<String> readKeys(List<String> sshKeys)
throws UnsupportedEncodingException, IOException {
int idx = -1;
if (sshKeys.isEmpty() || ((idx = sshKeys.indexOf("-")) >= 0)) {
if ((idx = sshKeys.indexOf("-")) >= 0) {
String sshKey = "";
BufferedReader br = new BufferedReader(new InputStreamReader(
in, Charsets.UTF_8));

+ 8
- 0
src/main/java/com/gitblit/transport/ssh/gitblit/ConfigCommand.java View File

@@ -14,9 +14,17 @@ 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")

+ 0
- 37
src/main/java/com/gitblit/transport/ssh/gitblit/CreateRepository.java View File

@@ -1,37 +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 org.kohsuke.args4j.Option;

import com.gitblit.transport.ssh.commands.CommandMetaData;
import com.gitblit.transport.ssh.commands.SshCommand;

@CommandMetaData(name = "create-repository", description = "Create new GIT repository", admin = true, hidden = true)
public class CreateRepository extends SshCommand {

@Option(name = "--name", aliases = {"-n"}, required = true, metaVar = "NAME", usage = "name of repository to be created")
private String name;

@Option(name = "--description", aliases = {"-d"}, metaVar = "DESCRIPTION", usage = "description of repository")
private String repositoryDescription;

@Override
public void run() {
stdout.println(String.format("Repository <%s> was created", name));
}
}

+ 0
- 2
src/main/java/com/gitblit/transport/ssh/gitblit/GitblitDispatcher.java View File

@@ -26,8 +26,6 @@ public class GitblitDispatcher extends DispatchCommand {
protected void setup(UserModel user) {
// commands in this dispatcher
register(user, VersionCommand.class);
register(user, CreateRepository.class);
register(user, SetAccountCommand.class);
register(user, ConfigCommand.class);

// nested dispatchers

+ 5
- 2
src/main/java/com/gitblit/transport/ssh/gitblit/KeysDispatcher.java View File

@@ -30,6 +30,7 @@ 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.SshCommand;
import com.gitblit.transport.ssh.commands.UsageExample;
import com.gitblit.utils.FlipTable;
import com.gitblit.utils.FlipTable.Borders;

@@ -50,11 +51,12 @@ public class KeysDispatcher extends DispatchCommand {
}

@CommandMetaData(name = "add", description = "Add an SSH public key to your account")
@UsageExample(syntax = "cat ~/.ssh/id_rsa.pub | ${ssh} ${cmd} -", description = "Upload your SSH public key and add it to your account")
public static class AddKey extends BaseKeyCommand {

protected final Logger log = LoggerFactory.getLogger(getClass());

@Argument(metaVar = "<stdin>|KEY", usage = "the key to add")
@Argument(metaVar = "-|<KEY>", usage = "the key(s) to add", required = true)
private List<String> addKeys = new ArrayList<String>();

@Override
@@ -70,6 +72,7 @@ public class KeysDispatcher extends DispatchCommand {
}

@CommandMetaData(name = "remove", aliases = { "rm" }, description = "Remove an SSH public key from your account")
@UsageExample(syntax = "${cmd} 2", description = "Remove the SSH key identified as #2 in `keys list`")
public static class RemoveKey extends BaseKeyCommand {

protected final Logger log = LoggerFactory.getLogger(getClass());
@@ -131,7 +134,7 @@ public class KeysDispatcher extends DispatchCommand {
}
}

@CommandMetaData(name = "list", aliases = { "ls" }, description = "List your registered public keys")
@CommandMetaData(name = "list", aliases = { "ls" }, description = "List your registered SSH public keys")
public static class ListKeys extends SshCommand {

@Option(name = "-L", usage = "list complete public key parameters")

+ 3
- 1
src/main/java/com/gitblit/transport/ssh/gitblit/RepositoriesDispatcher.java View File

@@ -23,6 +23,7 @@ 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.UsageExample;
import com.gitblit.utils.ArrayUtils;
import com.gitblit.utils.FlipTable;
import com.gitblit.utils.FlipTable.Borders;
@@ -38,6 +39,7 @@ public class RepositoriesDispatcher extends DispatchCommand {

/* 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<RepositoryModel> {

@Override
@@ -72,7 +74,7 @@ public class RepositoriesDispatcher extends DispatchCommand {
String size = r.size;
if (!r.hasCommits) {
lm = "";
size = "(empty)";
size = FlipTable.EMPTY;
}
if (verbose) {
String owners = "";

+ 0
- 88
src/main/java/com/gitblit/transport/ssh/gitblit/SetAccountCommand.java View File

@@ -1,88 +0,0 @@
//Copyright (C) 2012 The Android Open Source Project
//
//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.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;

import com.gitblit.transport.ssh.SshKey;
import com.gitblit.transport.ssh.commands.CommandMetaData;

/** Set a user's account settings. **/
@CommandMetaData(name = "set-account", description = "Change an account's settings", admin = true)
public class SetAccountCommand extends BaseKeyCommand {

private static final String ALL = "ALL";

@Argument(index = 0, required = true, metaVar = "USER", usage = "full name, email-address, ssh username or account id")
private String user;

@Option(name = "--add-ssh-key", metaVar = "-|KEY", usage = "public keys to add to the account")
private List<String> addSshKeys = new ArrayList<String>();

@Option(name = "--delete-ssh-key", metaVar = "-|KEY", usage = "public keys to delete from the account")
private List<String> deleteSshKeys = new ArrayList<String>();

@Override
public void run() throws IOException, UnloggedFailure {
validate();
setAccount();
}

private void validate() throws UnloggedFailure {
if (addSshKeys.contains("-") && deleteSshKeys.contains("-")) {
throw new UnloggedFailure(1, "Only one option may use the stdin");
}
if (deleteSshKeys.contains(ALL)) {
deleteSshKeys = Collections.singletonList(ALL);
}
}

private void setAccount() throws IOException, UnloggedFailure {
addSshKeys = readKeys(addSshKeys);
if (!addSshKeys.isEmpty()) {
addSshKeys(addSshKeys);
}

deleteSshKeys = readKeys(deleteSshKeys);
if (!deleteSshKeys.isEmpty()) {
deleteSshKeys(deleteSshKeys);
}
}

private void addSshKeys(List<String> keys) throws UnloggedFailure,
IOException {
for (String key : keys) {
SshKey sshKey = new SshKey(key);
getKeyManager().addKey(user, sshKey);
}
}

private void deleteSshKeys(List<String> keys) {
if (keys.contains(ALL)) {
getKeyManager().removeAllKeys(user);
} else {
for (String key : keys) {
SshKey sshKey = new SshKey(key);
getKeyManager().removeKey(user, sshKey);
}
}
}
}

+ 266
- 27
src/main/java/com/gitblit/transport/ssh/gitblit/UsersDispatcher.java View File

@@ -15,75 +15,308 @@
*/
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.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 = "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, RemoveUser.class);
register(user, ShowUser.class);
register(user, ListUsers.class);

// user-specific commands
register(user, SetName.class);
register(user, Permissions.class);
register(user, DisableUser.class);
register(user, EnableUser.class);
}

@CommandMetaData(name = "show", description = "Show a user")
public static class ShowUser extends SshCommand {
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", 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();
if (gitblit.updateUserModel(username, user)) {
stdout.println(String.format("%s created.", username));
} else {
throw new UnloggedFailure(1, String.format("Failed to create %s!", username));
}
}
}

@CommandMetaData(name = "set-name", description = "Set the display name of an account")
@UsageExample(syntax = "${cmd} john John Smith", description = "The display name to \"John Smith\" for john's account")
public static class SetName extends UserCommand {

@Argument(index = 1, multiValued = true, required = true, metaVar = "NAME", usage = "display name")
protected List<String> displayName = new ArrayList<String>();

@Override
public void run() throws UnloggedFailure {
UserModel user = getUser(true);

IGitblit gitblit = getContext().getGitblit();
user.displayName = Joiner.on(" ").join(displayName);
if (gitblit.updateUserModel(username, user)) {
stdout.println(String.format("Set the display name of %s to \"%s\".", username, user.displayName));
} else {
throw new UnloggedFailure(1, String.format("Failed to set the display name of %s!", username));
}
}
}

@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<String> permissions;

@Option(name = "--remove", aliases = { "-r" }, metaVar = "REPOSITORY|ALL", usage = "remove a repository permission")
protected List<String> 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<RegistrantAccessPermission> 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();
UserModel u = gitblit.getUserModel(username);
if (u == null) {
throw new UnloggedFailure(1, String.format("Unknown user \"%s\"", username));
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
String [] fheaders = new String [] { "Field", "Value" };
Object [][] fdata = new Object[5][];
fdata[0] = new Object [] { "Email", u.emailAddress };
fdata[1] = new Object [] { "Type", u.accountType };
fdata[2] = new Object [] { "Can Admin", u.canAdmin() ? "Y":"N" };
fdata[3] = new Object [] { "Can Fork", u.canFork() ? "Y":"N" };
fdata[4] = new Object [] { "Can Create", u.canCreate() ? "Y":"N" };
fdata[2] = new Object [] { "Can Admin", u.canAdmin() ? "Y":"" };
fdata[3] = new Object [] { "Can Fork", u.canFork() ? "Y":"" };
fdata[4] = new Object [] { "Can Create", u.canCreate() ? "Y":"" };
String fields = FlipTable.of(fheaders, fdata, Borders.COLS);

// teams
String [] theaders = new String [] { "Team", "Type" };
Object [][] tdata = new Object[u.teams.size()][];
int i = 0;
for (TeamModel t : u.teams) {
tdata[i] = new Object [] { t.name, t.accountType };
i++;
String teams;
if (u.teams.size() == 0) {
teams = FlipTable.EMPTY;
} else {
String [] theaders = new String [] { "Team", "Type" };
Object [][] tdata = new Object[u.teams.size()][];
int i = 0;
for (TeamModel t : u.teams) {
tdata[i] = new Object [] { t.name, t.accountType };
i++;
}
teams = FlipTable.of(theaders, tdata, Borders.COLS);
}
String teams = FlipTable.of(theaders, tdata, Borders.COLS);

// permissions
List<RegistrantAccessPermission> perms = u.getRepositoryPermissions();
String[] pheaders = { "Repository", "Permission", "Type", "Source", "Mutable" };
Object [][] pdata = new Object[perms.size()][];
for (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":"N" };
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);
}
String permissions = FlipTable.of(pheaders, pdata, Borders.COLS);

// assemble user table
String [] headers = new String[] { u.getDisplayName() + (u.username.equals(u.getDisplayName()) ? "" : (" (" + u.username + ")")) };
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[6][];
data[0] = new String [] { "FIELDS" };
data[1] = new String [] { fields };
@@ -95,7 +328,11 @@ public class UsersDispatcher extends DispatchCommand {
}
}

@CommandMetaData(name = "list", aliases= { "ls" }, description = "List users")
@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<UserModel> {

@Override
@@ -125,10 +362,12 @@ public class UsersDispatcher extends DispatchCommand {
for (int i = 0; i < list.size(); i++) {
UserModel u = list.get(i);

String name = u.disabled ? "-" : ((u.canAdmin() ? "*" : " ")) + u.username;
String name = (u.disabled ? "-" : ((u.canAdmin() ? "*" : " "))) + u.username;
if (verbose) {
data[i] = new Object[] { name, u.displayName, u.accountType,
u.emailAddress, u.canCreate() ? "Y":"", u.canFork() ? "Y" : ""};
u.emailAddress,
(u.canAdmin() || u.canCreate()) ? "Y":"",
(u.canAdmin() || u.canFork()) ? "Y" : ""};
} else {
data[i] = new Object[] { name, u.displayName, u.accountType,
u.emailAddress };
@@ -147,8 +386,8 @@ public class UsersDispatcher extends DispatchCommand {
u.getDisplayName(),
u.accountType,
u.emailAddress == null ? "" : u.emailAddress,
u.canCreate() ? "Y":"",
u.canFork() ? "Y" : "");
(u.canAdmin() || u.canCreate()) ? "Y":"",
(u.canAdmin() || u.canFork()) ? "Y" : "");
}
} else {
for (UserModel u : users) {

+ 1
- 1
src/main/java/com/gitblit/utils/FlipTable.java View File

@@ -36,7 +36,7 @@ package com.gitblit.utils;
* </pre>
*/
public final class FlipTable {
private static final String EMPTY = "(empty)";
public static final String EMPTY = "(empty)";

public static enum Borders {
FULL(15), BODY_HCOLS(13), HCOLS(12), BODY(9), HEADER(8), COLS(4);

+ 13
- 14
src/site/setup_transport_ssh.mkd View File

@@ -23,14 +23,14 @@ 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 <username> -p 29418 <hostname> gitblit keys add
cat c:\<userfolder>\.ssh\id_rsa.pub | ssh -l <username> -p 29418 <hostname> gitblit keys add
cat ~/.ssh/id_rsa.pub | ssh -l <username> -p 29418 <hostname> gitblit keys add -
cat c:\<userfolder>\.ssh\id_rsa.pub | ssh -l <username> -p 29418 <hostname> gitblit 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.
Once you've done both of those steps you should be able to execute the following command without a password prompt.
ssh -l <username> -p 29418 <hostname> gitblit version
ssh -l <username> -p 29418 <hostname>
### Setting up an SSH alias
@@ -40,7 +40,7 @@ Typing the following command syntax all the time gets to be rather tedious.
You can define an alias for your server which will reduce your command syntax to something like this.
ssh <alias> gitblit version
ssh <alias>
Create or modify your `~/.ssh/config` file and add a host entry. If you are on Windows, you'll want to create or modify `<userfolder>\.ssh\config`, where *userfolder* is dependent on your version of Windows. Most recently this is `c:\users\<userfolder>`.
@@ -62,22 +62,21 @@ The *gitblit* command has many subcommands for interacting with Gitblit.
Add an SSH public key to your account. This command accepts a public key piped to stdin.
cat ~/.ssh/id_rsa.pub | ssh -l <username> -p 29418 <hostname> gitblit keys add
##### keys remove
cat ~/.ssh/id_rsa.pub | ssh -l <username> -p 29418 <hostname> gitblit keys add -
Remove an SSH public key from your account. This command accepts a public key piped to stdin.
##### keys list
cat ~/.ssh/id_rsa.pub | ssh -l <username> -p 29418 <hostname> gitblit keys remove
Show the SSH public keys you have added to your account.
You can also remove all your public keys from your account.
ssh -l <username> -p 29418 <hostname> gitblit keys list
ssh -l <username> -p 29418 <hostname> gitblit keys remove ALL
##### keys remove
##### keys list
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.
Show the SSH keys you have added to your account.
ssh -l <username> -p 29418 <hostname> gitblit keys remove 2
ssh -l <username> -p 29418 <hostname> gitblit keys list
You can also remove all your public keys from your account.
ssh -l <username> -p 29418 <hostname> gitblit keys remove ALL

Loading…
Cancel
Save