@@ -2,6 +2,7 @@ package middleware
22
33import (
44 "errors"
5+ "fmt"
56 "net/http"
67 "net/http/httptest"
78 "net/url"
@@ -404,3 +405,194 @@ func TestJWTwithKID(t *testing.T) {
404405 }
405406 }
406407}
408+
409+ func TestJWTConfig_skipper (t * testing.T ) {
410+ e := echo .New ()
411+
412+ e .Use (JWTWithConfig (JWTConfig {
413+ Skipper : func (context echo.Context ) bool {
414+ return true // skip everything
415+ },
416+ SigningKey : []byte ("secret" ),
417+ }))
418+
419+ isCalled := false
420+ e .GET ("/" , func (c echo.Context ) error {
421+ isCalled = true
422+ return c .String (http .StatusTeapot , "test" )
423+ })
424+
425+ req := httptest .NewRequest (http .MethodGet , "/" , nil )
426+ res := httptest .NewRecorder ()
427+ e .ServeHTTP (res , req )
428+
429+ assert .Equal (t , http .StatusTeapot , res .Code )
430+ assert .True (t , isCalled )
431+ }
432+
433+ func TestJWTConfig_BeforeFunc (t * testing.T ) {
434+ e := echo .New ()
435+ e .GET ("/" , func (c echo.Context ) error {
436+ return c .String (http .StatusTeapot , "test" )
437+ })
438+
439+ isCalled := false
440+ e .Use (JWTWithConfig (JWTConfig {
441+ BeforeFunc : func (context echo.Context ) {
442+ isCalled = true
443+ },
444+ SigningKey : []byte ("secret" ),
445+ }))
446+
447+ req := httptest .NewRequest (http .MethodGet , "/" , nil )
448+ req .Header .Set (echo .HeaderAuthorization , DefaultJWTConfig .AuthScheme + " eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ" )
449+ res := httptest .NewRecorder ()
450+ e .ServeHTTP (res , req )
451+
452+ assert .Equal (t , http .StatusTeapot , res .Code )
453+ assert .True (t , isCalled )
454+ }
455+
456+ func TestJWTConfig_extractorErrorHandling (t * testing.T ) {
457+ var testCases = []struct {
458+ name string
459+ given JWTConfig
460+ expectStatusCode int
461+ }{
462+ {
463+ name : "ok, ErrorHandler is executed" ,
464+ given : JWTConfig {
465+ SigningKey : []byte ("secret" ),
466+ ErrorHandler : func (err error ) error {
467+ return echo .NewHTTPError (http .StatusTeapot , "custom_error" )
468+ },
469+ },
470+ expectStatusCode : http .StatusTeapot ,
471+ },
472+ {
473+ name : "ok, ErrorHandlerWithContext is executed" ,
474+ given : JWTConfig {
475+ SigningKey : []byte ("secret" ),
476+ ErrorHandlerWithContext : func (err error , context echo.Context ) error {
477+ return echo .NewHTTPError (http .StatusTeapot , "custom_error" )
478+ },
479+ },
480+ expectStatusCode : http .StatusTeapot ,
481+ },
482+ }
483+
484+ for _ , tc := range testCases {
485+ t .Run (tc .name , func (t * testing.T ) {
486+ e := echo .New ()
487+ e .GET ("/" , func (c echo.Context ) error {
488+ return c .String (http .StatusNotImplemented , "should not end up here" )
489+ })
490+
491+ e .Use (JWTWithConfig (tc .given ))
492+
493+ req := httptest .NewRequest (http .MethodGet , "/" , nil )
494+ res := httptest .NewRecorder ()
495+ e .ServeHTTP (res , req )
496+
497+ assert .Equal (t , tc .expectStatusCode , res .Code )
498+ })
499+ }
500+ }
501+
502+ func TestJWTConfig_parseTokenErrorHandling (t * testing.T ) {
503+ var testCases = []struct {
504+ name string
505+ given JWTConfig
506+ expectErr string
507+ }{
508+ {
509+ name : "ok, ErrorHandler is executed" ,
510+ given : JWTConfig {
511+ SigningKey : []byte ("secret" ),
512+ ErrorHandler : func (err error ) error {
513+ return echo .NewHTTPError (http .StatusTeapot , "ErrorHandler: " + err .Error ())
514+ },
515+ },
516+ expectErr : "{\" message\" :\" ErrorHandler: parsing failed\" }\n " ,
517+ },
518+ {
519+ name : "ok, ErrorHandlerWithContext is executed" ,
520+ given : JWTConfig {
521+ SigningKey : []byte ("secret" ),
522+ ErrorHandlerWithContext : func (err error , context echo.Context ) error {
523+ return echo .NewHTTPError (http .StatusTeapot , "ErrorHandlerWithContext: " + err .Error ())
524+ },
525+ },
526+ expectErr : "{\" message\" :\" ErrorHandlerWithContext: parsing failed\" }\n " ,
527+ },
528+ }
529+
530+ for _ , tc := range testCases {
531+ t .Run (tc .name , func (t * testing.T ) {
532+ e := echo .New ()
533+ //e.Debug = true
534+ e .GET ("/" , func (c echo.Context ) error {
535+ return c .String (http .StatusNotImplemented , "should not end up here" )
536+ })
537+
538+ config := tc .given
539+ parseTokenCalled := false
540+ config .ParseTokenFunc = func (auth string , c echo.Context ) (interface {}, error ) {
541+ parseTokenCalled = true
542+ return nil , errors .New ("parsing failed" )
543+ }
544+ e .Use (JWTWithConfig (config ))
545+
546+ req := httptest .NewRequest (http .MethodGet , "/" , nil )
547+ req .Header .Set (echo .HeaderAuthorization , DefaultJWTConfig .AuthScheme + " eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ" )
548+ res := httptest .NewRecorder ()
549+
550+ e .ServeHTTP (res , req )
551+
552+ assert .Equal (t , http .StatusTeapot , res .Code )
553+ assert .Equal (t , tc .expectErr , res .Body .String ())
554+ assert .True (t , parseTokenCalled )
555+ })
556+ }
557+ }
558+
559+ func TestJWTConfig_custom_ParseTokenFunc_Keyfunc (t * testing.T ) {
560+ e := echo .New ()
561+ e .GET ("/" , func (c echo.Context ) error {
562+ return c .String (http .StatusTeapot , "test" )
563+ })
564+
565+ // example of minimal custom ParseTokenFunc implementation. Allows you to use different versions of `github.com/dgrijalva/jwt-go`
566+ // with current JWT middleware
567+ signingKey := []byte ("secret" )
568+
569+ config := JWTConfig {
570+ ParseTokenFunc : func (auth string , c echo.Context ) (interface {}, error ) {
571+ keyFunc := func (t * jwt.Token ) (interface {}, error ) {
572+ if t .Method .Alg () != "HS256" {
573+ return nil , fmt .Errorf ("unexpected jwt signing method=%v" , t .Header ["alg" ])
574+ }
575+ return signingKey , nil
576+ }
577+
578+ // claims are of type `jwt.MapClaims` when token is created with `jwt.Parse`
579+ token , err := jwt .Parse (auth , keyFunc )
580+ if err != nil {
581+ return nil , err
582+ }
583+ if ! token .Valid {
584+ return nil , errors .New ("invalid token" )
585+ }
586+ return token , nil
587+ },
588+ }
589+
590+ e .Use (JWTWithConfig (config ))
591+
592+ req := httptest .NewRequest (http .MethodGet , "/" , nil )
593+ req .Header .Set (echo .HeaderAuthorization , DefaultJWTConfig .AuthScheme + " eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ" )
594+ res := httptest .NewRecorder ()
595+ e .ServeHTTP (res , req )
596+
597+ assert .Equal (t , http .StatusTeapot , res .Code )
598+ }
0 commit comments