From 7215126b6674abd4b5ff6b97d30bab6c544bf8df Mon Sep 17 00:00:00 2001 From: Bob Van Landuyt Date: Fri, 21 Dec 2018 18:05:18 +0100 Subject: Allow enabling gitlab-shell "discover"-feature This adds the possibility to enable features for GitLab shell. The first feature being recognized is "Discover": It's the command that is executed when running `ssh git@gitlab.example.com` and is called without a command. The gitlab key id or username is already parsed from the command line arguments. Currently we only support communicating with GitLab-rails using unix sockets. So features will not be enabled if the GitLab-url is using a different protocol. The url for this read from the config yaml. Pending ruby-specs have been added for the gitlab-shell command. Refactor to have separate command packages --- go/internal/command/commandargs/command_args.go | 82 +++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 go/internal/command/commandargs/command_args.go (limited to 'go/internal/command/commandargs/command_args.go') diff --git a/go/internal/command/commandargs/command_args.go b/go/internal/command/commandargs/command_args.go new file mode 100644 index 0000000..7bc13b6 --- /dev/null +++ b/go/internal/command/commandargs/command_args.go @@ -0,0 +1,82 @@ +package commandargs + +import ( + "errors" + "os" + "regexp" +) + +type CommandType string + +const ( + Discover CommandType = "discover" +) + +var ( + whoKeyRegex = regexp.MustCompile(`\bkey-(?P\d+)\b`) + whoUsernameRegex = regexp.MustCompile(`\busername-(?P\S+)\b`) +) + +type CommandArgs struct { + GitlabUsername string + GitlabKeyId string + SshCommand string + CommandType CommandType +} + +func Parse(arguments []string) (*CommandArgs, error) { + if sshConnection := os.Getenv("SSH_CONNECTION"); sshConnection == "" { + return nil, errors.New("Only ssh allowed") + } + + info := &CommandArgs{} + + info.parseWho(arguments) + info.parseCommand(os.Getenv("SSH_ORIGINAL_COMMAND")) + + return info, nil +} + +func (info *CommandArgs) parseWho(arguments []string) { + for _, argument := range arguments { + if keyId := tryParseKeyId(argument); keyId != "" { + info.GitlabKeyId = keyId + break + } + + if username := tryParseUsername(argument); username != "" { + info.GitlabUsername = username + break + } + } +} + +func tryParseKeyId(argument string) string { + matchInfo := whoKeyRegex.FindStringSubmatch(argument) + if len(matchInfo) == 2 { + // The first element is the full matched string + // The second element is the named `keyid` + return matchInfo[1] + } + + return "" +} + +func tryParseUsername(argument string) string { + matchInfo := whoUsernameRegex.FindStringSubmatch(argument) + if len(matchInfo) == 2 { + // The first element is the full matched string + // The second element is the named `username` + return matchInfo[1] + } + + return "" +} + +func (c *CommandArgs) parseCommand(commandString string) { + c.SshCommand = commandString + + if commandString == "" { + c.CommandType = Discover + } +} -- cgit v1.2.1