pub async fn resolve_client(
http: &Client,
cache: &dyn ClientMetadataCache,
client_id: &str,
loopback: LoopbackClients,
) -> Result<(ClientMetadataDocument, ClientKey), ClientMetadataError>Expand description
Fetches, validates, and caches the client metadata document for
client_id.
A cache hit skips the network entirely. A miss fetches over http,
validates the result, and stores it — keyed by the URL, carrying the
content key — before returning it. A confidential client’s jwks_uri is
fetched on the same miss, under the same bounds, and cached with the
document, so its keys are read again whenever the document is.
client_id is attacker-chosen on the one endpoint that reaches this
(crate::oauth::par, which is unauthenticated), so the fetch is bounded
here rather than left to whichever client is passed: the host must
resolve to a public address (didbot_http::REFUSED_BLOCKS) and the
fetch connects to the addresses that check approved,
FETCH_TIMEOUT is a
per-request total deadline, MAX_DOCUMENT_BYTES bounds the body, no
redirect is followed at all — see ClientMetadataError::Redirected —
and only a 200 OK served as application/json is read.
http makes the fetch only on a deployment that reaches its own machine
(LoopbackClients::Fetched); every other one fetches through
pinned_public_client.
Every variant this returns reaches POST /oauth/par’s caller as one
sentence that names none of them — see
crate::oauth::par::ParError::ClientMetadata — so the distinctions
here are for this deployment’s own log.