github.com/nats-io/jwt/v2@v2.5.6/decoder_test.go (about)

     1  /*
     2   * Copyright 2018 The NATS Authors
     3   * Licensed under the Apache License, Version 2.0 (the "License");
     4   * you may not use this file except in compliance with the License.
     5   * You may obtain a copy of the License at
     6   *
     7   * http://www.apache.org/licenses/LICENSE-2.0
     8   *
     9   * Unless required by applicable law or agreed to in writing, software
    10   * distributed under the License is distributed on an "AS IS" BASIS,
    11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12   * See the License for the specific language governing permissions and
    13   * limitations under the License.
    14   */
    15  
    16  package jwt
    17  
    18  import (
    19  	"encoding/json"
    20  	"fmt"
    21  	"reflect"
    22  	"strings"
    23  	"testing"
    24  	"time"
    25  
    26  	"github.com/nats-io/nkeys"
    27  )
    28  
    29  func TestNewToken(t *testing.T) {
    30  	kp, err := nkeys.CreateAccount()
    31  	if err != nil {
    32  		t.Fatal("unable to create account key", err)
    33  	}
    34  
    35  	claims := NewGenericClaims(publicKey(createUserNKey(t), t))
    36  	claims.Data["foo"] = "bar"
    37  
    38  	token, err := claims.Encode(kp)
    39  	if err != nil {
    40  		t.Fatal("error encoding token", err)
    41  	}
    42  
    43  	c, err := DecodeGeneric(token)
    44  	if err != nil {
    45  		t.Fatal(err)
    46  	}
    47  
    48  	if claims.NotBefore != c.NotBefore {
    49  		t.Fatal("notbefore don't match")
    50  	}
    51  
    52  	if claims.Issuer != c.Issuer {
    53  		t.Fatal("notbefore don't match")
    54  	}
    55  
    56  	if !reflect.DeepEqual(claims.Data, c.Data) {
    57  		t.Fatal("data sections don't match")
    58  	}
    59  }
    60  
    61  func TestBadType(t *testing.T) {
    62  	kp, err := nkeys.CreateAccount()
    63  	if err != nil {
    64  		t.Fatal("unable to create account key", err)
    65  	}
    66  
    67  	h := Header{"JWS", AlgorithmNkey}
    68  	c := NewGenericClaims(publicKey(createUserNKey(t), t))
    69  	c.Data["foo"] = "bar"
    70  
    71  	token, err := c.doEncode(&h, kp, c)
    72  	if err != nil {
    73  		t.Fatal(err)
    74  	}
    75  
    76  	claim, err := DecodeGeneric(token)
    77  	if claim != nil {
    78  		t.Fatal("non nil claim on bad token")
    79  	}
    80  
    81  	if err == nil {
    82  		t.Fatal("nil error on bad token")
    83  	}
    84  
    85  	if err.Error() != fmt.Sprintf("not supported type %q", "JWS") {
    86  		t.Fatal("expected not supported type error")
    87  	}
    88  }
    89  
    90  func TestBadAlgo(t *testing.T) {
    91  	kp, err := nkeys.CreateAccount()
    92  	if err != nil {
    93  		t.Fatal("unable to create account key", err)
    94  	}
    95  
    96  	h := Header{TokenTypeJwt, "foobar"}
    97  	c := NewGenericClaims(publicKey(createUserNKey(t), t))
    98  	c.Data["foo"] = "bar"
    99  
   100  	if _, err := c.doEncode(&h, kp, c); err == nil {
   101  		t.Fatal("expected an error due to bad algorithm")
   102  	}
   103  
   104  	h = Header{TokenTypeJwt, AlgorithmNkeyOld}
   105  	c = NewGenericClaims(publicKey(createUserNKey(t), t))
   106  	c.Data["foo"] = "bar"
   107  
   108  	if _, err := c.doEncode(&h, kp, c); err == nil {
   109  		t.Fatal("expected an error due to bad algorithm")
   110  	}
   111  }
   112  
   113  func TestBadJWT(t *testing.T) {
   114  	kp, err := nkeys.CreateAccount()
   115  	if err != nil {
   116  		t.Fatal("unable to create account key", err)
   117  	}
   118  
   119  	h := Header{"JWS", AlgorithmNkey}
   120  	c := NewGenericClaims(publicKey(createUserNKey(t), t))
   121  	c.Data["foo"] = "bar"
   122  
   123  	token, err := c.doEncode(&h, kp, c)
   124  	if err != nil {
   125  		t.Fatal(err)
   126  	}
   127  
   128  	chunks := strings.Split(token, ".")
   129  	badToken := fmt.Sprintf("%s.%s", chunks[0], chunks[1])
   130  
   131  	claim, err := DecodeGeneric(badToken)
   132  	if claim != nil {
   133  		t.Fatal("non nil claim on bad token")
   134  	}
   135  
   136  	if err == nil {
   137  		t.Fatal("nil error on bad token")
   138  	}
   139  
   140  	if err.Error() != "expected 3 chunks" {
   141  		t.Fatalf("unexpeced error: %q", err.Error())
   142  	}
   143  }
   144  
   145  func TestBadSignature(t *testing.T) {
   146  	kp := createAccountNKey(t)
   147  	for algo, error := range map[string]string{
   148  		AlgorithmNkey: "claim failed V2 signature verification",
   149  	} {
   150  		h := Header{TokenTypeJwt, algo}
   151  		c := NewGenericClaims(publicKey(createUserNKey(t), t))
   152  		c.Data["foo"] = "bar"
   153  
   154  		token, err := c.doEncode(&h, kp, c)
   155  		if err != nil {
   156  			t.Fatal(err)
   157  		}
   158  
   159  		token = token + "A"
   160  
   161  		claim, err := DecodeGeneric(token)
   162  		if claim != nil {
   163  			t.Fatal("non nil claim on bad token")
   164  		}
   165  
   166  		if err == nil {
   167  			t.Fatal("nil error on bad token")
   168  		}
   169  
   170  		if err.Error() != error {
   171  			m := fmt.Sprintf("expected failed signature: %q", err.Error())
   172  			t.Fatal(m)
   173  		}
   174  	}
   175  }
   176  
   177  func TestDifferentPayload(t *testing.T) {
   178  	akp1 := createAccountNKey(t)
   179  
   180  	c1 := NewGenericClaims(publicKey(createUserNKey(t), t))
   181  	c1.Data["foo"] = "barz"
   182  	jwt1 := encode(c1, akp1, t)
   183  	c1t := strings.Split(jwt1, ".")
   184  	c1.Data["foo"] = "bar"
   185  
   186  	kp2 := createAccountNKey(t)
   187  	token2 := encode(c1, kp2, t)
   188  	c2t := strings.Split(token2, ".")
   189  
   190  	c1t[1] = c2t[1]
   191  
   192  	claim, err := DecodeGeneric(fmt.Sprintf("%s.%s.%s", c1t[0], c1t[1], c1t[2]))
   193  	if claim != nil {
   194  		t.Fatal("non nil claim on bad token")
   195  	}
   196  
   197  	if err == nil {
   198  		t.Fatal("nil error on bad token")
   199  	}
   200  
   201  	if err.Error() != "claim failed V2 signature verification" {
   202  		m := fmt.Sprintf("expected failed signature: %q", err.Error())
   203  		t.Fatal(m)
   204  	}
   205  }
   206  
   207  func TestExpiredToken(t *testing.T) {
   208  	akp := createAccountNKey(t)
   209  	c := NewGenericClaims(publicKey(akp, t))
   210  	c.Expires = time.Now().UTC().Unix() - 100
   211  	c.Data["foo"] = "barz"
   212  
   213  	vr := CreateValidationResults()
   214  	c.Validate(vr)
   215  	if !vr.IsBlocking(true) {
   216  		t.Fatalf("expired tokens should be blocking when time is included")
   217  	}
   218  
   219  	if vr.IsBlocking(false) {
   220  		t.Fatalf("expired tokens should not be blocking when time is not included")
   221  	}
   222  }
   223  
   224  func TestNotYetValid(t *testing.T) {
   225  	akp1, err := nkeys.CreateAccount()
   226  	if err != nil {
   227  		t.Fatal("unable to create account key", err)
   228  	}
   229  	c := NewGenericClaims(publicKey(akp1, t))
   230  	c.NotBefore = time.Now().Add(time.Duration(1) * time.Hour).UTC().Unix()
   231  
   232  	vr := CreateValidationResults()
   233  	c.Validate(vr)
   234  	if !vr.IsBlocking(true) {
   235  		t.Fatalf("not yet valid tokens should be blocking when time is included")
   236  	}
   237  
   238  	if vr.IsBlocking(false) {
   239  		t.Fatalf("not yet valid tokens should not be blocking when time is not included")
   240  	}
   241  }
   242  
   243  func TestIssuedAtIsSet(t *testing.T) {
   244  	akp := createAccountNKey(t)
   245  	c := NewGenericClaims(publicKey(akp, t))
   246  	c.Data["foo"] = "barz"
   247  
   248  	token, err := c.Encode(akp)
   249  	if err != nil {
   250  		t.Fatal(err)
   251  	}
   252  
   253  	claim, err := DecodeGeneric(token)
   254  	if err != nil {
   255  		t.Fatalf("unexpected error: %v", err)
   256  	}
   257  
   258  	if claim.IssuedAt == 0 {
   259  		t.Fatalf("issued at is not set")
   260  	}
   261  }
   262  
   263  func TestSample(t *testing.T) {
   264  	// Need a private key to sign the claim
   265  	akp := createAccountNKey(t)
   266  	claims := NewGenericClaims(publicKey(akp, t))
   267  	// add a bunch of claims
   268  	claims.Data["foo"] = "bar"
   269  
   270  	// serialize the claim to a JWT token
   271  	token, err := claims.Encode(akp)
   272  	if err != nil {
   273  		t.Fatal("error encoding token", err)
   274  	}
   275  
   276  	// on the receiving side, decode the token
   277  	c, err := DecodeGeneric(token)
   278  	if err != nil {
   279  		t.Fatal(err)
   280  	}
   281  
   282  	// if the token was decoded, it means that it
   283  	// validated and it wasn't tampered. the remaining and
   284  	// required test is to insure the issuer is trusted
   285  	pk, err := akp.PublicKey()
   286  	if err != nil {
   287  		t.Fatalf("unable to read public key: %v", err)
   288  	}
   289  
   290  	if c.Issuer != pk {
   291  		t.Fatalf("the public key is not trusted")
   292  	}
   293  }
   294  
   295  func TestBadHeaderEncoding(t *testing.T) {
   296  	// the '=' will be illegal
   297  	_, err := parseHeaders("=hello=")
   298  	if err == nil {
   299  		t.Fatal("should have failed it is not encoded")
   300  	}
   301  }
   302  
   303  func TestBadClaimsEncoding(t *testing.T) {
   304  	// the '=' will be illegal
   305  	c := GenericClaims{}
   306  	err := parseClaims("=hello=", &c)
   307  	if err == nil {
   308  		t.Fatal("should have failed it is not encoded")
   309  	}
   310  }
   311  
   312  func TestBadHeaderJSON(t *testing.T) {
   313  	payload := encodeToString([]byte("{foo: bar}"))
   314  	_, err := parseHeaders(payload)
   315  	if err == nil {
   316  		t.Fatal("should have failed bad json")
   317  	}
   318  }
   319  
   320  func TestBadClaimsJSON(t *testing.T) {
   321  	payload := encodeToString([]byte("{foo: bar}"))
   322  	c := GenericClaims{}
   323  	err := parseClaims(payload, &c)
   324  	if err == nil {
   325  		t.Fatal("should have failed bad json")
   326  	}
   327  }
   328  
   329  func TestBadPublicKeyDecodeGeneric(t *testing.T) {
   330  	c := &GenericClaims{}
   331  	c.Issuer = "foo"
   332  	if ok := c.verify("foo", []byte("bar")); ok {
   333  		t.Fatal("Should have failed to verify")
   334  	}
   335  }
   336  
   337  func TestBadSig(t *testing.T) {
   338  	opk := createOperatorNKey(t)
   339  	kp := createAccountNKey(t)
   340  	claims := NewGenericClaims(publicKey(kp, t))
   341  	claims.Data["foo"] = "bar"
   342  
   343  	// serialize the claim to a JWT token
   344  	token := encode(claims, opk, t)
   345  
   346  	tokens := strings.Split(token, ".")
   347  	badToken := fmt.Sprintf("%s.%s.=hello=", tokens[0], tokens[1])
   348  	_, err := DecodeGeneric(badToken)
   349  	if err == nil {
   350  		t.Fatal("should have failed to base64  decode signature")
   351  	}
   352  }
   353  
   354  func TestClaimsStringIsJSON(t *testing.T) {
   355  	akp := createAccountNKey(t)
   356  	claims := NewGenericClaims(publicKey(akp, t))
   357  	// add a bunch of claims
   358  	claims.Data["foo"] = "bar"
   359  
   360  	claims2 := NewGenericClaims(publicKey(akp, t))
   361  	json.Unmarshal([]byte(claims.String()), claims2)
   362  	if claims2.Data["foo"] != "bar" {
   363  		t.Fatalf("Failed to decode expected claim from String representation: %q", claims.String())
   364  	}
   365  }
   366  
   367  func TestDoEncodeNilHeader(t *testing.T) {
   368  	akp := createAccountNKey(t)
   369  	claims := NewGenericClaims(publicKey(akp, t))
   370  	_, err := claims.doEncode(nil, nil, claims)
   371  	if err == nil {
   372  		t.Fatal("should have failed to encode")
   373  	}
   374  	if err.Error() != "header is required" {
   375  		t.Fatalf("unexpected error on encode: %v", err)
   376  	}
   377  }
   378  
   379  func TestDoEncodeNilKeyPair(t *testing.T) {
   380  	akp := createAccountNKey(t)
   381  	claims := NewGenericClaims(publicKey(akp, t))
   382  	_, err := claims.doEncode(&Header{}, nil, claims)
   383  	if err == nil {
   384  		t.Fatal("should have failed to encode")
   385  	}
   386  	if err.Error() != "keypair is required" {
   387  		t.Fatalf("unexpected error on encode: %v", err)
   388  	}
   389  }
   390  
   391  // if this fails, the URL decoder was changed and JWTs will flap
   392  func TestUsingURLDecoder(t *testing.T) {
   393  	token := "eyJ0eXAiOiJqd3QiLCJhbGciOiJlZDI1NTE5In0.eyJqdGkiOiJGQ1lZRjJLR0EzQTZHTlZQR0pIVjNUSExYR1VZWkFUREZLV1JTT1czUUo1T0k3QlJST0ZRIiwiaWF0IjoxNTQzOTQzNjc1LCJpc3MiOiJBQ1NKWkhOWlI0QUFUVE1KNzdUV1JONUJHVUZFWFhUS0gzWEtGTldDRkFCVzJRWldOUTRDQkhRRSIsInN1YiI6IkFEVEFHWVZYRkpPRENRM0g0VUZQQU43R1dXWk1BVU9FTTJMMkRWQkFWVFdLM01TU0xUS1JUTzVGIiwidHlwZSI6ImFjdGl2YXRpb24iLCJuYXRzIjp7InN1YmplY3QiOiJmb28iLCJ0eXBlIjoic2VydmljZSJ9fQ.HCZTCF-7wolS3Wjx3swQWMkoDhoo_4gp9EsuM5diJfZrH8s6NTpO0iT7_fKZm7dNDeEoqjwU--3ebp8j-Mm_Aw"
   394  	ac, err := DecodeActivationClaims(token)
   395  	if err != nil {
   396  		t.Fatal("shouldn't have failed to decode", err)
   397  	}
   398  	if ac == nil {
   399  		t.Fatal("should have returned activation")
   400  	}
   401  }