summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Drozdov <idrozdov@gitlab.com>2019-06-03 19:05:29 +0300
committerIgor Drozdov <idrozdov@gitlab.com>2019-06-04 09:20:23 +0300
commitbe2a0dea5da664102d5709b30a260bed559269cf (patch)
tree1cf7111fb454449d5fbfcd3494c70295d75d40c6
parent5ee3270e07b0f7cca8c2352816ea86a3b640a772 (diff)
downloadgitlab-shell-id-git-upload-archive.tar.gz
Go implementation for git-upload-archiveid-git-upload-archive
-rw-r--r--go/internal/command/command.go3
-rw-r--r--go/internal/command/command_test.go13
-rw-r--r--go/internal/command/commandargs/command_args.go1
-rw-r--r--go/internal/command/commandargs/command_args_test.go7
-rw-r--r--go/internal/command/uploadarchive/gitalycall.go32
-rw-r--r--go/internal/command/uploadarchive/gitalycall_test.go40
-rw-r--r--go/internal/command/uploadarchive/uploadarchive.go36
-rw-r--r--go/internal/command/uploadarchive/uploadarchive_test.go31
-rw-r--r--go/internal/gitlabnet/testserver/gitalyserver.go8
9 files changed, 171 insertions, 0 deletions
diff --git a/go/internal/command/command.go b/go/internal/command/command.go
index 8b02f16..7bc1994 100644
--- a/go/internal/command/command.go
+++ b/go/internal/command/command.go
@@ -7,6 +7,7 @@ import (
"gitlab.com/gitlab-org/gitlab-shell/go/internal/command/readwriter"
"gitlab.com/gitlab-org/gitlab-shell/go/internal/command/receivepack"
"gitlab.com/gitlab-org/gitlab-shell/go/internal/command/twofactorrecover"
+ "gitlab.com/gitlab-org/gitlab-shell/go/internal/command/uploadarchive"
"gitlab.com/gitlab-org/gitlab-shell/go/internal/command/uploadpack"
"gitlab.com/gitlab-org/gitlab-shell/go/internal/config"
)
@@ -41,6 +42,8 @@ func buildCommand(args *commandargs.CommandArgs, config *config.Config, readWrit
return &receivepack.Command{Config: config, Args: args, ReadWriter: readWriter}
case commandargs.UploadPack:
return &uploadpack.Command{Config: config, Args: args, ReadWriter: readWriter}
+ case commandargs.UploadArchive:
+ return &uploadarchive.Command{Config: config, Args: args, ReadWriter: readWriter}
}
return nil
diff --git a/go/internal/command/command_test.go b/go/internal/command/command_test.go
index 37db89f..cbdfc56 100644
--- a/go/internal/command/command_test.go
+++ b/go/internal/command/command_test.go
@@ -9,6 +9,7 @@ import (
"gitlab.com/gitlab-org/gitlab-shell/go/internal/command/fallback"
"gitlab.com/gitlab-org/gitlab-shell/go/internal/command/receivepack"
"gitlab.com/gitlab-org/gitlab-shell/go/internal/command/twofactorrecover"
+ "gitlab.com/gitlab-org/gitlab-shell/go/internal/command/uploadarchive"
"gitlab.com/gitlab-org/gitlab-shell/go/internal/command/uploadpack"
"gitlab.com/gitlab-org/gitlab-shell/go/internal/config"
"gitlab.com/gitlab-org/gitlab-shell/go/internal/testhelper"
@@ -82,6 +83,18 @@ func TestNew(t *testing.T) {
expectedType: &uploadpack.Command{},
},
{
+ desc: "it returns a UploadArchive command if the feature is enabled",
+ config: &config.Config{
+ GitlabUrl: "http+unix://gitlab.socket",
+ Migration: config.MigrationConfig{Enabled: true, Features: []string{"git-upload-archive"}},
+ },
+ environment: map[string]string{
+ "SSH_CONNECTION": "1",
+ "SSH_ORIGINAL_COMMAND": "git-upload-archive",
+ },
+ expectedType: &uploadarchive.Command{},
+ },
+ {
desc: "it returns a Fallback command if the feature is unimplemented",
config: &config.Config{
GitlabUrl: "http+unix://gitlab.socket",
diff --git a/go/internal/command/commandargs/command_args.go b/go/internal/command/commandargs/command_args.go
index 6789c5b..fd9d741 100644
--- a/go/internal/command/commandargs/command_args.go
+++ b/go/internal/command/commandargs/command_args.go
@@ -15,6 +15,7 @@ const (
TwoFactorRecover CommandType = "2fa_recovery_codes"
ReceivePack CommandType = "git-receive-pack"
UploadPack CommandType = "git-upload-pack"
+ UploadArchive CommandType = "git-upload-archive"
)
var (
diff --git a/go/internal/command/commandargs/command_args_test.go b/go/internal/command/commandargs/command_args_test.go
index c3c6ff2..7c360ad 100644
--- a/go/internal/command/commandargs/command_args_test.go
+++ b/go/internal/command/commandargs/command_args_test.go
@@ -83,6 +83,13 @@ func TestParseSuccess(t *testing.T) {
"SSH_ORIGINAL_COMMAND": `git upload-pack "group/repo"`,
},
expectedArgs: &CommandArgs{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},
},
}
diff --git a/go/internal/command/uploadarchive/gitalycall.go b/go/internal/command/uploadarchive/gitalycall.go
new file mode 100644
index 0000000..c899588
--- /dev/null
+++ b/go/internal/command/uploadarchive/gitalycall.go
@@ -0,0 +1,32 @@
+package uploadarchive
+
+import (
+ "context"
+
+ "google.golang.org/grpc"
+
+ pb "gitlab.com/gitlab-org/gitaly-proto/go/gitalypb"
+ "gitlab.com/gitlab-org/gitaly/client"
+ "gitlab.com/gitlab-org/gitlab-shell/go/internal/command/commandargs"
+ "gitlab.com/gitlab-org/gitlab-shell/go/internal/gitlabnet/accessverifier"
+ "gitlab.com/gitlab-org/gitlab-shell/go/internal/handler"
+)
+
+func (c *Command) performGitalyCall(response *accessverifier.Response) error {
+ gc := &handler.GitalyCommand{
+ Config: c.Config,
+ ServiceName: string(commandargs.UploadArchive),
+ Address: response.Gitaly.Address,
+ Token: response.Gitaly.Token,
+ }
+
+ request := &pb.SSHUploadArchiveRequest{Repository: &response.Gitaly.Repo}
+
+ return gc.RunGitalyCommand(func(ctx context.Context, conn *grpc.ClientConn) (int32, error) {
+ ctx, cancel := context.WithCancel(ctx)
+ defer cancel()
+
+ rw := c.ReadWriter
+ return client.UploadArchive(ctx, conn, rw.In, rw.Out, rw.ErrOut, request)
+ })
+}
diff --git a/go/internal/command/uploadarchive/gitalycall_test.go b/go/internal/command/uploadarchive/gitalycall_test.go
new file mode 100644
index 0000000..78953a7
--- /dev/null
+++ b/go/internal/command/uploadarchive/gitalycall_test.go
@@ -0,0 +1,40 @@
+package uploadarchive
+
+import (
+ "bytes"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+
+ "gitlab.com/gitlab-org/gitlab-shell/go/internal/command/commandargs"
+ "gitlab.com/gitlab-org/gitlab-shell/go/internal/command/readwriter"
+ "gitlab.com/gitlab-org/gitlab-shell/go/internal/config"
+ "gitlab.com/gitlab-org/gitlab-shell/go/internal/gitlabnet/testserver"
+ "gitlab.com/gitlab-org/gitlab-shell/go/internal/testhelper/requesthandlers"
+)
+
+func TestUploadPack(t *testing.T) {
+ gitalyAddress, cleanup := testserver.StartGitalyServer(t)
+ defer cleanup()
+
+ requests := requesthandlers.BuildAllowedWithGitalyHandlers(t, gitalyAddress)
+ url, cleanup := testserver.StartHttpServer(t, requests)
+ defer cleanup()
+
+ output := &bytes.Buffer{}
+ input := &bytes.Buffer{}
+
+ userId := "1"
+ repo := "group/repo"
+
+ cmd := &Command{
+ Config: &config.Config{GitlabUrl: url},
+ Args: &commandargs.CommandArgs{GitlabKeyId: userId, CommandType: commandargs.UploadArchive, SshArgs: []string{"git-upload-archive", repo}},
+ ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output, In: input},
+ }
+
+ err := cmd.Execute()
+ require.NoError(t, err)
+
+ require.Equal(t, "UploadArchive: "+repo, output.String())
+}
diff --git a/go/internal/command/uploadarchive/uploadarchive.go b/go/internal/command/uploadarchive/uploadarchive.go
new file mode 100644
index 0000000..93a52c0
--- /dev/null
+++ b/go/internal/command/uploadarchive/uploadarchive.go
@@ -0,0 +1,36 @@
+package uploadarchive
+
+import (
+ "gitlab.com/gitlab-org/gitlab-shell/go/internal/command/commandargs"
+ "gitlab.com/gitlab-org/gitlab-shell/go/internal/command/readwriter"
+ "gitlab.com/gitlab-org/gitlab-shell/go/internal/command/shared/accessverifier"
+ "gitlab.com/gitlab-org/gitlab-shell/go/internal/command/shared/disallowedcommand"
+ "gitlab.com/gitlab-org/gitlab-shell/go/internal/config"
+)
+
+type Command struct {
+ Config *config.Config
+ Args *commandargs.CommandArgs
+ ReadWriter *readwriter.ReadWriter
+}
+
+func (c *Command) Execute() error {
+ args := c.Args.SshArgs
+ if len(args) != 2 {
+ return disallowedcommand.Error
+ }
+
+ repo := args[1]
+ response, err := c.verifyAccess(repo)
+ if err != nil {
+ return err
+ }
+
+ return c.performGitalyCall(response)
+}
+
+func (c *Command) verifyAccess(repo string) (*accessverifier.Response, error) {
+ cmd := accessverifier.Command{c.Config, c.Args, c.ReadWriter}
+
+ return cmd.Verify(c.Args.CommandType, repo)
+}
diff --git a/go/internal/command/uploadarchive/uploadarchive_test.go b/go/internal/command/uploadarchive/uploadarchive_test.go
new file mode 100644
index 0000000..369bee7
--- /dev/null
+++ b/go/internal/command/uploadarchive/uploadarchive_test.go
@@ -0,0 +1,31 @@
+package uploadarchive
+
+import (
+ "bytes"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+
+ "gitlab.com/gitlab-org/gitlab-shell/go/internal/command/commandargs"
+ "gitlab.com/gitlab-org/gitlab-shell/go/internal/command/readwriter"
+ "gitlab.com/gitlab-org/gitlab-shell/go/internal/config"
+ "gitlab.com/gitlab-org/gitlab-shell/go/internal/gitlabnet/testserver"
+ "gitlab.com/gitlab-org/gitlab-shell/go/internal/testhelper/requesthandlers"
+)
+
+func TestForbiddenAccess(t *testing.T) {
+ requests := requesthandlers.BuildDisallowedByApiHandlers(t)
+ url, cleanup := testserver.StartHttpServer(t, requests)
+ defer cleanup()
+
+ output := &bytes.Buffer{}
+
+ cmd := &Command{
+ Config: &config.Config{GitlabUrl: url},
+ Args: &commandargs.CommandArgs{GitlabKeyId: "disallowed", SshArgs: []string{"git-upload-archive", "group/repo"}},
+ ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output},
+ }
+
+ err := cmd.Execute()
+ require.Equal(t, "Disallowed by API call", err.Error())
+}
diff --git a/go/internal/gitlabnet/testserver/gitalyserver.go b/go/internal/gitlabnet/testserver/gitalyserver.go
index a31dfe2..35234c1 100644
--- a/go/internal/gitlabnet/testserver/gitalyserver.go
+++ b/go/internal/gitlabnet/testserver/gitalyserver.go
@@ -41,6 +41,14 @@ func (s *testGitalyServer) SSHUploadPack(stream pb.SSHService_SSHUploadPackServe
}
func (s *testGitalyServer) SSHUploadArchive(stream pb.SSHService_SSHUploadArchiveServer) error {
+ req, err := stream.Recv()
+ if err != nil {
+ return err
+ }
+
+ response := []byte("UploadArchive: " + req.Repository.GlRepository)
+ stream.Send(&pb.SSHUploadArchiveResponse{Stdout: response})
+
return nil
}