summaryrefslogtreecommitdiff
path: root/go/internal/command/lfsauthenticate/lfsauthenticate.go
diff options
context:
space:
mode:
authorIgor <idrozdov@gitlab.com>2019-06-06 16:02:02 +0000
committerNick Thomas <nick@gitlab.com>2019-06-06 16:02:02 +0000
commit888cd2c4ecb7d8a82328c5b3d68545596466b1a2 (patch)
tree3557c79227b01376a90f381c5f60f0ef42727baa /go/internal/command/lfsauthenticate/lfsauthenticate.go
parenteb2b186f7d209a638b7523c674bc79cbafe764b6 (diff)
downloadgitlab-shell-888cd2c4ecb7d8a82328c5b3d68545596466b1a2.tar.gz
Go implementation for LFS authenticate
Diffstat (limited to 'go/internal/command/lfsauthenticate/lfsauthenticate.go')
-rw-r--r--go/internal/command/lfsauthenticate/lfsauthenticate.go104
1 files changed, 104 insertions, 0 deletions
diff --git a/go/internal/command/lfsauthenticate/lfsauthenticate.go b/go/internal/command/lfsauthenticate/lfsauthenticate.go
new file mode 100644
index 0000000..c1dc45f
--- /dev/null
+++ b/go/internal/command/lfsauthenticate/lfsauthenticate.go
@@ -0,0 +1,104 @@
+package lfsauthenticate
+
+import (
+ "encoding/base64"
+ "encoding/json"
+ "fmt"
+
+ "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"
+ "gitlab.com/gitlab-org/gitlab-shell/go/internal/gitlabnet/lfsauthenticate"
+)
+
+const (
+ downloadAction = "download"
+ uploadAction = "upload"
+)
+
+type Command struct {
+ Config *config.Config
+ Args *commandargs.CommandArgs
+ ReadWriter *readwriter.ReadWriter
+}
+
+type PayloadHeader struct {
+ Auth string `json:"Authorization"`
+}
+
+type Payload struct {
+ Header PayloadHeader `json:"header"`
+ Href string `json:"href"`
+ ExpiresIn int `json:"expires_in,omitempty"`
+}
+
+func (c *Command) Execute() error {
+ args := c.Args.SshArgs
+ if len(args) < 3 {
+ return disallowedcommand.Error
+ }
+
+ repo := args[1]
+ action, err := actionToCommandType(args[2])
+ if err != nil {
+ return err
+ }
+
+ accessResponse, err := c.verifyAccess(action, repo)
+ if err != nil {
+ return err
+ }
+
+ payload, err := c.authenticate(action, repo, accessResponse.UserId)
+ if err != nil {
+ // return nothing just like Ruby's GitlabShell#lfs_authenticate does
+ return nil
+ }
+
+ fmt.Fprintf(c.ReadWriter.Out, "%s\n", payload)
+
+ return nil
+}
+
+func actionToCommandType(action string) (commandargs.CommandType, error) {
+ var accessAction commandargs.CommandType
+ switch action {
+ case downloadAction:
+ accessAction = commandargs.UploadPack
+ case uploadAction:
+ accessAction = commandargs.ReceivePack
+ default:
+ return "", disallowedcommand.Error
+ }
+
+ return accessAction, nil
+}
+
+func (c *Command) verifyAccess(action commandargs.CommandType, repo string) (*accessverifier.Response, error) {
+ cmd := accessverifier.Command{c.Config, c.Args, c.ReadWriter}
+
+ return cmd.Verify(action, repo)
+}
+
+func (c *Command) authenticate(action commandargs.CommandType, repo, userId string) ([]byte, error) {
+ client, err := lfsauthenticate.NewClient(c.Config, c.Args)
+ if err != nil {
+ return nil, err
+ }
+
+ response, err := client.Authenticate(action, repo, userId)
+ if err != nil {
+ return nil, err
+ }
+
+ basicAuth := base64.StdEncoding.EncodeToString([]byte(response.Username + ":" + response.LfsToken))
+ payload := &Payload{
+ Header: PayloadHeader{Auth: "Basic " + basicAuth},
+ Href: response.RepoPath + "/info/lfs",
+ ExpiresIn: response.ExpiresIn,
+ }
+
+ return json.Marshal(payload)
+}