package oauth import "net/http" // OAuthError is a standard RFC 6749 / OAuth 2.1 error: a stable machine code plus // a human description, rendered as {"error":...,"error_description":...}. type OAuthError struct { Code string `json:"error"` Description string `json:"error_description,omitempty"` HTTPStatus int `json:"-"` } func (e *OAuthError) Error() string { return e.Code + ": " + e.Description } func newOAuthError(status int, code, desc string) *OAuthError { return &OAuthError{Code: code, Description: desc, HTTPStatus: status} } // The error constructors below cover every code the authorize + token endpoints // can emit. Status codes follow RFC 6749 §5.2 (invalid_client is 401, the rest // of the request errors are 400). func errInvalidRequest(desc string) *OAuthError { return newOAuthError(http.StatusBadRequest, "invalid_request", desc) } func errInvalidClient(desc string) *OAuthError { return newOAuthError(http.StatusUnauthorized, "invalid_client", desc) } func errInvalidGrant(desc string) *OAuthError { return newOAuthError(http.StatusBadRequest, "invalid_grant", desc) } func errUnauthorizedClient(desc string) *OAuthError { return newOAuthError(http.StatusBadRequest, "unauthorized_client", desc) } func errUnsupportedGrantType(desc string) *OAuthError { return newOAuthError(http.StatusBadRequest, "unsupported_grant_type", desc) } func errInvalidScope(desc string) *OAuthError { return newOAuthError(http.StatusBadRequest, "invalid_scope", desc) } func errAccessDenied(desc string) *OAuthError { return newOAuthError(http.StatusForbidden, "access_denied", desc) } func errServer(desc string) *OAuthError { return newOAuthError(http.StatusInternalServerError, "server_error", desc) } // Dynamic Client Registration errors (RFC 7591 §3.2.2). func errInvalidRedirectURI(desc string) *OAuthError { return newOAuthError(http.StatusBadRequest, "invalid_redirect_uri", desc) } func errInvalidClientMetadata(desc string) *OAuthError { return newOAuthError(http.StatusBadRequest, "invalid_client_metadata", desc) } // errTooManyRegistrations throttles the open (unauthenticated) registration // endpoint per source IP so it can't be used to bloat the clients table. func errTooManyRegistrations() *OAuthError { return newOAuthError(http.StatusTooManyRequests, "temporarily_unavailable", "registration rate limit exceeded, retry later") }