Skip to content

refactor: refactor proxy controller to handle proxy auth modules better#714

Merged
steveiliop56 merged 6 commits intomainfrom
refactor/proxy-controller
Mar 14, 2026
Merged

refactor: refactor proxy controller to handle proxy auth modules better#714
steveiliop56 merged 6 commits intomainfrom
refactor/proxy-controller

Conversation

@steveiliop56
Copy link
Owner

@steveiliop56 steveiliop56 commented Mar 14, 2026

Summary by CodeRabbit

  • Refactor

    • Centralized authentication flow using a request context for more consistent handling across proxies.
    • Improved browser detection to tailor behavior for browser vs non-browser requests.
    • Unified error/fallback handling to provide friendlier, more consistent redirects and responses.
  • Tests

    • Expanded coverage across multiple proxy and auth-module scenarios, including ACL, missing headers, and redirect cases.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 14, 2026

📝 Walkthrough

Walkthrough

Introduces a ProxyContext type and AuthModuleType enum; centralizes auth-module-driven request context construction (ForwardAuth, ExtAuthz, AuthRequest); refactors error handling and routing to operate on the consolidated ProxyContext instead of ad-hoc request-specific extraction.

Changes

Cohort / File(s) Summary
Authentication Context Refactoring
internal/controller/proxy_controller.go
Adds ProxyContext and AuthModuleType; implements getProxyContext, determineAuthModules, getContextFromAuthModule, and module-specific context builders; replaces per-proxy branching with proxyCtx-driven logic; changes handleError signature to accept ProxyContext; adds browser detection and friendly-error path.
Tests: setup & scenarios
internal/controller/proxy_controller_test.go
Updates setupProxyController signature (pointer -> value for middlewares) and return values (removes AuthService); introduces loggedInCtx test context; updates AppURL in test config; expands test scenarios across traefik/nginx/envoy/ACL and header combinations to exercise ForwardAuth/ExtAuthz/AuthRequest flows.

Sequence Diagram(s)

sequenceDiagram
    participant Client as Client
    participant ProxyCtrl as ProxyController
    participant AuthMod as Auth Module
    participant App as Protected App

    Client->>ProxyCtrl: HTTP request
    ProxyCtrl->>ProxyCtrl: determineAuthModules() / getProxyContext()
    ProxyCtrl->>AuthMod: getContextFromAuthModule()
    AuthMod-->>ProxyCtrl: ProxyContext (Host, Proto, Path, Method, Type, IsBrowser)
    ProxyCtrl->>ProxyCtrl: useFriendlyError(proxyCtx)?
    alt Auth passes
        ProxyCtrl->>App: route/proxy request
        App-->>Client: response
    else Auth fails
        ProxyCtrl->>ProxyCtrl: handleError(proxyCtx)
        ProxyCtrl-->>Client: error/redirect
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐰 I stitched a context neat and bright,

Auth modules hum in shared daylight,
Paths converge where logic sings,
Friendly errors and clearer springs,
Hop on — the proxy dances light.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: refactoring the proxy controller with a context-driven approach for handling proxy auth modules (ForwardAuth, ExtAuthz, AuthRequest).

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/proxy-controller
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@steveiliop56 steveiliop56 marked this pull request as ready for review March 14, 2026 11:27
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
internal/controller/proxy_controller_test.go (1)

101-302: Add a browser redirect regression case.

All of these requests omit User-Agent, so the new useFriendlyError branch never executes. One ForwardAuth/ExtAuthz case that asserts the 307 /login or /unauthorized response would cover the main new behavior here, and it can double as a regression test for preserving x-original-url query strings.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/controller/proxy_controller_test.go` around lines 101 - 302, Add a
regression test in TestProxyHandler that exercises the new useFriendlyError
branch by sending a logged-out browser-like request (set a common User-Agent
header, e.g. "Mozilla/5.0") to one of the forward auth/ext_authz endpoints (use
the existing "/api/auth/traefik" or "/api/auth/envoy" case), include the same
upstream URL header(s) used in other tests
(x-forwarded-host/x-forwarded-proto/x-forwarded-uri or Host + x-forwarded-proto)
and assert the handler responds with a 307 redirect and that the Location header
points to the friendly login/unauthorized path ("/login" or "/unauthorized") and
preserves the original upstream URL as a query string (e.g., x-original-url or
return_to). Place this new case near the logged-out tests so it runs with the
same setup used by setupProxyController and refers to TestProxyHandler,
setupProxyController, and the specific route "/api/auth/traefik" or
"/api/auth/envoy".
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@internal/controller/proxy_controller.go`:
- Around line 457-459: The Trace log is currently dumping c.Request.Header via
tlog.App.Trace().Interface("headers", c.Request.Header), which exposes sensitive
values; replace this with a sanitized headers map by either building an
allowlist of safe header names (e.g.
"Content-Type","User-Agent","Accept","Host","X-Request-ID") and only logging
those, or by copying c.Request.Header and redacting sensitive keys
("Authorization","Cookie","Set-Cookie","X-Forwarded-For","X-Auth-*" etc.) before
passing the map to tlog.App.Trace(); update the call site that invokes
tlog.App.Trace().Interface("headers", ...) in proxy_controller.go to use the
sanitized map instead.
- Around line 412-421: determineAuthModules currently defaults unknown proxy
names to ForwardAuth which masks typos; change determineAuthModules on
ProxyController to return an error for unsupported proxy names (e.g., return
([]AuthModuleType, error)) instead of a default slice, update the caller in
proxyHandler to check that error and respond with 400 when unsupported, and
apply the same change to the other proxy-name switch in this file (the other
function handling proxy-based decisions) so all unknown proxy names are rejected
rather than mapped to ForwardAuth.
- Around line 362-379: The parsed xOriginalUrl must be validated as an absolute
URL and its query string preserved: after calling url.Parse(xOriginalUrl) (in
getAuthRequestContext), check that parsed.Scheme and parsed.Host are non-empty
and return an error if they are missing (so relative URLs don't produce an empty
Host/Proto), and include parsed.RawQuery when constructing the ProxyContext.Path
or when later building RedirectURI so query parameters are preserved; update the
code that returns ProxyContext (fields Host, Proto, Path, Method,
Type=AuthRequest) to use parsed.Path + "?" + parsed.RawQuery (when RawQuery is
non-empty) or otherwise keep parsed.Path.

