Skip to content

refactor: keep user-router runtime state out of options#1036

Merged
jranson merged 2 commits into
trickstercache:mainfrom
houyuwushang:refactor-ur-runtime-state-1010
Jul 3, 2026
Merged

refactor: keep user-router runtime state out of options#1036
jranson merged 2 commits into
trickstercache:mainfrom
houyuwushang:refactor-ur-runtime-state-1010

Conversation

@houyuwushang

Copy link
Copy Markdown
Contributor

Description

Fixes #1010.

Moves resolved user-router runtime state out of ur/options.Options:

  • stores the default handler, effective no-route status, and per-user route handlers on ur.Handler
  • removes DefaultHandler, ToHandler, and ToStatus from the user-router options structs
  • builds runtime routes locally during validateAndStartUserRouter and applies them only after validation succeeds
  • keeps the configured NoRouteStatusCode unchanged while still using the effective startup response code

Tests:

  • go test -count=1 ./pkg/backends/alb/mech/ur ./pkg/backends/alb
  • go test -count=1 ./pkg/backends/alb/...
  • go tool golangci-lint run --timeout 5m ./pkg/backends/alb/...
  • go test -run '^$' ./...

Type of Change

    • Bug fix
    • New feature
    • Optimization
    • Test coverage
    • Documentation
    • Infrastructure

AI Disclosure

    • This contribution DOES NOT include AI-generated changes
    • This contribution DOES include AI-generated changes, and I have reviewed the relevant contributing guidelines.

Signed-off-by: houyuwushang <liuluoqianqiu@outlook.com>
@jranson

jranson commented Jul 2, 2026

Copy link
Copy Markdown
Member

@houyuwushang thanks for this contribution, and for your patience while I tested it out.

I've identified a regression in this change that breaks the 'user remapping' feature by causing a remapped user to be sent through the incorrect user route (or the default fallthrough route), instead of the expected/configured route for the inbound username when the user is configured with to_backend.

The main issue is that at pkg/backends/alb/mech/ur/user_router.go:124-125, username can be mutated (e.g., alice -> admin). Then at L150, routes[username] is used to route the request to a backend target. Even if the username undergoes remapping, the original username is what should be used for routing (so in my example, the alice route should still be used, even though the effective username to the backend is remapped to admin). However, in your change, my hypothetical inbound alice user would be improperly routed to the admin route (or the default route if admin is not configured) instead of their configured to_backend route due to the mutation of the username var in the remapping branch.

One fix might be to set an outboundUsername value instead of mutating username at all, and use outboundUsername in the SetCredentials call:

outboundUsername := username
if u.ToUser != "" {
    outboundUsername = u.ToUser
}
…
    if err := auth.SetCredentials(r, outboundUsername, cred); err != nil {
        h.handleDefault(w, r)
        return
    }
…
if route, ok := routes[username]; ok && route.Handler != nil {
    …
}

This way, the outbound username is properly remapped while the inbound username is still used for the routes map lookup.

@jranson jranson left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comments above.

Signed-off-by: houyuwushang <liuluoqianqiu@outlook.com>
@houyuwushang

houyuwushang commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for catching and explaining the regression. I pushed 584ff7f to address it.

The fix keeps the inbound username unchanged for routes[username] lookup and uses a separate outboundUsername only for SetCredentials. I also added a regression test where inbound alice is remapped to outbound admin while both alice and admin routes exist; the request must still dispatch through the alice route while writing admin credentials downstream.

Local validation:

  • go test ./pkg/backends/alb/mech/ur -run 'TestServeHTTP/credential_remapping|TestURRetainsInboundCredWhenToCredentialEmpty' -count=1
  • go test -count=1 ./pkg/backends/alb/mech/ur ./pkg/backends/alb
  • go test -count=1 ./pkg/backends/alb/...
  • go test -race ./pkg/backends/alb/mech/ur -run 'TestServeHTTP/credential_remapping_keeps_inbound_username_for_routing' -count=1
  • go tool golangci-lint run --timeout 5m ./pkg/backends/alb/mech/ur ./pkg/backends/alb
  • git diff --check

@jranson jranson merged commit 4e6d312 into trickstercache:main Jul 3, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ur: move runtime handler state out of options.Options

2 participants