mirror of
https://github.com/coder/coder.git
synced 2025-07-03 16:13:58 +00:00
feat: Add serving applications on subdomains and port-based proxying (#3753)
Co-authored-by: Dean Sheather <dean@deansheather.com>
This commit is contained in:
@ -9,6 +9,7 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -58,6 +59,24 @@ const (
|
||||
internalErrorMessage string = "An internal error occurred. Please try again or contact the system administrator."
|
||||
)
|
||||
|
||||
type loginURLKey struct{}
|
||||
|
||||
func getLoginURL(r *http.Request) (*url.URL, bool) {
|
||||
val, ok := r.Context().Value(loginURLKey{}).(*url.URL)
|
||||
return val, ok
|
||||
}
|
||||
|
||||
// UseLoginURL sets the login URL to use for the request for handlers like
|
||||
// ExtractAPIKey.
|
||||
func UseLoginURL(loginURL *url.URL) func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx := context.WithValue(r.Context(), loginURLKey{}, loginURL)
|
||||
next.ServeHTTP(rw, r.WithContext(ctx))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// ExtractAPIKey requires authentication using a valid API key.
|
||||
// It handles extending an API key if it comes close to expiry,
|
||||
// updating the last used time in the database.
|
||||
@ -70,14 +89,37 @@ func ExtractAPIKey(db database.Store, oauth *OAuth2Configs, redirectToLogin bool
|
||||
// pages like workspace applications.
|
||||
write := func(code int, response codersdk.Response) {
|
||||
if redirectToLogin {
|
||||
var (
|
||||
u = &url.URL{
|
||||
Path: "/login",
|
||||
}
|
||||
redirectURL = func() string {
|
||||
path := r.URL.Path
|
||||
if r.URL.RawQuery != "" {
|
||||
path += "?" + r.URL.RawQuery
|
||||
}
|
||||
return path
|
||||
}()
|
||||
)
|
||||
if loginURL, ok := getLoginURL(r); ok {
|
||||
u = loginURL
|
||||
// Don't redirect to the current page, as it may be on
|
||||
// a different domain and we have issues determining the
|
||||
// scheme to redirect to.
|
||||
redirectURL = ""
|
||||
}
|
||||
|
||||
q := r.URL.Query()
|
||||
q.Add("message", response.Message)
|
||||
q.Add("redirect", r.URL.Path+"?"+r.URL.RawQuery)
|
||||
r.URL.RawQuery = q.Encode()
|
||||
r.URL.Path = "/login"
|
||||
http.Redirect(rw, r, r.URL.String(), http.StatusTemporaryRedirect)
|
||||
if redirectURL != "" {
|
||||
q.Add("redirect", redirectURL)
|
||||
}
|
||||
u.RawQuery = q.Encode()
|
||||
|
||||
http.Redirect(rw, r, u.String(), http.StatusTemporaryRedirect)
|
||||
return
|
||||
}
|
||||
|
||||
httpapi.Write(rw, code, response)
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user