diff options
Diffstat (limited to 'go/internal/keyline')
-rw-r--r-- | go/internal/keyline/key_line.go | 53 | ||||
-rw-r--r-- | go/internal/keyline/key_line_test.go | 51 |
2 files changed, 104 insertions, 0 deletions
diff --git a/go/internal/keyline/key_line.go b/go/internal/keyline/key_line.go new file mode 100644 index 0000000..7b19c87 --- /dev/null +++ b/go/internal/keyline/key_line.go @@ -0,0 +1,53 @@ +package keyline + +import ( + "errors" + "fmt" + "path" + "regexp" + "strings" + + "gitlab.com/gitlab-org/gitlab-shell/go/internal/executable" +) + +var ( + keyRegex = regexp.MustCompile(`\A[a-z0-9-]+\z`) +) + +const ( + PublicKeyPrefix = "key" + SshOptions = "no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty" +) + +type KeyLine struct { + Id string // This can be either an ID of a Key or username + Value string // This can be either a public key or a principal name + Prefix string + RootDir string +} + +func NewPublicKeyLine(id string, publicKey string, rootDir string) (*KeyLine, error) { + if err := validate(id, publicKey); err != nil { + return nil, err + } + + return &KeyLine{Id: id, Value: publicKey, Prefix: PublicKeyPrefix, RootDir: rootDir}, nil +} + +func (k *KeyLine) ToString() string { + command := fmt.Sprintf("%s %s-%s", path.Join(k.RootDir, executable.BinDir, executable.GitlabShell), k.Prefix, k.Id) + + return fmt.Sprintf(`command="%s",%s %s`, command, SshOptions, k.Value) +} + +func validate(id string, value string) error { + if !keyRegex.MatchString(id) { + return errors.New(fmt.Sprintf("Invalid key_id: %s", id)) + } + + if strings.Contains(value, "\n") { + return errors.New(fmt.Sprintf("Invalid value: %s", value)) + } + + return nil +} diff --git a/go/internal/keyline/key_line_test.go b/go/internal/keyline/key_line_test.go new file mode 100644 index 0000000..fc2bdf3 --- /dev/null +++ b/go/internal/keyline/key_line_test.go @@ -0,0 +1,51 @@ +package keyline + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestFailingNewPublicKeyLine(t *testing.T) { + testCases := []struct { + desc string + id string + publicKey string + expectedError string + }{ + { + desc: "When Id has non-alphanumeric and non-dash characters in it", + id: "key\n1", + publicKey: "public-key", + expectedError: "Invalid key_id: key\n1", + }, + { + desc: "When public key has newline in it", + id: "key", + publicKey: "public\nkey", + expectedError: "Invalid value: public\nkey", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + result, err := NewPublicKeyLine(tc.id, tc.publicKey, "root-dir") + + require.Empty(t, result) + require.EqualError(t, err, tc.expectedError) + }) + } +} + +func TestToString(t *testing.T) { + keyLine := &KeyLine{ + Id: "1", + Value: "public-key", + Prefix: "key", + RootDir: "/tmp", + } + + result := keyLine.ToString() + + require.Equal(t, `command="/tmp/bin/gitlab-shell key-1",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty public-key`, result) +} |