summaryrefslogtreecommitdiff
path: root/go/internal/command/commandargs
diff options
context:
space:
mode:
Diffstat (limited to 'go/internal/command/commandargs')
-rw-r--r--go/internal/command/commandargs/command_args.go39
-rw-r--r--go/internal/command/commandargs/command_args_test.go45
2 files changed, 55 insertions, 29 deletions
diff --git a/go/internal/command/commandargs/command_args.go b/go/internal/command/commandargs/command_args.go
index d8fe32d..d68f5d2 100644
--- a/go/internal/command/commandargs/command_args.go
+++ b/go/internal/command/commandargs/command_args.go
@@ -3,12 +3,14 @@ package commandargs
import (
"errors"
"os"
+ "path/filepath"
"regexp"
"github.com/mattn/go-shellwords"
)
type CommandType string
+type Executable string
const (
Discover CommandType = "discover"
@@ -17,6 +19,7 @@ const (
ReceivePack CommandType = "git-receive-pack"
UploadPack CommandType = "git-upload-pack"
UploadArchive CommandType = "git-upload-archive"
+ GitlabShell Executable = "gitlab-shell"
)
var (
@@ -25,6 +28,7 @@ var (
)
type CommandArgs struct {
+ arguments []string
GitlabUsername string
GitlabKeyId string
SshArgs []string
@@ -32,23 +36,36 @@ type CommandArgs struct {
}
func Parse(arguments []string) (*CommandArgs, error) {
- if sshConnection := os.Getenv("SSH_CONNECTION"); sshConnection == "" {
- return nil, errors.New("Only ssh allowed")
- }
+ args := &CommandArgs{arguments: arguments}
+
+ if args.Executable() == GitlabShell {
+ if sshConnection := os.Getenv("SSH_CONNECTION"); sshConnection == "" {
+ return nil, errors.New("Only ssh allowed")
+ }
- args := &CommandArgs{}
- args.parseWho(arguments)
+ args.parseWho()
+
+ if err := args.parseCommand(os.Getenv("SSH_ORIGINAL_COMMAND")); err != nil {
+ return nil, errors.New("Invalid ssh command")
+ }
+ args.defineCommandType()
- if err := args.parseCommand(os.Getenv("SSH_ORIGINAL_COMMAND")); err != nil {
- return nil, errors.New("Invalid ssh command")
+ return args, nil
+ } else {
+ return args, nil
}
- args.defineCommandType()
+}
+
+func (c *CommandArgs) Executable() Executable {
+ return Executable(filepath.Base(c.arguments[0]))
+}
- return args, nil
+func (c *CommandArgs) Arguments() []string {
+ return c.arguments[1:]
}
-func (c *CommandArgs) parseWho(arguments []string) {
- for _, argument := range arguments {
+func (c *CommandArgs) parseWho() {
+ for _, argument := range c.arguments {
if keyId := tryParseKeyId(argument); keyId != "" {
c.GitlabKeyId = keyId
break
diff --git a/go/internal/command/commandargs/command_args_test.go b/go/internal/command/commandargs/command_args_test.go
index e60bb92..21a676c 100644
--- a/go/internal/command/commandargs/command_args_test.go
+++ b/go/internal/command/commandargs/command_args_test.go
@@ -3,16 +3,16 @@ package commandargs
import (
"testing"
- "github.com/stretchr/testify/require"
-
"gitlab.com/gitlab-org/gitlab-shell/go/internal/testhelper"
+
+ "github.com/stretchr/testify/require"
)
func TestParseSuccess(t *testing.T) {
testCases := []struct {
desc string
- arguments []string
environment map[string]string
+ arguments []string
expectedArgs *CommandArgs
}{
// Setting the used env variables for every case to ensure we're
@@ -23,7 +23,8 @@ func TestParseSuccess(t *testing.T) {
"SSH_CONNECTION": "1",
"SSH_ORIGINAL_COMMAND": "",
},
- expectedArgs: &CommandArgs{SshArgs: []string{}, CommandType: Discover},
+ arguments: []string{string(GitlabShell)},
+ expectedArgs: &CommandArgs{arguments: []string{string(GitlabShell)}, SshArgs: []string{}, CommandType: Discover},
},
{
desc: "It finds the key id in any passed arguments",
@@ -31,72 +32,80 @@ func TestParseSuccess(t *testing.T) {
"SSH_CONNECTION": "1",
"SSH_ORIGINAL_COMMAND": "",
},
- arguments: []string{"hello", "key-123"},
- expectedArgs: &CommandArgs{SshArgs: []string{}, CommandType: Discover, GitlabKeyId: "123"},
+ arguments: []string{string(GitlabShell), "hello", "key-123"},
+ expectedArgs: &CommandArgs{arguments: []string{string(GitlabShell), "hello", "key-123"}, SshArgs: []string{}, CommandType: Discover, GitlabKeyId: "123"},
}, {
desc: "It finds the username in any passed arguments",
environment: map[string]string{
"SSH_CONNECTION": "1",
"SSH_ORIGINAL_COMMAND": "",
},
- arguments: []string{"hello", "username-jane-doe"},
- expectedArgs: &CommandArgs{SshArgs: []string{}, CommandType: Discover, GitlabUsername: "jane-doe"},
+ arguments: []string{string(GitlabShell), "hello", "username-jane-doe"},
+ expectedArgs: &CommandArgs{arguments: []string{string(GitlabShell), "hello", "username-jane-doe"}, SshArgs: []string{}, CommandType: Discover, GitlabUsername: "jane-doe"},
}, {
desc: "It parses 2fa_recovery_codes command",
environment: map[string]string{
"SSH_CONNECTION": "1",
"SSH_ORIGINAL_COMMAND": "2fa_recovery_codes",
},
- expectedArgs: &CommandArgs{SshArgs: []string{"2fa_recovery_codes"}, CommandType: TwoFactorRecover},
+ arguments: []string{string(GitlabShell)},
+ expectedArgs: &CommandArgs{arguments: []string{string(GitlabShell)}, SshArgs: []string{"2fa_recovery_codes"}, CommandType: TwoFactorRecover},
}, {
desc: "It parses git-receive-pack command",
environment: map[string]string{
"SSH_CONNECTION": "1",
"SSH_ORIGINAL_COMMAND": "git-receive-pack group/repo",
},
- expectedArgs: &CommandArgs{SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: ReceivePack},
+ arguments: []string{string(GitlabShell)},
+ expectedArgs: &CommandArgs{arguments: []string{string(GitlabShell)}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: ReceivePack},
}, {
desc: "It parses git-receive-pack command and a project with single quotes",
environment: map[string]string{
"SSH_CONNECTION": "1",
"SSH_ORIGINAL_COMMAND": "git receive-pack 'group/repo'",
},
- expectedArgs: &CommandArgs{SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: ReceivePack},
+ arguments: []string{string(GitlabShell)},
+ expectedArgs: &CommandArgs{arguments: []string{string(GitlabShell)}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: ReceivePack},
}, {
desc: `It parses "git receive-pack" command`,
environment: map[string]string{
"SSH_CONNECTION": "1",
"SSH_ORIGINAL_COMMAND": `git receive-pack "group/repo"`,
},
- expectedArgs: &CommandArgs{SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: ReceivePack},
+ arguments: []string{string(GitlabShell)},
+ expectedArgs: &CommandArgs{arguments: []string{string(GitlabShell)}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: ReceivePack},
}, {
desc: `It parses a command followed by control characters`,
environment: map[string]string{
"SSH_CONNECTION": "1",
"SSH_ORIGINAL_COMMAND": `git-receive-pack group/repo; any command`,
},
- expectedArgs: &CommandArgs{SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: ReceivePack},
+ arguments: []string{string(GitlabShell)},
+ expectedArgs: &CommandArgs{arguments: []string{string(GitlabShell)}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: ReceivePack},
}, {
desc: "It parses git-upload-pack command",
environment: map[string]string{
"SSH_CONNECTION": "1",
"SSH_ORIGINAL_COMMAND": `git upload-pack "group/repo"`,
},
- expectedArgs: &CommandArgs{SshArgs: []string{"git-upload-pack", "group/repo"}, CommandType: UploadPack},
+ arguments: []string{string(GitlabShell)},
+ expectedArgs: &CommandArgs{arguments: []string{string(GitlabShell)}, SshArgs: []string{"git-upload-pack", "group/repo"}, CommandType: UploadPack},
}, {
desc: "It parses git-upload-archive command",
environment: map[string]string{
"SSH_CONNECTION": "1",
"SSH_ORIGINAL_COMMAND": "git-upload-archive 'group/repo'",
},
- expectedArgs: &CommandArgs{SshArgs: []string{"git-upload-archive", "group/repo"}, CommandType: UploadArchive},
+ arguments: []string{string(GitlabShell)},
+ expectedArgs: &CommandArgs{arguments: []string{string(GitlabShell)}, SshArgs: []string{"git-upload-archive", "group/repo"}, CommandType: UploadArchive},
}, {
desc: "It parses git-lfs-authenticate command",
environment: map[string]string{
"SSH_CONNECTION": "1",
"SSH_ORIGINAL_COMMAND": "git-lfs-authenticate 'group/repo' download",
},
- expectedArgs: &CommandArgs{SshArgs: []string{"git-lfs-authenticate", "group/repo", "download"}, CommandType: LfsAuthenticate},
+ arguments: []string{string(GitlabShell)},
+ expectedArgs: &CommandArgs{arguments: []string{string(GitlabShell)}, SshArgs: []string{"git-lfs-authenticate", "group/repo", "download"}, CommandType: LfsAuthenticate},
},
}
@@ -115,7 +124,7 @@ func TestParseSuccess(t *testing.T) {
func TestParseFailure(t *testing.T) {
t.Run("It fails if SSH connection is not set", func(t *testing.T) {
- _, err := Parse([]string{})
+ _, err := Parse([]string{string(GitlabShell)})
require.Error(t, err, "Only ssh allowed")
})
@@ -128,7 +137,7 @@ func TestParseFailure(t *testing.T) {
restoreEnv := testhelper.TempEnv(environment)
defer restoreEnv()
- _, err := Parse([]string{})
+ _, err := Parse([]string{string(GitlabShell)})
require.Error(t, err, "Invalid ssh command")
})