Improved conditions

master
Niels Westland 3 months from now
parent 1f979eb1ad
commit 3aeee35f96

@ -0,0 +1,7 @@
package nwjwt
type Condition struct {
Key string
Op FilterOp
Value any
}

@ -0,0 +1,12 @@
package nwjwt
type FilterOp int
const (
FilterOpEqual FilterOp = iota
FilterOpNotEqual
FilterOpGreaterThan
FilterOpLessThan
FilterOpGreaterOrEqual
FilterOpLessOrEqual
)

@ -5,9 +5,12 @@ import (
"errors"
)
//https://auth0.com/docs/security/tokens/json-web-tokens/json-web-token-claims
//https://en.wikipedia.org/wiki/JSON_Web_Token
//https://connect2id.com/products/nimbus-jose-jwt/examples/jwk-generation
/*
Sources:
https://auth0.com/docs/security/tokens/json-web-tokens/json-web-token-claims
https://en.wikipedia.org/wiki/JSON_Web_Token
https://connect2id.com/products/nimbus-jose-jwt/examples/jwk-generation
*/
type ClaimSet map[string]any
@ -38,3 +41,14 @@ func GenerateRandomSecret() []byte {
return key
}
func anyToNum(value any) (float64, bool) {
switch value.(type) {
case int:
return float64(value.(int)), true
case float64:
return value.(float64), true
default:
return 0, false
}
}

@ -23,8 +23,8 @@ func NewToken() *Token {
}
}
func TokenFromString(token string) *Token {
parts := strings.SplitN(token, ".", 3)
func TokenFromString(tokenAsString string) *Token {
parts := strings.SplitN(tokenAsString, ".", 3)
if len(parts) != 3 {
return nil
}
@ -33,7 +33,7 @@ func TokenFromString(token string) *Token {
headerData, _ := base64.RawURLEncoding.DecodeString(parts[0])
json.Unmarshal(headerData, &header)
var claims map[string]interface{}
var claims map[string]any
claimsData, _ := base64.RawURLEncoding.DecodeString(parts[1])
json.Unmarshal(claimsData, &claims)
@ -70,7 +70,7 @@ func (t Token) Claim(key string) any {
return t.claims[key]
}
func (t Token) Validate(secret []byte, conditions ClaimSet) error {
func (t Token) Validate(secret []byte, conditions []Condition) error {
if !bytes.Equal(t.sign(secret), t.signature) {
return ErrSignatureInvalid
}
@ -93,11 +93,45 @@ func (t Token) Validate(secret []byte, conditions ClaimSet) error {
}
}
for name, value := range conditions {
if claim, hasClaim := t.claims[name]; hasClaim {
if claim != value {
return ErrConditionsDoNotMatch
//Check extra conditions
for _, condition := range conditions {
if claim, hasClaim := t.claims[condition.Key]; hasClaim {
switch condition.Op {
case FilterOpEqual:
if claim == condition.Value {
continue
}
case FilterOpNotEqual:
if claim != condition.Value {
continue
}
case FilterOpGreaterThan:
claimAsNum, claimIsNum := anyToNum(claim)
conditionAsNum, conditionIsNum := anyToNum(condition.Value)
if claimIsNum && conditionIsNum && conditionAsNum > claimAsNum {
continue
}
case FilterOpLessThan:
claimAsNum, claimIsNum := anyToNum(claim)
conditionAsNum, conditionIsNum := anyToNum(condition.Value)
if claimIsNum && conditionIsNum && conditionAsNum < claimAsNum {
continue
}
case FilterOpGreaterOrEqual:
claimAsNum, claimIsNum := anyToNum(claim)
conditionAsNum, conditionIsNum := anyToNum(condition.Value)
if claimIsNum && conditionIsNum && conditionAsNum >= claimAsNum {
continue
}
case FilterOpLessOrEqual:
claimAsNum, claimIsNum := anyToNum(claim)
conditionAsNum, conditionIsNum := anyToNum(condition.Value)
if claimIsNum && conditionIsNum && conditionAsNum <= claimAsNum {
continue
}
}
return ErrConditionsDoNotMatch
}
}

Loading…
Cancel
Save