diff options
Diffstat (limited to 'internal/auth/auth.go')
-rw-r--r-- | internal/auth/auth.go | 39 |
1 files changed, 32 insertions, 7 deletions
diff --git a/internal/auth/auth.go b/internal/auth/auth.go index dcc81eee..fe092ae9 100644 --- a/internal/auth/auth.go +++ b/internal/auth/auth.go @@ -67,6 +67,7 @@ type Auth struct { store sessions.Store now func() time.Time // allows to stub time.Now() easily in tests cookieSessionTimeout time.Duration + allowNamespaceInPath bool } type tokenResponse struct { @@ -140,7 +141,8 @@ func (a *Auth) checkAuthenticationResponse(session *hostSession, w http.Response return } - decryptedCode, err := a.DecryptCode(r.URL.Query().Get("code"), getRequestDomain(r)) + decryptedCode, err := a.DecryptCode(r.URL.Query().Get("code"), + getRequestDomain(r, session.getNamespaceInPathFromSession())) if err != nil { logRequest(r).WithError(err).Error("failed to decrypt secure code") errortracking.CaptureErrWithReqAndStackTrace(err, r) @@ -317,11 +319,16 @@ func getRequestAddress(r *http.Request) string { return "http://" + r.Host + r.RequestURI } -func getRequestDomain(r *http.Request) string { +func getRequestDomain(r *http.Request, namespace string) string { + requestDomain := r.Host + if len(namespace) > 0 && strings.HasPrefix(r.Host, namespace) { + requestDomain = strings.TrimPrefix(r.Host, namespace+".") + "/" + namespace + } + if request.IsHTTPS(r) { - return "https://" + r.Host + return "https://" + requestDomain } - return "http://" + r.Host + return "http://" + requestDomain } func shouldProxyAuthToGitlab(r *http.Request) bool { @@ -440,15 +447,18 @@ 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)), http.StatusFound) + http.Redirect(w, + r, + a.getProxyAddress(r, session.Values["state"].(string), session.getNamespaceInPathFromSession()), + http.StatusFound) return true } return false } -func (a *Auth) getProxyAddress(r *http.Request, state string) string { - return fmt.Sprintf(authorizeProxyTemplate, a.redirectURI, getRequestDomain(r), state) +func (a *Auth) getProxyAddress(r *http.Request, state string, namespace string) string { + return fmt.Sprintf(authorizeProxyTemplate, a.redirectURI, getRequestDomain(r, namespace), state) } func destroySession(session *hostSession, w http.ResponseWriter, r *http.Request) { @@ -602,6 +612,19 @@ func (a *Auth) CheckResponseForInvalidToken(w http.ResponseWriter, r *http.Reque return false } +func (a *Auth) getNamespaceInPath(r *http.Request) string { + if !a.allowNamespaceInPath { + return "" + } + + namespaceInPath := r.Header.Get("X-Gitlab-Namespace-In-Path") + if namespaceInPath == "" || !strings.HasPrefix(r.Host, namespaceInPath+"."+a.pagesDomain) { + return "" + } + + return namespaceInPath +} + func checkResponseForInvalidToken(resp *http.Response, session *hostSession, w http.ResponseWriter, r *http.Request) bool { if resp.StatusCode == http.StatusUnauthorized { errResp := errorResponse{} @@ -664,6 +687,7 @@ type Options struct { AuthScope string AuthTimeout time.Duration CookieSessionTimeout time.Duration + AllowNamespaceInPath bool } // New when authentication supported this will be used to create authentication handler @@ -692,5 +716,6 @@ func New(options *Options) (*Auth, error) { jwtExpiry: time.Minute, now: time.Now, cookieSessionTimeout: options.CookieSessionTimeout, + allowNamespaceInPath: options.AllowNamespaceInPath, }, nil } |