diff options
author | Igor Drozdov <idrozdov@gitlab.com> | 2019-04-28 20:42:19 +0300 |
---|---|---|
committer | Igor Drozdov <idrozdov@gitlab.com> | 2019-06-06 13:21:58 +0300 |
commit | 5aa947ed705b48b2980894012eb32e7ee5147b5e (patch) | |
tree | 3557c79227b01376a90f381c5f60f0ef42727baa /go/internal/gitlabnet | |
parent | eb2b186f7d209a638b7523c674bc79cbafe764b6 (diff) | |
download | gitlab-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.go | 66 | ||||
-rw-r--r-- | go/internal/gitlabnet/lfsauthenticate/client_test.go | 117 |
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) +} |