James Moger
2014-03-19 eec333e07be744bcc3a1fea4449000d48bd5234c
Refactor 'gitblit' commands into several nested dispatchers
4 files deleted
3 files added
2 files modified
693 ■■■■ changed files
src/main/java/com/gitblit/transport/ssh/gitblit/AddKeyCommand.java 51 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/transport/ssh/gitblit/GitblitDispatcher.java 14 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/transport/ssh/gitblit/KeysDispatcher.java 121 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/transport/ssh/gitblit/ListDispatcher.java 190 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/transport/ssh/gitblit/LsCommand.java 122 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/transport/ssh/gitblit/LsUsersCommand.java 73 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/transport/ssh/gitblit/RemoveKeyCommand.java 59 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/transport/ssh/gitblit/TicketsDispatcher.java 29 ●●●●● patch | view | raw | blame | history
src/site/setup_transport_ssh.mkd 34 ●●●●● patch | view | raw | blame | history
src/main/java/com/gitblit/transport/ssh/gitblit/AddKeyCommand.java
File was deleted
src/main/java/com/gitblit/transport/ssh/gitblit/GitblitDispatcher.java
@@ -24,16 +24,14 @@
    @Override
    protected void registerCommands(UserModel user) {
        // normal usage commands
        // commands in this dispatcher
        registerCommand(user, VersionCommand.class);
        registerCommand(user, AddKeyCommand.class);
        registerCommand(user, RemoveKeyCommand.class);
        registerCommand(user, LsCommand.class);
        registerCommand(user, ReviewCommand.class);
        // administrative commands
        registerCommand(user, LsUsersCommand.class);
        registerCommand(user, CreateRepository.class);
        registerCommand(user, SetAccountCommand.class);
        // nested dispatchers
        registerDispatcher(user, ListDispatcher.class);
        registerDispatcher(user, KeysDispatcher.class);
        registerDispatcher(user, TicketsDispatcher.class);
    }
}
src/main/java/com/gitblit/transport/ssh/gitblit/KeysDispatcher.java
New file
@@ -0,0 +1,121 @@
/*
 * 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.io.IOException;
import java.security.PublicKey;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.codec.binary.Base64;
import org.apache.sshd.common.util.Buffer;
import org.kohsuke.args4j.Argument;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.gitblit.models.UserModel;
import com.gitblit.transport.ssh.IPublicKeyManager;
import com.gitblit.transport.ssh.commands.CommandMetaData;
import com.gitblit.transport.ssh.commands.DispatchCommand;
import com.gitblit.transport.ssh.commands.SshCommand;
/**
 * The dispatcher and it's commands for SSH public key management.
 *
 * @author James Moger
 *
 */
