mirror of
https://github.com/fosrl/newt.git
synced 2026-10-21 20:19:08 +02:00
99 lines
2.9 KiB
Go
99 lines
2.9 KiB
Go
package netstack2
|
|
|
|
import (
|
|
"context"
|
|
"net"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"net/url"
|
|
"testing"
|
|
)
|
|
|
|
func TestHTTPHandlerSetsRemoteHeaders(t *testing.T) {
|
|
received := make(chan http.Header, 1)
|
|
backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
received <- r.Header.Clone()
|
|
}))
|
|
defer backend.Close()
|
|
|
|
backendURL, err := url.Parse(backend.URL)
|
|
if err != nil {
|
|
t.Fatalf("parse backend URL: %v", err)
|
|
}
|
|
backendHost, backendPort, err := net.SplitHostPort(backendURL.Host)
|
|
if err != nil {
|
|
t.Fatalf("split backend host: %v", err)
|
|
}
|
|
port, err := net.LookupPort("tcp", backendPort)
|
|
if err != nil {
|
|
t.Fatalf("parse backend port: %v", err)
|
|
}
|
|
|
|
handler := NewHTTPHandler(nil, nil)
|
|
handler.ReplaceClientIdentities([]ClientIdentity{
|
|
{IP: "100.90.128.5", UserID: "u1", Username: "alice", Email: "alice@example.com", Name: "Alice", Role: "Admin, Member"},
|
|
{IP: "100.90.128.6", Name: "build-server", Role: "CI"},
|
|
})
|
|
rule := &SubnetRule{
|
|
Protocol: "http",
|
|
HTTPTargets: []HTTPTarget{
|
|
{DestAddr: backendHost, DestPort: uint16(port), Scheme: backendURL.Scheme},
|
|
},
|
|
}
|
|
|
|
send := func(remoteAddr string) http.Header {
|
|
t.Helper()
|
|
req := httptest.NewRequest(http.MethodGet, "http://app.internal/", nil)
|
|
req.RemoteAddr = remoteAddr
|
|
// a client must not be able to spoof any of these
|
|
req.Header.Set("Remote-User", "mallory")
|
|
req.Header.Set("Remote-Role", "Admin")
|
|
req = req.WithContext(context.WithValue(req.Context(), connCtxKey{}, rule))
|
|
handler.handleRequest(httptest.NewRecorder(), req)
|
|
return <-received
|
|
}
|
|
|
|
user := send("100.90.128.5:51234")
|
|
for name, want := range map[string]string{
|
|
"Remote-User-Id": "u1",
|
|
"Remote-User": "alice",
|
|
"Remote-Email": "alice@example.com",
|
|
"Remote-Name": "Alice",
|
|
"Remote-Role": "Admin, Member",
|
|
} {
|
|
if got := user.Get(name); got != want {
|
|
t.Errorf("user client: %s = %q, want %q", name, got, want)
|
|
}
|
|
}
|
|
|
|
machine := send("100.90.128.6:51234")
|
|
for name, want := range map[string]string{
|
|
"Remote-User-Id": "",
|
|
"Remote-User": "",
|
|
"Remote-Email": "",
|
|
"Remote-Name": "build-server",
|
|
"Remote-Role": "CI",
|
|
} {
|
|
if got := machine.Get(name); got != want {
|
|
t.Errorf("machine client: %s = %q, want %q", name, got, want)
|
|
}
|
|
}
|
|
|
|
unknown := send("100.90.128.7:51234")
|
|
for _, name := range []string{"Remote-User", "Remote-Role"} {
|
|
if got := unknown.Get(name); got != "" {
|
|
t.Errorf("unknown client: %s = %q, want it stripped", name, got)
|
|
}
|
|
}
|
|
|
|
// an incremental add overwrites a stale entry for a reused IP
|
|
handler.AddClientIdentities([]ClientIdentity{{IP: "100.90.128.5", Name: "other-machine"}})
|
|
reused := send("100.90.128.5:51234")
|
|
if got := reused.Get("Remote-User"); got != "" {
|
|
t.Errorf("reused IP: Remote-User = %q, want empty", got)
|
|
}
|
|
if got := reused.Get("Remote-Name"); got != "other-machine" {
|
|
t.Errorf("reused IP: Remote-Name = %q, want %q", got, "other-machine")
|
|
}
|
|
}
|