diff options
Diffstat (limited to 'internal/gitlabnet')
-rw-r--r-- | internal/gitlabnet/accessverifier/client.go | 3 | ||||
-rw-r--r-- | internal/gitlabnet/accessverifier/client_test.go | 7 | ||||
-rw-r--r-- | internal/gitlabnet/authorizedkeys/client.go | 3 | ||||
-rw-r--r-- | internal/gitlabnet/authorizedkeys/client_test.go | 7 | ||||
-rw-r--r-- | internal/gitlabnet/client.go | 125 | ||||
-rw-r--r-- | internal/gitlabnet/client_test.go | 246 | ||||
-rw-r--r-- | internal/gitlabnet/discover/client.go | 3 | ||||
-rw-r--r-- | internal/gitlabnet/discover/client_test.go | 8 | ||||
-rw-r--r-- | internal/gitlabnet/healthcheck/client.go | 3 | ||||
-rw-r--r-- | internal/gitlabnet/healthcheck/client_test.go | 2 | ||||
-rw-r--r-- | internal/gitlabnet/httpclient_test.go | 96 | ||||
-rw-r--r-- | internal/gitlabnet/httpsclient_test.go | 125 | ||||
-rw-r--r-- | internal/gitlabnet/lfsauthenticate/client.go | 3 | ||||
-rw-r--r-- | internal/gitlabnet/lfsauthenticate/client_test.go | 2 | ||||
-rw-r--r-- | internal/gitlabnet/testserver/gitalyserver.go | 86 | ||||
-rw-r--r-- | internal/gitlabnet/testserver/testserver.go | 82 | ||||
-rw-r--r-- | internal/gitlabnet/twofactorrecover/client.go | 3 | ||||
-rw-r--r-- | internal/gitlabnet/twofactorrecover/client_test.go | 7 |
18 files changed, 33 insertions, 778 deletions
diff --git a/internal/gitlabnet/accessverifier/client.go b/internal/gitlabnet/accessverifier/client.go index 302a9e1..a9c7d97 100644 --- a/internal/gitlabnet/accessverifier/client.go +++ b/internal/gitlabnet/accessverifier/client.go @@ -5,6 +5,7 @@ import ( "net/http" pb "gitlab.com/gitlab-org/gitaly/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitlab-shell/client" "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" @@ -17,7 +18,7 @@ const ( ) type Client struct { - client *gitlabnet.GitlabClient + client *client.GitlabNetClient } type Request struct { diff --git a/internal/gitlabnet/accessverifier/client_test.go b/internal/gitlabnet/accessverifier/client_test.go index 009dcc0..7ddbb5e 100644 --- a/internal/gitlabnet/accessverifier/client_test.go +++ b/internal/gitlabnet/accessverifier/client_test.go @@ -8,12 +8,11 @@ import ( "testing" "github.com/stretchr/testify/require" - pb "gitlab.com/gitlab-org/gitaly/proto/go/gitalypb" + "gitlab.com/gitlab-org/gitlab-shell/client" + "gitlab.com/gitlab-org/gitlab-shell/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/testserver" "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" ) @@ -214,7 +213,7 @@ func setup(t *testing.T, allowedPayload string) (*Client, func()) { require.NoError(t, err) case "2": w.WriteHeader(http.StatusForbidden) - errBody := &gitlabnet.ErrorResponse{ + errBody := &client.ErrorResponse{ Message: "Not allowed!", } require.NoError(t, json.NewEncoder(w).Encode(errBody)) diff --git a/internal/gitlabnet/authorizedkeys/client.go b/internal/gitlabnet/authorizedkeys/client.go index ac23a96..e4fec28 100644 --- a/internal/gitlabnet/authorizedkeys/client.go +++ b/internal/gitlabnet/authorizedkeys/client.go @@ -4,6 +4,7 @@ import ( "fmt" "net/url" + "gitlab.com/gitlab-org/gitlab-shell/client" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" ) @@ -14,7 +15,7 @@ const ( type Client struct { config *config.Config - client *gitlabnet.GitlabClient + client *client.GitlabNetClient } type Response struct { diff --git a/internal/gitlabnet/authorizedkeys/client_test.go b/internal/gitlabnet/authorizedkeys/client_test.go index 965025f..c9c76a1 100644 --- a/internal/gitlabnet/authorizedkeys/client_test.go +++ b/internal/gitlabnet/authorizedkeys/client_test.go @@ -6,10 +6,9 @@ import ( "testing" "github.com/stretchr/testify/require" - + "gitlab.com/gitlab-org/gitlab-shell/client" + "gitlab.com/gitlab-org/gitlab-shell/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/testserver" ) var ( @@ -29,7 +28,7 @@ func init() { json.NewEncoder(w).Encode(body) } else if r.URL.Query().Get("key") == "broken-message" { w.WriteHeader(http.StatusForbidden) - body := &gitlabnet.ErrorResponse{ + body := &client.ErrorResponse{ Message: "Not allowed!", } json.NewEncoder(w).Encode(body) diff --git a/internal/gitlabnet/client.go b/internal/gitlabnet/client.go index 78ceb44..923b064 100644 --- a/internal/gitlabnet/client.go +++ b/internal/gitlabnet/client.go @@ -1,140 +1,27 @@ package gitlabnet import ( - "bytes" - "encoding/base64" "encoding/json" "fmt" - "io" "net/http" - "strings" - "time" - log "github.com/sirupsen/logrus" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/logger" -) + "gitlab.com/gitlab-org/gitlab-shell/client" -const ( - internalApiPath = "/api/v4/internal" - secretHeaderName = "Gitlab-Shared-Secret" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" ) var ( ParsingError = fmt.Errorf("Parsing failed") ) -type ErrorResponse struct { - Message string `json:"message"` -} - -type GitlabClient struct { - httpClient *http.Client - config *config.Config - host string -} +func GetClient(config *config.Config) (*client.GitlabNetClient, error) { + httpClient := config.GetHttpClient() -func GetClient(config *config.Config) (*GitlabClient, error) { - client := config.GetHttpClient() - - if client == nil { + if httpClient == nil { return nil, fmt.Errorf("Unsupported protocol") } - return &GitlabClient{httpClient: client.HttpClient, config: config, host: client.Host}, nil -} - -func normalizePath(path string) string { - if !strings.HasPrefix(path, "/") { - path = "/" + path - } - - if !strings.HasPrefix(path, internalApiPath) { - path = internalApiPath + path - } - return path -} - -func newRequest(method, host, path string, data interface{}) (*http.Request, error) { - var jsonReader io.Reader - if data != nil { - jsonData, err := json.Marshal(data) - if err != nil { - return nil, err - } - - jsonReader = bytes.NewReader(jsonData) - } - - request, err := http.NewRequest(method, host+path, jsonReader) - if err != nil { - return nil, err - } - - return request, nil -} - -func parseError(resp *http.Response) error { - if resp.StatusCode >= 200 && resp.StatusCode <= 399 { - return nil - } - defer resp.Body.Close() - parsedResponse := &ErrorResponse{} - - if err := json.NewDecoder(resp.Body).Decode(parsedResponse); err != nil { - return fmt.Errorf("Internal API error (%v)", resp.StatusCode) - } else { - return fmt.Errorf(parsedResponse.Message) - } - -} - -func (c *GitlabClient) Get(path string) (*http.Response, error) { - return c.DoRequest(http.MethodGet, normalizePath(path), nil) -} - -func (c *GitlabClient) Post(path string, data interface{}) (*http.Response, error) { - return c.DoRequest(http.MethodPost, normalizePath(path), data) -} - -func (c *GitlabClient) DoRequest(method, path string, data interface{}) (*http.Response, error) { - request, err := newRequest(method, c.host, path, data) - if err != nil { - return nil, err - } - - user, password := c.config.HttpSettings.User, c.config.HttpSettings.Password - if user != "" && password != "" { - request.SetBasicAuth(user, password) - } - - encodedSecret := base64.StdEncoding.EncodeToString([]byte(c.config.Secret)) - request.Header.Set(secretHeaderName, encodedSecret) - - request.Header.Add("Content-Type", "application/json") - request.Close = true - - start := time.Now() - response, err := c.httpClient.Do(request) - fields := log.Fields{ - "method": method, - "url": request.URL.String(), - "duration_ms": logger.ElapsedTimeMs(start, time.Now()), - } - - if err != nil { - log.WithError(err).WithFields(fields).Error("Internal API unreachable") - return nil, fmt.Errorf("Internal API unreachable") - } - - if err := parseError(response); err != nil { - log.WithError(err).WithFields(fields).Error("Internal API error") - return nil, err - } - - log.WithFields(fields).Info("Finished HTTP request") - - return response, nil + return client.NewGitlabNetClient(config.HttpSettings.User, config.HttpSettings.Password, config.SecretFilePath, httpClient) } func ParseJSON(hr *http.Response, response interface{}) error { diff --git a/internal/gitlabnet/client_test.go b/internal/gitlabnet/client_test.go deleted file mode 100644 index d6ca91d..0000000 --- a/internal/gitlabnet/client_test.go +++ /dev/null @@ -1,246 +0,0 @@ -package gitlabnet - -import ( - "encoding/base64" - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - "path" - "strings" - "testing" - - "github.com/sirupsen/logrus" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" -) - -func TestClients(t *testing.T) { - testDirCleanup, err := testhelper.PrepareTestRootDir() - require.NoError(t, err) - defer testDirCleanup() - - requests := []testserver.TestRequestHandler{ - { - Path: "/api/v4/internal/hello", - Handler: func(w http.ResponseWriter, r *http.Request) { - require.Equal(t, http.MethodGet, r.Method) - - fmt.Fprint(w, "Hello") - }, - }, - { - Path: "/api/v4/internal/post_endpoint", - Handler: func(w http.ResponseWriter, r *http.Request) { - require.Equal(t, http.MethodPost, r.Method) - - b, err := ioutil.ReadAll(r.Body) - defer r.Body.Close() - - require.NoError(t, err) - - fmt.Fprint(w, "Echo: "+string(b)) - }, - }, - { - Path: "/api/v4/internal/auth", - Handler: func(w http.ResponseWriter, r *http.Request) { - fmt.Fprint(w, r.Header.Get(secretHeaderName)) - }, - }, - { - Path: "/api/v4/internal/error", - Handler: func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusBadRequest) - body := map[string]string{ - "message": "Don't do that", - } - json.NewEncoder(w).Encode(body) - }, - }, - { - Path: "/api/v4/internal/broken", - Handler: func(w http.ResponseWriter, r *http.Request) { - panic("Broken") - }, - }, - } - - testCases := []struct { - desc string - config *config.Config - server func(*testing.T, []testserver.TestRequestHandler) (string, func()) - }{ - { - desc: "Socket client", - config: &config.Config{}, - server: testserver.StartSocketHttpServer, - }, - { - desc: "Http client", - config: &config.Config{}, - server: testserver.StartHttpServer, - }, - { - desc: "Https client", - config: &config.Config{ - HttpSettings: config.HttpSettingsConfig{CaFile: path.Join(testhelper.TestRoot, "certs/valid/server.crt")}, - }, - server: testserver.StartHttpsServer, - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - url, cleanup := tc.server(t, requests) - defer cleanup() - - tc.config.GitlabUrl = url - tc.config.Secret = "sssh, it's a secret" - - client, err := GetClient(tc.config) - require.NoError(t, err) - - testBrokenRequest(t, client) - testSuccessfulGet(t, client) - testSuccessfulPost(t, client) - testMissing(t, client) - testErrorMessage(t, client) - testAuthenticationHeader(t, client) - }) - } -} - -func testSuccessfulGet(t *testing.T, client *GitlabClient) { - t.Run("Successful get", func(t *testing.T) { - hook := testhelper.SetupLogger() - response, err := client.Get("/hello") - require.NoError(t, err) - require.NotNil(t, response) - - defer response.Body.Close() - - responseBody, err := ioutil.ReadAll(response.Body) - assert.NoError(t, err) - assert.Equal(t, string(responseBody), "Hello") - - assert.Equal(t, 1, len(hook.Entries)) - assert.Equal(t, logrus.InfoLevel, hook.LastEntry().Level) - assert.True(t, strings.Contains(hook.LastEntry().Message, "method=GET")) - assert.True(t, strings.Contains(hook.LastEntry().Message, "Finished HTTP request")) - }) -} - -func testSuccessfulPost(t *testing.T, client *GitlabClient) { - t.Run("Successful Post", func(t *testing.T) { - hook := testhelper.SetupLogger() - data := map[string]string{"key": "value"} - - response, err := client.Post("/post_endpoint", data) - require.NoError(t, err) - require.NotNil(t, response) - - defer response.Body.Close() - - responseBody, err := ioutil.ReadAll(response.Body) - assert.NoError(t, err) - assert.Equal(t, "Echo: {\"key\":\"value\"}", string(responseBody)) - - assert.Equal(t, 1, len(hook.Entries)) - assert.Equal(t, logrus.InfoLevel, hook.LastEntry().Level) - assert.True(t, strings.Contains(hook.LastEntry().Message, "method=POST")) - assert.True(t, strings.Contains(hook.LastEntry().Message, "Finished HTTP request")) - }) -} - -func testMissing(t *testing.T, client *GitlabClient) { - t.Run("Missing error for GET", func(t *testing.T) { - hook := testhelper.SetupLogger() - response, err := client.Get("/missing") - assert.EqualError(t, err, "Internal API error (404)") - assert.Nil(t, response) - - assert.Equal(t, 1, len(hook.Entries)) - assert.Equal(t, logrus.InfoLevel, hook.LastEntry().Level) - assert.True(t, strings.Contains(hook.LastEntry().Message, "method=GET")) - assert.True(t, strings.Contains(hook.LastEntry().Message, "Internal API error")) - }) - - t.Run("Missing error for POST", func(t *testing.T) { - hook := testhelper.SetupLogger() - response, err := client.Post("/missing", map[string]string{}) - assert.EqualError(t, err, "Internal API error (404)") - assert.Nil(t, response) - - assert.Equal(t, 1, len(hook.Entries)) - assert.Equal(t, logrus.InfoLevel, hook.LastEntry().Level) - assert.True(t, strings.Contains(hook.LastEntry().Message, "method=POST")) - assert.True(t, strings.Contains(hook.LastEntry().Message, "Internal API error")) - }) -} - -func testErrorMessage(t *testing.T, client *GitlabClient) { - t.Run("Error with message for GET", func(t *testing.T) { - response, err := client.Get("/error") - assert.EqualError(t, err, "Don't do that") - assert.Nil(t, response) - }) - - t.Run("Error with message for POST", func(t *testing.T) { - response, err := client.Post("/error", map[string]string{}) - assert.EqualError(t, err, "Don't do that") - assert.Nil(t, response) - }) -} - -func testBrokenRequest(t *testing.T, client *GitlabClient) { - t.Run("Broken request for GET", func(t *testing.T) { - response, err := client.Get("/broken") - assert.EqualError(t, err, "Internal API unreachable") - assert.Nil(t, response) - }) - - t.Run("Broken request for POST", func(t *testing.T) { - response, err := client.Post("/broken", map[string]string{}) - assert.EqualError(t, err, "Internal API unreachable") - assert.Nil(t, response) - }) -} - -func testAuthenticationHeader(t *testing.T, client *GitlabClient) { - t.Run("Authentication headers for GET", func(t *testing.T) { - response, err := client.Get("/auth") - require.NoError(t, err) - require.NotNil(t, response) - - defer response.Body.Close() - - responseBody, err := ioutil.ReadAll(response.Body) - require.NoError(t, err) - - header, err := base64.StdEncoding.DecodeString(string(responseBody)) - require.NoError(t, err) - assert.Equal(t, "sssh, it's a secret", string(header)) - }) - - t.Run("Authentication headers for POST", func(t *testing.T) { - response, err := client.Post("/auth", map[string]string{}) - require.NoError(t, err) - require.NotNil(t, response) - - defer response.Body.Close() - - responseBody, err := ioutil.ReadAll(response.Body) - require.NoError(t, err) - - header, err := base64.StdEncoding.DecodeString(string(responseBody)) - require.NoError(t, err) - assert.Equal(t, "sssh, it's a secret", string(header)) - }) -} diff --git a/internal/gitlabnet/discover/client.go b/internal/gitlabnet/discover/client.go index 3faef53..d1e1906 100644 --- a/internal/gitlabnet/discover/client.go +++ b/internal/gitlabnet/discover/client.go @@ -5,6 +5,7 @@ import ( "net/http" "net/url" + "gitlab.com/gitlab-org/gitlab-shell/client" "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" @@ -12,7 +13,7 @@ import ( type Client struct { config *config.Config - client *gitlabnet.GitlabClient + client *client.GitlabNetClient } type Response struct { diff --git a/internal/gitlabnet/discover/client_test.go b/internal/gitlabnet/discover/client_test.go index 66e234b..96b3162 100644 --- a/internal/gitlabnet/discover/client_test.go +++ b/internal/gitlabnet/discover/client_test.go @@ -7,12 +7,12 @@ import ( "net/url" "testing" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/testserver" + "gitlab.com/gitlab-org/gitlab-shell/client" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitlab-shell/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/internal/config" ) var ( @@ -40,7 +40,7 @@ func init() { json.NewEncoder(w).Encode(body) } else if r.URL.Query().Get("username") == "broken_message" { w.WriteHeader(http.StatusForbidden) - body := &gitlabnet.ErrorResponse{ + body := &client.ErrorResponse{ Message: "Not allowed!", } json.NewEncoder(w).Encode(body) diff --git a/internal/gitlabnet/healthcheck/client.go b/internal/gitlabnet/healthcheck/client.go index 7db682a..09b45af 100644 --- a/internal/gitlabnet/healthcheck/client.go +++ b/internal/gitlabnet/healthcheck/client.go @@ -4,6 +4,7 @@ import ( "fmt" "net/http" + "gitlab.com/gitlab-org/gitlab-shell/client" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" ) @@ -14,7 +15,7 @@ const ( type Client struct { config *config.Config - client *gitlabnet.GitlabClient + client *client.GitlabNetClient } type Response struct { diff --git a/internal/gitlabnet/healthcheck/client_test.go b/internal/gitlabnet/healthcheck/client_test.go index d7212b0..c66ddbd 100644 --- a/internal/gitlabnet/healthcheck/client_test.go +++ b/internal/gitlabnet/healthcheck/client_test.go @@ -5,8 +5,8 @@ import ( "net/http" "testing" + "gitlab.com/gitlab-org/gitlab-shell/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/testserver" "github.com/stretchr/testify/require" ) diff --git a/internal/gitlabnet/httpclient_test.go b/internal/gitlabnet/httpclient_test.go deleted file mode 100644 index a40ab6d..0000000 --- a/internal/gitlabnet/httpclient_test.go +++ /dev/null @@ -1,96 +0,0 @@ -package gitlabnet - -import ( - "encoding/base64" - "fmt" - "io/ioutil" - "net/http" - "strings" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/testserver" -) - -const ( - username = "basic_auth_user" - password = "basic_auth_password" -) - -func TestBasicAuthSettings(t *testing.T) { - requests := []testserver.TestRequestHandler{ - { - Path: "/api/v4/internal/get_endpoint", - Handler: func(w http.ResponseWriter, r *http.Request) { - require.Equal(t, http.MethodGet, r.Method) - - fmt.Fprint(w, r.Header.Get("Authorization")) - }, - }, - { - Path: "/api/v4/internal/post_endpoint", - Handler: func(w http.ResponseWriter, r *http.Request) { - require.Equal(t, http.MethodPost, r.Method) - - fmt.Fprint(w, r.Header.Get("Authorization")) - }, - }, - } - config := &config.Config{HttpSettings: config.HttpSettingsConfig{User: username, Password: password}} - - client, cleanup := setup(t, config, requests) - defer cleanup() - - response, err := client.Get("/get_endpoint") - require.NoError(t, err) - testBasicAuthHeaders(t, response) - - response, err = client.Post("/post_endpoint", nil) - require.NoError(t, err) - testBasicAuthHeaders(t, response) -} - -func testBasicAuthHeaders(t *testing.T, response *http.Response) { - defer response.Body.Close() - - require.NotNil(t, response) - responseBody, err := ioutil.ReadAll(response.Body) - assert.NoError(t, err) - - headerParts := strings.Split(string(responseBody), " ") - assert.Equal(t, "Basic", headerParts[0]) - - credentials, err := base64.StdEncoding.DecodeString(headerParts[1]) - require.NoError(t, err) - - assert.Equal(t, username+":"+password, string(credentials)) -} - -func TestEmptyBasicAuthSettings(t *testing.T) { - requests := []testserver.TestRequestHandler{ - { - Path: "/api/v4/internal/empty_basic_auth", - Handler: func(w http.ResponseWriter, r *http.Request) { - assert.Equal(t, "", r.Header.Get("Authorization")) - }, - }, - } - - client, cleanup := setup(t, &config.Config{}, requests) - defer cleanup() - - _, err := client.Get("/empty_basic_auth") - require.NoError(t, err) -} - -func setup(t *testing.T, config *config.Config, requests []testserver.TestRequestHandler) (*GitlabClient, func()) { - url, cleanup := testserver.StartHttpServer(t, requests) - - config.GitlabUrl = url - client, err := GetClient(config) - require.NoError(t, err) - - return client, cleanup -} diff --git a/internal/gitlabnet/httpsclient_test.go b/internal/gitlabnet/httpsclient_test.go deleted file mode 100644 index 0acd425..0000000 --- a/internal/gitlabnet/httpsclient_test.go +++ /dev/null @@ -1,125 +0,0 @@ -package gitlabnet - -import ( - "fmt" - "io/ioutil" - "net/http" - "path" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/testserver" - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" -) - -func TestSuccessfulRequests(t *testing.T) { - testCases := []struct { - desc string - config *config.Config - }{ - { - desc: "Valid CaFile", - config: &config.Config{ - HttpSettings: config.HttpSettingsConfig{CaFile: path.Join(testhelper.TestRoot, "certs/valid/server.crt")}, - }, - }, - { - desc: "Valid CaPath", - config: &config.Config{ - HttpSettings: config.HttpSettingsConfig{CaPath: path.Join(testhelper.TestRoot, "certs/valid")}, - }, - }, - { - desc: "Self signed cert option enabled", - config: &config.Config{ - HttpSettings: config.HttpSettingsConfig{SelfSignedCert: true}, - }, - }, - { - desc: "Invalid cert with self signed cert option enabled", - config: &config.Config{ - HttpSettings: config.HttpSettingsConfig{SelfSignedCert: true, CaFile: path.Join(testhelper.TestRoot, "certs/valid/server.crt")}, - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - client, cleanup := setupWithRequests(t, tc.config) - defer cleanup() - - response, err := client.Get("/hello") - require.NoError(t, err) - require.NotNil(t, response) - - defer response.Body.Close() - - responseBody, err := ioutil.ReadAll(response.Body) - assert.NoError(t, err) - assert.Equal(t, string(responseBody), "Hello") - }) - } -} - -func TestFailedRequests(t *testing.T) { - testCases := []struct { - desc string - config *config.Config - }{ - { - desc: "Invalid CaFile", - config: &config.Config{ - HttpSettings: config.HttpSettingsConfig{CaFile: path.Join(testhelper.TestRoot, "certs/invalid/server.crt")}, - }, - }, - { - desc: "Invalid CaPath", - config: &config.Config{ - HttpSettings: config.HttpSettingsConfig{CaPath: path.Join(testhelper.TestRoot, "certs/invalid")}, - }, - }, - { - desc: "Empty config", - config: &config.Config{}, - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - client, cleanup := setupWithRequests(t, tc.config) - defer cleanup() - - _, err := client.Get("/hello") - require.Error(t, err) - - assert.Equal(t, err.Error(), "Internal API unreachable") - }) - } -} - -func setupWithRequests(t *testing.T, config *config.Config) (*GitlabClient, func()) { - testDirCleanup, err := testhelper.PrepareTestRootDir() - require.NoError(t, err) - defer testDirCleanup() - - requests := []testserver.TestRequestHandler{ - { - Path: "/api/v4/internal/hello", - Handler: func(w http.ResponseWriter, r *http.Request) { - require.Equal(t, http.MethodGet, r.Method) - - fmt.Fprint(w, "Hello") - }, - }, - } - - url, cleanup := testserver.StartHttpsServer(t, requests) - - config.GitlabUrl = url - client, err := GetClient(config) - require.NoError(t, err) - - return client, cleanup -} diff --git a/internal/gitlabnet/lfsauthenticate/client.go b/internal/gitlabnet/lfsauthenticate/client.go index d797321..fffc225 100644 --- a/internal/gitlabnet/lfsauthenticate/client.go +++ b/internal/gitlabnet/lfsauthenticate/client.go @@ -5,6 +5,7 @@ import ( "net/http" "strings" + "gitlab.com/gitlab-org/gitlab-shell/client" "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" @@ -12,7 +13,7 @@ import ( type Client struct { config *config.Config - client *gitlabnet.GitlabClient + client *client.GitlabNetClient args *commandargs.Shell } diff --git a/internal/gitlabnet/lfsauthenticate/client_test.go b/internal/gitlabnet/lfsauthenticate/client_test.go index 0a06960..82e364b 100644 --- a/internal/gitlabnet/lfsauthenticate/client_test.go +++ b/internal/gitlabnet/lfsauthenticate/client_test.go @@ -8,9 +8,9 @@ import ( "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitlab-shell/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/testserver" ) const ( diff --git a/internal/gitlabnet/testserver/gitalyserver.go b/internal/gitlabnet/testserver/gitalyserver.go deleted file mode 100644 index 6d0c130..0000000 --- a/internal/gitlabnet/testserver/gitalyserver.go +++ /dev/null @@ -1,86 +0,0 @@ -package testserver - -import ( - "io/ioutil" - "net" - "os" - "path" - "path/filepath" - "testing" - - "github.com/stretchr/testify/require" - "google.golang.org/grpc" - "google.golang.org/grpc/metadata" - - pb "gitlab.com/gitlab-org/gitaly/proto/go/gitalypb" -) - -type TestGitalyServer struct{ ReceivedMD metadata.MD } - -func (s *TestGitalyServer) SSHReceivePack(stream pb.SSHService_SSHReceivePackServer) error { - req, err := stream.Recv() - if err != nil { - return err - } - - s.ReceivedMD, _ = metadata.FromIncomingContext(stream.Context()) - - response := []byte("ReceivePack: " + req.GlId + " " + req.Repository.GlRepository) - stream.Send(&pb.SSHReceivePackResponse{Stdout: response}) - - return nil -} - -func (s *TestGitalyServer) SSHUploadPack(stream pb.SSHService_SSHUploadPackServer) error { - req, err := stream.Recv() - if err != nil { - return err - } - - s.ReceivedMD, _ = metadata.FromIncomingContext(stream.Context()) - - response := []byte("UploadPack: " + req.Repository.GlRepository) - stream.Send(&pb.SSHUploadPackResponse{Stdout: response}) - - return nil -} - -func (s *TestGitalyServer) SSHUploadArchive(stream pb.SSHService_SSHUploadArchiveServer) error { - req, err := stream.Recv() - if err != nil { - return err - } - - s.ReceivedMD, _ = metadata.FromIncomingContext(stream.Context()) - - response := []byte("UploadArchive: " + req.Repository.GlRepository) - stream.Send(&pb.SSHUploadArchiveResponse{Stdout: response}) - - return nil -} - -func StartGitalyServer(t *testing.T) (string, *TestGitalyServer, func()) { - tempDir, _ := ioutil.TempDir("", "gitlab-shell-test-api") - gitalySocketPath := path.Join(tempDir, "gitaly.sock") - - err := os.MkdirAll(filepath.Dir(gitalySocketPath), 0700) - require.NoError(t, err) - - server := grpc.NewServer() - - listener, err := net.Listen("unix", gitalySocketPath) - require.NoError(t, err) - - testServer := TestGitalyServer{} - pb.RegisterSSHServiceServer(server, &testServer) - - go server.Serve(listener) - - gitalySocketUrl := "unix:" + gitalySocketPath - cleanup := func() { - server.Stop() - os.RemoveAll(tempDir) - } - - return gitalySocketUrl, &testServer, cleanup -} diff --git a/internal/gitlabnet/testserver/testserver.go b/internal/gitlabnet/testserver/testserver.go deleted file mode 100644 index f3b7b71..0000000 --- a/internal/gitlabnet/testserver/testserver.go +++ /dev/null @@ -1,82 +0,0 @@ -package testserver - -import ( - "crypto/tls" - "io/ioutil" - "log" - "net" - "net/http" - "net/http/httptest" - "os" - "path" - "path/filepath" - "testing" - - "github.com/stretchr/testify/require" - - "gitlab.com/gitlab-org/gitlab-shell/internal/testhelper" -) - -var ( - tempDir, _ = ioutil.TempDir("", "gitlab-shell-test-api") - testSocket = path.Join(tempDir, "internal.sock") -) - -type TestRequestHandler struct { - Path string - Handler func(w http.ResponseWriter, r *http.Request) -} - -func StartSocketHttpServer(t *testing.T, handlers []TestRequestHandler) (string, func()) { - err := os.MkdirAll(filepath.Dir(testSocket), 0700) - require.NoError(t, err) - - socketListener, err := net.Listen("unix", testSocket) - require.NoError(t, err) - - server := http.Server{ - Handler: buildHandler(handlers), - // We'll put this server through some nasty stuff we don't want - // in our test output - ErrorLog: log.New(ioutil.Discard, "", 0), - } - go server.Serve(socketListener) - - url := "http+unix://" + testSocket - - return url, cleanupSocket -} - -func StartHttpServer(t *testing.T, handlers []TestRequestHandler) (string, func()) { - server := httptest.NewServer(buildHandler(handlers)) - - return server.URL, server.Close -} - -func StartHttpsServer(t *testing.T, handlers []TestRequestHandler) (string, func()) { - crt := path.Join(testhelper.TestRoot, "certs/valid/server.crt") - key := path.Join(testhelper.TestRoot, "certs/valid/server.key") - - server := httptest.NewUnstartedServer(buildHandler(handlers)) - cer, err := tls.LoadX509KeyPair(crt, key) - require.NoError(t, err) - - server.TLS = &tls.Config{Certificates: []tls.Certificate{cer}} - server.StartTLS() - - return server.URL, server.Close -} - -func cleanupSocket() { - os.RemoveAll(tempDir) -} - -func buildHandler(handlers []TestRequestHandler) http.Handler { - h := http.NewServeMux() - - for _, handler := range handlers { - h.HandleFunc(handler.Path, handler.Handler) - } - - return h -} diff --git a/internal/gitlabnet/twofactorrecover/client.go b/internal/gitlabnet/twofactorrecover/client.go index a3052f8..d22daca 100644 --- a/internal/gitlabnet/twofactorrecover/client.go +++ b/internal/gitlabnet/twofactorrecover/client.go @@ -5,6 +5,7 @@ import ( "fmt" "net/http" + "gitlab.com/gitlab-org/gitlab-shell/client" "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/config" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" @@ -13,7 +14,7 @@ import ( type Client struct { config *config.Config - client *gitlabnet.GitlabClient + client *client.GitlabNetClient } type Response struct { diff --git a/internal/gitlabnet/twofactorrecover/client_test.go b/internal/gitlabnet/twofactorrecover/client_test.go index d5073e3..372afec 100644 --- a/internal/gitlabnet/twofactorrecover/client_test.go +++ b/internal/gitlabnet/twofactorrecover/client_test.go @@ -8,12 +8,11 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - + "gitlab.com/gitlab-org/gitlab-shell/client" + "gitlab.com/gitlab-org/gitlab-shell/client/testserver" "gitlab.com/gitlab-org/gitlab-shell/internal/command/commandargs" "gitlab.com/gitlab-org/gitlab-shell/internal/config" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet" "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/discover" - "gitlab.com/gitlab-org/gitlab-shell/internal/gitlabnet/testserver" ) var ( @@ -48,7 +47,7 @@ func initialize(t *testing.T) { json.NewEncoder(w).Encode(body) case "2": w.WriteHeader(http.StatusForbidden) - body := &gitlabnet.ErrorResponse{ + body := &client.ErrorResponse{ Message: "Not allowed!", } json.NewEncoder(w).Encode(body) |