Skip to content

Commit a7bf269

Browse files
committed
More validation testing
1 parent 6d0139f commit a7bf269

File tree

7 files changed

+311
-28
lines changed

7 files changed

+311
-28
lines changed

errors.go

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,23 @@ import (
55
"strings"
66
)
77

8-
// Error constants
98
var (
10-
ErrInvalidKey = errors.New("key is invalid")
11-
ErrInvalidKeyType = errors.New("key is of invalid type")
12-
ErrHashUnavailable = errors.New("the requested hash function is unavailable")
13-
9+
ErrInvalidKey = errors.New("key is invalid")
10+
ErrInvalidKeyType = errors.New("key is of invalid type")
11+
ErrHashUnavailable = errors.New("the requested hash function is unavailable")
1412
ErrTokenMalformed = errors.New("token is malformed")
1513
ErrTokenUnverifiable = errors.New("token is unverifiable")
16-
ErrTokenRequiredClaimMissing = errors.New("a required claim is missing")
1714
ErrTokenSignatureInvalid = errors.New("token signature is invalid")
18-
19-
ErrTokenInvalidAudience = errors.New("token has invalid audience")
20-
ErrTokenExpired = errors.New("token is expired")
21-
ErrTokenUsedBeforeIssued = errors.New("token used before issued")
22-
ErrTokenInvalidIssuer = errors.New("token has invalid issuer")
23-
ErrTokenInvalidSubject = errors.New("token has invalid subject")
24-
ErrTokenNotValidYet = errors.New("token is not valid yet")
25-
ErrTokenInvalidId = errors.New("token has invalid id")
26-
ErrTokenInvalidClaims = errors.New("token has invalid claims")
27-
28-
ErrInvalidType = errors.New("invalid type for claim")
15+
ErrTokenRequiredClaimMissing = errors.New("token is missing required claim")
16+
ErrTokenInvalidAudience = errors.New("token has invalid audience")
17+
ErrTokenExpired = errors.New("token is expired")
18+
ErrTokenUsedBeforeIssued = errors.New("token used before issued")
19+
ErrTokenInvalidIssuer = errors.New("token has invalid issuer")
20+
ErrTokenInvalidSubject = errors.New("token has invalid subject")
21+
ErrTokenNotValidYet = errors.New("token is not valid yet")
22+
ErrTokenInvalidId = errors.New("token has invalid id")
23+
ErrTokenInvalidClaims = errors.New("token has invalid claims")
24+
ErrInvalidType = errors.New("invalid type for claim")
2925
)
3026

3127
// joinedError is an error type that works similar to what [errors.Join]
@@ -46,7 +42,7 @@ func (je joinedError) Error() string {
4642

4743
// joinErrors joins together multiple errors. Useful for scenarios where
4844
// multiple errors next to each other occur, e.g., in claims validation.
49-
func joinErrors(errs []error) error {
45+
func joinErrors(errs ...error) error {
5046
return &joinedError{
5147
errs: errs,
5248
}

errors_go1_20.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,15 @@ func (je joinedError) Unwrap() []error {
2727
//
2828
// "token is unverifiable: no keyfunc was provided"
2929
func newError(message string, err error, more ...error) error {
30-
format := "%w: %s"
31-
args := []any{err, message}
30+
var format string
31+
var args []any
32+
if message != "" {
33+
format = "%w: %s"
34+
args = []any{err, message}
35+
} else {
36+
format = "%w"
37+
args = []any{err}
38+
}
3239

3340
for _, e := range more {
3441
format += ": %w"

errors_go_other.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,15 @@ func newError(message string, err error, more ...error) error {
5353
// We cannot wrap multiple errors here with %w, so we have to be a little
5454
// bit creative. Basically, we are using %s instead of %w to produce the
5555
// same error message and then throw the result into a custom error struct.
56-
format := "%s: %s"
57-
args := []any{err, message}
56+
var format string
57+
var args []any
58+
if message != "" {
59+
format = "%s: %s"
60+
args = []any{err, message}
61+
} else {
62+
format = "%s"
63+
args = []any{err}
64+
}
5865
errs := []error{err}
5966

6067
for _, e := range more {

errors_test.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func Test_joinErrors(t *testing.T) {
2727
}
2828
for _, tt := range tests {
2929
t.Run(tt.name, func(t *testing.T) {
30-
err := joinErrors(tt.args.errs)
30+
err := joinErrors(tt.args.errs...)
3131
for _, wantErr := range tt.wantErrors {
3232
if !errors.Is(err, wantErr) {
3333
t.Errorf("joinErrors() error = %v, does not contain %v", err, wantErr)
@@ -65,6 +65,18 @@ func Test_newError(t *testing.T) {
6565
wantMessage: "token is malformed: something is wrong: unexpected EOF",
6666
wantErrors: []error{ErrTokenMalformed},
6767
},
68+
{
69+
name: "two errors, no detail",
70+
args: args{message: "", err: ErrTokenInvalidClaims, more: []error{ErrTokenExpired}},
71+
wantMessage: "token has invalid claims: token is expired",
72+
wantErrors: []error{ErrTokenInvalidClaims, ErrTokenExpired},
73+
},
74+
{
75+
name: "two errors, no detail and join error",
76+
args: args{message: "", err: ErrTokenInvalidClaims, more: []error{joinErrors(ErrTokenExpired, ErrTokenNotValidYet)}},
77+
wantMessage: "token has invalid claims: token is expired, token is not valid yet",
78+
wantErrors: []error{ErrTokenInvalidClaims, ErrTokenExpired, ErrTokenNotValidYet},
79+
},
6880
}
6981
for _, tt := range tests {
7082
t.Run(tt.name, func(t *testing.T) {

parser.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyf
8282
// Perform signature validation
8383
token.Signature = parts[2]
8484
if err = token.Method.Verify(strings.Join(parts[0:2], "."), token.Signature, key); err != nil {
85-
return token, newError("could not verify", ErrTokenSignatureInvalid, err)
85+
return token, newError("", ErrTokenSignatureInvalid, err)
8686
}
8787

8888
// Validate Claims
@@ -93,7 +93,7 @@ func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyf
9393
}
9494

9595
if err := p.validator.Validate(claims); err != nil {
96-
return token, err
96+
return token, newError("", ErrTokenInvalidClaims, err)
9797
}
9898
}
9999

validator.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ func (v *validator) Validate(claims Claims) error {
120120
// If we have an expected subject, we also require the subject claim
121121
if v.expectedSub != "" {
122122
if err = v.verifySubject(claims, v.expectedSub, true); err != nil {
123-
errs = append(errs, ErrTokenInvalidSubject)
123+
errs = append(errs, err)
124124
}
125125
}
126126

@@ -137,7 +137,7 @@ func (v *validator) Validate(claims Claims) error {
137137
return nil
138138
}
139139

140-
return joinErrors(errs)
140+
return joinErrors(errs...)
141141
}
142142

143143
// verifyExpiresAt compares the exp claim in claims against cmp. This function
@@ -276,7 +276,7 @@ func (v *validator) verifySubject(claims Claims, cmp string, required bool) erro
276276
return errorIfRequired(required, "sub")
277277
}
278278

279-
return errorIfFalse(sub == cmp, ErrTokenInvalidIssuer)
279+
return errorIfFalse(sub == cmp, ErrTokenInvalidSubject)
280280
}
281281

282282
// errorIfFalse returns the error specified in err, if the value is true.

0 commit comments

Comments
 (0)