👽 Refactored metadata support due IndieAuth spec changes
This commit is contained in:
parent
0dcfdfc1ac
commit
02c459b5c2
|
@ -13,58 +13,51 @@ import (
|
||||||
type (
|
type (
|
||||||
//nolint: tagliatelle // https://indieauth.net/source/#indieauth-server-metadata
|
//nolint: tagliatelle // https://indieauth.net/source/#indieauth-server-metadata
|
||||||
MetadataResponse struct {
|
MetadataResponse struct {
|
||||||
// The server's issuer identifier. The issuer identifier is a
|
// The server's issuer identifier.
|
||||||
// URL that uses the "https" scheme and has no query or fragment
|
Issuer string `json:"issuer"`
|
||||||
// components. The identifier MUST be a prefix of the
|
|
||||||
// indieauth-metadata URL. e.g. for an indieauth-metadata
|
|
||||||
// endpoint
|
|
||||||
// https://example.com/.well-known/oauth-authorization-server,
|
|
||||||
// the issuer URL could be https://example.com/, or for a
|
|
||||||
// metadata URL of
|
|
||||||
// https://example.com/wp-json/indieauth/1.0/metadata, the
|
|
||||||
// issuer URL could be https://example.com/wp-json/indieauth/1.0
|
|
||||||
Issuer *domain.ClientID `json:"issuer"`
|
|
||||||
|
|
||||||
// The Authorization Endpoint.
|
// The Authorization Endpoint.
|
||||||
AuthorizationEndpoint *domain.URL `json:"authorization_endpoint"`
|
AuthorizationEndpoint string `json:"authorization_endpoint"`
|
||||||
|
|
||||||
// The Token Endpoint.
|
// The Token Endpoint.
|
||||||
TokenEndpoint *domain.URL `json:"token_endpoint"`
|
TokenEndpoint string `json:"token_endpoint"`
|
||||||
|
|
||||||
|
// The Introspection Endpoint.
|
||||||
|
IntrospectionEndpoint string `json:"introspection_endpoint"`
|
||||||
|
|
||||||
|
// JSON array containing a list of client authentication methods
|
||||||
|
// supported by this introspection endpoint.
|
||||||
|
IntrospectionEndpointAuthMethodsSupported []string `json:"introspection_endpoint_auth_methods_supported,omitempty"` //nolint: lll
|
||||||
|
|
||||||
|
// The Revocation Endpoint.
|
||||||
|
RevocationEndpoint string `json:"revocation_endpoint,omitempty"`
|
||||||
|
|
||||||
|
// JSON array containing the value "none".
|
||||||
|
RevocationEndpointAuthMethodsSupported []string `json:"revocation_endpoint_auth_methods_supported,omitempty"` //nolint: lll
|
||||||
|
|
||||||
// JSON array containing scope values supported by the
|
// JSON array containing scope values supported by the
|
||||||
// IndieAuth server. Servers MAY choose not to advertise some
|
// IndieAuth server.
|
||||||
// supported scope values even when this parameter is used.
|
ScopesSupported []string `json:"scopes_supported,omitempty"`
|
||||||
ScopesSupported []domain.Scope `json:"scopes_supported,omitempty"`
|
|
||||||
|
|
||||||
// JSON array containing the response_type values supported.
|
// JSON array containing the response_type values supported.
|
||||||
// This differs from RFC8414 in that this parameter is OPTIONAL
|
ResponseTypesSupported []string `json:"response_types_supported,omitempty"`
|
||||||
// and that, if omitted, the default is code.
|
|
||||||
ResponseTypesSupported []domain.ResponseType `json:"response_types_supported,omitempty"`
|
|
||||||
|
|
||||||
// JSON array containing grant type values supported. If
|
// JSON array containing grant type values supported.
|
||||||
// omitted, the default value differs from RFC8414 and is
|
GrantTypesSupported []string `json:"grant_types_supported,omitempty"`
|
||||||
// authorization_code.
|
|
||||||
GrantTypesSupported []domain.GrantType `json:"grant_types_supported,omitempty"`
|
|
||||||
|
|
||||||
// URL of a page containing human-readable information that
|
// URL of a page containing human-readable information that
|
||||||
// developers might need to know when using the server. This
|
// developers might need to know when using the server.
|
||||||
// might be a link to the IndieAuth spec or something more
|
ServiceDocumentation string `json:"service_documentation,omitempty"`
|
||||||
// personal to your implementation.
|
|
||||||
ServiceDocumentation *domain.URL `json:"service_documentation,omitempty"`
|
|
||||||
|
|
||||||
// JSON array containing the methods supported for PKCE. This
|
// JSON array containing the methods supported for PKCE.
|
||||||
// parameter differs from RFC8414 in that it is not optional as
|
CodeChallengeMethodsSupported []string `json:"code_challenge_methods_supported"`
|
||||||
// PKCE is REQUIRED.
|
|
||||||
CodeChallengeMethodsSupported []domain.CodeChallengeMethod `json:"code_challenge_methods_supported"`
|
|
||||||
|
|
||||||
// Boolean parameter indicating whether the authorization server
|
// Boolean parameter indicating whether the authorization server
|
||||||
// provides the iss parameter. If omitted, the default value is
|
// provides the iss parameter.
|
||||||
// false. As the iss parameter is REQUIRED, this is provided for
|
AuthorizationResponseIssParameterSupported bool `json:"authorization_response_iss_parameter_supported,omitempty"` //nolint: lll
|
||||||
// compatibility with OAuth 2.0 servers implementing the
|
|
||||||
// parameter.
|
// The User Info Endpoint.
|
||||||
//
|
UserinfoEndpoint string `json:"userinfo_endpoint,omitempty"`
|
||||||
//nolint: lll
|
|
||||||
AuthorizationResponseIssParameterSupported bool `json:"authorization_response_iss_parameter_supported,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RequestHandler struct {
|
RequestHandler struct {
|
||||||
|
@ -89,15 +82,45 @@ func (h *RequestHandler) Register(r *router.Router) {
|
||||||
func (h *RequestHandler) read(ctx *http.RequestCtx) {
|
func (h *RequestHandler) read(ctx *http.RequestCtx) {
|
||||||
ctx.SetStatusCode(http.StatusOK)
|
ctx.SetStatusCode(http.StatusOK)
|
||||||
ctx.SetContentType(common.MIMEApplicationJSONCharsetUTF8)
|
ctx.SetContentType(common.MIMEApplicationJSONCharsetUTF8)
|
||||||
|
|
||||||
|
scopes, responseTypes, grantTypes, codeChallengeMethods := make([]string, 0), make([]string, 0),
|
||||||
|
make([]string, 0), make([]string, 0)
|
||||||
|
|
||||||
|
for i := range h.metadata.ScopesSupported {
|
||||||
|
scopes = append(scopes, h.metadata.ScopesSupported[i].String())
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range h.metadata.ResponseTypesSupported {
|
||||||
|
responseTypes = append(responseTypes, h.metadata.ResponseTypesSupported[i].String())
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range h.metadata.GrantTypesSupported {
|
||||||
|
grantTypes = append(grantTypes, h.metadata.GrantTypesSupported[i].String())
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range h.metadata.CodeChallengeMethodsSupported {
|
||||||
|
codeChallengeMethods = append(codeChallengeMethods,
|
||||||
|
h.metadata.CodeChallengeMethodsSupported[i].String())
|
||||||
|
}
|
||||||
|
|
||||||
_ = json.NewEncoder(ctx).Encode(&MetadataResponse{
|
_ = json.NewEncoder(ctx).Encode(&MetadataResponse{
|
||||||
Issuer: h.metadata.Issuer,
|
AuthorizationEndpoint: h.metadata.AuthorizationEndpoint.String(),
|
||||||
AuthorizationEndpoint: h.metadata.AuthorizationEndpoint,
|
IntrospectionEndpoint: h.metadata.IntrospectionEndpoint.String(),
|
||||||
TokenEndpoint: h.metadata.TokenEndpoint,
|
Issuer: h.metadata.Issuer.String(),
|
||||||
ScopesSupported: h.metadata.ScopesSupported,
|
RevocationEndpoint: h.metadata.RevocationEndpoint.String(),
|
||||||
ResponseTypesSupported: h.metadata.ResponseTypesSupported,
|
ServiceDocumentation: h.metadata.ServiceDocumentation.String(),
|
||||||
GrantTypesSupported: h.metadata.GrantTypesSupported,
|
TokenEndpoint: h.metadata.TokenEndpoint.String(),
|
||||||
ServiceDocumentation: h.metadata.ServiceDocumentation,
|
UserinfoEndpoint: h.metadata.UserinfoEndpoint.String(),
|
||||||
CodeChallengeMethodsSupported: h.metadata.CodeChallengeMethodsSupported,
|
|
||||||
AuthorizationResponseIssParameterSupported: h.metadata.AuthorizationResponseIssParameterSupported,
|
AuthorizationResponseIssParameterSupported: h.metadata.AuthorizationResponseIssParameterSupported,
|
||||||
|
CodeChallengeMethodsSupported: codeChallengeMethods,
|
||||||
|
GrantTypesSupported: grantTypes,
|
||||||
|
IntrospectionEndpointAuthMethodsSupported: h.metadata.IntrospectionEndpointAuthMethodsSupported,
|
||||||
|
ResponseTypesSupported: responseTypes,
|
||||||
|
ScopesSupported: scopes,
|
||||||
|
// NOTE(toby3d): If a revocation endpoint is provided, this
|
||||||
|
// property should also be provided with the value ["none"],
|
||||||
|
// since the omission of this value defaults to
|
||||||
|
// client_secret_basic according to RFC8414.
|
||||||
|
RevocationEndpointAuthMethodsSupported: h.metadata.RevocationEndpointAuthMethodsSupported,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,6 @@ func TestMetadata(t *testing.T) {
|
||||||
|
|
||||||
result := new(delivery.MetadataResponse)
|
result := new(delivery.MetadataResponse)
|
||||||
if err = json.Unmarshal(body, result); err != nil {
|
if err = json.Unmarshal(body, result); err != nil {
|
||||||
e := err.(*json.SyntaxError)
|
t.Fatal(err)
|
||||||
t.Fatalf("%s#ERROR#%s", body[:e.Offset], body[e.Offset:])
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
13
main.go
13
main.go
|
@ -283,6 +283,15 @@ func (app *App) Register(r *router.Router) {
|
||||||
Issuer: indieAuthClient.ID,
|
Issuer: indieAuthClient.ID,
|
||||||
AuthorizationEndpoint: domain.MustParseURL(indieAuthClient.ID.String() + "authorize"),
|
AuthorizationEndpoint: domain.MustParseURL(indieAuthClient.ID.String() + "authorize"),
|
||||||
TokenEndpoint: domain.MustParseURL(indieAuthClient.ID.String() + "token"),
|
TokenEndpoint: domain.MustParseURL(indieAuthClient.ID.String() + "token"),
|
||||||
|
TicketEndpoint: domain.MustParseURL(indieAuthClient.ID.String() + "ticket"),
|
||||||
|
MicropubEndpoint: nil,
|
||||||
|
MicrosubEndpoint: nil,
|
||||||
|
IntrospectionEndpoint: domain.MustParseURL(indieAuthClient.ID.String() + "introspect"),
|
||||||
|
RevocationEndpoint: domain.MustParseURL(indieAuthClient.ID.String() + "revocation"),
|
||||||
|
UserinfoEndpoint: domain.MustParseURL(indieAuthClient.ID.String() + "userinfo"),
|
||||||
|
ServiceDocumentation: domain.MustParseURL("https://indieauth.net/source/"),
|
||||||
|
IntrospectionEndpointAuthMethodsSupported: []string{"Bearer"},
|
||||||
|
RevocationEndpointAuthMethodsSupported: []string{"none"},
|
||||||
ScopesSupported: domain.Scopes{
|
ScopesSupported: domain.Scopes{
|
||||||
domain.ScopeBlock,
|
domain.ScopeBlock,
|
||||||
domain.ScopeChannels,
|
domain.ScopeChannels,
|
||||||
|
@ -305,7 +314,6 @@ func (app *App) Register(r *router.Router) {
|
||||||
domain.GrantTypeAuthorizationCode,
|
domain.GrantTypeAuthorizationCode,
|
||||||
domain.GrantTypeTicket,
|
domain.GrantTypeTicket,
|
||||||
},
|
},
|
||||||
ServiceDocumentation: domain.MustParseURL("https://indieauth.net/source/"),
|
|
||||||
CodeChallengeMethodsSupported: []domain.CodeChallengeMethod{
|
CodeChallengeMethodsSupported: []domain.CodeChallengeMethod{
|
||||||
domain.CodeChallengeMethodMD5,
|
domain.CodeChallengeMethodMD5,
|
||||||
domain.CodeChallengeMethodPLAIN,
|
domain.CodeChallengeMethodPLAIN,
|
||||||
|
@ -314,9 +322,6 @@ func (app *App) Register(r *router.Router) {
|
||||||
domain.CodeChallengeMethodS512,
|
domain.CodeChallengeMethodS512,
|
||||||
},
|
},
|
||||||
AuthorizationResponseIssParameterSupported: true,
|
AuthorizationResponseIssParameterSupported: true,
|
||||||
TicketEndpoint: domain.MustParseURL(indieAuthClient.ID.String() + "ticket"),
|
|
||||||
Micropub: nil,
|
|
||||||
Microsub: nil,
|
|
||||||
}).Register(r)
|
}).Register(r)
|
||||||
tokenhttpdelivery.NewRequestHandler(app.tokens, app.tickets).Register(r)
|
tokenhttpdelivery.NewRequestHandler(app.tokens, app.tickets).Register(r)
|
||||||
clienthttpdelivery.NewRequestHandler(clienthttpdelivery.NewRequestHandlerOptions{
|
clienthttpdelivery.NewRequestHandler(clienthttpdelivery.NewRequestHandlerOptions{
|
||||||
|
|
Loading…
Reference in New Issue