Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-pages.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaime Martinez <jmartinez@gitlab.com>2021-08-16 09:05:37 +0300
committerJaime Martinez <jmartinez@gitlab.com>2021-08-16 10:13:33 +0300
commitd2cb598421d42936e0e7c35f314e49f7a9526616 (patch)
tree1983185eed73386323f420a81dd71d6b1fe752d7
parentc557db08544f6ee551334f53005c3f45611b7444 (diff)
tests: more cases for access control enabled
-rw-r--r--app.go7
-rw-r--r--go.mod1
-rw-r--r--go.sum2
-rw-r--r--internal/domain/domain.go11
-rw-r--r--internal/httptransport/metered_round_tripper.go5
-rw-r--r--shared/pages/group.404/private_project/public.zipbin0 -> 352 bytes
-rw-r--r--shared/pages/group.404/private_unauthorized/public.zipbin0 -> 352 bytes
-rw-r--r--shared/pages/group.auth/group.auth.gitlab-example.com/public.zipbin0 -> 934 bytes
-rw-r--r--shared/pages/group.auth/private.project.1/public.zipbin0 -> 550 bytes
-rw-r--r--test/acceptance/auth_test.go90
-rw-r--r--test/acceptance/helpers_test.go21
-rw-r--r--test/acceptance/stub_test.go68
-rw-r--r--test/acceptance/testdata/api_responses.go23
13 files changed, 129 insertions, 99 deletions
diff --git a/app.go b/app.go
index 43f50d9c..058c56a0 100644
--- a/app.go
+++ b/app.go
@@ -94,6 +94,13 @@ func (a *theApp) redirectToHTTPS(w http.ResponseWriter, r *http.Request, statusC
func (a *theApp) getHostAndDomain(r *http.Request) (string, *domain.Domain, error) {
host := request.GetHostWithoutPort(r)
+
+ // TODO: @jaime REMOVE THIS CHECK AND OPEN AN ISSUE
+ if host == a.config.General.Domain || host == "127.0.0.1" {
+ // skip resolving the domain with the internal API
+ return host, nil, nil
+ }
+
domain, err := a.domain(r.Context(), host)
return host, domain, err
diff --git a/go.mod b/go.mod
index 6729a78e..1dac1973 100644
--- a/go.mod
+++ b/go.mod
@@ -9,6 +9,7 @@ require (
github.com/golang/mock v1.3.1
github.com/golangci/golangci-lint v1.27.0
github.com/gorilla/handlers v1.4.2
+ github.com/gorilla/mux v1.8.0
github.com/gorilla/securecookie v1.1.1
github.com/gorilla/sessions v1.2.0
github.com/hashicorp/go-multierror v1.1.1
diff --git a/go.sum b/go.sum
index c84151f2..5c60e5ee 100644
--- a/go.sum
+++ b/go.sum
@@ -225,6 +225,8 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGa
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/handlers v1.4.2 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YARg=
github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
+github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
+github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
github.com/gorilla/sessions v1.2.0 h1:S7P+1Hm5V/AT9cjEcUD5uDaQSX0OE577aCXgoaKpYbQ=
diff --git a/internal/domain/domain.go b/internal/domain/domain.go
index 94888e34..eb4d8e86 100644
--- a/internal/domain/domain.go
+++ b/internal/domain/domain.go
@@ -4,6 +4,7 @@ import (
"context"
"crypto/tls"
"errors"
+ "fmt"
"net/http"
"sync"
@@ -161,6 +162,7 @@ func (d *Domain) ServeNotFoundHTTP(w http.ResponseWriter, r *http.Request) {
// that failed authentication so that we serve the custom namespace error page for
// public namespace domains
func (d *Domain) serveNamespaceNotFound(w http.ResponseWriter, r *http.Request) {
+ fmt.Printf("serveNamespaceNotFound-1\n")
// clone r and override the path and try to resolve the domain name
clonedReq := r.Clone(context.Background())
clonedReq.URL.Path = "/"
@@ -177,29 +179,32 @@ func (d *Domain) serveNamespaceNotFound(w http.ResponseWriter, r *http.Request)
httperrors.Serve503(w)
return
}
-
+ fmt.Printf("serveNamespaceNotFound-2\n")
+ fmt.Printf("namespaceDomain.LookupPath:%+v\n", namespaceDomain.LookupPath)
// for namespace domains that have no access control enabled
if !namespaceDomain.LookupPath.HasAccessControl {
namespaceDomain.ServeNotFoundHTTP(w, r)
return
}
-
+ fmt.Printf("serveNamespaceNotFound-3\n")
httperrors.Serve404(w)
}
// ServeNotFoundAuthFailed handler to be called when auth failed so the correct custom
// 404 page is served.
func (d *Domain) ServeNotFoundAuthFailed(w http.ResponseWriter, r *http.Request) {
+ fmt.Printf("ServeNotFoundAuthFailed-1\n")
lookupPath, err := d.GetLookupPath(r)
if err != nil {
httperrors.Serve404(w)
return
}
+ fmt.Printf("ServeNotFoundAuthFailed-2\n")
if d.IsNamespaceProject(r) && !lookupPath.HasAccessControl {
d.ServeNotFoundHTTP(w, r)
return
}
-
+ fmt.Printf("ServeNotFoundAuthFailed-3\n")
d.serveNamespaceNotFound(w, r)
}
diff --git a/internal/httptransport/metered_round_tripper.go b/internal/httptransport/metered_round_tripper.go
index 8978f824..45dfeb7e 100644
--- a/internal/httptransport/metered_round_tripper.go
+++ b/internal/httptransport/metered_round_tripper.go
@@ -3,7 +3,6 @@ package httptransport
import (
"context"
"net/http"
- "net/http/httptrace"
"strconv"
"time"
@@ -45,8 +44,8 @@ func NewMeteredRoundTripper(transport http.RoundTripper, name string, tracerVec,
func (mrt *meteredRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) {
start := time.Now()
- ctx := httptrace.WithClientTrace(r.Context(), mrt.newTracer(start))
- ctx, cancel := context.WithCancel(ctx)
+ //ctx := httptrace.WithClientTrace(r.Context(), mrt.newTracer(start))
+ ctx, cancel := context.WithCancel(r.Context())
timer := time.AfterFunc(mrt.ttfbTimeout, cancel)
defer timer.Stop()
diff --git a/shared/pages/group.404/private_project/public.zip b/shared/pages/group.404/private_project/public.zip
new file mode 100644
index 00000000..7f158bcf
--- /dev/null
+++ b/shared/pages/group.404/private_project/public.zip
Binary files differ
diff --git a/shared/pages/group.404/private_unauthorized/public.zip b/shared/pages/group.404/private_unauthorized/public.zip
new file mode 100644
index 00000000..7f158bcf
--- /dev/null
+++ b/shared/pages/group.404/private_unauthorized/public.zip
Binary files differ
diff --git a/shared/pages/group.auth/group.auth.gitlab-example.com/public.zip b/shared/pages/group.auth/group.auth.gitlab-example.com/public.zip
new file mode 100644
index 00000000..8ff37318
--- /dev/null
+++ b/shared/pages/group.auth/group.auth.gitlab-example.com/public.zip
Binary files differ
diff --git a/shared/pages/group.auth/private.project.1/public.zip b/shared/pages/group.auth/private.project.1/public.zip
new file mode 100644
index 00000000..23b7e646
--- /dev/null
+++ b/shared/pages/group.auth/private.project.1/public.zip
Binary files differ
diff --git a/test/acceptance/auth_test.go b/test/acceptance/auth_test.go
index 4dceaad0..fd92a582 100644
--- a/test/acceptance/auth_test.go
+++ b/test/acceptance/auth_test.go
@@ -7,7 +7,6 @@ import (
"net/http"
"net/url"
"os"
- "regexp"
"testing"
"time"
@@ -107,78 +106,7 @@ func TestWhenLoginCallbackWithUnencryptedCode(t *testing.T) {
require.Equal(t, http.StatusInternalServerError, authrsp.StatusCode)
}
-// TODO: NEED TO MOVE THIS to handler in api_responses
-func handleAccessControlArtifactRequests(t *testing.T, w http.ResponseWriter, r *http.Request) bool {
- authorization := r.Header.Get("Authorization")
-
- switch {
- case regexp.MustCompile(`/api/v4/projects/group/private/jobs/\d+/artifacts/delayed_200.html`).MatchString(r.URL.Path):
- sleepIfAuthorized(t, authorization, w)
- return true
- case regexp.MustCompile(`/api/v4/projects/group/private/jobs/\d+/artifacts/404.html`).MatchString(r.URL.Path):
- w.WriteHeader(http.StatusNotFound)
- return true
- case regexp.MustCompile(`/api/v4/projects/group/private/jobs/\d+/artifacts/500.html`).MatchString(r.URL.Path):
- returnIfAuthorized(t, authorization, w, http.StatusInternalServerError)
- return true
- case regexp.MustCompile(`/api/v4/projects/group/private/jobs/\d+/artifacts/200.html`).MatchString(r.URL.Path):
- returnIfAuthorized(t, authorization, w, http.StatusOK)
- return true
- case regexp.MustCompile(`/api/v4/projects/group/subgroup/private/jobs/\d+/artifacts/200.html`).MatchString(r.URL.Path):
- returnIfAuthorized(t, authorization, w, http.StatusOK)
- return true
- default:
- return false
- }
-}
-
-func handleAccessControlRequests(t *testing.T, w http.ResponseWriter, r *http.Request) {
- allowedProjects := regexp.MustCompile(`/api/v4/projects/1\d{3}/pages_access`)
- deniedProjects := regexp.MustCompile(`/api/v4/projects/2\d{3}/pages_access`)
- invalidTokenProjects := regexp.MustCompile(`/api/v4/projects/3\d{3}/pages_access`)
-
- switch {
- case allowedProjects.MatchString(r.URL.Path):
- require.Equal(t, "Bearer abc", r.Header.Get("Authorization"))
- w.WriteHeader(http.StatusOK)
- case deniedProjects.MatchString(r.URL.Path):
- require.Equal(t, "Bearer abc", r.Header.Get("Authorization"))
- w.WriteHeader(http.StatusUnauthorized)
- case invalidTokenProjects.MatchString(r.URL.Path):
- require.Equal(t, "Bearer abc", r.Header.Get("Authorization"))
- w.WriteHeader(http.StatusUnauthorized)
- fmt.Fprint(w, "{\"error\":\"invalid_token\"}")
- default:
- t.Logf("Unexpected r.URL.RawPath: %q", r.URL.Path)
- w.Header().Set("Content-Type", "text/html; charset=utf-8")
- w.WriteHeader(http.StatusNotFound)
- }
-}
-
-func returnIfAuthorized(t *testing.T, authorization string, w http.ResponseWriter, status int) {
- if authorization != "" {
- require.Equal(t, "Bearer abc", authorization)
- w.WriteHeader(status)
- } else {
- w.WriteHeader(http.StatusNotFound)
- }
-}
-
-func sleepIfAuthorized(t *testing.T, authorization string, w http.ResponseWriter) {
- if authorization != "" {
- require.Equal(t, "Bearer abc", authorization)
- time.Sleep(2 * time.Second)
- } else {
- w.WriteHeader(http.StatusNotFound)
- }
-}
-
func TestAccessControlUnderCustomDomainStandalone(t *testing.T) {
- skipUnlessEnabled(t, "not-inplace-chroot")
-
- //
- //teardown := RunPagesProcessWithAuth(t, *pagesBinary, supportedListeners(), testServer.URL, "https://public-gitlab-auth.com")
- //defer teardown()
runPagesWithAuth(t, []ListenSpec{httpListener})
tests := map[string]struct {
@@ -254,13 +182,7 @@ func TestAccessControlUnderCustomDomainStandalone(t *testing.T) {
}
func TestCustomErrorPageWithAuth(t *testing.T) {
- skipUnlessEnabled(t, "not-inplace-chroot")
- testServer := makeGitLabPagesAccessStub(t)
- testServer.Start()
- defer testServer.Close()
-
- teardown := RunPagesProcessWithAuth(t, *pagesBinary, supportedListeners(), testServer.URL, "https://public-gitlab-auth.com")
- defer teardown()
+ runPagesWithAuth(t, []ListenSpec{httpListener})
tests := []struct {
name string
@@ -290,7 +212,7 @@ func TestCustomErrorPageWithAuth(t *testing.T) {
{
name: "private_namespace_with_private_project_auth_failed",
domain: "group.auth.gitlab-example.com",
- // project ID is 2000
+ // project ID is 2005 which causes a 401
path: "/private.project.1/unknown",
expectedErrorPage: "The page you're looking for could not be found.",
},
@@ -722,12 +644,12 @@ func getValidCookieAndState(t *testing.T, domain string) (string, string) {
func runPagesWithAuth(t *testing.T, listeners []ListenSpec) {
t.Helper()
- testServer := makeGitLabPagesAccessStub(t)
- testServer.Start()
- t.Cleanup(testServer.Close)
+ //testServer := makeGitLabPagesAccessStub(t)
+ //testServer.Start()
+ //t.Cleanup(testServer.Close)
configFile := defaultConfigFileWith(t,
- "internal-gitlab-server="+testServer.URL,
+ //"internal-gitlab-server="+testServer.URL,
"gitlab-server=https://public-gitlab-auth.com",
"auth-redirect-uri=https://projects.gitlab-example.com/auth",
)
diff --git a/test/acceptance/helpers_test.go b/test/acceptance/helpers_test.go
index 20af4095..376a94b8 100644
--- a/test/acceptance/helpers_test.go
+++ b/test/acceptance/helpers_test.go
@@ -20,6 +20,7 @@ import (
"testing"
"time"
+ "github.com/gorilla/mux"
"github.com/pires/go-proxyproto"
"github.com/stretchr/testify/require"
"golang.org/x/net/nettest"
@@ -584,7 +585,7 @@ func NewGitlabDomainsSourceStub(t *testing.T, opts *stubOpts) *httptest.Server {
currentStatusCount := 0
- mux := http.NewServeMux()
+ router := mux.NewRouter()
statusHandler := func(w http.ResponseWriter, r *http.Request) {
if currentStatusCount < opts.statusReadyCount {
w.WriteHeader(http.StatusBadGateway)
@@ -598,30 +599,38 @@ func NewGitlabDomainsSourceStub(t *testing.T, opts *stubOpts) *httptest.Server {
statusHandler = opts.statusHandler
}
- mux.HandleFunc("/api/v4/internal/pages/status", statusHandler)
+ router.HandleFunc("/api/v4/internal/pages/status", statusHandler)
pagesHandler := defaultAPIHandler(t, opts)
if opts.pagesHandler != nil {
pagesHandler = opts.pagesHandler
}
- mux.HandleFunc("/api/v4/internal/pages", pagesHandler)
+ router.HandleFunc("/api/v4/internal/pages", pagesHandler)
authHandler := defaultAuthHandler(t, opts)
if opts.authHandler != nil {
authHandler = opts.authHandler
}
- mux.HandleFunc("/oauth/token", authHandler)
+ router.HandleFunc("/oauth/token", authHandler)
userHandler := defaultUserHandler(t, opts)
if opts.userHandler != nil {
userHandler = opts.userHandler
}
- mux.HandleFunc("/api/v4/user", userHandler)
+ router.HandleFunc("/api/v4/user", userHandler)
- return httptest.NewServer(mux)
+ router.HandleFunc("/api/v4/projects/{project_id:[0-9]+}/pages_access", func(w http.ResponseWriter, r *http.Request) {
+ if handleAccessControlArtifactRequests(t, w, r) {
+ return
+ }
+
+ handleAccessControlRequests(t, w, r)
+ })
+
+ return httptest.NewServer(router)
}
func (o *stubOpts) setAPICalled(v bool) {
diff --git a/test/acceptance/stub_test.go b/test/acceptance/stub_test.go
index a22f798a..6523c672 100644
--- a/test/acceptance/stub_test.go
+++ b/test/acceptance/stub_test.go
@@ -5,7 +5,9 @@ import (
"io/ioutil"
"net/http"
"net/http/httptest"
+ "regexp"
"testing"
+ "time"
"github.com/stretchr/testify/require"
@@ -135,3 +137,69 @@ func CreateGitLabAPISecretKeyFixtureFile(t *testing.T) (filepath string) {
return secretfile.Name()
}
+
+// TODO: NEED TO MOVE THIS to handler in api_responses
+func handleAccessControlArtifactRequests(t *testing.T, w http.ResponseWriter, r *http.Request) bool {
+ authorization := r.Header.Get("Authorization")
+
+ switch {
+ case regexp.MustCompile(`/api/v4/projects/group/private/jobs/\d+/artifacts/delayed_200.html`).MatchString(r.URL.Path):
+ sleepIfAuthorized(t, authorization, w)
+ return true
+ case regexp.MustCompile(`/api/v4/projects/group/private/jobs/\d+/artifacts/404.html`).MatchString(r.URL.Path):
+ w.WriteHeader(http.StatusNotFound)
+ return true
+ case regexp.MustCompile(`/api/v4/projects/group/private/jobs/\d+/artifacts/500.html`).MatchString(r.URL.Path):
+ returnIfAuthorized(t, authorization, w, http.StatusInternalServerError)
+ return true
+ case regexp.MustCompile(`/api/v4/projects/group/private/jobs/\d+/artifacts/200.html`).MatchString(r.URL.Path):
+ returnIfAuthorized(t, authorization, w, http.StatusOK)
+ return true
+ case regexp.MustCompile(`/api/v4/projects/group/subgroup/private/jobs/\d+/artifacts/200.html`).MatchString(r.URL.Path):
+ returnIfAuthorized(t, authorization, w, http.StatusOK)
+ return true
+ default:
+ return false
+ }
+}
+
+func handleAccessControlRequests(t *testing.T, w http.ResponseWriter, r *http.Request) {
+ allowedProjects := regexp.MustCompile(`/api/v4/projects/1\d{3}/pages_access`)
+ deniedProjects := regexp.MustCompile(`/api/v4/projects/2\d{3}/pages_access`)
+ invalidTokenProjects := regexp.MustCompile(`/api/v4/projects/3\d{3}/pages_access`)
+
+ switch {
+ case allowedProjects.MatchString(r.URL.Path):
+ require.Equal(t, "Bearer abc", r.Header.Get("Authorization"))
+ w.WriteHeader(http.StatusOK)
+ case deniedProjects.MatchString(r.URL.Path):
+ require.Equal(t, "Bearer abc", r.Header.Get("Authorization"))
+ w.WriteHeader(http.StatusUnauthorized)
+ case invalidTokenProjects.MatchString(r.URL.Path):
+ require.Equal(t, "Bearer abc", r.Header.Get("Authorization"))
+ w.WriteHeader(http.StatusUnauthorized)
+ fmt.Fprint(w, "{\"error\":\"invalid_token\"}")
+ default:
+ t.Logf("Unexpected r.URL.RawPath: %q", r.URL.Path)
+ w.Header().Set("Content-Type", "text/html; charset=utf-8")
+ w.WriteHeader(http.StatusNotFound)
+ }
+}
+
+func returnIfAuthorized(t *testing.T, authorization string, w http.ResponseWriter, status int) {
+ if authorization != "" {
+ require.Equal(t, "Bearer abc", authorization)
+ w.WriteHeader(status)
+ } else {
+ w.WriteHeader(http.StatusNotFound)
+ }
+}
+
+func sleepIfAuthorized(t *testing.T, authorization string, w http.ResponseWriter) {
+ if authorization != "" {
+ require.Equal(t, "Bearer abc", authorization)
+ time.Sleep(2 * time.Second)
+ } else {
+ w.WriteHeader(http.StatusNotFound)
+ }
+}
diff --git a/test/acceptance/testdata/api_responses.go b/test/acceptance/testdata/api_responses.go
index 80e761d7..4bc0b24e 100644
--- a/test/acceptance/testdata/api_responses.go
+++ b/test/acceptance/testdata/api_responses.go
@@ -27,7 +27,16 @@ var DomainResponses = map[string]responseFn{
"zip-not-allowed-path.gitlab.io": customDomain(projectConfig{pathOnDisk: "../../../../"}),
"group.gitlab-example.com": generateVirtualDomainFromDir("group", "group.gitlab-example.com", nil),
"CapitalGroup.gitlab-example.com": generateVirtualDomainFromDir("CapitalGroup", "CapitalGroup.gitlab-example.com", nil),
- "group.404.gitlab-example.com": generateVirtualDomainFromDir("group.404", "group.404.gitlab-example.com", nil),
+ "group.404.gitlab-example.com": generateVirtualDomainFromDir("group.404", "group.404.gitlab-example.com", map[string]projectConfig{
+ "/private_project": {
+ projectID: 1300,
+ accessControl: true,
+ },
+ "/private_unauthorized": {
+ projectID: 2000,
+ accessControl: true,
+ },
+ }),
"group.https-only.gitlab-example.com": generateVirtualDomainFromDir("group.https-only", "group.https-only.gitlab-example.com", map[string]projectConfig{
"/project1": {
projectID: 1000,
@@ -67,13 +76,21 @@ var DomainResponses = map[string]responseFn{
pathOnDisk: "group.https-only/project5",
}),
"group.auth.gitlab-example.com": generateVirtualDomainFromDir("group.auth", "group.auth.gitlab-example.com", map[string]projectConfig{
- "/private.project": {
+ "/": {
projectID: 1005,
accessControl: true,
},
+ "/private.project": {
+ projectID: 1006,
+ accessControl: true,
+ },
+ "/private.project.1": {
+ projectID: 2006,
+ accessControl: true,
+ },
}),
"private.domain.com": customDomain(projectConfig{
- projectID: 1006,
+ projectID: 1007,
accessControl: true,
pathOnDisk: "group.auth/private.project",
}),