summaryrefslogtreecommitdiff
path: root/go/internal/keyline
diff options
context:
space:
mode:
Diffstat (limited to 'go/internal/keyline')
-rw-r--r--go/internal/keyline/key_line.go53
-rw-r--r--go/internal/keyline/key_line_test.go51
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)
+}