Skip to content

Commit

Permalink
move echocontext to echox (#4)
Browse files Browse the repository at this point in the history
Signed-off-by: Sarah Funkhouser <[email protected]>
  • Loading branch information
golanglemonade authored Sep 13, 2024
1 parent 433987e commit daf522b
Show file tree
Hide file tree
Showing 11 changed files with 152 additions and 11 deletions.
1 change: 1 addition & 0 deletions bind.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ func bindData(destination interface{}, data map[string][]string, tag string) err
return err
}
}

val.Field(i).Set(slice)
} else if err := setWithProperType(typeField.Type.Kind(), inputValue[0], structField); err != nil {
return err
Expand Down
3 changes: 3 additions & 0 deletions binder.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ func (b *ValueBinder) customFunc(sourceParam string, customFunc func(values []st
}

values := b.ValuesFunc(sourceParam)

if len(values) == 0 {
if valueMustExist {
b.setError(b.ErrorFunc(sourceParam, []string{}, "required field value is empty", nil))
Expand Down Expand Up @@ -547,6 +548,7 @@ func (b *ValueBinder) intValue(sourceParam string, dest interface{}, bitSize int
return b.int(sourceParam, value, dest, bitSize)
}

// #nosec: G115
func (b *ValueBinder) int(sourceParam string, value string, dest interface{}, bitSize int) *ValueBinder {
n, err := strconv.ParseInt(value, 10, bitSize)
if err != nil {
Expand Down Expand Up @@ -795,6 +797,7 @@ func (b *ValueBinder) uintValue(sourceParam string, dest interface{}, bitSize in
return b.uint(sourceParam, value, dest, bitSize)
}

// #nosec: G115
func (b *ValueBinder) uint(sourceParam string, value string, dest interface{}, bitSize int) *ValueBinder {
n, err := strconv.ParseUint(value, 10, bitSize)
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions echo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,12 +303,12 @@ func TestEcho_StaticPanic(t *testing.T) {
{
name: "panics for ../",
givenRoot: "../assets",
expectError: "can not create sub FS, invalid root given, err: sub ../assets: invalid name",
expectError: "can not create sub FS, invalid root given, err: sub ../assets: invalid argument",
},
{
name: "panics for /",
givenRoot: "/assets",
expectError: "can not create sub FS, invalid root given, err: sub /assets: invalid name",
expectError: "can not create sub FS, invalid root given, err: sub /assets: invalid argument",
},
}

Expand Down
7 changes: 4 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
module github.com/theopenlane/echox

go 1.22.2
go 1.23.1

require (
github.com/golang-jwt/jwt/v5 v5.2.1
github.com/stretchr/testify v1.9.0
github.com/valyala/fasttemplate v1.2.2
golang.org/x/time v0.6.0
Expand All @@ -11,8 +12,8 @@ require (
require golang.org/x/text v0.18.0 // indirect

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
golang.org/x/net v0.29.0
gopkg.in/yaml.v3 v3.0.1 // indirect
Expand Down
10 changes: 6 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
Expand Down
4 changes: 2 additions & 2 deletions group_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -745,12 +745,12 @@ func TestGroup_StaticPanic(t *testing.T) {
{
name: "panics for ../",
givenRoot: "../images",
expectError: "can not create sub FS, invalid root given, err: sub ../images: invalid name",
expectError: "can not create sub FS, invalid root given, err: sub ../images: invalid argument",
},
{
name: "panics for /",
givenRoot: "/images",
expectError: "can not create sub FS, invalid root given, err: sub /images: invalid name",
expectError: "can not create sub FS, invalid root given, err: sub /images: invalid argument",
},
}

Expand Down
53 changes: 53 additions & 0 deletions middleware/echocontext/context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package echocontext

import (
"context"

echo "github.com/theopenlane/echox"
)

// EchoContextKey is the context key for the echo.Context
var EchoContextKey = &ContextKey{"EchoContextKey"}

// ContextKey is the key name for the additional context
type ContextKey struct {
name string
}

// CustomContext contains the echo.Context and request context.Context
type CustomContext struct {
echo.Context
ctx context.Context
}

// EchoContextToContextMiddleware is the middleware that adds the echo.Context to the parent context
func EchoContextToContextMiddleware() echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
ctx := context.WithValue(c.Request().Context(), EchoContextKey, c)

c.SetRequest(c.Request().WithContext(ctx))

cc := &CustomContext{c, ctx}

return next(cc)
}
}
}

// EchoContextFromContext gets the echo.Context from the parent context
func EchoContextFromContext(ctx context.Context) (echo.Context, error) {
// retrieve echo.Context from provided context
echoContext := ctx.Value(EchoContextKey)
if echoContext == nil {
return nil, ErrUnableToRetrieveEchoContext
}

// type cast the context to ensure echo.Context
ec, ok := echoContext.(echo.Context)
if !ok {
return ec, ErrUnableToRetrieveEchoContext
}

return ec, nil
}
2 changes: 2 additions & 0 deletions middleware/echocontext/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Package echocontext adds the echo context to the parent context
package echocontext
10 changes: 10 additions & 0 deletions middleware/echocontext/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package echocontext

import (
"errors"
)

var (
// ErrUnableToRetrieveEchoContext is returned when the echo context is unable to be parsed from parent context
ErrUnableToRetrieveEchoContext = errors.New("unable to retrieve echo context")
)
68 changes: 68 additions & 0 deletions middleware/echocontext/test_tools.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package echocontext

import (
"context"
"net/http"
"net/http/httptest"
"time"

"github.com/golang-jwt/jwt/v5"

echo "github.com/theopenlane/echox"
)

// NewTestEchoContext used for testing purposes ONLY
func NewTestEchoContext() echo.Context {
// create echo context
e := echo.New()
req := &http.Request{
Header: http.Header{},
}

// Set writer for tests that write on the response
recorder := httptest.NewRecorder()

return e.NewContext(req, recorder)
}

func NewTestContext() context.Context {
c := NewTestEchoContext()
ctx := context.WithValue(c.Request().Context(), EchoContextKey, c)

c.SetRequest(c.Request().WithContext(ctx))

return ctx
}

// newValidSignedJWT creates a jwt with a fake subject for testing purposes ONLY
func newValidSignedJWT(subject string) (*jwt.Token, error) {
iat := time.Now().Unix()
nbf := time.Now().Unix()
exp := time.Now().Add(time.Hour).Unix()

claims := jwt.MapClaims{
"sub": subject,
"issuer": "test suite",
"iat": iat,
"nbf": nbf,
"exp": exp,
}

jwt := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

return jwt, nil
}

// NewTestContextWithValidUser creates an echo context with a fake subject for testing purposes ONLY
func NewTestContextWithValidUser(subject string) (*echo.Context, error) {
ec := NewTestEchoContext()

j, err := newValidSignedJWT(subject)
if err != nil {
return nil, err
}

ec.Set("user", j)

return &ec, nil
}
1 change: 1 addition & 0 deletions route.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ func (r routeInfo) Reverse(params ...interface{}) string {
// in case of `*` wildcard or `:` (unescaped colon) param we replace everything till next slash or end of path
for ; i < l && r.path[i] != '/'; i++ {
}

uri.WriteString(fmt.Sprintf("%v", params[n]))

n++
Expand Down

0 comments on commit daf522b

Please sign in to comment.