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