github.com/nats-io/jwt/v2@v2.5.6/v1compat/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  	token, err := c.doEncode(&h, kp, c)
   101  	if err != nil {
   102  		t.Fatal(err)
   103  	}
   104  
   105  	claim, err := DecodeGeneric(token)
   106  	if claim != nil {
   107  		t.Fatal("non nil claim on bad token")
   108  	}
   109  
   110  	if err == nil {
   111  		t.Fatal("nil error on bad token")
   112  	}
   113  
   114  	if err.Error() != fmt.Sprintf("unexpected %q algorithm", "foobar") {
   115  		t.Fatal("expected unexpected algorithm")
   116  	}
   117  }
   118  
   119  func TestBadJWT(t *testing.T) {
   120  	kp, err := nkeys.CreateAccount()
   121  	if err != nil {
   122  		t.Fatal("unable to create account key", err)
   123  	}
   124  
   125  	h := Header{"JWS", AlgorithmNkey}
   126  	c := NewGenericClaims(publicKey(createUserNKey(t), t))
   127  	c.Data["foo"] = "bar"
   128  
   129  	token, err := c.doEncode(&h, kp, c)
   130  	if err != nil {
   131  		t.Fatal(err)
   132  	}
   133  
   134  	chunks := strings.Split(token, ".")
   135  	badToken := fmt.Sprintf("%s.%s", chunks[0], chunks[1])
   136  
   137  	claim, err := DecodeGeneric(badToken)
   138  	if claim != nil {
   139  		t.Fatal("non nil claim on bad token")
   140  	}
   141  
   142  	if err == nil {
   143  		t.Fatal("nil error on bad token")
   144  	}
   145  
   146  	if err.Error() != "expected 3 chunks" {
   147  		t.Fatalf("unexpeced error: %q", err.Error())
   148  	}
   149  }
   150  
   151  func TestBadSignature(t *testing.T) {
   152  	kp := createAccountNKey(t)
   153  
   154  	h := Header{TokenTypeJwt, AlgorithmNkey}
   155  	c := NewGenericClaims(publicKey(createUserNKey(t), t))
   156  	c.Data["foo"] = "bar"
   157  
   158  	token, err := c.doEncode(&h, kp, c)
   159  	if err != nil {
   160  		t.Fatal(err)
   161  	}
   162  
   163  	token = token + "A"
   164  
   165  	claim, err := DecodeGeneric(token)
   166  	if claim != nil {
   167  		t.Fatal("non nil claim on bad token")
   168  	}
   169  
   170  	if err == nil {
   171  		t.Fatal("nil error on bad token")
   172  	}
   173  
   174  	if err.Error() != "claim failed signature verification" {
   175  		m := fmt.Sprintf("expected failed signature: %q", err.Error())
   176  		t.Fatal(m)
   177  	}
   178  }
   179  
   180  func TestDifferentPayload(t *testing.T) {
   181  	akp1 := createAccountNKey(t)
   182  
   183  	c1 := NewGenericClaims(publicKey(createUserNKey(t), t))
   184  	c1.Data["foo"] = "barz"
   185  	jwt1 := encode(c1, akp1, t)
   186  	c1t := strings.Split(jwt1, ".")
   187  	c1.Data["foo"] = "bar"
   188  
   189  	kp2 := createAccountNKey(t)
   190  	token2 := encode(c1, kp2, t)
   191  	c2t := strings.Split(token2, ".")
   192  
   193  	c1t[1] = c2t[1]
   194  
   195  	claim, err := DecodeGeneric(fmt.Sprintf("%s.%s.%s", c1t[0], c1t[1], c1t[2]))
   196  	if claim != nil {
   197  		t.Fatal("non nil claim on bad token")
   198  	}
   199  
   200  	if err == nil {
   201  		t.Fatal("nil error on bad token")
   202  	}
   203  
   204  	if err.Error() != "claim failed signature verification" {
   205  		m := fmt.Sprintf("expected failed signature: %q", err.Error())
   206  		t.Fatal(m)
   207  	}
   208  }
   209  
   210  func TestExpiredToken(t *testing.T) {
   211  	akp := createAccountNKey(t)
   212  	c := NewGenericClaims(publicKey(akp, t))
   213  	c.Expires = time.Now().UTC().Unix() - 100
   214  	c.Data["foo"] = "barz"
   215  
   216  	vr := CreateValidationResults()
   217  	c.Validate(vr)
   218  	if !vr.IsBlocking(true) {
   219  		t.Fatalf("expired tokens should be blocking when time is included")
   220  	}
   221  
   222  	if vr.IsBlocking(false) {
   223  		t.Fatalf("expired tokens should not be blocking when time is not included")
   224  	}
   225  }
   226  
   227  func TestNotYetValid(t *testing.T) {
   228  	akp1, err := nkeys.CreateAccount()
   229  	if err != nil {
   230  		t.Fatal("unable to create account key", err)
   231  	}
   232  	c := NewGenericClaims(publicKey(akp1, t))
   233  	c.NotBefore = time.Now().Add(time.Duration(1) * time.Hour).UTC().Unix()
   234  
   235  	vr := CreateValidationResults()
   236  	c.Validate(vr)
   237  	if !vr.IsBlocking(true) {
   238  		t.Fatalf("not yet valid tokens should be blocking when time is included")
   239  	}
   240  
   241  	if vr.IsBlocking(false) {
   242  		t.Fatalf("not yet valid tokens should not be blocking when time is not included")
   243  	}
   244  }
   245  
   246  func TestIssuedAtIsSet(t *testing.T) {
   247  	akp := createAccountNKey(t)
   248  	c := NewGenericClaims(publicKey(akp, t))
   249  	c.Data["foo"] = "barz"
   250  
   251  	token, err := c.Encode(akp)
   252  	if err != nil {
   253  		t.Fatal(err)
   254  	}
   255  
   256  	claim, err := DecodeGeneric(token)
   257  	if err != nil {
   258  		t.Fatalf("unexpected error: %v", err)
   259  	}
   260  
   261  	if claim.IssuedAt == 0 {
   262  		t.Fatalf("issued at is not set")
   263  	}
   264  }
   265  
   266  func TestSample(t *testing.T) {
   267  	// Need a private key to sign the claim
   268  	akp := createAccountNKey(t)
   269  	claims := NewGenericClaims(publicKey(akp, t))
   270  	// add a bunch of claims
   271  	claims.Data["foo"] = "bar"
   272  
   273  	// serialize the claim to a JWT token
   274  	token, err := claims.Encode(akp)
   275  	if err != nil {
   276  		t.Fatal("error encoding token", err)
   277  	}
   278  
   279  	// on the receiving side, decode the token
   280  	c, err := DecodeGeneric(token)
   281  	if err != nil {
   282  		t.Fatal(err)
   283  	}
   284  
   285  	// if the token was decoded, it means that it
   286  	// validated and it wasn't tampered. the remaining and
   287  	// required test is to insure the issuer is trusted
   288  	pk, err := akp.PublicKey()
   289  	if err != nil {
   290  		t.Fatalf("unable to read public key: %v", err)
   291  	}
   292  
   293  	if c.Issuer != string(pk) {
   294  		t.Fatalf("the public key is not trusted")
   295  	}
   296  }
   297  
   298  func TestBadHeaderEncoding(t *testing.T) {
   299  	// the '=' will be illegal
   300  	_, err := parseHeaders("=hello=")
   301  	if err == nil {
   302  		t.Fatal("should have failed it is not encoded")
   303  	}
   304  }
   305  
   306  func TestBadClaimsEncoding(t *testing.T) {
   307  	// the '=' will be illegal
   308  	c := GenericClaims{}
   309  	err := parseClaims("=hello=", &c)
   310  	if err == nil {
   311  		t.Fatal("should have failed it is not encoded")
   312  	}
   313  }
   314  
   315  func TestBadHeaderJSON(t *testing.T) {
   316  	payload := encodeToString([]byte("{foo: bar}"))
   317  	_, err := parseHeaders(payload)
   318  	if err == nil {
   319  		t.Fatal("should have failed bad json")
   320  	}
   321  }
   322  
   323  func TestBadClaimsJSON(t *testing.T) {
   324  	payload := encodeToString([]byte("{foo: bar}"))
   325  	c := GenericClaims{}
   326  	err := parseClaims(payload, &c)
   327  	if err == nil {
   328  		t.Fatal("should have failed bad json")
   329  	}
   330  }
   331  
   332  func TestBadPublicKeyDecodeGeneric(t *testing.T) {
   333  	c := &GenericClaims{}
   334  	c.Issuer = "foo"
   335  	if ok := c.Verify("foo", []byte("bar")); ok {
   336  		t.Fatal("Should have failed to verify")
   337  	}
   338  }
   339  
   340  func TestBadSig(t *testing.T) {
   341  	opk := createOperatorNKey(t)
   342  	kp := createAccountNKey(t)
   343  	claims := NewGenericClaims(publicKey(kp, t))
   344  	claims.Data["foo"] = "bar"
   345  
   346  	// serialize the claim to a JWT token
   347  	token := encode(claims, opk, t)
   348  
   349  	tokens := strings.Split(token, ".")
   350  	badToken := fmt.Sprintf("%s.%s.=hello=", tokens[0], tokens[1])
   351  	_, err := DecodeGeneric(badToken)
   352  	if err == nil {
   353  		t.Fatal("should have failed to base64  decode signature")
   354  	}
   355  }
   356  
   357  func TestClaimsStringIsJSON(t *testing.T) {
   358  	akp := createAccountNKey(t)
   359  	claims := NewGenericClaims(publicKey(akp, t))
   360  	// add a bunch of claims
   361  	claims.Data["foo"] = "bar"
   362  
   363  	claims2 := NewGenericClaims(publicKey(akp, t))
   364  	json.Unmarshal([]byte(claims.String()), claims2)
   365  	if claims2.Data["foo"] != "bar" {
   366  		t.Fatalf("Failed to decode expected claim from String representation: %q", claims.String())
   367  	}
   368  }
   369  
   370  func TestDoEncodeNilHeader(t *testing.T) {
   371  	akp := createAccountNKey(t)
   372  	claims := NewGenericClaims(publicKey(akp, t))
   373  	_, err := claims.doEncode(nil, nil, claims)
   374  	if err == nil {
   375  		t.Fatal("should have failed to encode")
   376  	}
   377  	if err.Error() != "header is required" {
   378  		t.Fatalf("unexpected error on encode: %v", err)
   379  	}
   380  }
   381  
   382  func TestDoEncodeNilKeyPair(t *testing.T) {
   383  	akp := createAccountNKey(t)
   384  	claims := NewGenericClaims(publicKey(akp, t))
   385  	_, err := claims.doEncode(&Header{}, nil, claims)
   386  	if err == nil {
   387  		t.Fatal("should have failed to encode")
   388  	}
   389  	if err.Error() != "keypair is required" {
   390  		t.Fatalf("unexpected error on encode: %v", err)
   391  	}
   392  }
   393  
   394  // if this fails, the URL decoder was changed and JWTs will flap
   395  func TestUsingURLDecoder(t *testing.T) {
   396  	token := "eyJ0eXAiOiJqd3QiLCJhbGciOiJlZDI1NTE5In0.eyJqdGkiOiJGQ1lZRjJLR0EzQTZHTlZQR0pIVjNUSExYR1VZWkFUREZLV1JTT1czUUo1T0k3QlJST0ZRIiwiaWF0IjoxNTQzOTQzNjc1LCJpc3MiOiJBQ1NKWkhOWlI0QUFUVE1KNzdUV1JONUJHVUZFWFhUS0gzWEtGTldDRkFCVzJRWldOUTRDQkhRRSIsInN1YiI6IkFEVEFHWVZYRkpPRENRM0g0VUZQQU43R1dXWk1BVU9FTTJMMkRWQkFWVFdLM01TU0xUS1JUTzVGIiwidHlwZSI6ImFjdGl2YXRpb24iLCJuYXRzIjp7InN1YmplY3QiOiJmb28iLCJ0eXBlIjoic2VydmljZSJ9fQ.HCZTCF-7wolS3Wjx3swQWMkoDhoo_4gp9EsuM5diJfZrH8s6NTpO0iT7_fKZm7dNDeEoqjwU--3ebp8j-Mm_Aw"
   397  	ac, err := DecodeActivationClaims(token)
   398  	if err != nil {
   399  		t.Fatal("shouldn't have failed to decode", err)
   400  	}
   401  	if ac == nil {
   402  		t.Fatal("should have returned activation")
   403  	}
   404  }