httputil

package
v0.8.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 6, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Index

Constants

View Source
const (
	GrantTypeTokenExchange = "urn:ietf:params:oauth:grant-type:token-exchange" //nolint:gosec // G101: an OAuth grant_type URN, not a credential
	TokenTypeAccessToken   = "urn:ietf:params:oauth:token-type:access_token"   //nolint:gosec // G101: an RFC 8693 token-type URN, not a credential
)

RFC 8693 grant + token-type URNs. Re-export the literals so callers composing /oauth/token forms don't keep parallel copies. Lifted out of core/repoadmin and core/api during COR-337 cleanup.

View Source
const OAuthClientID = "entire-cli"

OAuthClientID is the public OAuth client_id the CLI identifies as on /oauth/token. Lifted into Basic auth by PostOAuthToken.

Variables

This section is empty.

Functions

func BodyReader

func BodyReader(body []byte) io.ReadCloser

BodyReader wraps a buffered request body so http.Request.Body / GetBody can replay it across a retry. Pair with BufferRequestBody.

func BufferRequestBody

func BufferRequestBody(req *http.Request) ([]byte, error)

BufferRequestBody reads the request body once so a fallback retry can replay it. http.NoBody (and nil) short-circuits — both signal "no body" but only the latter is a runtime nil, so the explicit identity check keeps the cloned request's Content-Length correct on the wire. Returns (nil, nil) for no-body requests; the caller can safely forward without replay state.

func PostOAuthToken

func PostOAuthToken(ctx context.Context, httpClient *http.Client, coreURL string, form url.Values) (accessToken string, expiresIn int, err error)

PostOAuthToken posts a form-encoded request to coreURL+"/oauth/token" and parses the standard {access_token, expires_in} response. Callers build the form (grant_type, subject_token, audience, etc.) so the helper stays neutral about which OAuth grant is being exercised.

If the form carries client_id (and optionally client_secret), the helper lifts both into an HTTP Basic Authorization header and drops them from the form body. zitadel/oidc's token endpoint reads client credentials only from Basic auth, so form-only client_id produces invalid_client even when the form is otherwise well-formed. Both values are url.QueryEscaped per RFC 6749 §2.3.1 because pkg/op QueryUnescapes them on the other side — a raw '+'/'%xx' would round-trip to a different value and fail invalid_client (matches core/api/token_endpoint.go).

coreURL must already be trimmed of any trailing slash. A non-200 response is surfaced as *OAuthError (RFC 6749 defines token-endpoint success as 200 only); transport and decode failures are wrapped plain errors.

func TokenExchangeForm added in v0.8.0

func TokenExchangeForm(subjectToken, audience, scope string) url.Values

TokenExchangeForm builds the RFC 8693 token-exchange form every CLI exchange POSTs to /oauth/token: subjectToken (the login JWT) is traded for an access token pinned to audience with the given scope. The one form shape serves repo-scoped and jurisdiction tokens alike — only audience and scope differ — so keep call sites on this builder rather than open-coding the fields.

Types

type OAuthError

type OAuthError struct {
	Status      int
	Code        string // RFC 6749 `error` code from the response body; "" when not present
	Description string // RFC 6749 `error_description` from the response body; "" when not present
	Body        string
}

OAuthError is returned by PostOAuthToken when the OAuth endpoint responds with a non-200 status. Callers can errors.As it to surface status-specific UX (e.g. a friendly 403 message) or branch on the RFC 6749 error code.

func (*OAuthError) Error

func (e *OAuthError) Error() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL