diff --git a/internal/auth/delivery/http/auth_http.go b/internal/auth/delivery/http/auth_http.go index 375fe9e..f65abc2 100644 --- a/internal/auth/delivery/http/auth_http.go +++ b/internal/auth/delivery/http/auth_http.go @@ -1,7 +1,6 @@ package http import ( - "bytes" "crypto/subtle" "errors" "path" @@ -65,7 +64,7 @@ type ( RedirectURI *domain.URL `form:"redirect_uri"` CodeChallengeMethod domain.CodeChallengeMethod `form:"code_challenge_method"` ResponseType domain.ResponseType `form:"response_type"` - Scope domain.Scopes `form:"scope[]"` // TODO(toby3d): fix parsing in form pkg + Scope domain.Scopes `form:"scope[]"` Authorize string `form:"authorize"` CodeChallenge string `form:"code_challenge"` State string `form:"state"` @@ -352,7 +351,7 @@ func NewAuthAuthorizationRequest() *AuthAuthorizationRequest { //nolint: cyclop func (r *AuthAuthorizationRequest) bind(ctx *http.RequestCtx) error { indieAuthError := new(domain.Error) - if err := form.Unmarshal(ctx.QueryArgs(), r); err != nil { + if err := form.Unmarshal(ctx.QueryArgs().QueryString(), r); err != nil { if errors.As(err, indieAuthError) { return indieAuthError } @@ -364,45 +363,6 @@ func (r *AuthAuthorizationRequest) bind(ctx *http.RequestCtx) error { ) } - if err := r.Scope.UnmarshalForm(ctx.QueryArgs().Peek("scope")); err != nil { - if errors.As(err, indieAuthError) { - return indieAuthError - } - - return domain.NewError( - domain.ErrorCodeInvalidScope, - err.Error(), - "https://indieweb.org/scope", - ) - } - - if ctx.QueryArgs().Has("code_challenge") { - err := r.CodeChallengeMethod.UnmarshalForm(ctx.QueryArgs().Peek("code_challenge_method")) - if err != nil { - if errors.As(err, indieAuthError) { - return indieAuthError - } - - return domain.NewError( - domain.ErrorCodeInvalidRequest, - err.Error(), - "", - ) - } - } - - if err := r.ResponseType.UnmarshalForm(ctx.QueryArgs().Peek("response_type")); err != nil { - if errors.As(err, indieAuthError) { - return indieAuthError - } - - return domain.NewError( - domain.ErrorCodeUnsupportedResponseType, - err.Error(), - "", - ) - } - if r.ResponseType == domain.ResponseTypeID { r.ResponseType = domain.ResponseTypeCode } @@ -429,7 +389,7 @@ func NewAuthVerifyRequest() *AuthVerifyRequest { func (r *AuthVerifyRequest) bind(ctx *http.RequestCtx) error { indieAuthError := new(domain.Error) - if err := form.Unmarshal(ctx.PostArgs(), r); err != nil { + if err := form.Unmarshal(ctx.PostArgs().QueryString(), r); err != nil { if errors.As(err, indieAuthError) { return indieAuthError } @@ -441,45 +401,6 @@ func (r *AuthVerifyRequest) bind(ctx *http.RequestCtx) error { ) } - if err := r.Scope.UnmarshalForm(bytes.Join(ctx.PostArgs().PeekMulti("scope[]"), []byte(" "))); err != nil { - if errors.As(err, indieAuthError) { - return indieAuthError - } - - return domain.NewError( - domain.ErrorCodeInvalidScope, - err.Error(), - "https://indieweb.org/scope", - ) - } - - if ctx.PostArgs().Has("code_challenge") { - err := r.CodeChallengeMethod.UnmarshalForm(ctx.PostArgs().Peek("code_challenge_method")) - if err != nil { - if errors.As(err, indieAuthError) { - return indieAuthError - } - - return domain.NewError( - domain.ErrorCodeInvalidRequest, - err.Error(), - "", - ) - } - } - - if err := r.ResponseType.UnmarshalForm(ctx.PostArgs().Peek("response_type")); err != nil { - if errors.As(err, indieAuthError) { - return indieAuthError - } - - return domain.NewError( - domain.ErrorCodeUnsupportedResponseType, - err.Error(), - "", - ) - } - // NOTE(toby3d): backwards-compatible support. // See: https://aaronparecki.com/2020/12/03/1/indieauth-2020#response-type if r.ResponseType == domain.ResponseTypeID { @@ -501,7 +422,7 @@ func (r *AuthVerifyRequest) bind(ctx *http.RequestCtx) error { func (r *AuthExchangeRequest) bind(ctx *http.RequestCtx) error { indieAuthError := new(domain.Error) - if err := form.Unmarshal(ctx.PostArgs(), r); err != nil { + if err := form.Unmarshal(ctx.PostArgs().QueryString(), r); err != nil { if errors.As(err, indieAuthError) { return indieAuthError } diff --git a/internal/client/delivery/http/client_http.go b/internal/client/delivery/http/client_http.go index b4a7d83..42f93de 100644 --- a/internal/client/delivery/http/client_http.go +++ b/internal/client/delivery/http/client_http.go @@ -168,7 +168,7 @@ func (h *RequestHandler) handleCallback(ctx *http.RequestCtx) { func (req *ClientCallbackRequest) bind(ctx *http.RequestCtx) error { indieAuthError := new(domain.Error) - if err := form.Unmarshal(ctx.QueryArgs(), req); err != nil { + if err := form.Unmarshal(ctx.QueryArgs().QueryString(), req); err != nil { if errors.As(err, indieAuthError) { return indieAuthError } @@ -176,16 +176,5 @@ func (req *ClientCallbackRequest) bind(ctx *http.RequestCtx) error { return domain.NewError(domain.ErrorCodeInvalidRequest, err.Error(), "") } - // TODO(toby3d): fix this in form package logic. - if ctx.QueryArgs().Has("error") { - if err := req.Error.UnmarshalForm(ctx.QueryArgs().Peek("error")); err != nil { - if errors.As(err, indieAuthError) { - return indieAuthError - } - - return domain.NewError(domain.ErrorCodeInvalidRequest, err.Error(), "") - } - } - return nil } diff --git a/internal/domain/token.go b/internal/domain/token.go index 30e9bde..c8303f8 100644 --- a/internal/domain/token.go +++ b/internal/domain/token.go @@ -5,8 +5,8 @@ import ( "testing" "time" - "github.com/lestrrat-go/jwx/jwa" - "github.com/lestrrat-go/jwx/jwt" + "github.com/lestrrat-go/jwx/v2/jwa" + "github.com/lestrrat-go/jwx/v2/jwt" http "github.com/valyala/fasthttp" "source.toby3d.me/toby3d/auth/internal/random" @@ -92,7 +92,7 @@ func NewToken(opts NewTokenOptions) (*Token, error) { } } - accessToken, err := jwt.Sign(tkn, jwa.SignatureAlgorithm(opts.Algorithm), opts.Secret) + accessToken, err := jwt.Sign(tkn, jwt.WithKey(jwa.SignatureAlgorithm(opts.Algorithm), opts.Secret)) if err != nil { return nil, fmt.Errorf("cannot sign a new access token: %w", err) } @@ -146,7 +146,7 @@ func TestToken(tb testing.TB) *Token { _ = tkn.Set(key, val) } - accessToken, err := jwt.Sign(tkn, jwa.HS256, []byte("hackme")) + accessToken, err := jwt.Sign(tkn, jwt.WithKey(jwa.HS256, []byte("hackme"))) if err != nil { tb.Fatal(err) } diff --git a/internal/ticket/delivery/http/ticket_http.go b/internal/ticket/delivery/http/ticket_http.go index 09ecb96..68c7aa6 100644 --- a/internal/ticket/delivery/http/ticket_http.go +++ b/internal/ticket/delivery/http/ticket_http.go @@ -7,7 +7,7 @@ import ( "github.com/fasthttp/router" "github.com/goccy/go-json" - "github.com/lestrrat-go/jwx/jwa" + "github.com/lestrrat-go/jwx/v2/jwa" http "github.com/valyala/fasthttp" "golang.org/x/text/language" "golang.org/x/text/message" @@ -200,7 +200,7 @@ func (h *RequestHandler) handleRedeem(ctx *http.RequestCtx) { func (req *TicketGenerateRequest) bind(ctx *http.RequestCtx) (err error) { indieAuthError := new(domain.Error) - if err = form.Unmarshal(ctx.Request.PostArgs(), req); err != nil { + if err = form.Unmarshal(ctx.Request.PostArgs().QueryString(), req); err != nil { if errors.As(err, indieAuthError) { return indieAuthError } @@ -231,9 +231,9 @@ func (req *TicketGenerateRequest) bind(ctx *http.RequestCtx) (err error) { return nil } -func (req *TicketExchangeRequest) bind(ctx *http.RequestCtx) (err error) { +func (req *TicketExchangeRequest) bind(ctx *http.RequestCtx) error { indieAuthError := new(domain.Error) - if err = form.Unmarshal(ctx.Request.PostArgs(), req); err != nil { + if err := form.Unmarshal(ctx.Request.PostArgs().QueryString(), req); err != nil { if errors.As(err, indieAuthError) { return indieAuthError } diff --git a/internal/token/delivery/http/token_http.go b/internal/token/delivery/http/token_http.go index d401ac9..26d60a9 100644 --- a/internal/token/delivery/http/token_http.go +++ b/internal/token/delivery/http/token_http.go @@ -6,7 +6,7 @@ import ( "github.com/fasthttp/router" json "github.com/goccy/go-json" - "github.com/lestrrat-go/jwx/jwa" + "github.com/lestrrat-go/jwx/v2/jwa" http "github.com/valyala/fasthttp" "source.toby3d.me/toby3d/auth/internal/common" @@ -38,11 +38,11 @@ type ( // The client may request a token with the same or fewer scopes // than the original access token. If omitted, is treated as // equal to the original scopes granted. - Scope domain.Scopes `form:"scope,omitempty"` + Scope domain.Scopes `form:"scope"` } TokenRevocationRequest struct { - Action domain.Action `form:"action"` + Action domain.Action `form:"action,omitempty"` Token string `form:"token"` } @@ -150,8 +150,7 @@ func (h *RequestHandler) Register(r *router.Router) { return matched }, SuccessHandler: nil, - TokenLookup: "header:" + http.HeaderAuthorization + ":Bearer " + - ",param:token", + TokenLookup: "param:token,header:" + http.HeaderAuthorization + ":Bearer ", }), middleware.LogFmt(), } @@ -303,7 +302,7 @@ func (h *RequestHandler) handleRevokation(ctx *http.RequestCtx) { encoder := json.NewEncoder(ctx) - req := new(TokenRevocationRequest) + req := NewTokenRevocationRequest() if err := req.bind(ctx); err != nil { ctx.SetStatusCode(http.StatusBadRequest) @@ -366,7 +365,7 @@ func (h *RequestHandler) handleTicket(ctx *http.RequestCtx) { func (r *TokenExchangeRequest) bind(ctx *http.RequestCtx) error { indieAuthError := new(domain.Error) - if err := form.Unmarshal(ctx.PostArgs(), r); err != nil { + if err := form.Unmarshal(ctx.QueryArgs().QueryString(), r); err != nil { if errors.As(err, indieAuthError) { return indieAuthError } @@ -381,9 +380,18 @@ func (r *TokenExchangeRequest) bind(ctx *http.RequestCtx) error { return nil } +func NewTokenRevocationRequest() *TokenRevocationRequest { + return &TokenRevocationRequest{ + Action: domain.ActionRevoke, + Token: "", + } +} + func (r *TokenRevocationRequest) bind(ctx *http.RequestCtx) error { indieAuthError := new(domain.Error) - if err := form.Unmarshal(ctx.PostArgs(), r); err != nil { + + err := form.Unmarshal(ctx.PostArgs().QueryString(), r) + if err != nil { if errors.As(err, indieAuthError) { return indieAuthError } @@ -400,7 +408,7 @@ func (r *TokenRevocationRequest) bind(ctx *http.RequestCtx) error { func (r *TokenTicketRequest) bind(ctx *http.RequestCtx) error { indieAuthError := new(domain.Error) - if err := form.Unmarshal(ctx.PostArgs(), r); err != nil { + if err := form.Unmarshal(ctx.QueryArgs().QueryString(), r); err != nil { if errors.As(err, indieAuthError) { return indieAuthError } @@ -417,7 +425,7 @@ func (r *TokenTicketRequest) bind(ctx *http.RequestCtx) error { func (r *TokenIntrospectRequest) bind(ctx *http.RequestCtx) error { indieAuthError := new(domain.Error) - if err := form.Unmarshal(ctx.PostArgs(), r); err != nil { + if err := form.Unmarshal(ctx.PostArgs().QueryString(), r); err != nil { if errors.As(err, indieAuthError) { return indieAuthError } diff --git a/internal/token/usecase/token_ucase.go b/internal/token/usecase/token_ucase.go index c2ee019..b246a6e 100644 --- a/internal/token/usecase/token_ucase.go +++ b/internal/token/usecase/token_ucase.go @@ -5,8 +5,8 @@ import ( "errors" "fmt" - "github.com/lestrrat-go/jwx/jwa" - "github.com/lestrrat-go/jwx/jwt" + "github.com/lestrrat-go/jwx/v2/jwa" + "github.com/lestrrat-go/jwx/v2/jwt" "source.toby3d.me/toby3d/auth/internal/domain" "source.toby3d.me/toby3d/auth/internal/profile" @@ -97,8 +97,8 @@ func (uc *tokenUseCase) Verify(ctx context.Context, accessToken string) (*domain return nil, nil, fmt.Errorf("cannot check token in store: %w", err) } - tkn, err := jwt.ParseString(accessToken, jwt.WithVerify(jwa.SignatureAlgorithm(uc.config.JWT.Algorithm), - []byte(uc.config.JWT.Secret))) + tkn, err := jwt.ParseString(accessToken, jwt.WithKey(jwa.SignatureAlgorithm(uc.config.JWT.Algorithm), + []byte(uc.config.JWT.Secret)), jwt.WithVerify(true)) if err != nil { return nil, nil, fmt.Errorf("cannot parse JWT token: %w", err) } diff --git a/internal/user/delivery/http/user_http.go b/internal/user/delivery/http/user_http.go index 99ad92b..272d84d 100644 --- a/internal/user/delivery/http/user_http.go +++ b/internal/user/delivery/http/user_http.go @@ -5,7 +5,7 @@ import ( "strings" "github.com/fasthttp/router" - "github.com/lestrrat-go/jwx/jwa" + "github.com/lestrrat-go/jwx/v2/jwa" http "github.com/valyala/fasthttp" "source.toby3d.me/toby3d/auth/internal/common"