Skip to content

Commit

Permalink
Add "missing required claims" error (#714)
Browse files Browse the repository at this point in the history
* Return `RequiredClaimValidationError` error when required claim is missing

* slightly rework #713

* Hide error type from users
  -> We would like to expose APIs, not data types (where applicable)
* Expose a function to create the error
* Changed the underlying error type to implement ValidationError interface

* appease linter

Co-authored-by: Stefano Arlandini <sarlandini@alice.it>
  • Loading branch information
lestrrat and ste93cry authored Apr 23, 2022
1 parent 6781a2a commit 46cf0ef
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 2 deletions.
7 changes: 7 additions & 0 deletions jwt/jwt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1291,6 +1291,13 @@ func TestGH430(t *testing.T) {
}
}

func TestGH706(t *testing.T) {
tok := jwt.New()
if !assert.ErrorIs(t, jwt.ErrMissingRequiredClaim(""), jwt.Validate(tok, jwt.WithRequiredClaim("foo")), `jwt.Validate should fail`) {
return
}
}

func TestBenHigginsByPassRegression(t *testing.T) {
key, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
Expand Down
26 changes: 24 additions & 2 deletions jwt/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,22 @@ func (err *validationError) Unwrap() error {
return err.error
}

type missingRequiredClaimError struct {
claim string
}

func (err *missingRequiredClaimError) Error() string {
return fmt.Sprintf("%q not satisfied: required claim not found", err.claim)
}

func (err *missingRequiredClaimError) Is(target error) bool {
_, ok := target.(*missingRequiredClaimError)
return ok
}

func (err *missingRequiredClaimError) isValidationError() {}
func (*missingRequiredClaimError) Unwrap() error { return nil }

var errTokenExpired = NewValidationError(fmt.Errorf(`"exp" not satisfied`))
var errInvalidIssuedAt = NewValidationError(fmt.Errorf(`"iat" not satisfied`))
var errTokenNotYetValid = NewValidationError(fmt.Errorf(`"nbf" not satisfied`))
Expand All @@ -179,6 +195,11 @@ func ErrTokenNotYetValid() ValidationError {
return errTokenNotYetValid
}

// ErrMissingRequiredClaim creates a new error for missing required claims.
func ErrMissingRequiredClaim(name string) ValidationError {
return &missingRequiredClaimError{claim: name}
}

// Validator describes interface to validate a Token.
type Validator interface {
// Validate should return an error if a required conditions is not met.
Expand Down Expand Up @@ -377,9 +398,10 @@ func IsRequired(name string) Validator {
type isRequired string

func (ir isRequired) Validate(_ context.Context, t Token) ValidationError {
_, ok := t.Get(string(ir))
name := string(ir)
_, ok := t.Get(name)
if !ok {
return NewValidationError(fmt.Errorf(`%q not satisfied: required claim not found`, string(ir)))
return ErrMissingRequiredClaim(name)
}
return nil
}

0 comments on commit 46cf0ef

Please sign in to comment.