diff options
Diffstat (limited to 'go/internal/command/uploadpack')
-rw-r--r-- | go/internal/command/uploadpack/gitalycall.go | 44 | ||||
-rw-r--r-- | go/internal/command/uploadpack/gitalycall_test.go | 40 | ||||
-rw-r--r-- | go/internal/command/uploadpack/uploadpack.go | 36 | ||||
-rw-r--r-- | go/internal/command/uploadpack/uploadpack_test.go | 31 |
4 files changed, 151 insertions, 0 deletions
diff --git a/go/internal/command/uploadpack/gitalycall.go b/go/internal/command/uploadpack/gitalycall.go new file mode 100644 index 0000000..bb81114 --- /dev/null +++ b/go/internal/command/uploadpack/gitalycall.go @@ -0,0 +1,44 @@ +package uploadpack + +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.UploadPack), + Address: response.Gitaly.Address, + Token: response.Gitaly.Token, + } + + repo := response.Gitaly.Repo + request := &pb.SSHUploadPackRequest{ + Repository: &pb.Repository{ + StorageName: repo.StorageName, + RelativePath: repo.RelativePath, + GitObjectDirectory: repo.GitObjectDirectory, + GitAlternateObjectDirectories: repo.GitAlternateObjectDirectories, + GlRepository: repo.RepoName, + GlProjectPath: repo.ProjectPath, + }, + GitProtocol: response.GitProtocol, + GitConfigOptions: response.GitConfigOptions, + } + + return gc.RunGitalyCommand(func(ctx context.Context, conn *grpc.ClientConn) (int32, error) { + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + rw := c.ReadWriter + return client.UploadPack(ctx, conn, rw.In, rw.Out, rw.ErrOut, request) + }) +} diff --git a/go/internal/command/uploadpack/gitalycall_test.go b/go/internal/command/uploadpack/gitalycall_test.go new file mode 100644 index 0000000..2097964 --- /dev/null +++ b/go/internal/command/uploadpack/gitalycall_test.go @@ -0,0 +1,40 @@ +package uploadpack + +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.UploadPack, SshArgs: []string{"git-upload-pack", repo}}, + ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output, In: input}, + } + + err := cmd.Execute() + require.NoError(t, err) + + require.Equal(t, "UploadPack: "+repo, output.String()) +} diff --git a/go/internal/command/uploadpack/uploadpack.go b/go/internal/command/uploadpack/uploadpack.go new file mode 100644 index 0000000..cff198d --- /dev/null +++ b/go/internal/command/uploadpack/uploadpack.go @@ -0,0 +1,36 @@ +package uploadpack + +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/uploadpack/uploadpack_test.go b/go/internal/command/uploadpack/uploadpack_test.go new file mode 100644 index 0000000..a06ba24 --- /dev/null +++ b/go/internal/command/uploadpack/uploadpack_test.go @@ -0,0 +1,31 @@ +package uploadpack + +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-pack", "group/repo"}}, + ReadWriter: &readwriter.ReadWriter{ErrOut: output, Out: output}, + } + + err := cmd.Execute() + require.Equal(t, "Disallowed by API call", err.Error()) +} |