♻️ Replaces xerrors to errors package

This commit is contained in:
Maxim Lebedev 2022-02-01 23:38:08 +05:00
parent 54de0d1dcb
commit f1245f334f
Signed by: toby3d
GPG Key ID: 1F14E25B7C119FC5
3 changed files with 58 additions and 72 deletions

View File

@ -9,7 +9,6 @@ import (
"testing" "testing"
http "github.com/valyala/fasthttp" http "github.com/valyala/fasthttp"
"golang.org/x/xerrors"
) )
// Me is a URL user identifier. // Me is a URL user identifier.
@ -22,87 +21,79 @@ type Me struct {
func ParseMe(raw string) (*Me, error) { func ParseMe(raw string) (*Me, error) {
me := http.AcquireURI() me := http.AcquireURI()
if err := me.Parse(nil, []byte(raw)); err != nil { if err := me.Parse(nil, []byte(raw)); err != nil {
return nil, Error{ return nil, NewError(
Code: ErrorCodeInvalidRequest, ErrorCodeInvalidRequest,
Description: err.Error(), err.Error(),
URI: "https://indieauth.net/source/#user-profile-url", "https://indieauth.net/source/#user-profile-url",
State: "", "",
frame: xerrors.Caller(1), )
}
} }
scheme := string(me.Scheme()) scheme := string(me.Scheme())
if scheme != "http" && scheme != "https" { if scheme != "http" && scheme != "https" {
return nil, Error{ return nil, NewError(
Code: ErrorCodeInvalidRequest, ErrorCodeInvalidRequest,
Description: "profile URL MUST have either an https or http scheme", "profile URL MUST have either an https or http scheme",
URI: "https://indieauth.net/source/#user-profile-url", "https://indieauth.net/source/#user-profile-url",
State: "", "",
frame: xerrors.Caller(1), )
}
} }
path := string(me.PathOriginal()) path := string(me.PathOriginal())
if path == "" || strings.Contains(path, "/.") || strings.Contains(path, "/..") { if path == "" || strings.Contains(path, "/.") || strings.Contains(path, "/..") {
return nil, Error{ return nil, NewError(
Code: ErrorCodeInvalidRequest, ErrorCodeInvalidRequest,
Description: "profile URL MUST contain a path component (/ is a valid path), MUST NOT " + "profile URL MUST contain a path component (/ is a valid path), MUST NOT contain single-dot "+
"contain single-dot or double-dot path segments", "or double-dot path segments",
URI: "https://indieauth.net/source/#user-profile-url", "https://indieauth.net/source/#user-profile-url",
State: "", "",
frame: xerrors.Caller(1), )
}
} }
if me.Hash() != nil { if me.Hash() != nil {
return nil, Error{ return nil, NewError(
Code: ErrorCodeInvalidRequest, ErrorCodeInvalidRequest,
Description: "profile URL MUST NOT contain a fragment component", "profile URL MUST NOT contain a fragment component",
URI: "https://indieauth.net/source/#user-profile-url", "https://indieauth.net/source/#user-profile-url",
State: "", "",
frame: xerrors.Caller(1), )
}
} }
if me.Username() != nil || me.Password() != nil { if me.Username() != nil || me.Password() != nil {
return nil, Error{ return nil, NewError(
Code: ErrorCodeInvalidRequest, ErrorCodeInvalidRequest,
Description: "profile URL MUST NOT contain a username or password component", "profile URL MUST NOT contain a username or password component",
URI: "https://indieauth.net/source/#user-profile-url", "https://indieauth.net/source/#user-profile-url",
State: "", "",
frame: xerrors.Caller(1), )
}
} }
domain := string(me.Host()) domain := string(me.Host())
if domain == "" { if domain == "" {
return nil, Error{ return nil, NewError(
Code: ErrorCodeInvalidRequest, ErrorCodeInvalidRequest,
Description: "profile host name MUST be a domain name", "profile host name MUST be a domain name",
URI: "https://indieauth.net/source/#user-profile-url", "https://indieauth.net/source/#user-profile-url",
State: "", "",
frame: xerrors.Caller(1), )
}
} }
if _, port, _ := net.SplitHostPort(domain); port != "" { if _, port, _ := net.SplitHostPort(domain); port != "" {
return nil, Error{ return nil, NewError(
Code: ErrorCodeInvalidRequest, ErrorCodeInvalidRequest,
Description: "profile MUST NOT contain a port", "profile MUST NOT contain a port",
URI: "https://indieauth.net/source/#user-profile-url", "https://indieauth.net/source/#user-profile-url",
State: "", "",
frame: xerrors.Caller(1), )
}
} }
if net.ParseIP(domain) != nil { if net.ParseIP(domain) != nil {
return nil, Error{ return nil, NewError(
Code: ErrorCodeInvalidRequest, ErrorCodeInvalidRequest,
Description: "profile MUST NOT be ipv4 or ipv6 addresses", "profile MUST NOT be ipv4 or ipv6 addresses",
URI: "https://indieauth.net/source/#user-profile-url", "https://indieauth.net/source/#user-profile-url",
State: "", "",
frame: xerrors.Caller(1), )
}
} }
return &Me{me: me}, nil return &Me{me: me}, nil

View File

@ -2,11 +2,10 @@ package memory
import ( import (
"context" "context"
"errors"
"path" "path"
"sync" "sync"
"golang.org/x/xerrors"
"source.toby3d.me/website/indieauth/internal/domain" "source.toby3d.me/website/indieauth/internal/domain"
"source.toby3d.me/website/indieauth/internal/token" "source.toby3d.me/website/indieauth/internal/token"
) )
@ -25,7 +24,7 @@ func NewMemoryTokenRepository(store *sync.Map) token.Repository {
func (repo *memoryTokenRepository) Create(ctx context.Context, accessToken *domain.Token) error { func (repo *memoryTokenRepository) Create(ctx context.Context, accessToken *domain.Token) error {
t, err := repo.Get(ctx, accessToken.AccessToken) t, err := repo.Get(ctx, accessToken.AccessToken)
if err != nil && !xerrors.Is(err, token.ErrNotExist) { if err != nil && !errors.Is(err, token.ErrNotExist) {
return err return err
} }

View File

@ -2,11 +2,11 @@ package usecase
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"github.com/lestrrat-go/jwx/jwa" "github.com/lestrrat-go/jwx/jwa"
"github.com/lestrrat-go/jwx/jwt" "github.com/lestrrat-go/jwx/jwt"
"golang.org/x/xerrors"
"source.toby3d.me/website/indieauth/internal/domain" "source.toby3d.me/website/indieauth/internal/domain"
"source.toby3d.me/website/indieauth/internal/session" "source.toby3d.me/website/indieauth/internal/session"
@ -15,16 +15,16 @@ import (
type tokenUseCase struct { type tokenUseCase struct {
sessions session.Repository sessions session.Repository
config *domain.Config
tokens token.Repository tokens token.Repository
config *domain.Config
} }
func NewTokenUseCase(tokens token.Repository, sessions session.Repository, config *domain.Config) token.UseCase { func NewTokenUseCase(tokens token.Repository, sessions session.Repository, config *domain.Config) token.UseCase {
jwt.RegisterCustomField("scope", make(domain.Scopes, 0)) jwt.RegisterCustomField("scope", make(domain.Scopes, 0))
return &tokenUseCase{ return &tokenUseCase{
sessions: sessions,
config: config, config: config,
sessions: sessions,
tokens: tokens, tokens: tokens,
} }
} }
@ -51,7 +51,7 @@ func (useCase *tokenUseCase) Exchange(ctx context.Context, opts token.ExchangeOp
// NOTE(toby3d): If the authorization code was issued with no scope, the // NOTE(toby3d): If the authorization code was issued with no scope, the
// token endpoint MUST NOT issue an access token, as empty scopes are // token endpoint MUST NOT issue an access token, as empty scopes are
// invalid per Section 3.3 of OAuth 2.0 RFC6749. // invalid (RFC 6749 section 3.3).
if session.Scope.IsEmpty() { if session.Scope.IsEmpty() {
return nil, nil, token.ErrEmptyScope return nil, nil, token.ErrEmptyScope
} }
@ -82,7 +82,7 @@ func (useCase *tokenUseCase) Exchange(ctx context.Context, opts token.ExchangeOp
func (useCase *tokenUseCase) Verify(ctx context.Context, accessToken string) (*domain.Token, error) { func (useCase *tokenUseCase) Verify(ctx context.Context, accessToken string) (*domain.Token, error) {
find, err := useCase.tokens.Get(ctx, accessToken) find, err := useCase.tokens.Get(ctx, accessToken)
if err != nil && !xerrors.Is(err, token.ErrNotExist) { if err != nil && !errors.Is(err, token.ErrNotExist) {
return nil, fmt.Errorf("cannot check token in store: %w", err) return nil, fmt.Errorf("cannot check token in store: %w", err)
} }
@ -100,12 +100,8 @@ func (useCase *tokenUseCase) Verify(ctx context.Context, accessToken string) (*d
return nil, fmt.Errorf("cannot validate JWT token: %w", err) return nil, fmt.Errorf("cannot validate JWT token: %w", err)
} }
result := &domain.Token{ result := new(domain.Token)
Scope: nil, result.AccessToken = accessToken
ClientID: nil,
Me: nil,
AccessToken: accessToken,
}
result.ClientID, _ = domain.ParseClientID(tkn.Issuer()) result.ClientID, _ = domain.ParseClientID(tkn.Issuer())
result.Me, _ = domain.ParseMe(tkn.Subject()) result.Me, _ = domain.ParseMe(tkn.Subject())