Skip to content

Commit c3edf89

Browse files
committed
Rename NoErrorContinuesExecution to ContinueOnIgnoredError, improve docs, add additional tests
1 parent db86f12 commit c3edf89

File tree

5 files changed

+90
-67
lines changed

5 files changed

+90
-67
lines changed

middleware/csrf_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,18 @@ func TestCSRF_tokenExtractors(t *testing.T) {
2424
givenHeaderTokens map[string][]string
2525
expectError string
2626
}{
27+
{
28+
name: "ok, multiple token lookups sources, succeeds on last one",
29+
whenTokenLookup: "header:X-CSRF-Token,form:csrf",
30+
givenCSRFCookie: "token",
31+
givenMethod: http.MethodPost,
32+
givenHeaderTokens: map[string][]string{
33+
echo.HeaderXCSRFToken: {"invalid_token"},
34+
},
35+
givenFormTokens: map[string][]string{
36+
"csrf": {"token"},
37+
},
38+
},
2739
{
2840
name: "ok, token from POST form",
2941
whenTokenLookup: "form:csrf",

middleware/jwt.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,12 @@ type (
3232
// ErrorHandlerWithContext is almost identical to ErrorHandler, but it's passed the current context.
3333
ErrorHandlerWithContext JWTErrorHandlerWithContext
3434

35-
// NoErrorContinuesExecution allows next middleware/handler to be called when ErrorHandlerWithContext decides to
36-
// swallow the error (returns nil).
37-
// This is useful in cases when portion of your site/api is publicly accessible and has extra features for authorized
38-
// users. In that case you can use ErrorHandlerWithContext to set default public JWT token value to request and
39-
// continue with handler chain. Assuming logic downstream execution chain has to check that (public) token value.
40-
NoErrorContinuesExecution bool
35+
// ContinueOnIgnoredError allows the next middleware/handler to be called when ErrorHandlerWithContext decides to
36+
// ignore the error (by returning `nil`).
37+
// This is useful when parts of your site/api allow public access and some authorized routes provide extra functionality.
38+
// In that case you can use ErrorHandlerWithContext to set a default public JWT token value in the request context
39+
// and continue. Some logic down the remaining execution chain needs to check that (public) token value then.
40+
ContinueOnIgnoredError bool
4141

4242
// Signing key to validate token.
4343
// This is one of the three options to provide a token validation key.
@@ -79,7 +79,7 @@ type (
7979
// - "cookie:<name>"
8080
// - "form:<name>"
8181
// Multiple sources example:
82-
// - "header:Authorization ,cookie:myowncookie"
82+
// - "header:Authorization,cookie:myowncookie"
8383
TokenLookup string
8484

8585
// TokenLookupFuncs defines a list of user-defined functions that extract JWT token from the given context.
@@ -242,7 +242,7 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc {
242242
}
243243
if config.ErrorHandlerWithContext != nil {
244244
tmpErr := config.ErrorHandlerWithContext(err, c)
245-
if config.NoErrorContinuesExecution && tmpErr == nil {
245+
if config.ContinueOnIgnoredError && tmpErr == nil {
246246
return next(c)
247247
}
248248
return tmpErr

middleware/jwt_test.go

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -704,42 +704,42 @@ func TestJWTConfig_SuccessHandler(t *testing.T) {
704704
}
705705
}
706706

707-
func TestJWTConfig_NoErrorContinuesExecution(t *testing.T) {
707+
func TestJWTConfig_ContinueOnIgnoredError(t *testing.T) {
708708
var testCases = []struct {
709-
name string
710-
whenNoErrorContinuesExecution bool
711-
givenToken string
712-
expectStatus int
713-
expectBody string
709+
name string
710+
whenContinueOnIgnoredError bool
711+
givenToken string
712+
expectStatus int
713+
expectBody string
714714
}{
715715
{
716-
name: "no error handler is called",
717-
whenNoErrorContinuesExecution: true,
718-
givenToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ",
719-
expectStatus: http.StatusTeapot,
720-
expectBody: "",
716+
name: "no error handler is called",
717+
whenContinueOnIgnoredError: true,
718+
givenToken: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ",
719+
expectStatus: http.StatusTeapot,
720+
expectBody: "",
721721
},
722722
{
723-
name: "NoErrorContinuesExecution is false and error handler is called for missing token",
724-
whenNoErrorContinuesExecution: false,
725-
givenToken: "",
723+
name: "ContinueOnIgnoredError is false and error handler is called for missing token",
724+
whenContinueOnIgnoredError: false,
725+
givenToken: "",
726726
// empty response with 200. This emulates previous behaviour when error handler swallowed the error
727727
expectStatus: http.StatusOK,
728728
expectBody: "",
729729
},
730730
{
731-
name: "error handler is called for missing token",
732-
whenNoErrorContinuesExecution: true,
733-
givenToken: "",
734-
expectStatus: http.StatusTeapot,
735-
expectBody: "public-token",
731+
name: "error handler is called for missing token",
732+
whenContinueOnIgnoredError: true,
733+
givenToken: "",
734+
expectStatus: http.StatusTeapot,
735+
expectBody: "public-token",
736736
},
737737
{
738-
name: "error handler is called for invalid token",
739-
whenNoErrorContinuesExecution: true,
740-
givenToken: "x.x.x",
741-
expectStatus: http.StatusUnauthorized,
742-
expectBody: "{\"message\":\"Unauthorized\"}\n",
738+
name: "error handler is called for invalid token",
739+
whenContinueOnIgnoredError: true,
740+
givenToken: "x.x.x",
741+
expectStatus: http.StatusUnauthorized,
742+
expectBody: "{\"message\":\"Unauthorized\"}\n",
743743
},
744744
}
745745

@@ -753,8 +753,8 @@ func TestJWTConfig_NoErrorContinuesExecution(t *testing.T) {
753753
})
754754

755755
e.Use(JWTWithConfig(JWTConfig{
756-
NoErrorContinuesExecution: tc.whenNoErrorContinuesExecution,
757-
SigningKey: []byte("secret"),
756+
ContinueOnIgnoredError: tc.whenContinueOnIgnoredError,
757+
SigningKey: []byte("secret"),
758758
ErrorHandlerWithContext: func(err error, c echo.Context) error {
759759
if err == ErrJWTMissing {
760760
c.Set("test", "public-token")

middleware/key_auth.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,12 @@ type (
4040
// It may be used to define a custom error.
4141
ErrorHandler KeyAuthErrorHandler
4242

43-
// NoErrorContinuesExecution allows next middleware/handler to be called when ErrorHandler decides to swallow
44-
// the error (returns nil).
45-
// This is useful in cases when portion of your site/api is publicly accessible and has extra features for valid
46-
// requests. In that case you can use ErrorHandler to set default public auth values to request and continue with
47-
// handler chain. Assuming logic downstream execution chain has to check that (public) auth value.
48-
NoErrorContinuesExecution bool
43+
// ContinueOnIgnoredError allows the next middleware/handler to be called when ErrorHandler decides to
44+
// ignore the error (by returning `nil`).
45+
// This is useful when parts of your site/api allow public access and some authorized routes provide extra functionality.
46+
// In that case you can use ErrorHandler to set a default public key auth value in the request context
47+
// and continue. Some logic down the remaining execution chain needs to check that (public) key auth value then.
48+
ContinueOnIgnoredError bool
4949
}
5050

5151
// KeyAuthValidator defines a function to validate KeyAuth credentials.
@@ -162,7 +162,7 @@ func KeyAuthWithConfig(config KeyAuthConfig) echo.MiddlewareFunc {
162162

163163
if config.ErrorHandler != nil {
164164
tmpErr := config.ErrorHandler(err, c)
165-
if config.NoErrorContinuesExecution && tmpErr == nil {
165+
if config.ContinueOnIgnoredError && tmpErr == nil {
166166
return next(c)
167167
}
168168
return tmpErr

middleware/key_auth_test.go

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,17 @@ func TestKeyAuthWithConfig(t *testing.T) {
9292
expectHandlerCalled: false,
9393
expectError: "code=400, message=missing key in request header",
9494
},
95+
{
96+
name: "ok, custom key lookup from multiple places, query and header",
97+
givenRequest: func(req *http.Request) {
98+
req.URL.RawQuery = "key=invalid-key"
99+
req.Header.Set("API-Key", "valid-key")
100+
},
101+
whenConfig: func(conf *KeyAuthConfig) {
102+
conf.KeyLookup = "query:key,header:API-Key"
103+
},
104+
expectHandlerCalled: true,
105+
},
95106
{
96107
name: "ok, custom key lookup, header",
97108
givenRequest: func(req *http.Request) {
@@ -289,42 +300,42 @@ func TestKeyAuthWithConfig_panicsOnEmptyValidator(t *testing.T) {
289300
)
290301
}
291302

292-
func TestKeyAuthWithConfig_NoErrorContinuesExecution(t *testing.T) {
303+
func TestKeyAuthWithConfig_ContinueOnIgnoredError(t *testing.T) {
293304
var testCases = []struct {
294-
name string
295-
whenNoErrorContinuesExecution bool
296-
givenKey string
297-
expectStatus int
298-
expectBody string
305+
name string
306+
whenContinueOnIgnoredError bool
307+
givenKey string
308+
expectStatus int
309+
expectBody string
299310
}{
300311
{
301-
name: "no error handler is called",
302-
whenNoErrorContinuesExecution: true,
303-
givenKey: "valid-key",
304-
expectStatus: http.StatusTeapot,
305-
expectBody: "",
312+
name: "no error handler is called",
313+
whenContinueOnIgnoredError: true,
314+
givenKey: "valid-key",
315+
expectStatus: http.StatusTeapot,
316+
expectBody: "",
306317
},
307318
{
308-
name: "NoErrorContinuesExecution is false and error handler is called for missing token",
309-
whenNoErrorContinuesExecution: false,
310-
givenKey: "",
319+
name: "ContinueOnIgnoredError is false and error handler is called for missing token",
320+
whenContinueOnIgnoredError: false,
321+
givenKey: "",
311322
// empty response with 200. This emulates previous behaviour when error handler swallowed the error
312323
expectStatus: http.StatusOK,
313324
expectBody: "",
314325
},
315326
{
316-
name: "error handler is called for missing token",
317-
whenNoErrorContinuesExecution: true,
318-
givenKey: "",
319-
expectStatus: http.StatusTeapot,
320-
expectBody: "public-auth",
327+
name: "error handler is called for missing token",
328+
whenContinueOnIgnoredError: true,
329+
givenKey: "",
330+
expectStatus: http.StatusTeapot,
331+
expectBody: "public-auth",
321332
},
322333
{
323-
name: "error handler is called for invalid token",
324-
whenNoErrorContinuesExecution: true,
325-
givenKey: "x.x.x",
326-
expectStatus: http.StatusUnauthorized,
327-
expectBody: "{\"message\":\"Unauthorized\"}\n",
334+
name: "error handler is called for invalid token",
335+
whenContinueOnIgnoredError: true,
336+
givenKey: "x.x.x",
337+
expectStatus: http.StatusUnauthorized,
338+
expectBody: "{\"message\":\"Unauthorized\"}\n",
328339
},
329340
}
330341

@@ -346,8 +357,8 @@ func TestKeyAuthWithConfig_NoErrorContinuesExecution(t *testing.T) {
346357
}
347358
return echo.ErrUnauthorized
348359
},
349-
KeyLookup: "header:X-API-Key",
350-
NoErrorContinuesExecution: tc.whenNoErrorContinuesExecution,
360+
KeyLookup: "header:X-API-Key",
361+
ContinueOnIgnoredError: tc.whenContinueOnIgnoredError,
351362
}))
352363

353364
req := httptest.NewRequest(http.MethodGet, "/", nil)

0 commit comments

Comments
 (0)