github.com/hellofresh/janus@v0.0.0-20230925145208-ce8de8183c67/pkg/jwt/claims.go (about)

     1  package jwt
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  
     7  	"github.com/dgrijalva/jwt-go"
     8  )
     9  
    10  // JanusClaims is the temporary solution for JWT claims validation with leeway support,
    11  // should be removed as soon as github.com/dgrijalva/jwt-go 4.0 will be released with
    12  // leeway support out of the box. This code is loosely based on the solution from
    13  // https://github.com/dgrijalva/jwt-go/issues/131
    14  type JanusClaims struct {
    15  	jwt.MapClaims
    16  
    17  	leeway int64
    18  }
    19  
    20  // NewJanusClaims instantiates new JanusClaims
    21  func NewJanusClaims(leeway int64) *JanusClaims {
    22  	return &JanusClaims{MapClaims: jwt.MapClaims{}, leeway: leeway}
    23  }
    24  
    25  // UnmarshalJSON is Unmarshaler interface implementation for JanusClaims to unmarshal nested map claims correctly
    26  func (c *JanusClaims) UnmarshalJSON(text []byte) error {
    27  	return json.Unmarshal(text, &c.MapClaims)
    28  }
    29  
    30  // Valid validates time based claims "exp, iat, nbf".
    31  // As well, if any of the above claims are not in the token, it will still
    32  // be considered a valid claim.
    33  func (c *JanusClaims) Valid() error {
    34  	vErr := new(jwt.ValidationError)
    35  	now := jwt.TimeFunc().Unix()
    36  
    37  	if c.VerifyExpiresAt(now, false) == false {
    38  		vErr.Inner = errors.New("token is expired")
    39  		vErr.Errors |= jwt.ValidationErrorExpired
    40  	}
    41  
    42  	if c.VerifyIssuedAt(now, false) == false {
    43  		vErr.Inner = errors.New("token used before issued")
    44  		vErr.Errors |= jwt.ValidationErrorIssuedAt
    45  	}
    46  
    47  	if c.VerifyNotBefore(now, false) == false {
    48  		vErr.Inner = errors.New("token is not valid yet")
    49  		vErr.Errors |= jwt.ValidationErrorNotValidYet
    50  	}
    51  
    52  	if vErr.Errors == 0 {
    53  		return nil
    54  	}
    55  
    56  	return vErr
    57  }
    58  
    59  // VerifyExpiresAt overrides jwt.StandardClaims.VerifyExpiresAt() to use leeway for check
    60  func (c *JanusClaims) VerifyExpiresAt(cmp int64, req bool) bool {
    61  	return c.MapClaims.VerifyExpiresAt(cmp-c.leeway, req)
    62  }
    63  
    64  // VerifyIssuedAt overrides jwt.StandardClaims.VerifyIssuedAt() to use leeway for check
    65  func (c *JanusClaims) VerifyIssuedAt(cmp int64, req bool) bool {
    66  	return c.MapClaims.VerifyIssuedAt(cmp+c.leeway, req)
    67  }
    68  
    69  // VerifyNotBefore overrides jwt.StandardClaims.VerifyNotBefore() to use leeway for check
    70  func (c *JanusClaims) VerifyNotBefore(cmp int64, req bool) bool {
    71  	return c.MapClaims.VerifyNotBefore(cmp+c.leeway, req)
    72  }