mirror of
https://github.com/muety/wakapi.git
synced 2023-08-10 21:12:56 +03:00
feat: implement relay endpoint (see #237)
This commit is contained in:
parent
5394349c73
commit
8d073aaef2
@ -39,6 +39,7 @@ security:
|
||||
cookie_max_age: 172800
|
||||
allow_signup: true
|
||||
expose_metrics: false
|
||||
enable_proxy: false # only intended for production instance at wakapi.dev
|
||||
|
||||
sentry:
|
||||
dsn: # leave blank to disable sentry integration
|
||||
|
@ -75,6 +75,7 @@ type appConfig struct {
|
||||
type securityConfig struct {
|
||||
AllowSignup bool `yaml:"allow_signup" default:"true" env:"WAKAPI_ALLOW_SIGNUP"`
|
||||
ExposeMetrics bool `yaml:"expose_metrics" default:"false" env:"WAKAPI_EXPOSE_METRICS"`
|
||||
EnableProxy bool `yaml:"enable_proxy" default:"false" env:"WAKAPI_ENABLE_PROXY"` // only intended for production instance at wakapi.dev
|
||||
// this is actually a pepper (https://en.wikipedia.org/wiki/Pepper_(cryptography))
|
||||
PasswordSalt string `yaml:"password_salt" default:"" env:"WAKAPI_PASSWORD_SALT"`
|
||||
InsecureCookies bool `yaml:"insecure_cookies" default:"false" env:"WAKAPI_INSECURE_COOKIES"`
|
||||
|
5
main.go
5
main.go
@ -3,6 +3,7 @@ package main
|
||||
import (
|
||||
"embed"
|
||||
"github.com/muety/wakapi/models"
|
||||
"github.com/muety/wakapi/routes/relay"
|
||||
"io/fs"
|
||||
"log"
|
||||
"net"
|
||||
@ -191,6 +192,9 @@ func main() {
|
||||
loginHandler := routes.NewLoginHandler(userService, mailService)
|
||||
imprintHandler := routes.NewImprintHandler(keyValueService)
|
||||
|
||||
// Other Handlers
|
||||
relayHandler := relay.NewRelayHandler()
|
||||
|
||||
// Setup Routers
|
||||
router := mux.NewRouter()
|
||||
rootRouter := router.PathPrefix("/").Subrouter()
|
||||
@ -219,6 +223,7 @@ func main() {
|
||||
imprintHandler.RegisterRoutes(rootRouter)
|
||||
summaryHandler.RegisterRoutes(rootRouter)
|
||||
settingsHandler.RegisterRoutes(rootRouter)
|
||||
relayHandler.RegisterRoutes(rootRouter)
|
||||
|
||||
// API route registrations
|
||||
summaryApiHandler.RegisterRoutes(apiRouter)
|
||||
|
75
routes/relay/relay.go
Normal file
75
routes/relay/relay.go
Normal file
@ -0,0 +1,75 @@
|
||||
package relay
|
||||
|
||||
import (
|
||||
"github.com/gorilla/mux"
|
||||
conf "github.com/muety/wakapi/config"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
const targetUrlHeader = "X-Target-URL"
|
||||
const pathMatcherPattern = `^/api/(heartbeat|heartbeats|summary|users|v1/users|compat/wakatime)`
|
||||
|
||||
type RelayHandler struct {
|
||||
config *conf.Config
|
||||
}
|
||||
|
||||
func NewRelayHandler() *RelayHandler {
|
||||
return &RelayHandler{
|
||||
config: conf.Get(),
|
||||
}
|
||||
}
|
||||
|
||||
type filteringMiddleware struct {
|
||||
handler http.Handler
|
||||
pathMatcher *regexp.Regexp
|
||||
}
|
||||
|
||||
func newFilteringMiddleware() func(http.Handler) http.Handler {
|
||||
return func(h http.Handler) http.Handler {
|
||||
return &filteringMiddleware{
|
||||
handler: h,
|
||||
pathMatcher: regexp.MustCompile(pathMatcherPattern),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (m *filteringMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
targetUrl, err := url.Parse(r.Header.Get(targetUrlHeader))
|
||||
if err != nil || !m.pathMatcher.MatchString(targetUrl.Path) {
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
w.Write([]byte{})
|
||||
return
|
||||
}
|
||||
m.handler.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
func (h *RelayHandler) RegisterRoutes(router *mux.Router) {
|
||||
if !h.config.Security.EnableProxy {
|
||||
return
|
||||
}
|
||||
|
||||
r := router.PathPrefix("/relay").Subrouter()
|
||||
r.Use(newFilteringMiddleware())
|
||||
r.Path("").HandlerFunc(h.Any)
|
||||
}
|
||||
|
||||
func (h *RelayHandler) Any(w http.ResponseWriter, r *http.Request) {
|
||||
targetUrl, err := url.Parse(r.Header.Get(targetUrlHeader))
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte{})
|
||||
return
|
||||
}
|
||||
|
||||
p := httputil.ReverseProxy{
|
||||
Director: func(r *http.Request) {
|
||||
r.URL = targetUrl
|
||||
r.Host = targetUrl.Host
|
||||
},
|
||||
}
|
||||
|
||||
p.ServeHTTP(w, r)
|
||||
}
|
Loading…
Reference in New Issue
Block a user