🎨 Format of the source code
This commit is contained in:
parent
c82e364a50
commit
ec83828a1e
|
@ -23,16 +23,16 @@ type (
|
||||||
NewHandlerOptions struct {
|
NewHandlerOptions struct {
|
||||||
Auth auth.UseCase
|
Auth auth.UseCase
|
||||||
Clients client.UseCase
|
Clients client.UseCase
|
||||||
Config domain.Config
|
|
||||||
Matcher language.Matcher
|
Matcher language.Matcher
|
||||||
Profiles profile.UseCase
|
Profiles profile.UseCase
|
||||||
|
Config domain.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
Handler struct {
|
Handler struct {
|
||||||
clients client.UseCase
|
clients client.UseCase
|
||||||
config domain.Config
|
|
||||||
matcher language.Matcher
|
matcher language.Matcher
|
||||||
useCase auth.UseCase
|
useCase auth.UseCase
|
||||||
|
config domain.Config
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -13,8 +13,8 @@ type (
|
||||||
Me domain.Me
|
Me domain.Me
|
||||||
RedirectURI *url.URL
|
RedirectURI *url.URL
|
||||||
CodeChallengeMethod domain.CodeChallengeMethod
|
CodeChallengeMethod domain.CodeChallengeMethod
|
||||||
Scope domain.Scopes
|
|
||||||
CodeChallenge string
|
CodeChallenge string
|
||||||
|
Scope domain.Scopes
|
||||||
}
|
}
|
||||||
|
|
||||||
ExchangeOptions struct {
|
ExchangeOptions struct {
|
||||||
|
|
|
@ -83,8 +83,10 @@ func extract(r io.Reader, u *url.URL, dst *domain.Client, header string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, logo := range httputil.ExtractProperty(bytes.NewReader(body), u, itemType, propertyLogo) {
|
for _, logo := range httputil.ExtractProperty(bytes.NewReader(body), u, itemType, propertyLogo) {
|
||||||
var logoURL *url.URL
|
var (
|
||||||
var err error
|
logoURL *url.URL
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
switch l := logo.(type) {
|
switch l := logo.(type) {
|
||||||
case string:
|
case string:
|
||||||
|
|
|
@ -73,7 +73,7 @@ func TestGet(t *testing.T) {
|
||||||
func testHandler(tb testing.TB, client domain.Client) http.Handler {
|
func testHandler(tb testing.TB, client domain.Client) http.Handler {
|
||||||
tb.Helper()
|
tb.Helper()
|
||||||
|
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||||
w.Header().Set(common.HeaderContentType, common.MIMETextHTMLCharsetUTF8)
|
w.Header().Set(common.HeaderContentType, common.MIMETextHTMLCharsetUTF8)
|
||||||
w.Header().Set(common.HeaderLink, `<`+client.RedirectURI[0].String()+`>; rel="redirect_uri"`)
|
w.Header().Set(common.HeaderLink, `<`+client.RedirectURI[0].String()+`>; rel="redirect_uri"`)
|
||||||
fmt.Fprintf(w, testBody, client.Name[0], client.URL[0], client.Logo[0], client.RedirectURI[1])
|
fmt.Fprintf(w, testBody, client.Name[0], client.URL[0], client.Logo[0], client.RedirectURI[1])
|
||||||
|
|
|
@ -22,10 +22,10 @@ func TestDiscovery(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range []struct {
|
for _, tc := range []struct {
|
||||||
name string
|
expError error
|
||||||
in *domain.Client
|
in *domain.Client
|
||||||
out *domain.Client
|
out *domain.Client
|
||||||
expError error
|
name string
|
||||||
}{{
|
}{{
|
||||||
name: "default",
|
name: "default",
|
||||||
in: testClient,
|
in: testClient,
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package common
|
package common
|
||||||
|
|
||||||
|
const charsetUTF8 = "charset=UTF-8"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
MIMEApplicationForm string = "application/x-www-form-urlencoded"
|
MIMEApplicationForm string = "application/x-www-form-urlencoded"
|
||||||
MIMEApplicationJSON string = "application/json"
|
MIMEApplicationJSON string = "application/json"
|
||||||
|
@ -8,8 +10,6 @@ const (
|
||||||
MIMETextHTMLCharsetUTF8 string = MIMETextHTML + "; " + charsetUTF8
|
MIMETextHTMLCharsetUTF8 string = MIMETextHTML + "; " + charsetUTF8
|
||||||
MIMETextPlain string = "text/plain"
|
MIMETextPlain string = "text/plain"
|
||||||
MIMETextPlainCharsetUTF8 string = MIMETextPlain + "; " + charsetUTF8
|
MIMETextPlainCharsetUTF8 string = MIMETextPlain + "; " + charsetUTF8
|
||||||
|
|
||||||
charsetUTF8 = "charset=UTF-8"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
@ -13,8 +13,8 @@ type (
|
||||||
Config struct {
|
Config struct {
|
||||||
Server ConfigServer `envPrefix:"SERVER_"`
|
Server ConfigServer `envPrefix:"SERVER_"`
|
||||||
Database ConfigDatabase `envPrefix:"DATABASE_"`
|
Database ConfigDatabase `envPrefix:"DATABASE_"`
|
||||||
Name string `env:"NAME" envDefault:"IndieAuth"`
|
Name string `env:"NAME" envDefault:"IndieAuth"`
|
||||||
RunMode string `env:"RUN_MODE" envDefault:"dev"`
|
RunMode string `env:"RUN_MODE" envDefault:"dev"`
|
||||||
IndieAuth ConfigIndieAuth `envPrefix:"INDIEAUTH_"`
|
IndieAuth ConfigIndieAuth `envPrefix:"INDIEAUTH_"`
|
||||||
JWT ConfigJWT `envPrefix:"JWT_"`
|
JWT ConfigJWT `envPrefix:"JWT_"`
|
||||||
Code ConfigCode `envPrefix:"CODE_"`
|
Code ConfigCode `envPrefix:"CODE_"`
|
||||||
|
@ -23,12 +23,12 @@ type (
|
||||||
|
|
||||||
ConfigServer struct {
|
ConfigServer struct {
|
||||||
CertificateFile string `env:"CERT_FILE"`
|
CertificateFile string `env:"CERT_FILE"`
|
||||||
Domain string `env:"DOMAIN" envDefault:"localhost"`
|
Domain string `env:"DOMAIN" envDefault:"localhost"`
|
||||||
Host string `env:"HOST" envDefault:"0.0.0.0"`
|
Host string `env:"HOST" envDefault:"0.0.0.0"`
|
||||||
KeyFile string `env:"KEY_FILE"`
|
KeyFile string `env:"KEY_FILE"`
|
||||||
Port string `env:"PORT" envDefault:"3000"`
|
Port string `env:"PORT" envDefault:"3000"`
|
||||||
Protocol string `env:"PROTOCOL" envDefault:"http"`
|
Protocol string `env:"PROTOCOL" envDefault:"http"`
|
||||||
RootURL string `env:"ROOT_URL" envDefault:"{{protocol}}://{{domain}}:{{port}}/"`
|
RootURL string `env:"ROOT_URL" envDefault:"{{protocol}}://{{domain}}:{{port}}/"`
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigDatabase struct {
|
ConfigDatabase struct {
|
||||||
|
@ -45,16 +45,16 @@ type (
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigJWT struct {
|
ConfigJWT struct {
|
||||||
Algorithm string `env:"ALGORITHM" envDefault:"HS256"`
|
Algorithm string `env:"ALGORITHM" envDefault:"HS256"`
|
||||||
Secret string `env:"SECRET"`
|
Secret string `env:"SECRET"`
|
||||||
Expiry time.Duration `env:"EXPIRY" envDefault:"1h"`
|
Expiry time.Duration `env:"EXPIRY" envDefault:"1h"`
|
||||||
NonceLength uint8 `env:"NONCE_LENGTH" envDefault:"22"`
|
NonceLength uint8 `env:"NONCE_LENGTH" envDefault:"22"`
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigIndieAuth struct {
|
ConfigIndieAuth struct {
|
||||||
Password string `env:"PASSWORD"`
|
Password string `env:"PASSWORD"`
|
||||||
Username string `env:"USERNAME"`
|
Username string `env:"USERNAME"`
|
||||||
Enabled bool `env:"ENABLED" envDefault:"true"` // true
|
Enabled bool `env:"ENABLED" envDefault:"true"` // true
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigTicketAuth struct {
|
ConfigTicketAuth struct {
|
||||||
|
@ -64,7 +64,7 @@ type (
|
||||||
|
|
||||||
ConfigRelMeAuth struct {
|
ConfigRelMeAuth struct {
|
||||||
Providers []ConfigRelMeAuthProvider `envPrefix:"PROVIDERS_"`
|
Providers []ConfigRelMeAuthProvider `envPrefix:"PROVIDERS_"`
|
||||||
Enabled bool `env:"ENABLED" envDefault:"true"` // true
|
Enabled bool `env:"ENABLED" envDefault:"true"` // true
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigRelMeAuthProvider struct {
|
ConfigRelMeAuthProvider struct {
|
||||||
|
|
|
@ -15,8 +15,6 @@ type (
|
||||||
// Error describes the format of a typical IndieAuth error.
|
// Error describes the format of a typical IndieAuth error.
|
||||||
//nolint:tagliatelle // RFC 6749 section 5.2
|
//nolint:tagliatelle // RFC 6749 section 5.2
|
||||||
Error struct {
|
Error struct {
|
||||||
frame xerrors.Frame `json:"-"`
|
|
||||||
|
|
||||||
// A single error code.
|
// A single error code.
|
||||||
Code ErrorCode `json:"error"`
|
Code ErrorCode `json:"error"`
|
||||||
|
|
||||||
|
@ -33,6 +31,8 @@ type (
|
||||||
// authorization request. The exact value received from the
|
// authorization request. The exact value received from the
|
||||||
// client.
|
// client.
|
||||||
State string `json:"-"`
|
State string `json:"-"`
|
||||||
|
|
||||||
|
frame xerrors.Frame `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ErrorCode represent error code described in RFC 6749.
|
// ErrorCode represent error code described in RFC 6749.
|
||||||
|
@ -135,7 +135,9 @@ var (
|
||||||
//
|
//
|
||||||
// RFC 6749 section 4.1.2.1: The authorization server does not support
|
// RFC 6749 section 4.1.2.1: The authorization server does not support
|
||||||
// obtaining an authorization code using this method.
|
// obtaining an authorization code using this method.
|
||||||
ErrorCodeUnsupportedResponseType = ErrorCode{errorCode: "unsupported_response_type"} // "unsupported_response_type"
|
ErrorCodeUnsupportedResponseType = ErrorCode{
|
||||||
|
errorCode: "unsupported_response_type",
|
||||||
|
} // "unsupported_response_type"
|
||||||
|
|
||||||
// ErrorCodeInvalidToken describes the invalid_token error code.
|
// ErrorCodeInvalidToken describes the invalid_token error code.
|
||||||
//
|
//
|
||||||
|
|
|
@ -60,8 +60,7 @@ type Metadata struct {
|
||||||
GrantTypesSupported []GrantType
|
GrantTypesSupported []GrantType
|
||||||
|
|
||||||
// JSON array containing the methods supported for PKCE. This parameter
|
// JSON array containing the methods supported for PKCE. This parameter
|
||||||
// parameter differs from RFC8414 in that it is not optional as PKCE is
|
// differs from RFC8414 in that it is not optional as PKCE is REQUIRED.
|
||||||
// REQUIRED.
|
|
||||||
CodeChallengeMethodsSupported []CodeChallengeMethod
|
CodeChallengeMethodsSupported []CodeChallengeMethod
|
||||||
|
|
||||||
// List of client authentication methods supported by this introspection endpoint.
|
// List of client authentication methods supported by this introspection endpoint.
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
|
|
||||||
// Provider represent 3rd party RelMeAuth provider.
|
// Provider represent 3rd party RelMeAuth provider.
|
||||||
type Provider struct {
|
type Provider struct {
|
||||||
Scopes []string
|
|
||||||
AuthURL string
|
AuthURL string
|
||||||
ClientID string
|
ClientID string
|
||||||
ClientSecret string
|
ClientSecret string
|
||||||
|
@ -18,6 +17,7 @@ type Provider struct {
|
||||||
TokenURL string
|
TokenURL string
|
||||||
UID string
|
UID string
|
||||||
URL string
|
URL string
|
||||||
|
Scopes []string
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gochecknoglobals // structs cannot be contants
|
//nolint:gochecknoglobals // structs cannot be contants
|
||||||
|
@ -95,6 +95,8 @@ func (p Provider) AuthCodeURL(state string) string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
q := u.Query()
|
||||||
|
|
||||||
for key, val := range map[string]string{
|
for key, val := range map[string]string{
|
||||||
"client_id": p.ClientID,
|
"client_id": p.ClientID,
|
||||||
"redirect_uri": p.RedirectURL,
|
"redirect_uri": p.RedirectURL,
|
||||||
|
@ -102,8 +104,10 @@ func (p Provider) AuthCodeURL(state string) string {
|
||||||
"scope": strings.Join(p.Scopes, " "),
|
"scope": strings.Join(p.Scopes, " "),
|
||||||
"state": state,
|
"state": state,
|
||||||
} {
|
} {
|
||||||
u.Query().Set(key, val)
|
q.Set(key, val)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u.RawQuery = q.Encode()
|
||||||
|
|
||||||
return u.String()
|
return u.String()
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,10 +13,10 @@ type Session struct {
|
||||||
RedirectURI *url.URL `json:"redirect_uri"`
|
RedirectURI *url.URL `json:"redirect_uri"`
|
||||||
Me Me `json:"me"`
|
Me Me `json:"me"`
|
||||||
Profile *Profile `json:"profile,omitempty"`
|
Profile *Profile `json:"profile,omitempty"`
|
||||||
Scope Scopes `json:"scope"`
|
|
||||||
CodeChallengeMethod CodeChallengeMethod `json:"code_challenge_method,omitempty"`
|
CodeChallengeMethod CodeChallengeMethod `json:"code_challenge_method,omitempty"`
|
||||||
CodeChallenge string `json:"code_challenge,omitempty"`
|
CodeChallenge string `json:"code_challenge,omitempty"`
|
||||||
Code string `json:"-"`
|
Code string `json:"-"`
|
||||||
|
Scope Scopes `json:"scope"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestSession returns valid random generated session for tests.
|
// TestSession returns valid random generated session for tests.
|
||||||
|
|
|
@ -20,19 +20,19 @@ type (
|
||||||
Expiry time.Time
|
Expiry time.Time
|
||||||
ClientID ClientID
|
ClientID ClientID
|
||||||
Me Me
|
Me Me
|
||||||
Scope Scopes
|
|
||||||
AccessToken string
|
AccessToken string
|
||||||
RefreshToken string
|
RefreshToken string
|
||||||
|
Scope Scopes
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTokenOptions contains options for NewToken function.
|
// NewTokenOptions contains options for NewToken function.
|
||||||
NewTokenOptions struct {
|
NewTokenOptions struct {
|
||||||
Expiration time.Duration
|
|
||||||
Issuer ClientID
|
Issuer ClientID
|
||||||
Subject Me
|
Subject Me
|
||||||
|
Algorithm string
|
||||||
Scope Scopes
|
Scope Scopes
|
||||||
Secret []byte
|
Secret []byte
|
||||||
Algorithm string
|
Expiration time.Duration
|
||||||
NonceLength uint8
|
NonceLength uint8
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -37,7 +36,7 @@ func ExtractFromMetadata(client *http.Client, u string) (*domain.Metadata, error
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package httputil_test
|
package httputil_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -32,10 +32,7 @@ func TestExtractEndpointsFromBody(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
in := &http.Response{
|
in := &http.Response{Body: io.NopCloser(strings.NewReader(testBody))}
|
||||||
Body: ioutil.NopCloser(strings.NewReader(testBody)),
|
|
||||||
Request: req,
|
|
||||||
}
|
|
||||||
|
|
||||||
out, err := httputil.ExtractEndpointsFromBody(in.Body, req.URL, "lipsum")
|
out, err := httputil.ExtractEndpointsFromBody(in.Body, req.URL, "lipsum")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -60,10 +57,7 @@ func TestExtractProperty(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
in := &http.Response{
|
in := &http.Response{Body: io.NopCloser(strings.NewReader(testBody))}
|
||||||
Body: ioutil.NopCloser(strings.NewReader(testBody)),
|
|
||||||
Request: req,
|
|
||||||
}
|
|
||||||
|
|
||||||
if out := httputil.ExtractProperty(in.Body, req.URL, "h-app", "name"); out == nil || out[0] != "Sample Name" {
|
if out := httputil.ExtractProperty(in.Body, req.URL, "h-app", "name"); out == nil || out[0] != "Sample Name" {
|
||||||
t.Errorf(`ExtractProperty(%s, %s, %s) = %+s, want %+s`, req.URL, "h-app", "name", out,
|
t.Errorf(`ExtractProperty(%s, %s, %s) = %+s, want %+s`, req.URL, "h-app", "name", out,
|
||||||
|
|
|
@ -55,10 +55,10 @@ func TestGet(t *testing.T) {
|
||||||
testMetadata := domain.TestMetadata(t)
|
testMetadata := domain.TestMetadata(t)
|
||||||
|
|
||||||
for _, tc := range []struct {
|
for _, tc := range []struct {
|
||||||
name string
|
|
||||||
header map[string]string
|
header map[string]string
|
||||||
body map[string]string
|
body map[string]string
|
||||||
out *domain.Metadata
|
out *domain.Metadata
|
||||||
|
name string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "header",
|
name: "header",
|
||||||
|
@ -83,11 +83,11 @@ func TestGet(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
mux.HandleFunc("/metadata", func(w http.ResponseWriter, r *http.Request) {
|
mux.HandleFunc("/metadata", func(w http.ResponseWriter, _ *http.Request) {
|
||||||
w.Header().Set(common.HeaderContentType, common.MIMEApplicationJSONCharsetUTF8)
|
w.Header().Set(common.HeaderContentType, common.MIMEApplicationJSONCharsetUTF8)
|
||||||
_ = json.NewEncoder(w).Encode(NewResponse(t, *testMetadata))
|
_ = json.NewEncoder(w).Encode(NewResponse(t, *testMetadata))
|
||||||
})
|
})
|
||||||
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
mux.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) {
|
||||||
links := make([]string, 0)
|
links := make([]string, 0)
|
||||||
for k, v := range tc.header {
|
for k, v := range tc.header {
|
||||||
links = append(links, `<`+v+`>; rel="`+k+`"`)
|
links = append(links, `<`+v+`>; rel="`+k+`"`)
|
||||||
|
@ -170,14 +170,11 @@ func NewResponse(tb testing.TB, src domain.Metadata) *Response {
|
||||||
out.ScopesSupported = append(out.ScopesSupported, scope.String())
|
out.ScopesSupported = append(out.ScopesSupported, scope.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, method := range src.IntrospectionEndpointAuthMethodsSupported {
|
out.IntrospectionEndpointAuthMethodsSupported = append(out.IntrospectionEndpointAuthMethodsSupported,
|
||||||
out.IntrospectionEndpointAuthMethodsSupported = append(out.IntrospectionEndpointAuthMethodsSupported,
|
src.IntrospectionEndpointAuthMethodsSupported...)
|
||||||
method)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, method := range src.RevocationEndpointAuthMethodsSupported {
|
out.RevocationEndpointAuthMethodsSupported = append(out.RevocationEndpointAuthMethodsSupported,
|
||||||
out.RevocationEndpointAuthMethodsSupported = append(out.RevocationEndpointAuthMethodsSupported, method)
|
src.RevocationEndpointAuthMethodsSupported...)
|
||||||
}
|
|
||||||
|
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ const DefaultRealm string = "Restricted"
|
||||||
|
|
||||||
const basic string = "basic"
|
const basic string = "basic"
|
||||||
|
|
||||||
// nolint: gochecknoglobals
|
//nolint:gochecknoglobals
|
||||||
var DefaultBasicAuthConfig = BasicAuthConfig{
|
var DefaultBasicAuthConfig = BasicAuthConfig{
|
||||||
Skipper: DefaultSkipper,
|
Skipper: DefaultSkipper,
|
||||||
Realm: DefaultRealm,
|
Realm: DefaultRealm,
|
||||||
|
|
|
@ -58,7 +58,7 @@ func createExtractors(lookups, authScheme string) ([]ValuesExtractor, error) {
|
||||||
for _, source := range sources {
|
for _, source := range sources {
|
||||||
parts := strings.Split(source, ":")
|
parts := strings.Split(source, ":")
|
||||||
|
|
||||||
if len(parts) < 2 {
|
if len(parts) <= 1 {
|
||||||
return nil, fmt.Errorf("extractor source for lookup could not be split into needed parts: %v",
|
return nil, fmt.Errorf("extractor source for lookup could not be split into needed parts: %v",
|
||||||
source)
|
source)
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,7 @@ func valuesFromHeader(header, valuePrefix string) ValuesExtractor {
|
||||||
// this
|
// this
|
||||||
header = textproto.CanonicalMIMEHeaderKey(header)
|
header = textproto.CanonicalMIMEHeaderKey(header)
|
||||||
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) ([]string, error) {
|
return func(_ http.ResponseWriter, r *http.Request) ([]string, error) {
|
||||||
values := r.Header.Values(header)
|
values := r.Header.Values(header)
|
||||||
if len(values) == 0 {
|
if len(values) == 0 {
|
||||||
return nil, errHeaderExtractorValueMissing
|
return nil, errHeaderExtractorValueMissing
|
||||||
|
@ -147,7 +147,7 @@ func valuesFromHeader(header, valuePrefix string) ValuesExtractor {
|
||||||
|
|
||||||
// valuesFromQuery returns a function that extracts values from the query string.
|
// valuesFromQuery returns a function that extracts values from the query string.
|
||||||
func valuesFromQuery(param string) ValuesExtractor {
|
func valuesFromQuery(param string) ValuesExtractor {
|
||||||
return func(w http.ResponseWriter, r *http.Request) ([]string, error) {
|
return func(_ http.ResponseWriter, r *http.Request) ([]string, error) {
|
||||||
result := r.URL.Query()[param]
|
result := r.URL.Query()[param]
|
||||||
|
|
||||||
if len(result) == 0 {
|
if len(result) == 0 {
|
||||||
|
@ -162,7 +162,7 @@ func valuesFromQuery(param string) ValuesExtractor {
|
||||||
|
|
||||||
// valuesFromCookie returns a function that extracts values from the named cookie.
|
// valuesFromCookie returns a function that extracts values from the named cookie.
|
||||||
func valuesFromCookie(name string) ValuesExtractor {
|
func valuesFromCookie(name string) ValuesExtractor {
|
||||||
return func(w http.ResponseWriter, r *http.Request) ([]string, error) {
|
return func(_ http.ResponseWriter, r *http.Request) ([]string, error) {
|
||||||
cookies := r.Cookies()
|
cookies := r.Cookies()
|
||||||
if len(cookies) == 0 {
|
if len(cookies) == 0 {
|
||||||
return nil, errCookieExtractorValueMissing
|
return nil, errCookieExtractorValueMissing
|
||||||
|
@ -190,7 +190,7 @@ func valuesFromCookie(name string) ValuesExtractor {
|
||||||
|
|
||||||
// valuesFromForm returns a function that extracts values from the form field.
|
// valuesFromForm returns a function that extracts values from the form field.
|
||||||
func valuesFromForm(name string) ValuesExtractor {
|
func valuesFromForm(name string) ValuesExtractor {
|
||||||
return func(w http.ResponseWriter, r *http.Request) ([]string, error) {
|
return func(_ http.ResponseWriter, r *http.Request) ([]string, error) {
|
||||||
if r.Form == nil {
|
if r.Form == nil {
|
||||||
_ = r.ParseMultipartForm(32 << 20) // same what `r.FormValue(name)` does
|
_ = r.ParseMultipartForm(32 << 20) // same what `r.FormValue(name)` does
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,7 +89,6 @@ func (h *Handler) handleFunc(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
h.handleRender(w, r)
|
h.handleRender(w, r)
|
||||||
case http.MethodPost:
|
case http.MethodPost:
|
||||||
|
|
||||||
switch head {
|
switch head {
|
||||||
default:
|
default:
|
||||||
http.NotFound(w, r)
|
http.NotFound(w, r)
|
||||||
|
|
|
@ -79,7 +79,7 @@ func (useCase *ticketUseCase) Generate(ctx context.Context, tkt domain.Ticket) e
|
||||||
return ticket.ErrTicketEndpointNotExist
|
return ticket.ErrTicketEndpointNotExist
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := useCase.tickets.Create(ctx, tkt); err != nil {
|
if err = useCase.tickets.Create(ctx, tkt); err != nil {
|
||||||
return fmt.Errorf("cannot save ticket in store: %w", err)
|
return fmt.Errorf("cannot save ticket in store: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ func TestRedeem(t *testing.T) {
|
||||||
}))
|
}))
|
||||||
t.Cleanup(tokenServer.Close)
|
t.Cleanup(tokenServer.Close)
|
||||||
|
|
||||||
subjectServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
subjectServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||||
w.Header().Set(common.HeaderContentType, common.MIMETextHTMLCharsetUTF8)
|
w.Header().Set(common.HeaderContentType, common.MIMETextHTMLCharsetUTF8)
|
||||||
fmt.Fprint(w, `<link rel="token_endpoint" href="`+tokenServer.URL+`/token">`)
|
fmt.Fprint(w, `<link rel="token_endpoint" href="`+tokenServer.URL+`/token">`)
|
||||||
}))
|
}))
|
||||||
|
|
|
@ -64,7 +64,8 @@ func (repo *httpUserRepository) Get(ctx context.Context, me domain.Me) (*domain.
|
||||||
TokenEndpoint: nil,
|
TokenEndpoint: nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
if metadata, err := httputil.ExtractFromMetadata(repo.client, me.String()); err == nil {
|
var metadata *domain.Metadata
|
||||||
|
if metadata, err = httputil.ExtractFromMetadata(repo.client, me.String()); err == nil {
|
||||||
user.AuthorizationEndpoint = metadata.AuthorizationEndpoint
|
user.AuthorizationEndpoint = metadata.AuthorizationEndpoint
|
||||||
user.Micropub = metadata.MicropubEndpoint
|
user.Micropub = metadata.MicropubEndpoint
|
||||||
user.Microsub = metadata.MicrosubEndpoint
|
user.Microsub = metadata.MicrosubEndpoint
|
||||||
|
@ -128,8 +129,8 @@ func extractProfile(u *url.URL, dst *domain.Profile, body []byte) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if u, err := url.Parse(rawURL); err == nil && !containsUrl(dst.URL, u) {
|
if parsedURL, err := url.Parse(rawURL); err == nil && !containsUrl(dst.URL, u) {
|
||||||
dst.URL = append(dst.URL, u)
|
dst.URL = append(dst.URL, parsedURL)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ func testHandler(tb testing.TB, user *domain.User) http.Handler {
|
||||||
tb.Helper()
|
tb.Helper()
|
||||||
|
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
mux.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) {
|
||||||
w.Header().Set(common.HeaderLink, strings.Join([]string{
|
w.Header().Set(common.HeaderLink, strings.Join([]string{
|
||||||
`<` + user.AuthorizationEndpoint.String() + `>; rel="authorization_endpoint"`,
|
`<` + user.AuthorizationEndpoint.String() + `>; rel="authorization_endpoint"`,
|
||||||
`<` + user.IndieAuthMetadata.String() + `>; rel="indieauth-metadata"`,
|
`<` + user.IndieAuthMetadata.String() + `>; rel="indieauth-metadata"`,
|
||||||
|
@ -72,7 +72,7 @@ func testHandler(tb testing.TB, user *domain.User) http.Handler {
|
||||||
w.Header().Set(common.HeaderContentType, common.MIMETextHTMLCharsetUTF8)
|
w.Header().Set(common.HeaderContentType, common.MIMETextHTMLCharsetUTF8)
|
||||||
fmt.Fprintf(w, testBody, user.Name[0], user.URL[0].String(), user.Photo[0].String(), user.Email[0])
|
fmt.Fprintf(w, testBody, user.Name[0], user.URL[0].String(), user.Photo[0].String(), user.Email[0])
|
||||||
})
|
})
|
||||||
mux.HandleFunc(user.IndieAuthMetadata.Path, func(w http.ResponseWriter, r *http.Request) {
|
mux.HandleFunc(user.IndieAuthMetadata.Path, func(w http.ResponseWriter, _ *http.Request) {
|
||||||
w.Header().Set(common.HeaderContentType, common.MIMEApplicationJSONCharsetUTF8)
|
w.Header().Set(common.HeaderContentType, common.MIMEApplicationJSONCharsetUTF8)
|
||||||
fmt.Fprint(w, `{
|
fmt.Fprint(w, `{
|
||||||
"issuer": "`+user.Me.String()+`",
|
"issuer": "`+user.Me.String()+`",
|
||||||
|
|
Loading…
Reference in New Issue