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/base_args.go34
-rw-r--r--go/internal/command/commandargs/command_args.go22
-rw-r--r--go/internal/command/commandargs/command_args_test.go104
-rw-r--r--go/internal/command/commandargs/generic_args.go14
-rw-r--r--go/internal/command/commandargs/shell.go35
5 files changed, 110 insertions, 99 deletions
diff --git a/go/internal/command/commandargs/base_args.go b/go/internal/command/commandargs/base_args.go
deleted file mode 100644
index f65373e..0000000
--- a/go/internal/command/commandargs/base_args.go
+++ /dev/null
@@ -1,34 +0,0 @@
-package commandargs
-
-import (
- "errors"
- "path/filepath"
-)
-
-type BaseArgs struct {
- arguments []string
-}
-
-func (b *BaseArgs) Parse() error {
- if b.hasEmptyArguments() {
- return errors.New("arguments should include the executable")
- }
-
- return nil
-}
-
-func (b *BaseArgs) Executable() Executable {
- if b.hasEmptyArguments() {
- return Executable("")
- }
-
- return Executable(filepath.Base(b.arguments[0]))
-}
-
-func (b *BaseArgs) Arguments() []string {
- return b.arguments[1:]
-}
-
-func (b *BaseArgs) hasEmptyArguments() bool {
- return len(b.arguments) == 0
-}
diff --git a/go/internal/command/commandargs/command_args.go b/go/internal/command/commandargs/command_args.go
index 9f28817..5338d6b 100644
--- a/go/internal/command/commandargs/command_args.go
+++ b/go/internal/command/commandargs/command_args.go
@@ -1,24 +1,22 @@
package commandargs
-type CommandType string
-type Executable string
-
-const (
- GitlabShell Executable = "gitlab-shell"
+import (
+ "gitlab.com/gitlab-org/gitlab-shell/go/internal/executable"
)
+type CommandType string
+
type CommandArgs interface {
Parse() error
- Executable() Executable
- Arguments() []string
+ GetArguments() []string
}
-func Parse(arguments []string) (CommandArgs, error) {
- var args CommandArgs = &BaseArgs{arguments: arguments}
+func Parse(e *executable.Executable, arguments []string) (CommandArgs, error) {
+ var args CommandArgs = &GenericArgs{Arguments: arguments}
- switch args.Executable() {
- case GitlabShell:
- args = &Shell{BaseArgs: args.(*BaseArgs)}
+ switch e.Name {
+ case executable.GitlabShell:
+ args = &Shell{Arguments: arguments}
}
if err := args.Parse(); err != nil {
diff --git a/go/internal/command/commandargs/command_args_test.go b/go/internal/command/commandargs/command_args_test.go
index 1fe3ba7..148c987 100644
--- a/go/internal/command/commandargs/command_args_test.go
+++ b/go/internal/command/commandargs/command_args_test.go
@@ -3,6 +3,7 @@ package commandargs
import (
"testing"
+ "gitlab.com/gitlab-org/gitlab-shell/go/internal/executable"
"gitlab.com/gitlab-org/gitlab-shell/go/internal/testhelper"
"github.com/stretchr/testify/require"
@@ -11,6 +12,7 @@ import (
func TestParseSuccess(t *testing.T) {
testCases := []struct {
desc string
+ executable *executable.Executable
environment map[string]string
arguments []string
expectedArgs CommandArgs
@@ -18,98 +20,110 @@ func TestParseSuccess(t *testing.T) {
// Setting the used env variables for every case to ensure we're
// not using anything set in the original env.
{
- desc: "It sets discover as the command when the command string was empty",
+ desc: "It sets discover as the command when the command string was empty",
+ executable: &executable.Executable{Name: executable.GitlabShell},
environment: map[string]string{
"SSH_CONNECTION": "1",
"SSH_ORIGINAL_COMMAND": "",
},
- arguments: []string{string(GitlabShell)},
- expectedArgs: &Shell{BaseArgs: &BaseArgs{arguments: []string{string(GitlabShell)}}, SshArgs: []string{}, CommandType: Discover},
+ arguments: []string{},
+ expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{}, CommandType: Discover},
},
{
- desc: "It finds the key id in any passed arguments",
+ desc: "It finds the key id in any passed arguments",
+ executable: &executable.Executable{Name: executable.GitlabShell},
environment: map[string]string{
"SSH_CONNECTION": "1",
"SSH_ORIGINAL_COMMAND": "",
},
- arguments: []string{string(GitlabShell), "hello", "key-123"},
- expectedArgs: &Shell{BaseArgs: &BaseArgs{arguments: []string{string(GitlabShell), "hello", "key-123"}}, SshArgs: []string{}, CommandType: Discover, GitlabKeyId: "123"},
+ arguments: []string{"hello", "key-123"},
+ expectedArgs: &Shell{Arguments: []string{"hello", "key-123"}, SshArgs: []string{}, CommandType: Discover, GitlabKeyId: "123"},
}, {
- desc: "It finds the username in any passed arguments",
+ desc: "It finds the username in any passed arguments",
+ executable: &executable.Executable{Name: executable.GitlabShell},
environment: map[string]string{
"SSH_CONNECTION": "1",
"SSH_ORIGINAL_COMMAND": "",
},
- arguments: []string{string(GitlabShell), "hello", "username-jane-doe"},
- expectedArgs: &Shell{BaseArgs: &BaseArgs{arguments: []string{string(GitlabShell), "hello", "username-jane-doe"}}, SshArgs: []string{}, CommandType: Discover, GitlabUsername: "jane-doe"},
+ arguments: []string{"hello", "username-jane-doe"},
+ expectedArgs: &Shell{Arguments: []string{"hello", "username-jane-doe"}, SshArgs: []string{}, CommandType: Discover, GitlabUsername: "jane-doe"},
}, {
- desc: "It parses 2fa_recovery_codes command",
+ desc: "It parses 2fa_recovery_codes command",
+ executable: &executable.Executable{Name: executable.GitlabShell},
environment: map[string]string{
"SSH_CONNECTION": "1",
"SSH_ORIGINAL_COMMAND": "2fa_recovery_codes",
},
- arguments: []string{string(GitlabShell)},
- expectedArgs: &Shell{BaseArgs: &BaseArgs{arguments: []string{string(GitlabShell)}}, SshArgs: []string{"2fa_recovery_codes"}, CommandType: TwoFactorRecover},
+ arguments: []string{},
+ expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"2fa_recovery_codes"}, CommandType: TwoFactorRecover},
}, {
- desc: "It parses git-receive-pack command",
+ desc: "It parses git-receive-pack command",
+ executable: &executable.Executable{Name: executable.GitlabShell},
environment: map[string]string{
"SSH_CONNECTION": "1",
"SSH_ORIGINAL_COMMAND": "git-receive-pack group/repo",
},
- arguments: []string{string(GitlabShell)},
- expectedArgs: &Shell{BaseArgs: &BaseArgs{arguments: []string{string(GitlabShell)}}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: ReceivePack},
+ arguments: []string{},
+ expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: ReceivePack},
}, {
- desc: "It parses git-receive-pack command and a project with single quotes",
+ desc: "It parses git-receive-pack command and a project with single quotes",
+ executable: &executable.Executable{Name: executable.GitlabShell},
environment: map[string]string{
"SSH_CONNECTION": "1",
"SSH_ORIGINAL_COMMAND": "git receive-pack 'group/repo'",
},
- arguments: []string{string(GitlabShell)},
- expectedArgs: &Shell{BaseArgs: &BaseArgs{arguments: []string{string(GitlabShell)}}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: ReceivePack},
+ arguments: []string{},
+ expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: ReceivePack},
}, {
- desc: `It parses "git receive-pack" command`,
+ desc: `It parses "git receive-pack" command`,
+ executable: &executable.Executable{Name: executable.GitlabShell},
environment: map[string]string{
"SSH_CONNECTION": "1",
"SSH_ORIGINAL_COMMAND": `git receive-pack "group/repo"`,
},
- arguments: []string{string(GitlabShell)},
- expectedArgs: &Shell{BaseArgs: &BaseArgs{arguments: []string{string(GitlabShell)}}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: ReceivePack},
+ arguments: []string{},
+ expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: ReceivePack},
}, {
- desc: `It parses a command followed by control characters`,
+ desc: `It parses a command followed by control characters`,
+ executable: &executable.Executable{Name: executable.GitlabShell},
environment: map[string]string{
"SSH_CONNECTION": "1",
"SSH_ORIGINAL_COMMAND": `git-receive-pack group/repo; any command`,
},
- arguments: []string{string(GitlabShell)},
- expectedArgs: &Shell{BaseArgs: &BaseArgs{arguments: []string{string(GitlabShell)}}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: ReceivePack},
+ arguments: []string{},
+ expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-receive-pack", "group/repo"}, CommandType: ReceivePack},
}, {
- desc: "It parses git-upload-pack command",
+ desc: "It parses git-upload-pack command",
+ executable: &executable.Executable{Name: executable.GitlabShell},
environment: map[string]string{
"SSH_CONNECTION": "1",
"SSH_ORIGINAL_COMMAND": `git upload-pack "group/repo"`,
},
- arguments: []string{string(GitlabShell)},
- expectedArgs: &Shell{BaseArgs: &BaseArgs{arguments: []string{string(GitlabShell)}}, SshArgs: []string{"git-upload-pack", "group/repo"}, CommandType: UploadPack},
+ arguments: []string{},
+ expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-upload-pack", "group/repo"}, CommandType: UploadPack},
}, {
- desc: "It parses git-upload-archive command",
+ desc: "It parses git-upload-archive command",
+ executable: &executable.Executable{Name: executable.GitlabShell},
environment: map[string]string{
"SSH_CONNECTION": "1",
"SSH_ORIGINAL_COMMAND": "git-upload-archive 'group/repo'",
},
- arguments: []string{string(GitlabShell)},
- expectedArgs: &Shell{BaseArgs: &BaseArgs{arguments: []string{string(GitlabShell)}}, SshArgs: []string{"git-upload-archive", "group/repo"}, CommandType: UploadArchive},
+ arguments: []string{},
+ expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-upload-archive", "group/repo"}, CommandType: UploadArchive},
}, {
- desc: "It parses git-lfs-authenticate command",
+ desc: "It parses git-lfs-authenticate command",
+ executable: &executable.Executable{Name: executable.GitlabShell},
environment: map[string]string{
"SSH_CONNECTION": "1",
"SSH_ORIGINAL_COMMAND": "git-lfs-authenticate 'group/repo' download",
},
- arguments: []string{string(GitlabShell)},
- expectedArgs: &Shell{BaseArgs: &BaseArgs{arguments: []string{string(GitlabShell)}}, SshArgs: []string{"git-lfs-authenticate", "group/repo", "download"}, CommandType: LfsAuthenticate},
+ arguments: []string{},
+ expectedArgs: &Shell{Arguments: []string{}, SshArgs: []string{"git-lfs-authenticate", "group/repo", "download"}, CommandType: LfsAuthenticate},
}, {
desc: "Unknown executable",
- arguments: []string{"unknown"},
- expectedArgs: &BaseArgs{arguments: []string{"unknown"}},
+ executable: &executable.Executable{Name: "unknown"},
+ arguments: []string{},
+ expectedArgs: &GenericArgs{Arguments: []string{}},
},
}
@@ -118,7 +132,7 @@ func TestParseSuccess(t *testing.T) {
restoreEnv := testhelper.TempEnv(tc.environment)
defer restoreEnv()
- result, err := Parse(tc.arguments)
+ result, err := Parse(tc.executable, tc.arguments)
require.NoError(t, err)
require.Equal(t, tc.expectedArgs, result)
@@ -129,28 +143,26 @@ func TestParseSuccess(t *testing.T) {
func TestParseFailure(t *testing.T) {
testCases := []struct {
desc string
+ executable *executable.Executable
environment map[string]string
arguments []string
expectedError string
}{
{
desc: "It fails if SSH connection is not set",
- arguments: []string{string(GitlabShell)},
- expectedError: "Only ssh allowed",
+ executable: &executable.Executable{Name: executable.GitlabShell},
+ arguments: []string{},
+ expectedError: "Only SSH allowed",
},
{
- desc: "It fails if SSH command is invalid",
+ desc: "It fails if SSH command is invalid",
+ executable: &executable.Executable{Name: executable.GitlabShell},
environment: map[string]string{
"SSH_CONNECTION": "1",
"SSH_ORIGINAL_COMMAND": `git receive-pack "`,
},
- arguments: []string{string(GitlabShell)},
- expectedError: "Only ssh allowed",
- },
- {
- desc: "It fails if arguments is empty",
arguments: []string{},
- expectedError: "arguments should include the executable",
+ expectedError: "Invalid SSH allowed",
},
}
@@ -159,7 +171,7 @@ func TestParseFailure(t *testing.T) {
restoreEnv := testhelper.TempEnv(tc.environment)
defer restoreEnv()
- _, err := Parse(tc.arguments)
+ _, err := Parse(tc.executable, tc.arguments)
require.Error(t, err, tc.expectedError)
})
diff --git a/go/internal/command/commandargs/generic_args.go b/go/internal/command/commandargs/generic_args.go
new file mode 100644
index 0000000..96bed99
--- /dev/null
+++ b/go/internal/command/commandargs/generic_args.go
@@ -0,0 +1,14 @@
+package commandargs
+
+type GenericArgs struct {
+ Arguments []string
+}
+
+func (b *GenericArgs) Parse() error {
+ // Do nothing
+ return nil
+}
+
+func (b *GenericArgs) GetArguments() []string {
+ return b.Arguments
+}
diff --git a/go/internal/command/commandargs/shell.go b/go/internal/command/commandargs/shell.go
index 04b1040..7e2b72e 100644
--- a/go/internal/command/commandargs/shell.go
+++ b/go/internal/command/commandargs/shell.go
@@ -23,7 +23,7 @@ var (
)
type Shell struct {
- *BaseArgs
+ Arguments []string
GitlabUsername string
GitlabKeyId string
SshArgs []string
@@ -31,23 +31,44 @@ type Shell struct {
}
func (s *Shell) Parse() error {
- if sshConnection := os.Getenv("SSH_CONNECTION"); sshConnection == "" {
- return errors.New("Only ssh allowed")
+ if err := s.validate(); err != nil {
+ return err
}
s.parseWho()
+ s.defineCommandType()
+
+ return nil
+}
+
+func (s *Shell) GetArguments() []string {
+ return s.Arguments
+}
- if err := s.parseCommand(os.Getenv("SSH_ORIGINAL_COMMAND")); err != nil {
- return errors.New("Invalid ssh command")
+func (s *Shell) validate() error {
+ if !s.isSshConnection() {
+ return errors.New("Only SSH allowed")
}
- s.defineCommandType()
+ if !s.isValidSshCommand() {
+ return errors.New("Invalid SSH command")
+ }
return nil
}
+func (s *Shell) isSshConnection() bool {
+ ok := os.Getenv("SSH_CONNECTION")
+ return ok != ""
+}
+
+func (s *Shell) isValidSshCommand() bool {
+ err := s.parseCommand(os.Getenv("SSH_ORIGINAL_COMMAND"))
+ return err == nil
+}
+
func (s *Shell) parseWho() {
- for _, argument := range s.arguments {
+ for _, argument := range s.Arguments {
if keyId := tryParseKeyId(argument); keyId != "" {
s.GitlabKeyId = keyId
break