🎨 Format of the exist code before refactoring
This commit is contained in:
parent
e494526389
commit
6a1e281ebb
|
@ -159,12 +159,12 @@ func (h *RequestHandler) Register(r *router.Router) {
|
|||
middleware.LogFmt(),
|
||||
}
|
||||
|
||||
r.GET("/authorize", chain.RequestHandler(h.handleRender))
|
||||
r.GET("/authorize", chain.RequestHandler(h.handleAuthorize))
|
||||
r.POST("/api/authorize", chain.RequestHandler(h.handleVerify))
|
||||
r.POST("/authorize", chain.RequestHandler(h.handleExchange))
|
||||
}
|
||||
|
||||
func (h *RequestHandler) handleRender(ctx *http.RequestCtx) {
|
||||
func (h *RequestHandler) handleAuthorize(ctx *http.RequestCtx) {
|
||||
ctx.SetContentType(common.MIMETextHTMLCharsetUTF8)
|
||||
|
||||
tags, _, _ := language.ParseAcceptLanguage(string(ctx.Request.Header.Peek(http.HeaderAcceptLanguage)))
|
||||
|
|
|
@ -35,7 +35,7 @@ type Dependencies struct {
|
|||
store *sync.Map
|
||||
}
|
||||
|
||||
func TestRender(t *testing.T) {
|
||||
func TestAuthorize(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
deps := NewDependencies(t)
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
//nolint: dupl
|
||||
package domain
|
||||
|
||||
import (
|
||||
|
@ -44,7 +43,7 @@ func ParseAction(uid string) (Action, error) {
|
|||
func (a *Action) UnmarshalForm(v []byte) error {
|
||||
action, err := ParseAction(string(v))
|
||||
if err != nil {
|
||||
return fmt.Errorf("UnmarshalForm: %w", err)
|
||||
return fmt.Errorf("Action: UnmarshalForm: %w", err)
|
||||
}
|
||||
|
||||
*a = action
|
||||
|
@ -56,12 +55,12 @@ func (a *Action) UnmarshalForm(v []byte) error {
|
|||
func (a *Action) UnmarshalJSON(v []byte) error {
|
||||
src, err := strconv.Unquote(string(v))
|
||||
if err != nil {
|
||||
return fmt.Errorf("UnmarshalJSON: %w", err)
|
||||
return fmt.Errorf("Action: UnmarshalJSON: %w", err)
|
||||
}
|
||||
|
||||
action, err := ParseAction(src)
|
||||
if err != nil {
|
||||
return fmt.Errorf("UnmarshalJSON: %w", err)
|
||||
return fmt.Errorf("Action: UnmarshalJSON: %w", err)
|
||||
}
|
||||
|
||||
*a = action
|
||||
|
|
|
@ -107,7 +107,7 @@ func ParseClientID(src string) (*ClientID, error) {
|
|||
func TestClientID(tb testing.TB) *ClientID {
|
||||
tb.Helper()
|
||||
|
||||
clientID, err := ParseClientID("https://app.example.com/")
|
||||
clientID, err := ParseClientID("https://indieauth.example.com/")
|
||||
if err != nil {
|
||||
tb.Fatal(err)
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ func TestClientID(tb testing.TB) *ClientID {
|
|||
func (cid *ClientID) UnmarshalForm(v []byte) error {
|
||||
clientID, err := ParseClientID(string(v))
|
||||
if err != nil {
|
||||
return fmt.Errorf("UnmarshalForm: %w", err)
|
||||
return fmt.Errorf("ClientID: UnmarshalForm: %w", err)
|
||||
}
|
||||
|
||||
*cid = *clientID
|
||||
|
@ -131,12 +131,12 @@ func (cid *ClientID) UnmarshalForm(v []byte) error {
|
|||
func (cid *ClientID) UnmarshalJSON(v []byte) error {
|
||||
src, err := strconv.Unquote(string(v))
|
||||
if err != nil {
|
||||
return fmt.Errorf("UnmarshalJSON: %w", err)
|
||||
return fmt.Errorf("ClientID: UnmarshalJSON: %w", err)
|
||||
}
|
||||
|
||||
clientID, err := ParseClientID(src)
|
||||
if err != nil {
|
||||
return fmt.Errorf("UnmarshalJSON: %w", err)
|
||||
return fmt.Errorf("ClientID: UnmarshalJSON: %w", err)
|
||||
}
|
||||
|
||||
*cid = *clientID
|
||||
|
|
|
@ -35,15 +35,13 @@ var (
|
|||
}
|
||||
|
||||
CodeChallengeMethodMD5 = CodeChallengeMethod{
|
||||
uid: "MD5",
|
||||
//nolint: gosec // support old clients
|
||||
hash: md5.New(),
|
||||
uid: "MD5",
|
||||
hash: md5.New(), //nolint: gosec // support old clients
|
||||
}
|
||||
|
||||
CodeChallengeMethodS1 = CodeChallengeMethod{
|
||||
uid: "S1",
|
||||
//nolint: gosec // support old clients
|
||||
hash: sha1.New(),
|
||||
uid: "S1",
|
||||
hash: sha1.New(), //nolint: gosec // support old clients
|
||||
}
|
||||
|
||||
CodeChallengeMethodS256 = CodeChallengeMethod{
|
||||
|
@ -64,7 +62,7 @@ var ErrCodeChallengeMethodUnknown error = NewError(
|
|||
)
|
||||
|
||||
//nolint: gochecknoglobals // maps cannot be constants
|
||||
var slugsMethods = map[string]CodeChallengeMethod{
|
||||
var uidsMethods = map[string]CodeChallengeMethod{
|
||||
CodeChallengeMethodMD5.uid: CodeChallengeMethodMD5,
|
||||
CodeChallengeMethodPLAIN.uid: CodeChallengeMethodPLAIN,
|
||||
CodeChallengeMethodS1.uid: CodeChallengeMethodS1,
|
||||
|
@ -75,7 +73,7 @@ var slugsMethods = map[string]CodeChallengeMethod{
|
|||
// ParseCodeChallengeMethod parse string identifier of code challenge method
|
||||
// into struct enum.
|
||||
func ParseCodeChallengeMethod(uid string) (CodeChallengeMethod, error) {
|
||||
if method, ok := slugsMethods[strings.ToUpper(uid)]; ok {
|
||||
if method, ok := uidsMethods[strings.ToUpper(uid)]; ok {
|
||||
return method, nil
|
||||
}
|
||||
|
||||
|
@ -86,7 +84,7 @@ func ParseCodeChallengeMethod(uid string) (CodeChallengeMethod, error) {
|
|||
func (ccm *CodeChallengeMethod) UnmarshalForm(v []byte) error {
|
||||
method, err := ParseCodeChallengeMethod(string(v))
|
||||
if err != nil {
|
||||
return fmt.Errorf("UnmarshalForm: %w", err)
|
||||
return fmt.Errorf("CodeChallengeMethod: UnmarshalForm: %w", err)
|
||||
}
|
||||
|
||||
*ccm = method
|
||||
|
@ -98,12 +96,12 @@ func (ccm *CodeChallengeMethod) UnmarshalForm(v []byte) error {
|
|||
func (ccm *CodeChallengeMethod) UnmarshalJSON(v []byte) error {
|
||||
src, err := strconv.Unquote(string(v))
|
||||
if err != nil {
|
||||
return fmt.Errorf("UnmarshalJSON: %w", err)
|
||||
return fmt.Errorf("CodeChallengeMethod: UnmarshalJSON: %w", err)
|
||||
}
|
||||
|
||||
method, err := ParseCodeChallengeMethod(src)
|
||||
if err != nil {
|
||||
return fmt.Errorf("UnmarshalJSON: %w", err)
|
||||
return fmt.Errorf("CodeChallengeMethod: UnmarshalJSON: %w", err)
|
||||
}
|
||||
|
||||
*ccm = method
|
||||
|
@ -111,6 +109,10 @@ func (ccm *CodeChallengeMethod) UnmarshalJSON(v []byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (ccm CodeChallengeMethod) MarshalJSON() ([]byte, error) {
|
||||
return []byte(strconv.Quote(ccm.uid)), nil
|
||||
}
|
||||
|
||||
// String returns string representation of code challenge method.
|
||||
func (ccm CodeChallengeMethod) String() string {
|
||||
return ccm.uid
|
||||
|
|
|
@ -46,7 +46,7 @@ func ParseGrantType(uid string) (GrantType, error) {
|
|||
func (gt *GrantType) UnmarshalForm(src []byte) error {
|
||||
responseType, err := ParseGrantType(string(src))
|
||||
if err != nil {
|
||||
return fmt.Errorf("UnmarshalForm: %w", err)
|
||||
return fmt.Errorf("GrantType: UnmarshalForm: %w", err)
|
||||
}
|
||||
|
||||
*gt = responseType
|
||||
|
@ -58,12 +58,12 @@ func (gt *GrantType) UnmarshalForm(src []byte) error {
|
|||
func (gt *GrantType) UnmarshalJSON(v []byte) error {
|
||||
src, err := strconv.Unquote(string(v))
|
||||
if err != nil {
|
||||
return fmt.Errorf("UnmarshalJSON: %w", err)
|
||||
return fmt.Errorf("GrantType: UnmarshalJSON: %w", err)
|
||||
}
|
||||
|
||||
responseType, err := ParseGrantType(src)
|
||||
if err != nil {
|
||||
return fmt.Errorf("UnmarshalJSON: %w", err)
|
||||
return fmt.Errorf("GrantType: UnmarshalJSON: %w", err)
|
||||
}
|
||||
|
||||
*gt = responseType
|
||||
|
@ -71,6 +71,10 @@ func (gt *GrantType) UnmarshalJSON(v []byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (gt GrantType) MarshalJSON() ([]byte, error) {
|
||||
return []byte(strconv.Quote(gt.uid)), nil
|
||||
}
|
||||
|
||||
// String returns string representation of grant type.
|
||||
func (gt GrantType) String() string {
|
||||
return gt.uid
|
||||
|
|
|
@ -115,7 +115,7 @@ func TestMe(tb testing.TB, src string) *Me {
|
|||
func (m *Me) UnmarshalForm(v []byte) error {
|
||||
me, err := ParseMe(string(v))
|
||||
if err != nil {
|
||||
return fmt.Errorf("UnmarshalForm: %w", err)
|
||||
return fmt.Errorf("Me: UnmarshalForm: %w", err)
|
||||
}
|
||||
|
||||
*m = *me
|
||||
|
@ -127,12 +127,12 @@ func (m *Me) UnmarshalForm(v []byte) error {
|
|||
func (m *Me) UnmarshalJSON(v []byte) error {
|
||||
src, err := strconv.Unquote(string(v))
|
||||
if err != nil {
|
||||
return fmt.Errorf("UnmarshalJSON: %w", err)
|
||||
return fmt.Errorf("Me: UnmarshalJSON: %w", err)
|
||||
}
|
||||
|
||||
me, err := ParseMe(src)
|
||||
if err != nil {
|
||||
return fmt.Errorf("UnmarshalJSON: %w", err)
|
||||
return fmt.Errorf("Me: UnmarshalJSON: %w", err)
|
||||
}
|
||||
|
||||
*m = *me
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package domain
|
||||
|
||||
import "testing"
|
||||
|
||||
//nolint: tagliatelle // https://indieauth.net/source/#indieauth-server-metadata
|
||||
type Metadata struct {
|
||||
// The server's issuer identifier. The issuer identifier is a URL that
|
||||
|
@ -10,7 +12,7 @@ type Metadata struct {
|
|||
// 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 *URL `json:"issuer"`
|
||||
Issuer *ClientID `json:"issuer"`
|
||||
|
||||
// The Authorization Endpoint.
|
||||
AuthorizationEndpoint *URL `json:"authorization_endpoint"`
|
||||
|
@ -60,3 +62,48 @@ type Metadata struct {
|
|||
// WARN(toby3d): experimental
|
||||
Microsub *URL `json:"microsub,omitempty"`
|
||||
}
|
||||
|
||||
// TestMetadata returns valid random generated Metadata for tests.
|
||||
func TestMetadata(tb testing.TB) *Metadata {
|
||||
tb.Helper()
|
||||
|
||||
return &Metadata{
|
||||
Issuer: TestClientID(tb),
|
||||
AuthorizationEndpoint: TestURL(tb, "https://indieauth.example.com/auth"),
|
||||
TokenEndpoint: TestURL(tb, "https://indieauth.example.com/token"),
|
||||
ScopesSupported: Scopes{
|
||||
ScopeBlock,
|
||||
ScopeChannels,
|
||||
ScopeCreate,
|
||||
ScopeDelete,
|
||||
ScopeDraft,
|
||||
ScopeEmail,
|
||||
ScopeFollow,
|
||||
ScopeMedia,
|
||||
ScopeMute,
|
||||
ScopeProfile,
|
||||
ScopeRead,
|
||||
ScopeUpdate,
|
||||
},
|
||||
ResponseTypesSupported: []ResponseType{
|
||||
ResponseTypeCode,
|
||||
ResponseTypeID,
|
||||
},
|
||||
GrantTypesSupported: []GrantType{
|
||||
GrantTypeAuthorizationCode,
|
||||
GrantTypeTicket,
|
||||
},
|
||||
ServiceDocumentation: TestURL(tb, "https://indieauth.net/draft/"),
|
||||
CodeChallengeMethodsSupported: []CodeChallengeMethod{
|
||||
CodeChallengeMethodMD5,
|
||||
CodeChallengeMethodPLAIN,
|
||||
CodeChallengeMethodS1,
|
||||
CodeChallengeMethodS256,
|
||||
CodeChallengeMethodS512,
|
||||
},
|
||||
AuthorizationResponseIssParameterSupported: true,
|
||||
TicketEndpoint: TestURL(tb, "https://auth.example.org/ticket"),
|
||||
Micropub: TestURL(tb, "https://example.com/micropub"),
|
||||
Microsub: TestURL(tb, "https://example.com/microsub"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
//nolint: dupl
|
||||
package domain
|
||||
|
||||
import (
|
||||
|
@ -51,7 +50,7 @@ func ParseResponseType(uid string) (ResponseType, error) {
|
|||
func (rt *ResponseType) UnmarshalForm(src []byte) error {
|
||||
responseType, err := ParseResponseType(string(src))
|
||||
if err != nil {
|
||||
return fmt.Errorf("UnmarshalForm: %w", err)
|
||||
return fmt.Errorf("ResponseType: UnmarshalForm: %w", err)
|
||||
}
|
||||
|
||||
*rt = responseType
|
||||
|
@ -63,12 +62,12 @@ func (rt *ResponseType) UnmarshalForm(src []byte) error {
|
|||
func (rt *ResponseType) UnmarshalJSON(v []byte) error {
|
||||
uid, err := strconv.Unquote(string(v))
|
||||
if err != nil {
|
||||
return fmt.Errorf("UnmarshalJSON: %w", err)
|
||||
return fmt.Errorf("ResponseType: UnmarshalJSON: %w", err)
|
||||
}
|
||||
|
||||
responseType, err := ParseResponseType(uid)
|
||||
if err != nil {
|
||||
return fmt.Errorf("UnmarshalJSON: %w", err)
|
||||
return fmt.Errorf("ResponseType: UnmarshalJSON: %w", err)
|
||||
}
|
||||
|
||||
*rt = responseType
|
||||
|
@ -76,6 +75,10 @@ func (rt *ResponseType) UnmarshalJSON(v []byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (rt ResponseType) MarshalJSON() ([]byte, error) {
|
||||
return []byte(strconv.Quote(rt.uid)), nil
|
||||
}
|
||||
|
||||
// String returns string representation of response type.
|
||||
func (rt ResponseType) String() string {
|
||||
return rt.uid
|
||||
|
|
|
@ -81,6 +81,15 @@ func ParseScope(uid string) (Scope, error) {
|
|||
return ScopeUndefined, fmt.Errorf("%w: %s", ErrScopeUnknown, uid)
|
||||
}
|
||||
|
||||
func (s Scope) MarshalJSON() ([]byte, error) {
|
||||
return []byte(strconv.Quote(s.uid)), nil
|
||||
}
|
||||
|
||||
// String returns string representation of scope.
|
||||
func (s Scope) String() string {
|
||||
return s.uid
|
||||
}
|
||||
|
||||
// UnmarshalForm implements custom unmarshler for form values.
|
||||
func (s *Scopes) UnmarshalForm(v []byte) error {
|
||||
scopes := make(Scopes, 0)
|
||||
|
@ -88,7 +97,7 @@ func (s *Scopes) UnmarshalForm(v []byte) error {
|
|||
for _, rawScope := range strings.Fields(string(v)) {
|
||||
scope, err := ParseScope(rawScope)
|
||||
if err != nil {
|
||||
return fmt.Errorf("UnmarshalForm: %w", err)
|
||||
return fmt.Errorf("Scopes: UnmarshalForm: %w", err)
|
||||
}
|
||||
|
||||
if scopes.Has(scope) {
|
||||
|
@ -107,7 +116,7 @@ func (s *Scopes) UnmarshalForm(v []byte) error {
|
|||
func (s *Scopes) UnmarshalJSON(v []byte) error {
|
||||
src, err := strconv.Unquote(string(v))
|
||||
if err != nil {
|
||||
return fmt.Errorf("UnmarshalJSON: %w", err)
|
||||
return fmt.Errorf("Scopes: UnmarshalJSON: %w", err)
|
||||
}
|
||||
|
||||
result := make(Scopes, 0)
|
||||
|
@ -115,7 +124,7 @@ func (s *Scopes) UnmarshalJSON(v []byte) error {
|
|||
for _, rawScope := range strings.Fields(src) {
|
||||
scope, err := ParseScope(rawScope)
|
||||
if err != nil {
|
||||
return fmt.Errorf("UnmarshalJSON: %w", err)
|
||||
return fmt.Errorf("Scopes: UnmarshalJSON: %w", err)
|
||||
}
|
||||
|
||||
if result.Has(scope) {
|
||||
|
@ -141,11 +150,6 @@ func (s Scopes) MarshalJSON() ([]byte, error) {
|
|||
return []byte(strconv.Quote(strings.Join(scopes, " "))), nil
|
||||
}
|
||||
|
||||
// String returns string representation of scope.
|
||||
func (s Scope) String() string {
|
||||
return s.uid
|
||||
}
|
||||
|
||||
// String returns string representation of scopes.
|
||||
func (s Scopes) String() string {
|
||||
scopes := make([]string, len(s))
|
||||
|
|
|
@ -14,7 +14,7 @@ type URL struct {
|
|||
*http.URI
|
||||
}
|
||||
|
||||
// ParseURL parse strings as URL.
|
||||
// ParseURL parse string as URL.
|
||||
func ParseURL(src string) (*URL, error) {
|
||||
u := http.AcquireURI()
|
||||
if err := u.Parse(nil, []byte(src)); err != nil {
|
||||
|
@ -24,6 +24,16 @@ func ParseURL(src string) (*URL, error) {
|
|||
return &URL{URI: u}, nil
|
||||
}
|
||||
|
||||
// MustParseURL parse string as URL or panic.
|
||||
func MustParseURL(src string) *URL {
|
||||
uri, err := ParseURL(src)
|
||||
if err != nil {
|
||||
panic("MustParseURL: " + err.Error())
|
||||
}
|
||||
|
||||
return uri
|
||||
}
|
||||
|
||||
// TestURL returns URL of provided input for tests.
|
||||
func TestURL(tb testing.TB, src string) *URL {
|
||||
tb.Helper()
|
||||
|
@ -40,7 +50,7 @@ func TestURL(tb testing.TB, src string) *URL {
|
|||
func (u *URL) UnmarshalForm(v []byte) error {
|
||||
url, err := ParseURL(string(v))
|
||||
if err != nil {
|
||||
return fmt.Errorf("UnmarshalForm: %w", err)
|
||||
return fmt.Errorf("URL: UnmarshalForm: %w", err)
|
||||
}
|
||||
|
||||
*u = *url
|
||||
|
@ -52,12 +62,12 @@ func (u *URL) UnmarshalForm(v []byte) error {
|
|||
func (u *URL) UnmarshalJSON(v []byte) error {
|
||||
src, err := strconv.Unquote(string(v))
|
||||
if err != nil {
|
||||
return fmt.Errorf("UnmarshalJSON: %w", err)
|
||||
return fmt.Errorf("URL: UnmarshalJSON: %w", err)
|
||||
}
|
||||
|
||||
url, err := ParseURL(src)
|
||||
if err != nil {
|
||||
return fmt.Errorf("UnmarshalJSON: %w", err)
|
||||
return fmt.Errorf("URL: UnmarshalJSON: %w", err)
|
||||
}
|
||||
|
||||
*u = *url
|
||||
|
@ -65,6 +75,10 @@ func (u *URL) UnmarshalJSON(v []byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (u URL) MarshalJSON() ([]byte, error) {
|
||||
return []byte(strconv.Quote(u.String())), nil
|
||||
}
|
||||
|
||||
// URL returns url.URL representation of URL.
|
||||
func (u URL) URL() *url.URL {
|
||||
if u.URI == nil {
|
||||
|
|
|
@ -23,39 +23,39 @@ type (
|
|||
// 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 string `json:"issuer"`
|
||||
Issuer *domain.ClientID `json:"issuer"`
|
||||
|
||||
// The Authorization Endpoint.
|
||||
AuthorizationEndpoint string `json:"authorization_endpoint"`
|
||||
AuthorizationEndpoint *domain.URL `json:"authorization_endpoint"`
|
||||
|
||||
// The Token Endpoint.
|
||||
TokenEndpoint string `json:"token_endpoint"`
|
||||
TokenEndpoint *domain.URL `json:"token_endpoint"`
|
||||
|
||||
// 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
|
||||
// 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.
|
||||
// This differs from RFC8414 in that this parameter is OPTIONAL
|
||||
// and that, if omitted, the default is code.
|
||||
ResponseTypesSupported []string `json:"response_types_supported,omitempty"`
|
||||
ResponseTypesSupported []domain.ResponseType `json:"response_types_supported,omitempty"`
|
||||
|
||||
// JSON array containing grant type values supported. If
|
||||
// omitted, the default value differs from RFC8414 and is
|
||||
// authorization_code.
|
||||
GrantTypesSupported []string `json:"grant_types_supported,omitempty"`
|
||||
GrantTypesSupported []domain.GrantType `json:"grant_types_supported,omitempty"`
|
||||
|
||||
// URL of a page containing human-readable information that
|
||||
// developers might need to know when using the server. This
|
||||
// might be a link to the IndieAuth spec or something more
|
||||
// personal to your implementation.
|
||||
ServiceDocumentation string `json:"service_documentation,omitempty"`
|
||||
ServiceDocumentation *domain.URL `json:"service_documentation,omitempty"`
|
||||
|
||||
// JSON array containing the methods supported for PKCE. This
|
||||
// parameter differs from RFC8414 in that it is not optional as
|
||||
// PKCE is REQUIRED.
|
||||
CodeChallengeMethodsSupported []string `json:"code_challenge_methods_supported"`
|
||||
CodeChallengeMethodsSupported []domain.CodeChallengeMethod `json:"code_challenge_methods_supported"`
|
||||
|
||||
// Boolean parameter indicating whether the authorization server
|
||||
// provides the iss parameter. If omitted, the default value is
|
||||
|
@ -68,52 +68,13 @@ type (
|
|||
}
|
||||
|
||||
RequestHandler struct {
|
||||
config *domain.Config
|
||||
metadata *domain.Metadata
|
||||
}
|
||||
)
|
||||
|
||||
// DefaultMetadataResponse contains all supported types by default.
|
||||
//nolint: gochecknoglobals // structs cannot be constants
|
||||
var DefaultMetadataResponse = MetadataResponse{
|
||||
AuthorizationEndpoint: "",
|
||||
AuthorizationResponseIssParameterSupported: true,
|
||||
CodeChallengeMethodsSupported: []string{
|
||||
domain.CodeChallengeMethodMD5.String(),
|
||||
domain.CodeChallengeMethodPLAIN.String(),
|
||||
domain.CodeChallengeMethodS1.String(),
|
||||
domain.CodeChallengeMethodS256.String(),
|
||||
domain.CodeChallengeMethodS512.String(),
|
||||
},
|
||||
GrantTypesSupported: []string{
|
||||
domain.GrantTypeAuthorizationCode.String(),
|
||||
domain.GrantTypeTicket.String(),
|
||||
},
|
||||
Issuer: "",
|
||||
ResponseTypesSupported: []string{
|
||||
domain.ResponseTypeCode.String(),
|
||||
domain.ResponseTypeID.String(),
|
||||
},
|
||||
ScopesSupported: []string{
|
||||
domain.ScopeBlock.String(),
|
||||
domain.ScopeChannels.String(),
|
||||
domain.ScopeCreate.String(),
|
||||
domain.ScopeDelete.String(),
|
||||
domain.ScopeDraft.String(),
|
||||
domain.ScopeEmail.String(),
|
||||
domain.ScopeFollow.String(),
|
||||
domain.ScopeMedia.String(),
|
||||
domain.ScopeMute.String(),
|
||||
domain.ScopeProfile.String(),
|
||||
domain.ScopeRead.String(),
|
||||
domain.ScopeUpdate.String(),
|
||||
},
|
||||
ServiceDocumentation: "https://indieauth.net/source/",
|
||||
TokenEndpoint: "",
|
||||
}
|
||||
|
||||
func NewRequestHandler(config *domain.Config) *RequestHandler {
|
||||
func NewRequestHandler(metadata *domain.Metadata) *RequestHandler {
|
||||
return &RequestHandler{
|
||||
config: config,
|
||||
metadata: metadata,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,12 +87,17 @@ func (h *RequestHandler) Register(r *router.Router) {
|
|||
}
|
||||
|
||||
func (h *RequestHandler) read(ctx *http.RequestCtx) {
|
||||
resp := DefaultMetadataResponse
|
||||
resp.Issuer = h.config.Server.GetRootURL()
|
||||
resp.AuthorizationEndpoint = resp.Issuer + "authorize"
|
||||
resp.TokenEndpoint = resp.Issuer + "token"
|
||||
|
||||
ctx.SetStatusCode(http.StatusOK)
|
||||
ctx.SetContentType(common.MIMEApplicationJSON)
|
||||
_ = json.NewEncoder(ctx).Encode(&resp)
|
||||
ctx.SetContentType(common.MIMEApplicationJSONCharsetUTF8)
|
||||
_ = json.NewEncoder(ctx).Encode(&MetadataResponse{
|
||||
Issuer: h.metadata.Issuer,
|
||||
AuthorizationEndpoint: h.metadata.AuthorizationEndpoint,
|
||||
TokenEndpoint: h.metadata.TokenEndpoint,
|
||||
ScopesSupported: h.metadata.ScopesSupported,
|
||||
ResponseTypesSupported: h.metadata.ResponseTypesSupported,
|
||||
GrantTypesSupported: h.metadata.GrantTypesSupported,
|
||||
ServiceDocumentation: h.metadata.ServiceDocumentation,
|
||||
CodeChallengeMethodsSupported: h.metadata.CodeChallengeMethodsSupported,
|
||||
AuthorizationResponseIssParameterSupported: h.metadata.AuthorizationResponseIssParameterSupported,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package http_test
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/fasthttp/router"
|
||||
|
@ -17,8 +16,8 @@ func TestMetadata(t *testing.T) {
|
|||
t.Parallel()
|
||||
|
||||
r := router.New()
|
||||
cfg := domain.TestConfig(t)
|
||||
delivery.NewRequestHandler(cfg).Register(r)
|
||||
metadata := domain.TestMetadata(t)
|
||||
delivery.NewRequestHandler(metadata).Register(r)
|
||||
|
||||
client, _, cleanup := httptest.New(t, r.Handler)
|
||||
t.Cleanup(cleanup)
|
||||
|
@ -36,15 +35,7 @@ func TestMetadata(t *testing.T) {
|
|||
|
||||
result := new(delivery.MetadataResponse)
|
||||
if err = json.Unmarshal(body, result); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
expResult := delivery.DefaultMetadataResponse
|
||||
expResult.Issuer = cfg.Server.GetRootURL()
|
||||
expResult.AuthorizationEndpoint = expResult.Issuer + "authorize"
|
||||
expResult.TokenEndpoint = expResult.Issuer + "token"
|
||||
|
||||
if !reflect.DeepEqual(*result, expResult) {
|
||||
t.Errorf("Unmarshal(%s) = %+v, want %+v", body, result, expResult)
|
||||
e := err.(*json.SyntaxError)
|
||||
t.Fatalf("%s#ERROR#%s", body[:e.Offset], body[e.Offset:])
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,8 +39,8 @@ type (
|
|||
TokenExchangeResponse struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
TokenType string `json:"token_type"`
|
||||
Scope string `json:"scope"`
|
||||
Me string `json:"me"`
|
||||
Scope domain.Scopes `json:"scope"`
|
||||
Me *domain.Me `json:"me"`
|
||||
Profile *TokenProfileResponse `json:"profile,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -176,8 +176,8 @@ func (h *RequestHandler) handleExchange(ctx *http.RequestCtx) {
|
|||
resp := &TokenExchangeResponse{
|
||||
AccessToken: token.AccessToken,
|
||||
TokenType: "Bearer",
|
||||
Scope: token.Scope.String(),
|
||||
Me: token.Me.String(),
|
||||
Scope: token.Scope,
|
||||
Me: token.Me,
|
||||
Profile: nil,
|
||||
}
|
||||
|
||||
|
@ -269,9 +269,9 @@ func (h *RequestHandler) handleTicket(ctx *http.RequestCtx) {
|
|||
_ = encoder.Encode(TokenExchangeResponse{
|
||||
AccessToken: tkn.AccessToken,
|
||||
TokenType: "Bearer",
|
||||
Scope: tkn.Scope.String(),
|
||||
Me: tkn.Me.String(),
|
||||
Profile: nil,
|
||||
Scope: tkn.Scope,
|
||||
Me: tkn.Me,
|
||||
Profile: nil, // TODO(toby3d)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
40
main.go
40
main.go
|
@ -279,7 +279,45 @@ func NewApp(opts NewAppOptions) *App {
|
|||
func (app *App) Register(r *router.Router) {
|
||||
tickethttpdelivery.NewRequestHandler(app.tickets, app.matcher, config).Register(r)
|
||||
healthhttpdelivery.NewRequestHandler().Register(r)
|
||||
metadatahttpdelivery.NewRequestHandler(config).Register(r)
|
||||
metadatahttpdelivery.NewRequestHandler(&domain.Metadata{
|
||||
Issuer: indieAuthClient.ID,
|
||||
AuthorizationEndpoint: domain.MustParseURL(indieAuthClient.ID.String() + "authorize"),
|
||||
TokenEndpoint: domain.MustParseURL(indieAuthClient.ID.String() + "token"),
|
||||
ScopesSupported: domain.Scopes{
|
||||
domain.ScopeBlock,
|
||||
domain.ScopeChannels,
|
||||
domain.ScopeCreate,
|
||||
domain.ScopeDelete,
|
||||
domain.ScopeDraft,
|
||||
domain.ScopeEmail,
|
||||
domain.ScopeFollow,
|
||||
domain.ScopeMedia,
|
||||
domain.ScopeMute,
|
||||
domain.ScopeProfile,
|
||||
domain.ScopeRead,
|
||||
domain.ScopeUpdate,
|
||||
},
|
||||
ResponseTypesSupported: []domain.ResponseType{
|
||||
domain.ResponseTypeCode,
|
||||
domain.ResponseTypeID,
|
||||
},
|
||||
GrantTypesSupported: []domain.GrantType{
|
||||
domain.GrantTypeAuthorizationCode,
|
||||
domain.GrantTypeTicket,
|
||||
},
|
||||
ServiceDocumentation: domain.MustParseURL("https://indieauth.net/source/"),
|
||||
CodeChallengeMethodsSupported: []domain.CodeChallengeMethod{
|
||||
domain.CodeChallengeMethodMD5,
|
||||
domain.CodeChallengeMethodPLAIN,
|
||||
domain.CodeChallengeMethodS1,
|
||||
domain.CodeChallengeMethodS256,
|
||||
domain.CodeChallengeMethodS512,
|
||||
},
|
||||
AuthorizationResponseIssParameterSupported: true,
|
||||
TicketEndpoint: domain.MustParseURL(indieAuthClient.ID.String() + "ticket"),
|
||||
Micropub: nil,
|
||||
Microsub: nil,
|
||||
}).Register(r)
|
||||
tokenhttpdelivery.NewRequestHandler(app.tokens, app.tickets).Register(r)
|
||||
clienthttpdelivery.NewRequestHandler(clienthttpdelivery.NewRequestHandlerOptions{
|
||||
Client: indieAuthClient,
|
||||
|
|
Loading…
Reference in New Issue