fix(pier): end only the revoked token's or client's MCP sessions and log the client address (B-WR-04, B-IN-04)

- pact.MCPSubjectChanged and pier.Event gain TokenID and ClientID; a
  narrowed revoked event closes only matching sessions and stateless servers
- cabana fires the admin token revoke with the token row id
- towel.WithClientIP/ClientIP; pier puts the address (surf applies
  http.trusted_proxies) on the resolve context and ResolveBackendToken logs it
This commit is contained in:
Jakub Zych
2026-10-23 16:21:37 +02:00
parent 0ec00f7f69
commit 24cf6cd931
16 changed files with 158 additions and 31 deletions

View File

@@ -5,6 +5,7 @@ package surf
import (
"fmt"
"net/http"
"net/netip"
"strings"
"git.golem15.com/golem15/summercms/modules/backpack"
@@ -19,13 +20,22 @@ import (
// handler lookup and the two mount kinds without pier importing surf.
func init() {
mountPier = func(r *Router, app *backpack.App, plugins []party.Plugin) error {
return pier.Mount(pierHost{r: r}, app, plugins)
return pier.Mount(pierHost{r: r, trusted: TrustedProxies(app.Config)}, app, plugins)
}
}
// pierHost adapts a Router to pier.Host.
// pierHost adapts a Router to pier.Host. trusted holds http.trusted_proxies
// for ClientIP.
type pierHost struct {
r *Router
r *Router
trusted []netip.Prefix
}
// ClientIP answers the request's client address with the application's
// trusted proxies applied, the same rule the throttle middleware uses; pier
// puts it on the token resolvers' context.
func (h pierHost) ClientIP(req *http.Request) string {
return ClientIP(req, h.trusted)
}
func (h pierHost) Routes() []pier.RouteInfo {