Class: Basecamp::Oauth::Discovery
- Inherits:
-
Object
- Object
- Basecamp::Oauth::Discovery
- Defined in:
- lib/basecamp/oauth/discovery.rb
Overview
Fetches RFC 8414 OAuth 2 Authorization Server Metadata and binds the
returned issuer to the requested issuer origin (hop 2 of resource-first
discovery).
Defined Under Namespace
Classes: IssuerBindingError
Instance Method Summary collapse
-
#discover(base_url) ⇒ Config
Discovers OAuth configuration from {base_url}/.well-known/oauth-authorization-server, binding the returned
issuertobase_urlby code-point (RFC 8414 §3.3/§4, no normalization beyond origin-root parsing). -
#discover_advertised(advertised_issuer) ⇒ Object
Resource-first entry: validate
advertised_issueras an origin root, then fetch from the normalized origin and bind the AS metadataissueragainst the RAW advertised string by code-point. -
#initialize(http_client: nil, timeout: 10, max_body_bytes: Fetcher::DEFAULT_MAX_BODY_BYTES) ⇒ Discovery
constructor
A new instance of Discovery.
Constructor Details
#initialize(http_client: nil, timeout: 10, max_body_bytes: Fetcher::DEFAULT_MAX_BODY_BYTES) ⇒ Discovery
Returns a new instance of Discovery.
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/basecamp/oauth/discovery.rb', line 24 def initialize(http_client: nil, timeout: 10, max_body_bytes: Fetcher::DEFAULT_MAX_BODY_BYTES) Fetcher.ensure_redirects_suppressed!(http_client) if http_client # Normalize before building the client and before the fetch computes its # wall-clock deadline: a non-finite/non-positive timeout must not disable # either bound (see Fetcher.normalize_timeout). @timeout = Fetcher.normalize_timeout(timeout) @http_client = http_client || Fetcher.build_client(@timeout) # Normalize the public cap to a finite non-negative Integer: a nil, float, # or Float::INFINITY would otherwise disable the streaming memory bound # (an infinite/undefined cap never trips +total > max_body_bytes+), # reintroducing an SSRF/OOM risk. Mirrors Resource#initialize. @max_body_bytes = if max_body_bytes.is_a?(Integer) && max_body_bytes >= 0 max_body_bytes else Fetcher::DEFAULT_MAX_BODY_BYTES end end |
Instance Method Details
#discover(base_url) ⇒ Config
Discovers OAuth configuration from
{base_url}/.well-known/oauth-authorization-server, binding the
returned issuer to base_url by code-point (RFC 8414 §3.3/§4, no
normalization beyond origin-root parsing). token_endpoint is required;
authorization_endpoint is optional (device-only servers omit it).
57 58 59 60 61 62 |
# File 'lib/basecamp/oauth/discovery.rb', line 57 def discover(base_url) issuer_origin = Basecamp::Security.require_origin_root!(base_url, "OAuth discovery base URL") # Bind against the caller's raw +base_url+ (RFC 8414 §3.3, SPEC.md §16 "NO # normalization"); the normalized origin is only for the fetch URL. discover_and_bind(issuer_origin, base_url) end |
#discover_advertised(advertised_issuer) ⇒ Object
Resource-first entry: validate advertised_issuer as an origin root, then
fetch from the normalized origin and bind the AS metadata issuer against
the RAW advertised string by code-point. Routing and binding are distinct —
an AS whose issuer matches what the resource advertised (e.g. a trailing
slash or explicit default port) binds instead of being normalized away into
a false issuer_mismatch. Validation happens HERE so there is NO public
unvalidated-fetch entry point: the SSRF origin policy is always enforced.
74 75 76 77 |
# File 'lib/basecamp/oauth/discovery.rb', line 74 def discover_advertised(advertised_issuer) issuer_origin = Basecamp::Security.require_origin_root!(advertised_issuer, "advertised issuer") discover_and_bind(issuer_origin, advertised_issuer) end |