summaryrefslogtreecommitdiff
path: root/go/internal/gitlabnet
diff options
context:
space:
mode:
authorIgor Drozdov <idrozdov@gitlab.com>2019-04-28 20:42:19 +0300
committerIgor Drozdov <idrozdov@gitlab.com>2019-06-06 13:21:58 +0300
commit5aa947ed705b48b2980894012eb32e7ee5147b5e (patch)
tree3557c79227b01376a90f381c5f60f0ef42727baa /go/internal/gitlabnet
parenteb2b186f7d209a638b7523c674bc79cbafe764b6 (diff)
downloadgitlab-shell-id-git-lfs-authenticate.tar.gz
Go implementation for LFS authenticateid-git-lfs-authenticate
Diffstat (limited to 'go/internal/gitlabnet')
-rw-r--r--go/internal/gitlabnet/lfsauthenticate/client.go66
-rw-r--r--go/internal/gitlabnet/lfsauthenticate/client_test.go117
2 files changed, 183 insertions, 0 deletions
diff --git a/go/internal/gitlabnet/lfsauthenticate/client.go b/go/internal/gitlabnet/lfsauthenticate/client.go
new file mode 100644
index 0000000..2a7cb03
--- /dev/null
+++ b/go/internal/gitlabnet/lfsauthenticate/client.go
@@ -0,0 +1,66 @@
+package lfsauthenticate
+
+import (
+ "fmt"
+ "net/http"
+ "strings"
+
+ "gitlab.com/gitlab-org/gitlab-shell/go/internal/command/commandargs"
+ "gitlab.com/gitlab-org/gitlab-shell/go/internal/config"
+ "gitlab.com/gitlab-org/gitlab-shell/go/internal/gitlabnet"
+)
+
+type Client struct {
+ config *config.Config
+ client *gitlabnet.GitlabClient
+ args *commandargs.CommandArgs
+}
+
+type Request struct {
+ Action commandargs.CommandType `json:"operation"`
+ Repo string `json:"project"`
+ KeyId string `json:"key_id,omitempty"`
+ UserId string `json:"user_id,omitempty"`
+}
+
+type Response struct {
+ Username string `json:"username"`
+ LfsToken string `json:"lfs_token"`
+ RepoPath string `json:"repository_http_path"`
+ ExpiresIn int `json:"expires_in"`
+}
+
+func NewClient(config *config.Config, args *commandargs.CommandArgs) (*Client, error) {
+ client, err := gitlabnet.GetClient(config)
+ if err != nil {
+ return nil, fmt.Errorf("Error creating http client: %v", err)
+ }
+
+ return &Client{config: config, client: client, args: args}, nil
+}
+
+func (c *Client) Authenticate(action commandargs.CommandType, repo, userId string) (*Response, error) {
+ request := &Request{Action: action, Repo: repo}
+ if c.args.GitlabKeyId != "" {
+ request.KeyId = c.args.GitlabKeyId
+ } else {
+ request.UserId = strings.TrimPrefix(userId, "user-")
+ }
+
+ response, err := c.client.Post("/lfs_authenticate", request)
+ if err != nil {
+ return nil, err
+ }
+ defer response.Body.Close()
+
+ return parse(response)
+}
+
+func parse(hr *http.Response) (*Response, error) {
+ response := &Response{}
+ if err := gitlabnet.ParseJSON(hr, response); err != nil {
+ return nil, err
+ }
+
+ return response, nil
+}
diff --git a/go/internal/gitlabnet/lfsauthenticate/client_test.go b/go/internal/gitlabnet/lfsauthenticate/client_test.go
new file mode 100644
index 0000000..7fd7aca
--- /dev/null
+++ b/go/internal/gitlabnet/lfsauthenticate/client_test.go
@@ -0,0 +1,117 @@
+package lfsauthenticate
+
+import (
+ "encoding/json"
+ "io/ioutil"
+ "net/http"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+
+ "gitlab.com/gitlab-org/gitlab-shell/go/internal/command/commandargs"
+ "gitlab.com/gitlab-org/gitlab-shell/go/internal/config"
+ "gitlab.com/gitlab-org/gitlab-shell/go/internal/gitlabnet/testserver"
+)
+
+const (
+ keyId = "123"
+ repo = "group/repo"
+ action = commandargs.UploadPack
+)
+
+func setup(t *testing.T) []testserver.TestRequestHandler {
+ requests := []testserver.TestRequestHandler{
+ {
+ Path: "/api/v4/internal/lfs_authenticate",
+ Handler: func(w http.ResponseWriter, r *http.Request) {
+ b, err := ioutil.ReadAll(r.Body)
+ defer r.Body.Close()
+ require.NoError(t, err)
+
+ var request *Request
+ require.NoError(t, json.Unmarshal(b, &request))
+
+ switch request.KeyId {
+ case keyId:
+ body := map[string]interface{}{
+ "username": "john",
+ "lfs_token": "sometoken",
+ "repository_http_path": "https://gitlab.com/repo/path",
+ "expires_in": 1800,
+ }
+ require.NoError(t, json.NewEncoder(w).Encode(body))
+ case "forbidden":
+ w.WriteHeader(http.StatusForbidden)
+ case "broken":
+ w.WriteHeader(http.StatusInternalServerError)
+ }
+ },
+ },
+ }
+
+ return requests
+}
+
+func TestFailedRequests(t *testing.T) {
+ requests := setup(t)
+ url, cleanup := testserver.StartHttpServer(t, requests)
+ defer cleanup()
+
+ testCases := []struct {
+ desc string
+ args *commandargs.CommandArgs
+ expectedOutput string
+ }{
+ {
+ desc: "With bad response",
+ args: &commandargs.CommandArgs{GitlabKeyId: "-1", CommandType: commandargs.UploadPack},
+ expectedOutput: "Parsing failed",
+ },
+ {
+ desc: "With API returns an error",
+ args: &commandargs.CommandArgs{GitlabKeyId: "forbidden", CommandType: commandargs.UploadPack},
+ expectedOutput: "Internal API error (403)",
+ },
+ {
+ desc: "With API fails",
+ args: &commandargs.CommandArgs{GitlabKeyId: "broken", CommandType: commandargs.UploadPack},
+ expectedOutput: "Internal API error (500)",
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.desc, func(t *testing.T) {
+ client, err := NewClient(&config.Config{GitlabUrl: url}, tc.args)
+ require.NoError(t, err)
+
+ repo := "group/repo"
+
+ _, err = client.Authenticate(tc.args.CommandType, repo, "")
+ require.Error(t, err)
+
+ require.Equal(t, tc.expectedOutput, err.Error())
+ })
+ }
+}
+
+func TestSuccessfulRequests(t *testing.T) {
+ requests := setup(t)
+ url, cleanup := testserver.StartHttpServer(t, requests)
+ defer cleanup()
+
+ args := &commandargs.CommandArgs{GitlabKeyId: keyId, CommandType: commandargs.LfsAuthenticate}
+ client, err := NewClient(&config.Config{GitlabUrl: url}, args)
+ require.NoError(t, err)
+
+ response, err := client.Authenticate(action, repo, "")
+ require.NoError(t, err)
+
+ expectedResponse := &Response{
+ Username: "john",
+ LfsToken: "sometoken",
+ RepoPath: "https://gitlab.com/repo/path",
+ ExpiresIn: 1800,
+ }
+
+ require.Equal(t, expectedResponse, response)
+}