From e1fe97ff76ac966039347465f79dc96e705f7f25 Mon Sep 17 00:00:00 2001 From: mo khan Date: Wed, 5 Mar 2025 13:02:36 -0700 Subject: feat: connect the reverse proxy to a casbin policy enforcement and separate hostnames --- cmd/gtwy/main.go | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) (limited to 'cmd') diff --git a/cmd/gtwy/main.go b/cmd/gtwy/main.go index 9b21c14..3d4a247 100644 --- a/cmd/gtwy/main.go +++ b/cmd/gtwy/main.go @@ -7,23 +7,37 @@ import ( "net/http/httputil" "strings" "time" + + "github.com/casbin/casbin/v2" + "github.com/xlgmokha/x/pkg/env" + "github.com/xlgmokha/x/pkg/x" ) -func NewProxy(from, to string) http.Handler { +func NewRouter(routes map[string]string) http.Handler { + authz := x.Must(casbin.NewEnforcer("model.conf", "policy.csv")) + return &httputil.ReverseProxy{ Director: func(r *http.Request) { - log.Printf("%v (from: %v to: %v)\n", r.URL, from, to) - r.URL.Scheme = "http" - r.Host = to - r.URL.Host = to - r.URL.Path = strings.TrimPrefix(r.URL.Path, strings.TrimSuffix(from, "/*")) - r.URL.RawPath = strings.TrimPrefix(r.URL.RawPath, strings.TrimSuffix(from, "/*")) + segments := strings.SplitN(r.Host, ":", 2) + host := segments[0] + destinationHost := routes[host] + + log.Printf("%v (from: %v to: %v)\n", r.URL, host, destinationHost) + + subject := "71cbc18e-bd41-4229-9ad2-749546a2a4a7" // TODO:: unpack sub claim in JWT + if x.Must(authz.Enforce(subject, host, r.Method, r.URL.Path)) { + r.URL.Scheme = "http" // TODO:: use TLS + r.Host = destinationHost + r.URL.Host = destinationHost + } else { + log.Println("UNAUTHORIZED") // TODO:: Return forbidden, unauthorized or not found status code + } }, Transport: http.DefaultTransport, FlushInterval: -1, ErrorLog: nil, ModifyResponse: func(r *http.Response) error { - r.Header.Add("Via", fmt.Sprintf("%v gateway", r.Proto)) + r.Header.Add("Via", fmt.Sprintf("%v gtwy", r.Proto)) return nil }, ErrorHandler: func(w http.ResponseWriter, r *http.Request, err error) { @@ -34,11 +48,16 @@ func NewProxy(from, to string) http.Handler { func main() { mux := http.NewServeMux() - mux.Handle("/idp/", NewProxy("/idp", "localhost:8282")) - mux.Handle("/sp/", NewProxy("/sp", "localhost:8283")) + routes := map[string]string{ + "idp.example.com": "localhost:8282", + "ui.example.com": "localhost:8283", + "api.example.com": "localhost:8284", + } + mux.Handle("/", NewRouter(routes)) + bindAddress := env.Fetch("BIND_ADDR", ":8080") log.Fatal((&http.Server{ - Addr: ":8080", + Addr: bindAddress, Handler: mux, ReadHeaderTimeout: 10 * time.Second, ReadTimeout: 30 * time.Second, -- cgit v1.2.3