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:
authorngala <ngala@gitlab.com>2023-11-10 09:50:05 +0300
committerngala <ngala@gitlab.com>2023-11-10 09:50:05 +0300
commit62c52f5cff34e307a0519a915afb55f8315deff9 (patch)
treebb6eb18b224b60bf1ea09f237a3e499774a3e029
parentceb6d345d860dc8c6cce1d92278858f154f14440 (diff)
Add test for X-Gitlab-Namespace-In-Path
-rw-r--r--internal/auth/auth.go6
-rw-r--r--internal/auth/session.go9
-rw-r--r--internal/request/request.go13
-rw-r--r--internal/request/request_test.go37
4 files changed, 55 insertions, 10 deletions
diff --git a/internal/auth/auth.go b/internal/auth/auth.go
index ad35c3e9..bbb8daa6 100644
--- a/internal/auth/auth.go
+++ b/internal/auth/auth.go
@@ -142,7 +142,7 @@ func (a *Auth) checkAuthenticationResponse(session *hostSession, w http.Response
return
}
- decryptedCode, err := a.DecryptCode(r.URL.Query().Get("code"), getRequestDomain(r, getNamespaceInPath(session)))
+ decryptedCode, err := a.DecryptCode(r.URL.Query().Get("code"), getRequestDomain(r, getNamespaceInPathFromSession(session)))
if err != nil {
logRequest(r).WithError(err).Error("failed to decrypt secure code")
errortracking.CaptureErrWithReqAndStackTrace(err, r)
@@ -333,7 +333,7 @@ func getRequestDomain(r *http.Request, namespace string) string {
return "http://" + requestDomain
}
-func getNamespaceInPath(session *hostSession) string {
+func getNamespaceInPathFromSession(session *hostSession) string {
namespaceInPath := ""
if len(session.Options.Path) > 1 && session.Options.Path[0] == '/' {
namespaceInPath = session.Options.Path[1:]
@@ -459,7 +459,7 @@ func (a *Auth) checkTokenExists(session *hostSession, w http.ResponseWriter, r *
// Because the pages domain might be in public suffix list, we have to
// redirect to pages domain to trigger authorization flow
- http.Redirect(w, r, a.getProxyAddress(r, session.Values["state"].(string), getNamespaceInPath(session)), http.StatusFound)
+ http.Redirect(w, r, a.getProxyAddress(r, session.Values["state"].(string), getNamespaceInPathFromSession(session)), http.StatusFound)
return true
}
diff --git a/internal/auth/session.go b/internal/auth/session.go
index 9a14e7f0..bbe83ba5 100644
--- a/internal/auth/session.go
+++ b/internal/auth/session.go
@@ -2,12 +2,10 @@ package auth
import (
"github.com/gorilla/sessions"
- "net/http"
- "strings"
-
"gitlab.com/gitlab-org/gitlab-pages/internal/errortracking"
"gitlab.com/gitlab-org/gitlab-pages/internal/httperrors"
"gitlab.com/gitlab-org/gitlab-pages/internal/request"
+ "net/http"
)
type hostSession struct {
@@ -28,10 +26,7 @@ func (a *Auth) getSessionFromStore(r *http.Request) (*hostSession, error) {
session, err := a.store.Get(r, "gitlab-pages")
if session != nil {
- namespaceInPath := r.Header.Get("X-Gitlab-Namespace-In-Path")
- if namespaceInPath != "" && !strings.HasPrefix(r.Host, namespaceInPath+"."+a.pagesDomain) {
- namespaceInPath = ""
- }
+ namespaceInPath := request.GetNamespaceInPathFromRequest(r, a.pagesDomain)
logRequest(r).WithField("X-Gitlab-Namespace-In-Path", namespaceInPath).Debug("> Inside getSessionFromStore")
// Cookie just for this domain
diff --git a/internal/request/request.go b/internal/request/request.go
index f98b0819..4a7e1e52 100644
--- a/internal/request/request.go
+++ b/internal/request/request.go
@@ -3,6 +3,7 @@ package request
import (
"net"
"net/http"
+ "strings"
)
const (
@@ -38,3 +39,15 @@ func GetRemoteAddrWithoutPort(r *http.Request) string {
return remoteAddr
}
+
+// GetNamespaceInPathFromRequest GetNamespaceInPath fetches X-Gitlab-Namespace-In-Path from r.Header and validates against pagesDomain before returning
+func GetNamespaceInPathFromRequest(r *http.Request, pagesDomain string) string {
+ namespaceInPath := ""
+ if pagesDomain != "" {
+ namespaceInPath = r.Header.Get("X-Gitlab-Namespace-In-Path")
+ if namespaceInPath != "" && !strings.HasPrefix(r.Host, namespaceInPath+"."+pagesDomain) {
+ namespaceInPath = ""
+ }
+ }
+ return namespaceInPath
+}
diff --git a/internal/request/request_test.go b/internal/request/request_test.go
index 9e71db37..8ee16f8c 100644
--- a/internal/request/request_test.go
+++ b/internal/request/request_test.go
@@ -87,3 +87,40 @@ func TestGetRemoteAddrWithoutPort(t *testing.T) {
})
}
}
+
+func TestGetNamespaceInPathFromRequest(t *testing.T) {
+ tests := map[string]struct {
+ pagesDomain string
+ u string
+ namespace string
+ expected string
+ }{
+ "when valid X-Gitlab-Namespace-In-Path is provided in request header": {
+ pagesDomain: "example.com",
+ u: "https://namespace.example.com/myProject",
+ namespace: "namespace",
+ expected: "namespace",
+ },
+ "when valid X-Gitlab-Namespace-In-Path with '.' in between in request header": {
+ pagesDomain: "example.com",
+ u: "https://namespace.test.example.com/myProject",
+ namespace: "namespace.test",
+ expected: "namespace.test",
+ },
+ "when forged X-Gitlab-Namespace-In-Path is provided in request header": {
+ pagesDomain: "example.com",
+ u: "https://namespace.example.com/myProject",
+ namespace: "namespace-forged",
+ expected: "",
+ },
+ }
+ for name, test := range tests {
+ t.Run(name, func(t *testing.T) {
+ req := httptest.NewRequest(http.MethodGet, test.u, nil)
+ req.Header.Set("X-Gitlab-Namespace-In-Path", test.namespace)
+
+ namespace := GetNamespaceInPathFromRequest(req, test.pagesDomain)
+ require.Equal(t, test.expected, namespace)
+ })
+ }
+}