• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

stacklok / toolhive / 25043810657

28 Apr 2026 09:01AM UTC coverage: 66.284% (+0.009%) from 66.275%
25043810657

push

github

web-flow
Add pkg/oauth grant-helper primitives (#5045)

Add pkg/oauthproto grant-helper primitives

Extract HTTP plumbing, response decoding, and RFC 6749 error parsing
that are currently duplicated between pkg/auth/tokenexchange and the
new pkg/oauthproto/jwtbearer grant on a feature branch. Landing these
first is a prerequisite for shrinking the JWT Bearer PR under the
400-LOC soft cap in CLAUDE.md.

pkg/oauthproto/grants.go consolidates:

- A process-wide *http.Client with 30s / 10s / 10s timeouts, matching
  pkg/auth/oauth/dynamic_registration.go. Deliberately not routed
  through pkg/networking.NewHttpClientBuilder, whose SSRF dialer
  control blocks 127.0.0.1 and would break every httptest.NewServer
  test as well as localhost-hosted IdPs used in development.

- TokenResponse plus ParseTokenResponse as the single entry point for
  decoding a token endpoint body, enforcing RFC 6749 Sections 5.1 and
  5.2 together. Body is decoded unconditionally so a 2xx response that
  carries an "error" field still routes to *oauth2.RetrieveError, as
  the spec requires and as x/oauth2 internal.RetrieveToken does.

- The tokenJSON wire struct and expirationTime.UnmarshalJSON are
  copied (with attribution) from x/oauth2/internal/token.go so that
  expires_in decodes from both JSON numbers and JSON strings. Naively
  embedding *oauth2.Token into TokenResponse would fail on the string
  form and silently leave Expiry zero; composition keeps the public
  surface stable and avoids leaking oauth2.Token's Valid / Extra /
  Type methods.

- NewFormRequest and DoTokenRequest mirror x/oauth2/internal helpers
  so that each grant's Token() method collapses to a request build
  plus a single high-level execute-and-parse call. DoTokenRequest
  reads the body through an io.LimitReader capped at 1 MiB and then
  closes without draining, matching x/oauth2/internal/token.go.
  Draining via io.Copy(io.Discard, resp.Body) is deliberately avoided
  because it would be unbounded on oversiz... (continued)

132 of 188 new or added lines in 2 files covered. (70.21%)

7 existing lines in 3 files now uncovered.

59806 of 90227 relevant lines covered (66.28%)

62.15 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

79.38
/pkg/transport/proxy/httpsse/http_proxy.go


Source Not Available

STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc