diff options
author | Grzegorz Bizon <grzesiek.bizon@gmail.com> | 2019-12-10 19:43:20 +0300 |
---|---|---|
committer | Grzegorz Bizon <grzesiek.bizon@gmail.com> | 2019-12-10 19:43:20 +0300 |
commit | 22a73c6be625c1cdbe676ac3e1bef9985fb47fd9 (patch) | |
tree | 02282b0b1277ad6c273093d8133c032cef41478c | |
parent | 185d5e494eb32b14f5f9340d8bd5cb8b95657f3f (diff) | |
parent | 266b942aba1f98c0548472542cfc6b7cec7a5f17 (diff) |
Merge branch 'master' into feature/gb/gitlab-domains-source
* master:
Add support for the port component in the Host header
Base64 decode GitLab API secret
-rw-r--r-- | acceptance_test.go | 3 | ||||
-rw-r--r-- | app.go | 7 | ||||
-rw-r--r-- | helpers_test.go | 10 | ||||
-rw-r--r-- | internal/fixture/fixtures.go | 4 | ||||
-rw-r--r-- | internal/request/request.go | 12 | ||||
-rw-r--r-- | internal/request/request_test.go | 21 | ||||
-rw-r--r-- | internal/source/gitlab/client/client_stub.go | 2 | ||||
-rw-r--r-- | internal/source/gitlab/client/client_test.go | 6 | ||||
-rw-r--r-- | internal/source/gitlab/gitlab.go | 4 | ||||
-rw-r--r-- | main.go | 22 |
10 files changed, 77 insertions, 14 deletions
diff --git a/acceptance_test.go b/acceptance_test.go index af6d86bc..ae1bf2b6 100644 --- a/acceptance_test.go +++ b/acceptance_test.go @@ -1535,7 +1535,8 @@ func TestGitlabDomainsSource(t *testing.T) { defer source.Close() newSourceDomains := "GITLAB_NEW_SOURCE_DOMAINS=new-source-test.gitlab.io,non-existent-domain.gitlab.io" - pagesArgs := []string{"-gitlab-server", source.URL, "-api-secret-key", "README.md"} + gitLabAPISecretKey := CreateGitLabAPISecretKeyFixtureFile(t) + pagesArgs := []string{"-gitlab-server", source.URL, "-api-secret-key", gitLabAPISecretKey} teardown := RunPagesProcessWithEnvs(t, true, *pagesBinary, listeners, "", []string{newSourceDomains}, pagesArgs...) defer teardown() @@ -3,7 +3,6 @@ package main import ( "crypto/tls" "errors" - "net" "net/http" "sync" @@ -87,11 +86,7 @@ func (a *theApp) redirectToHTTPS(w http.ResponseWriter, r *http.Request, statusC } func (a *theApp) getHostAndDomain(r *http.Request) (string, *domain.Domain, error) { - host, _, err := net.SplitHostPort(r.Host) - if err != nil { - host = r.Host - } - + host := request.GetHostWithoutPort(r) domain, err := a.domain(host) return host, domain, err diff --git a/helpers_test.go b/helpers_test.go index 26f432c6..bcc43d63 100644 --- a/helpers_test.go +++ b/helpers_test.go @@ -75,6 +75,16 @@ func CreateHTTPSFixtureFiles(t *testing.T) (key string, cert string) { return keyfile.Name(), certfile.Name() } +func CreateGitLabAPISecretKeyFixtureFile(t *testing.T) (filepath string) { + secretfile, err := ioutil.TempFile("", "gitlab-api-secret") + require.NoError(t, err) + secretfile.Close() + + require.NoError(t, ioutil.WriteFile(secretfile.Name(), []byte(fixture.GitLabAPISecretKey), 0644)) + + return secretfile.Name() +} + // ListenSpec is used to point at a gitlab-pages http server, preserving the // type of port it is (http, https, proxy) type ListenSpec struct { diff --git a/internal/fixture/fixtures.go b/internal/fixture/fixtures.go index 38bbd375..e425da1b 100644 --- a/internal/fixture/fixtures.go +++ b/internal/fixture/fixtures.go @@ -53,4 +53,8 @@ yhGSbQKBgD3VEnPiSUmXBo39kPcnPg93E3JfdAOiOwIB2qwfYzg9kpmuTWws+DFz lKpMI27YkmnPqROQ2NTUfdxYmw3EHHMAsvnmHeMNGn3ijSUZVKmPfV436Qc8iVci s4wKoCRhBUZ52sHki/ieb+5hycT3JnVXMDtbJxgXFW5a86usXEpO -----END RSA PRIVATE KEY-----` + + // GitLabAPISecretKey used in tests + // 32 bytes, base64 encoded + GitLabAPISecretKey = "e41rcFh7XBA7sNABWVCe2AZvxMsy6QDtJ8S9Ql1UiN8=" ) diff --git a/internal/request/request.go b/internal/request/request.go index 74982f33..06a45071 100644 --- a/internal/request/request.go +++ b/internal/request/request.go @@ -2,6 +2,7 @@ package request import ( "context" + "net" "net/http" "gitlab.com/gitlab-org/gitlab-pages/internal/domain" @@ -45,3 +46,14 @@ func GetHost(r *http.Request) string { func GetDomain(r *http.Request) *domain.Domain { return r.Context().Value(ctxDomainKey).(*domain.Domain) } + +// GetHostWithoutPort returns a host without the port. The host(:port) comes +// from a Host: header if it is provided, otherwise it is a server name. +func GetHostWithoutPort(r *http.Request) string { + host, _, err := net.SplitHostPort(r.Host) + if err != nil { + return r.Host + } + + return host +} diff --git a/internal/request/request_test.go b/internal/request/request_test.go index e092448b..642209f0 100644 --- a/internal/request/request_test.go +++ b/internal/request/request_test.go @@ -2,6 +2,7 @@ package request import ( "net/http" + "net/http/httptest" "testing" "github.com/stretchr/testify/require" @@ -65,3 +66,23 @@ func TestWithHostAndDomain(t *testing.T) { }) } } + +func TestGetHostWithoutPort(t *testing.T) { + t.Run("when port component is provided", func(t *testing.T) { + request := httptest.NewRequest("GET", "https://example.com:443", nil) + request.Host = "my.example.com:8080" + + host := GetHostWithoutPort(request) + + require.Equal(t, "my.example.com", host) + }) + + t.Run("when port component is not provided", func(t *testing.T) { + request := httptest.NewRequest("GET", "http://example.com", nil) + request.Host = "my.example.com" + + host := GetHostWithoutPort(request) + + require.Equal(t, "my.example.com", host) + }) +} diff --git a/internal/source/gitlab/client/client_stub.go b/internal/source/gitlab/client/client_stub.go index 70c00511..00a689d8 100644 --- a/internal/source/gitlab/client/client_stub.go +++ b/internal/source/gitlab/client/client_stub.go @@ -18,11 +18,11 @@ func (c StubClient) GetLookup(ctx context.Context, host string) api.Lookup { lookup := api.Lookup{Name: host} f, err := os.Open(c.File) - defer f.Close() if err != nil { lookup.Error = err return lookup } + defer f.Close() lookup.Error = json.NewDecoder(f).Decode(&lookup.Domain) diff --git a/internal/source/gitlab/client/client_test.go b/internal/source/gitlab/client/client_test.go index 5f6be9ca..247de5c7 100644 --- a/internal/source/gitlab/client/client_test.go +++ b/internal/source/gitlab/client/client_test.go @@ -10,10 +10,8 @@ import ( jwt "github.com/dgrijalva/jwt-go" "github.com/stretchr/testify/require" -) -var ( - encodedSecret = "e41rcFh7XBA7sNABWVCe2AZvxMsy6QDtJ8S9Ql1UiN8=" // 32 bytes, base64 encoded + "gitlab.com/gitlab-org/gitlab-pages/internal/fixture" ) func TestNewValidBaseURL(t *testing.T) { @@ -162,6 +160,6 @@ func validateToken(t *testing.T, tokenString string) { } func secretKey() []byte { - secretKey, _ := base64.StdEncoding.DecodeString(encodedSecret) + secretKey, _ := base64.StdEncoding.DecodeString(fixture.GitLabAPISecretKey) return secretKey } diff --git a/internal/source/gitlab/gitlab.go b/internal/source/gitlab/gitlab.go index 0221fd11..7977e35a 100644 --- a/internal/source/gitlab/gitlab.go +++ b/internal/source/gitlab/gitlab.go @@ -8,6 +8,7 @@ import ( "strings" "gitlab.com/gitlab-org/gitlab-pages/internal/domain" + "gitlab.com/gitlab-org/gitlab-pages/internal/request" "gitlab.com/gitlab-org/gitlab-pages/internal/serving" "gitlab.com/gitlab-org/gitlab-pages/internal/source/gitlab/api" "gitlab.com/gitlab-org/gitlab-pages/internal/source/gitlab/cache" @@ -58,7 +59,8 @@ func (g *Gitlab) GetDomain(name string) (*domain.Domain, error) { // Resolve is supposed to get the serving lookup path based on the request from // the GitLab source func (g *Gitlab) Resolve(r *http.Request) (*serving.LookupPath, string, error) { - response := g.client.GetLookup(r.Context(), r.Host) + host := request.GetHostWithoutPort(r) + response := g.client.GetLookup(r.Context(), host) if response.Error != nil { return nil, "", response.Error } @@ -1,6 +1,7 @@ package main import ( + "encoding/base64" "errors" "fmt" "io" @@ -121,6 +122,22 @@ func setArtifactsServer(artifactsServer string, artifactsServerTimeout int, conf config.ArtifactsServer = artifactsServer } +func setGitLabAPISecretKey(secretFile string, config *appConfig) { + encoded := readFile(secretFile) + + decoded := make([]byte, base64.StdEncoding.DecodedLen(len(encoded))) + secretLength, err := base64.StdEncoding.Decode(decoded, encoded) + if err != nil { + log.WithError(err).Fatal("Failed to decode GitLab API secret") + } + + if secretLength != 32 { + log.WithError(fmt.Errorf("Expected 32 bytes GitLab API secret but got %d bytes", secretLength)).Fatal("Failed to decode GitLab API secret") + } + + config.GitLabAPISecretKey = decoded +} + func configFromFlags() appConfig { var config appConfig @@ -144,13 +161,16 @@ func configFromFlags() appConfig { }{ {&config.RootCertificate, *pagesRootCert}, {&config.RootKey, *pagesRootKey}, - {&config.GitLabAPISecretKey, *gitLabAPISecretKey}, } { if file.path != "" { *file.contents = readFile(file.path) } } + if *gitLabAPISecretKey != "" { + setGitLabAPISecretKey(*gitLabAPISecretKey, &config) + } + if *artifactsServer != "" { setArtifactsServer(*artifactsServer, *artifactsServerTimeout, &config) } |