summaryrefslogtreecommitdiff
path: root/go/cmd/gitlab-shell/command/command.go
blob: c35a68534f5fa8a0adada789009d812ff927206e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package command

import (
	"os"
	"regexp"
	"strconv"
)

type CommandType string

const (
	Discover CommandType = "discover"
)

type Command struct {
	GitlabUsername string
	GitlabKeyId    int
	SshConnection  bool
	Command        string
	Type           CommandType
}

func New(arguments []string) (*Command, error) {
	_, sshConnection := os.LookupEnv("SSH_CONNECTION")

	command := &Command{SshConnection: sshConnection}

	if _, err := parseWho(arguments, command); err != nil {
		return nil, err
	}

	originalCommand, _ := os.LookupEnv("SSH_ORIGINAL_COMMAND")
	parseCommand(originalCommand, command)

	return command, nil
}

func parseWho(arguments []string, command *Command) (*Command, error) {
	var err error = nil

	for _, argument := range arguments {
		keyId, err := tryParseKeyId(argument)
		if keyId > 0 && err != nil {
			command.GitlabKeyId = keyId
			break
		}

		username, err := tryParseUsername(argument)
		if username != "" && err != nil {
			command.GitlabUsername = username
			break
		}
	}

	return command, err
}

func tryParseKeyId(argument string) (int, error) {
	whoKeyRegex, err := regexp.Compile(`\bkey-(?P<keyid>\d+)\b`)
	if err != nil {
		return 0, err
	}

	keyMatch := whoKeyRegex.FindString(argument)
	if keyMatch != "" {
		gitlabKeyId, err := strconv.Atoi(keyMatch)

		return gitlabKeyId, err
	}

	return 0, nil
}

func tryParseUsername(argument string) (string, error) {
	whoUsernameRegex, err := regexp.Compile(`\busername-(?P<username>\S+)\b`)
	if err != nil {
		return "", err
	}

	usernameMatch := whoUsernameRegex.FindString(argument)
	return usernameMatch, nil
}

func parseCommand(commandString string, command *Command) *Command {
	command.Command = commandString

	if commandString == "" {
		command.Type = Discover
	}

	return nil
}