---

Nitpick comments:
In `@internal/controller/proxy_controller_test.go`:
- Around line 101-302: Add a regression test in TestProxyHandler that exercises
the new useFriendlyError branch by sending a logged-out browser-like request
(set a common User-Agent header, e.g. "Mozilla/5.0") to one of the forward
auth/ext_authz endpoints (use the existing "/api/auth/traefik" or
"/api/auth/envoy" case), include the same upstream URL header(s) used in other
tests (x-forwarded-host/x-forwarded-proto/x-forwarded-uri or Host +
x-forwarded-proto) and assert the handler responds with a 307 redirect and that
the Location header points to the friendly login/unauthorized path ("/login" or
"/unauthorized") and preserves the original upstream URL as a query string
(e.g., x-original-url or return_to). Place this new case near the logged-out
tests so it runs with the same setup used by setupProxyController and refers to
TestProxyHandler, setupProxyController, and the specific route
"/api/auth/traefik" or "/api/auth/envoy".

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c65afbf0-c572-4518-ae08-b5688f78c753

📥 Commits

Reviewing files that changed from the base of the PR and between 03f13ef and 1c7ef96.

📒 Files selected for processing (2)
  • internal/controller/proxy_controller.go
  • internal/controller/proxy_controller_test.go

@codecov
Copy link

codecov bot commented Mar 14, 2026

Codecov Report

❌ Patch coverage is 75.55556% with 33 lines in your changes missing coverage. Please review.
✅ Project coverage is 16.85%. Comparing base (03f13ef) to head (b98fa34).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
internal/controller/proxy_controller.go 75.55% 24 Missing and 9 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #714      +/-   ##
==========================================
+ Coverage   15.20%   16.85%   +1.65%     
==========================================
  Files          50       50              
  Lines        3748     3820      +72     
==========================================
+ Hits          570      644      +74     
+ Misses       3117     3112       -5     
- Partials       61       64       +3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
internal/controller/proxy_controller.go (1)

132-134: Extract resource-name derivation into one helper.

strings.Split(proxyCtx.Host, ".")[0] is repeated in multiple branches. Centralizing this avoids drift and makes it easier to normalize host formats (e.g., host with port) in one place.

Also applies to: 166-167, 177-178, 206-207, 217-218

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/controller/proxy_controller.go` around lines 132 - 134, Repeated
extraction of the resource name using strings.Split(proxyCtx.Host, ".")[0]
should be centralized: add a helper function (e.g., deriveResourceFromHost(host
string) string) that normalizes the host (trim whitespace, strip port via
net.SplitHostPort or strings.Split on ':' when needed, handle empty host) and
returns the left-most label; then replace all inline occurrences in
proxy_controller.go (places building UnauthorizedQuery and any other branches
referencing proxyCtx.Host) with calls to deriveResourceFromHost(proxyCtx.Host)
so normalization and future changes live in one place.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@internal/controller/proxy_controller.go`:
- Around line 353-388: getAuthRequestContext currently errors when
x-original-url is a path-only value; change it to accept path-only auth_request
flows by treating the header as a path if url.Parse yields no scheme/host: keep
extracting Path from the parsed URL (or use the raw header if parsing fails to
produce a Path), and avoid returning errors for empty host/proto for
AuthRequest; instead populate Host from c.Request.Host (or the Host header) and
Proto from X-Forwarded-Proto or c.Request.TLS (default "http"/"https") before
returning the ProxyContext (note function getAuthRequestContext and struct
fields Host, Proto, Path, Type (AuthRequest)).

---

Nitpick comments:
In `@internal/controller/proxy_controller.go`:
- Around line 132-134: Repeated extraction of the resource name using
strings.Split(proxyCtx.Host, ".")[0] should be centralized: add a helper
function (e.g., deriveResourceFromHost(host string) string) that normalizes the
host (trim whitespace, strip port via net.SplitHostPort or strings.Split on ':'
when needed, handle empty host) and returns the left-most label; then replace
all inline occurrences in proxy_controller.go (places building UnauthorizedQuery
and any other branches referencing proxyCtx.Host) with calls to
deriveResourceFromHost(proxyCtx.Host) so normalization and future changes live
in one place.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 67a7107d-c707-445e-b970-52811754e7ef

📥 Commits

Reviewing files that changed from the base of the PR and between 1c7ef96 and b98fa34.

📒 Files selected for processing (1)
  • internal/controller/proxy_controller.go

@steveiliop56 steveiliop56 merged commit dc3fa58 into main Mar 14, 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.

1 participant