@CommandMetaData(name = "keys", description = "SSH public key management commands")
public class KeysDispatcher extends DispatchCommand {
    @Override
    protected void registerCommands(UserModel user) {
        registerCommand(user, AddKey.class);
        registerCommand(user, RemoveKey.class);
        registerCommand(user, ListKeys.class);
    }
    @CommandMetaData(name = "add", description = "Add an SSH public key 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")
        private List<String> addKeys = new ArrayList<String>();
        @Override
        public void run() throws IOException, UnloggedFailure {
            String username = getContext().getClient().getUsername();
            List<String> keys = readKeys(addKeys);
            for (String key : keys) {
                getKeyManager().addKey(username, key);
                log.info("added SSH public key for {}", username);
            }
        }
    }
    @CommandMetaData(name = "remove", aliases = { "rm" }, description = "Remove an SSH public key from your account")
    public static class RemoveKey extends BaseKeyCommand {
        protected final Logger log = LoggerFactory.getLogger(getClass());
        private final String ALL = "ALL";
        @Argument(metaVar = "<stdin>|<KEY>|ALL", usage = "the key to remove")
        private List<String> removeKeys = new ArrayList<String>();
        @Override
        public void run() throws IOException, UnloggedFailure {
            String username = getContext().getClient().getUsername();
            List<String> keys = readKeys(removeKeys);
            if (keys.contains(ALL)) {
                getKeyManager().removeAllKeys(username);
                log.info("removed all SSH public keys from {}", username);
            } else {
                for (String key : keys) {
                    getKeyManager().removeKey(username, key);
                    log.info("removed SSH public key from {}", username);
                }
            }
        }
    }
    @CommandMetaData(name = "list", aliases = { "ls" }, description = "List your public keys")
    public static class ListKeys extends SshCommand {
        @Override
        public void run() {
            IPublicKeyManager keyManager = getContext().getGitblit().getPublicKeyManager();
            List<PublicKey> keys = keyManager.getKeys(getContext().getClient().getUsername());
            for (PublicKey key : keys) {
                // two-steps - perhaps this could be improved
                Buffer buf = new Buffer();
                // 1: identify the algorithm
                buf.putRawPublicKey(key);
                String alg = buf.getString();
                // 2: encode the key
                buf.clear();
                buf.putPublicKey(key);
                String b64 = Base64.encodeBase64String(buf.getBytes());
                stdout.println(alg + " " + b64);
            }
        }
    }
}
src/main/java/com/gitblit/transport/ssh/gitblit/ListDispatcher.java
New file
@@ -0,0 +1,190 @@
/*
 * 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.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.List;
import org.kohsuke.args4j.Option;
import org.parboiled.common.StringUtils;
import com.gitblit.manager.IGitblit;
import com.gitblit.models.ProjectModel;
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.SshCommand;
/**
 * 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 registerCommands(UserModel user) {
        registerCommand(user, ListRepositories.class);
        registerCommand(user, ListProjects.class);
        registerCommand(user, ListUsers.class);
        registerCommand(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 SshCommand {
        @Option(name = "--verbose", aliases = { "-v" }, usage = "verbose")
        private boolean verbose;
        @Override
        public void run() {
            IGitblit gitblit = getContext().getGitblit();
            UserModel user = getContext().getClient().getUser();
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
            List<RepositoryModel> repositories = gitblit.getRepositoryModels(user);
            int nameLen = 0;
            int descLen = 0;
            for (RepositoryModel repo : repositories) {
                int len = repo.name.length();
                if (len > nameLen) {
                    nameLen = len;
                }
                if (!StringUtils.isEmpty(repo.description)) {
                    len = repo.description.length();
                    if (len > descLen) {
                        descLen = len;
                    }
                }
            }
            String pattern;
            if (verbose) {
                pattern = MessageFormat.format("%-{0,number,0}s\t%-{1,number,0}s\t%s", nameLen, descLen);
            } else {
                pattern = "%s";
            }
            for (RepositoryModel repo : repositories) {
                stdout.println(String.format(pattern,
                        repo.name,
                        repo.description == null ? "" : repo.description,
                        df.format(repo.lastChange)));
            }
        }
    }
    /* List projects */
    @CommandMetaData(name = "projects", description = "List projects")
    public static class ListProjects extends SshCommand {
        @Option(name = "--verbose", aliases = { "-v" }, usage = "verbose")
        private boolean verbose;
        @Override
        public void run() {
            IGitblit gitblit = getContext().getGitblit();
            UserModel user = getContext().getClient().getUser();
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
            List<ProjectModel> projects = gitblit.getProjectModels(user, false);
            int nameLen = 0;
            int descLen = 0;
            for (ProjectModel project : projects) {
                int len = project.name.length();
                if (len > nameLen) {
                    nameLen = len;
                }
                if (!StringUtils.isEmpty(project.description)) {
                    len = project.description.length();
                    if (len > descLen) {
                        descLen = len;
                    }
                }
            }
            String pattern;
            if (verbose) {
                pattern = MessageFormat.format("%-{0,number,0}s\t%-{1,number,0}s\t%s", nameLen, descLen);
            } else {
                pattern = "%s";
            }
            for (ProjectModel project : projects) {
                stdout.println(String.format(pattern,
                        project.name,
                        project.description == null ? "" : project.description,
                        df.format(project.lastChange)));
            }
        }
    }
    /* List users */
    @CommandMetaData(name = "users", description = "List users", admin = true)
    public static class ListUsers extends SshCommand {
        @Option(name = "--verbose", aliases = { "-v" }, usage = "verbose")
        private boolean verbose;
        @Override
        public void run() {
            IGitblit gitblit = getContext().getGitblit();
            List<UserModel> users = gitblit.getAllUsers();
            int displaynameLen = 0;
            int usernameLen = 0;
            for (UserModel user : users) {
                int len = user.getDisplayName().length();
                if (len > displaynameLen) {
                    displaynameLen = len;
                }
                if (!StringUtils.isEmpty(user.username)) {
                    len = user.username.length();
                    if (len > usernameLen) {
                        usernameLen = len;
                    }
                }
            }
            String pattern;
            if (verbose) {
                pattern = MessageFormat.format("%-{0,number,0}s\t%-{1,number,0}s\t%-10s\t%s", displaynameLen, usernameLen);
            } else {
                pattern = MessageFormat.format("%-{0,number,0}s\t%-{1,number,0}s", displaynameLen, usernameLen);
            }
            for (UserModel user : users) {
                if (user.disabled) {
                    continue;
                }
                stdout.println(String.format(pattern,
                        user.getDisplayName(),
                        (user.canAdmin() ? "*":" ") + user.username,
                        user.accountType,
                        user.emailAddress == null ? "" : user.emailAddress));
            }
        }
    }
}
src/main/java/com/gitblit/transport/ssh/gitblit/LsCommand.java
File was deleted
src/main/java/com/gitblit/transport/ssh/gitblit/LsUsersCommand.java
File was deleted
src/main/java/com/gitblit/transport/ssh/gitblit/RemoveKeyCommand.java
File was deleted
src/main/java/com/gitblit/transport/ssh/gitblit/TicketsDispatcher.java
New file
@@ -0,0 +1,29 @@
/*
 * 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 = "tickets", description = "Ticket commands", hidden = true)
public class TicketsDispatcher extends DispatchCommand {
    @Override
    protected void registerCommands(UserModel user) {
        registerCommand(user, ReviewCommand.class);
    }
}
src/site/setup_transport_ssh.mkd
@@ -23,8 +23,8 @@
Then you can upload your *public* key right from the command-line.
    cat ~/.ssh/id_rsa.pub | ssh -l <username> -p 29418 <hostname> gitblit add-key
    cat c:\<userfolder>\.ssh\id_rsa.pub | ssh -l <username> -p 29418 <hostname> gitblit add-key
    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.
@@ -52,36 +52,32 @@
### SSH Commands
#### git
You will likely never directly interact with the git command, but it is used by your git client to clone, fetch, and push commits to/from your Gitblit server.
##### git-receive-pack
This is the command for processing pushes sent from clients.
##### git-upload-pack
This is the command for sending refs and commits to clients.
Gitblit supports SSH command plugins and provides several commands out-of-the-box.
#### gitblit
The *gitblit* command has many subcommands for interacting gitblit.
The *gitblit* command has many subcommands for interacting with Gitblit.
##### add-key
##### 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 <username> -p 29418 <hostname> gitblit add-key
    cat ~/.ssh/id_rsa.pub | ssh -l <username> -p 29418 <hostname> gitblit keys add
##### rm-key
##### keys remove
Remove an SSH public key from your account.  This command accepts a public key piped to stdin.
    cat ~/.ssh/id_rsa.pub | ssh -l <username> -p 29418 <hostname> gitblit rm-key
    cat ~/.ssh/id_rsa.pub | ssh -l <username> -p 29418 <hostname> gitblit keys remove
You can also remove all your public keys from your account.
    ssh -l <username> -p 29418 <hostname> gitblit rm-key ALL
    ssh -l <username> -p 29418 <hostname> gitblit keys remove ALL
##### keys list
Show the SSH keys you have added to your account.
    ssh -l <username> -p 29418 <hostname> gitblit keys list