🎨 Format code of domains

This commit is contained in:
Maxim Lebedev 2022-01-12 23:04:40 +05:00
parent 257759e47c
commit 4127eca29d
Signed by: toby3d
GPG Key ID: 1F14E25B7C119FC5
9 changed files with 97 additions and 79 deletions

View File

@ -76,7 +76,7 @@ func (c *Client) ValidateRedirectURI(redirectURI *URL) bool {
return false
}
func (c *Client) GetName() string {
func (c Client) GetName() string {
if len(c.Name) < 1 {
return ""
}
@ -84,7 +84,7 @@ func (c *Client) GetName() string {
return c.Name[0]
}
func (c *Client) GetURL() *URL {
func (c Client) GetURL() *URL {
if len(c.URL) < 1 {
return nil
}
@ -92,7 +92,7 @@ func (c *Client) GetURL() *URL {
return c.URL[0]
}
func (c *Client) GetLogo() *URL {
func (c Client) GetLogo() *URL {
if len(c.Logo) < 1 {
return nil
}

View File

@ -25,6 +25,7 @@ var (
localhostIPv6 = netaddr.MustParseIP("::1")
)
//nolint: funlen
func NewClientID(raw string) (*ClientID, error) {
clientID := http.AcquireURI()
if err := clientID.Parse(nil, []byte(raw)); err != nil {
@ -146,16 +147,20 @@ func (cid *ClientID) UnmarshalJSON(v []byte) error {
return nil
}
func (cid ClientID) MarshalJSON() ([]byte, error) {
return []byte(strconv.Quote(cid.String())), nil
}
// URI returns copy of parsed *fasthttp.URI.
// This copy MUST be released via fasthttp.ReleaseURI.
func (cid *ClientID) URI() *http.URI {
func (cid ClientID) URI() *http.URI {
u := http.AcquireURI()
cid.clientID.CopyTo(u)
return u
}
func (cid *ClientID) URL() *url.URL {
func (cid ClientID) URL() *url.URL {
return &url.URL{
Scheme: string(cid.clientID.Scheme()),
Host: string(cid.clientID.Host()),
@ -167,6 +172,6 @@ func (cid *ClientID) URL() *url.URL {
}
// String returns string representation of client ID.
func (cid *ClientID) String() string {
func (cid ClientID) String() string {
return cid.clientID.String()
}

View File

@ -49,7 +49,7 @@ type (
ConfigJWT struct {
Expiry time.Duration `yaml:"expiry"` // 1h
Secret interface{} `yaml:"secret"`
Secret string `yaml:"secret"`
Algorithm string `yaml:"algorithm"` // HS256
NonceLength int `yaml:"nonceLength"` // 22
}
@ -64,23 +64,6 @@ type (
}
)
// GetAddress return host:port address.
func (cs *ConfigServer) GetAddress() string {
return net.JoinHostPort(cs.Host, cs.Port)
}
// GetRootURL returns generated from template RootURL.
func (cs *ConfigServer) GetRootURL() string {
return fasttemplate.ExecuteString(cs.RootURL, `{{`, `}}`, map[string]interface{}{
"domain": cs.Domain,
"host": cs.Host,
"port": cs.Port,
"protocol": cs.Protocol,
"staticRootPath": cs.StaticRootPath,
"staticUrlPrefix": cs.StaticURLPrefix,
})
}
// TestConfig returns a valid *viper.Viper with the generated test data filled in.
func TestConfig(tb testing.TB) *Config {
tb.Helper()
@ -111,7 +94,7 @@ func TestConfig(tb testing.TB) *Config {
JWT: ConfigJWT{
Expiry: time.Hour,
NonceLength: 22,
Secret: []byte("hackme"),
Secret: "hackme",
Algorithm: "HS256",
},
IndieAuth: ConfigIndieAuth{
@ -123,3 +106,20 @@ func TestConfig(tb testing.TB) *Config {
},
}
}
// GetAddress return host:port address.
func (cs ConfigServer) GetAddress() string {
return net.JoinHostPort(cs.Host, cs.Port)
}
// GetRootURL returns generated from template RootURL.
func (cs ConfigServer) GetRootURL() string {
return fasttemplate.ExecuteString(cs.RootURL, `{{`, `}}`, map[string]interface{}{
"domain": cs.Domain,
"host": cs.Host,
"port": cs.Port,
"protocol": cs.Protocol,
"staticRootPath": cs.StaticRootPath,
"staticUrlPrefix": cs.StaticURLPrefix,
})
}

View File

@ -18,6 +18,7 @@ type Me struct {
me *http.URI
}
//nolint: funlen
func NewMe(raw string) (*Me, error) {
me := http.AcquireURI()
if err := me.Parse(nil, []byte(raw)); err != nil {
@ -137,9 +138,13 @@ func (m *Me) UnmarshalJSON(v []byte) error {
return nil
}
func (m Me) MarshalJSON() ([]byte, error) {
return []byte(strconv.Quote(m.String())), nil
}
// URI returns copy of parsed Me in *fasthttp.URI representation.
// This copy MUST be released via fasthttp.ReleaseURI.
func (m *Me) URI() *http.URI {
func (m Me) URI() *http.URI {
if m.me == nil {
return nil
}
@ -151,7 +156,7 @@ func (m *Me) URI() *http.URI {
}
// URL returns copy of parsed Me in *url.URL representation.
func (m *Me) URL() *url.URL {
func (m Me) URL() *url.URL {
if m.me == nil {
return nil
}
@ -167,7 +172,7 @@ func (m *Me) URL() *url.URL {
}
// String returns string representation of Me.
func (m *Me) String() string {
func (m Me) String() string {
if m.me == nil {
return ""
}

View File

@ -15,24 +15,18 @@ type ResponseType struct {
//nolint: gochecknoglobals // NOTE(toby3d): structs cannot be constants
var (
ResponseTypeUndefined ResponseType = ResponseType{
slug: "",
}
ResponseTypeUndefined ResponseType = ResponseType{slug: ""}
// Deprecated(toby3d): Only accept response_type=code requests, and for
// backwards-compatible support, treat response_type=id requests as
// response_type=code requests:
// https://aaronparecki.com/2020/12/03/1/indieauth-2020#response-type
ResponseTypeID ResponseType = ResponseType{
slug: "id",
}
ResponseTypeID ResponseType = ResponseType{slug: "id"}
// Indicates to the authorization server that an authorization code
// should be returned as the response:
// https://indieauth.net/source/#authorization-request-li-1
ResponseTypeCode ResponseType = ResponseType{
slug: "code",
}
ResponseTypeCode ResponseType = ResponseType{slug: "code"}
)
var ErrResponseTypeUnknown = errors.New("unknown grant type")

View File

@ -42,9 +42,7 @@ var (
// which include the following properties: name, `photo, url.
//
// NOTE(toby3d): https://indieauth.net/source/#profile-information
ScopeProfile = Scope{
slug: "profile",
}
ScopeProfile = Scope{slug: "profile"}
// This scope requests access to the user's email address in the
// following property: email.
@ -54,9 +52,7 @@ var (
// and must be requested along with the profile scope if desired.
//
// NOTE(toby3d): https://indieauth.net/source/#profile-information
ScopeEmail = Scope{
slug: "email",
}
ScopeEmail = Scope{slug: "email"}
)
//nolint: gochecknoglobals // NOTE(toby3d): maps cannot be constants
@ -85,29 +81,19 @@ func ParseScope(slug string) (Scope, error) {
}
// UnmarshalForm parses the value of the form key into the Scope domain.
func (s *Scope) UnmarshalForm(v []byte) (err error) {
scope, err := ParseScope(string(v))
if err != nil {
return fmt.Errorf("scope: %w", err)
func (s *Scopes) UnmarshalForm(v []byte) error {
scopes := make(Scopes, 0)
for _, rawScope := range strings.Fields(string(v)) {
scope, err := ParseScope(rawScope)
if err != nil {
return fmt.Errorf("scopes: %w", err)
}
*s = append(scopes, scope)
}
*s = scope
return nil
}
func (s *Scope) UnmarshalJSON(v []byte) error {
src, err := strconv.Unquote(string(v))
if err != nil {
return err
}
scope, err := ParseScope(src)
if err != nil {
return fmt.Errorf("scope: %w", err)
}
*s = scope
*s = scopes
return nil
}

View File

@ -6,19 +6,47 @@ import (
"github.com/goccy/go-json"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
http "github.com/valyala/fasthttp"
"source.toby3d.me/toby3d/form"
"source.toby3d.me/website/indieauth/internal/domain"
)
func TestScopes_UnmarshalForm(t *testing.T) {
t.Parallel()
args := http.AcquireArgs()
defer http.ReleaseArgs(args)
args.Set("scope", "read update delete")
result := struct {
Scope domain.Scopes
}{
Scope: make(domain.Scopes, 0),
}
require.NoError(t, form.Unmarshal(args, &result))
assert.Equal(t, "read update delete", result.Scope.String())
}
func TestScopes_UnmarshalJSON(t *testing.T) {
t.Parallel()
result := &struct {
Scope domain.Scopes `json:"scope"`
}{}
require.NoError(t, json.Unmarshal([]byte(`{"scope": "read update delete"}`), result))
for _, scope := range []domain.Scope{domain.ScopeRead, domain.ScopeUpdate, domain.ScopeDelete} {
assert.Contains(t, result.Scope, scope)
}
result := make(map[string]domain.Scopes)
require.NoError(t, json.Unmarshal([]byte(`{"scope":"read update delete"}`), &result))
assert.Equal(t, domain.Scopes{domain.ScopeRead, domain.ScopeUpdate, domain.ScopeDelete}, result["scope"])
}
func TestScopes_MarshalJSON(t *testing.T) {
t.Parallel()
result, err := json.Marshal(map[string]domain.Scopes{
"scope": {
domain.ScopeEmail,
domain.ScopeProfile,
domain.ScopeRead,
},
})
require.NoError(t, err)
assert.Equal(t, `{"scope":"email profile read"}`, string(result))
}

View File

@ -28,14 +28,14 @@ type (
Issuer *ClientID
NonceLength int
Scope Scopes
Secret interface{}
Secret []byte
Subject *Me
}
)
var DefaultNewTokenOptions = NewTokenOptions{
NonceLength: 32,
Algorithm: "HS256",
NonceLength: 32,
}
func NewToken(opts NewTokenOptions) (*Token, error) {
@ -83,7 +83,7 @@ func NewToken(opts NewTokenOptions) (*Token, error) {
func TestToken(tb testing.TB) *Token {
tb.Helper()
nonce, err := random.String(42)
nonce, err := random.String(22)
require.NoError(tb, err)
t := jwt.New()
@ -98,7 +98,7 @@ func TestToken(tb testing.TB) *Token {
// NOTE(toby3d): required
t.Set(jwt.IssuerKey, cid.String())
t.Set(jwt.SubjectKey, me.me.String())
t.Set(jwt.SubjectKey, me.String())
// TODO(toby3d): t.Set(jwt.AudienceKey, nil)
t.Set(jwt.ExpirationKey, now.Add(1*time.Hour))
t.Set(jwt.NotBeforeKey, now.Add(-1*time.Hour))
@ -121,7 +121,7 @@ func TestToken(tb testing.TB) *Token {
}
// SetAuthHeader writes an Access Token to the request header.
func (t *Token) SetAuthHeader(r *http.Request) {
func (t Token) SetAuthHeader(r *http.Request) {
if t.AccessToken == "" {
return
}
@ -129,7 +129,7 @@ func (t *Token) SetAuthHeader(r *http.Request) {
r.Header.Set(http.HeaderAuthorization, t.String())
}
func (t *Token) String() string {
func (t Token) String() string {
if t.AccessToken == "" {
return ""
}

View File

@ -61,7 +61,7 @@ func (u *URL) UnmarshalJSON(v []byte) error {
return nil
}
func (u *URL) URL() *url.URL {
func (u URL) URL() *url.URL {
if u.URI == nil {
return nil
}