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

     1  /*
     2   * Copyright 2018-2023 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  	"fmt"
    20  	"strings"
    21  	"testing"
    22  	"time"
    23  
    24  	"github.com/nats-io/nkeys"
    25  )
    26  
    27  func TestNewAccountClaims(t *testing.T) {
    28  	akp := createAccountNKey(t)
    29  	akp2 := createAccountNKey(t)
    30  	apk := publicKey(akp, t)
    31  	apk2 := publicKey(akp2, t)
    32  
    33  	activation := NewActivationClaims(apk)
    34  	activation.Expires = time.Now().Add(time.Hour).UTC().Unix()
    35  	activation.ImportSubject = "test"
    36  	activation.ImportType = Stream
    37  	actJWT := encode(activation, akp2, t)
    38  
    39  	account := NewAccountClaims(apk)
    40  	if !account.Limits.NatsLimits.IsUnlimited() {
    41  		t.Fatalf("Expected unlimited nats operator limits")
    42  	}
    43  	if !account.Limits.AccountLimits.IsUnlimited() {
    44  		t.Fatalf("Expected unlimited account operator limits")
    45  	}
    46  	if account.Limits.JetStreamLimits.DiskStorage != 0 ||
    47  		account.Limits.JetStreamLimits.MemoryStorage != 0 ||
    48  		account.Limits.JetStreamLimits.Consumer != 0 ||
    49  		account.Limits.JetStreamLimits.Streams != 0 {
    50  		t.Fatalf("Expected unlimited operator limits")
    51  	}
    52  
    53  	account.Expires = time.Now().Add(time.Hour * 24 * 365).UTC().Unix()
    54  
    55  	account.InfoURL = "http://localhost/my-account/doc"
    56  	account.Description = "my account"
    57  	account.Imports = Imports{}
    58  	account.Imports.Add(&Import{Subject: "test", Name: "test import", Account: apk2, Token: actJWT, LocalSubject: "my", Type: Stream})
    59  
    60  	vr := CreateValidationResults()
    61  	account.Validate(vr)
    62  
    63  	if !vr.IsEmpty() {
    64  		t.Fatal("Valid account will have no validation results")
    65  	}
    66  
    67  	actJwt := encode(account, akp, t)
    68  
    69  	account2, err := DecodeAccountClaims(actJwt)
    70  	if err != nil {
    71  		t.Fatal("error decoding account jwt", err)
    72  	}
    73  
    74  	AssertEquals(account.String(), account2.String(), t)
    75  	AssertEquals(account2.IsSelfSigned(), true, t)
    76  
    77  	AssertEquals(account2.Claims() != nil, true, t)
    78  	AssertEquals(account2.Payload() != nil, true, t)
    79  	AssertEquals(account.InfoURL, account2.InfoURL, t)
    80  	AssertEquals(account.Description, account2.Description, t)
    81  }
    82  
    83  func TestAccountCanSignOperatorLimits(t *testing.T) { // don't block encoding!!!
    84  	akp := createAccountNKey(t)
    85  	apk := publicKey(akp, t)
    86  
    87  	account := NewAccountClaims(apk)
    88  	account.Expires = time.Now().Add(time.Hour * 24 * 365).Unix()
    89  	account.Limits.Conn = 10
    90  	account.Limits.LeafNodeConn = 2
    91  
    92  	_, err := account.Encode(akp)
    93  	if err != nil {
    94  		t.Fatal("account should not be able to encode operator limits", err)
    95  	}
    96  }
    97  
    98  func TestOperatorCanSignClaims(t *testing.T) {
    99  	akp := createAccountNKey(t)
   100  	okp := createOperatorNKey(t)
   101  	apk := publicKey(akp, t)
   102  
   103  	account := NewAccountClaims(apk)
   104  	account.Expires = time.Now().Add(time.Hour * 24 * 365).Unix()
   105  	account.Limits.Conn = 1
   106  	account.Limits.LeafNodeConn = 4
   107  
   108  	actJwt := encode(account, okp, t)
   109  
   110  	account2, err := DecodeAccountClaims(actJwt)
   111  	if err != nil {
   112  		t.Fatal("error decoding account jwt", err)
   113  	}
   114  
   115  	AssertEquals(account.String(), account2.String(), t)
   116  	AssertEquals(account2.IsSelfSigned(), false, t)
   117  
   118  	if account2.Limits.Conn != 1 {
   119  		t.Fatalf("Expected Limits.Conn == 1, got %d", account2.Limits.Conn)
   120  	}
   121  	if account2.Limits.LeafNodeConn != 4 {
   122  		t.Fatalf("Expected Limits.Conn == 4, got %d", account2.Limits.LeafNodeConn)
   123  	}
   124  }
   125  
   126  func TestInvalidAccountClaimIssuer(t *testing.T) {
   127  	akp := createAccountNKey(t)
   128  	ac := NewAccountClaims(publicKey(akp, t))
   129  	ac.Expires = time.Now().Add(time.Hour).Unix()
   130  	aJwt := encode(ac, akp, t)
   131  
   132  	temp, err := DecodeGeneric(aJwt)
   133  	if err != nil {
   134  		t.Fatal("failed to decode", err)
   135  	}
   136  
   137  	type kpInputs struct {
   138  		name string
   139  		kp   nkeys.KeyPair
   140  		ok   bool
   141  	}
   142  
   143  	inputs := []kpInputs{
   144  		{"account", createAccountNKey(t), true},
   145  		{"user", createUserNKey(t), false},
   146  		{"operator", createOperatorNKey(t), true},
   147  		{"server", createServerNKey(t), false},
   148  		{"cluster", createClusterNKey(t), false},
   149  	}
   150  
   151  	for _, i := range inputs {
   152  		bad := encode(temp, i.kp, t)
   153  		_, err = DecodeAccountClaims(bad)
   154  		if i.ok && err != nil {
   155  			t.Fatalf("unexpected error for %q: %v", i.name, err)
   156  		}
   157  		if !i.ok && err == nil {
   158  			t.Logf("should have failed to decode account signed by %q", i.name)
   159  			t.Fail()
   160  		}
   161  	}
   162  }
   163  
   164  func TestInvalidAccountSubjects(t *testing.T) {
   165  	type kpInputs struct {
   166  		name string
   167  		kp   nkeys.KeyPair
   168  		ok   bool
   169  	}
   170  
   171  	inputs := []kpInputs{
   172  		{"account", createAccountNKey(t), true},
   173  		{"user", createUserNKey(t), false},
   174  		{"operator", createOperatorNKey(t), false},
   175  		{"server", createServerNKey(t), false},
   176  		{"cluster", createClusterNKey(t), false},
   177  	}
   178  
   179  	for _, i := range inputs {
   180  		pk := publicKey(i.kp, t)
   181  		var err error
   182  
   183  		c := NewAccountClaims(pk)
   184  		_, err = c.Encode(i.kp)
   185  		if i.ok && err != nil {
   186  			t.Fatalf("unexpected error for %q: %v", i.name, err)
   187  		}
   188  		if !i.ok && err == nil {
   189  			t.Logf("should have failed to encode account with with %q subject", i.name)
   190  			t.Fail()
   191  		}
   192  	}
   193  }
   194  
   195  func TestAccountImports(t *testing.T) {
   196  	akp := createAccountNKey(t)
   197  	apk := publicKey(akp, t)
   198  
   199  	account := NewAccountClaims(apk)
   200  	account.Expires = time.Now().Add(time.Hour * 24 * 365).Unix()
   201  
   202  	actJwt := encode(account, akp, t)
   203  
   204  	account2, err := DecodeAccountClaims(actJwt)
   205  	if err != nil {
   206  		t.Fatal("error decoding account jwt", err)
   207  	}
   208  
   209  	AssertEquals(account.String(), account2.String(), t)
   210  }
   211  
   212  func TestNewNilAccountClaim(t *testing.T) {
   213  	v := NewAccountClaims("")
   214  	if v != nil {
   215  		t.Fatal("expected nil account claim")
   216  	}
   217  }
   218  
   219  func TestLimitValidationInAccount(t *testing.T) {
   220  	akp := createAccountNKey(t)
   221  	apk := publicKey(akp, t)
   222  
   223  	account := NewAccountClaims(apk)
   224  	account.Expires = time.Now().Add(time.Hour * 24 * 365).Unix()
   225  	account.Limits.Conn = 10
   226  	account.Limits.Imports = 10
   227  	account.Limits.Exports = 10
   228  	account.Limits.Data = 1024
   229  	account.Limits.Payload = 1024
   230  	account.Limits.Subs = 10
   231  	account.Limits.WildcardExports = true
   232  
   233  	vr := CreateValidationResults()
   234  	account.Validate(vr)
   235  
   236  	if len(vr.Issues) != 0 {
   237  		t.Fatal("valid account should have no validation issues")
   238  	}
   239  
   240  	account.Limits.Conn = -1
   241  	account.Limits.Imports = -1
   242  	account.Limits.Exports = -1
   243  	account.Limits.Subs = -1
   244  	account.Limits.Data = -1
   245  	account.Limits.Payload = -1
   246  	vr = CreateValidationResults()
   247  	account.Validate(vr)
   248  
   249  	if len(vr.Issues) != 0 {
   250  		t.Fatal("valid account should have no validation issues")
   251  	}
   252  
   253  	op := createOperatorNKey(t)
   254  	opk := publicKey(op, t)
   255  	account.Issuer = opk
   256  
   257  	vr = CreateValidationResults()
   258  	account.Validate(vr)
   259  
   260  	if !vr.IsEmpty() || vr.IsBlocking(true) {
   261  		t.Fatal("operator can encode limits and identity")
   262  	}
   263  
   264  	account.Issuer = apk
   265  	vr = CreateValidationResults()
   266  	account.Validate(vr)
   267  
   268  	if vr.IsEmpty() || vr.IsBlocking(true) {
   269  		t.Fatal("bad issuer for limits should have non-blocking validation results")
   270  	}
   271  }
   272  
   273  func TestWildcardExportLimit(t *testing.T) {
   274  	akp := createAccountNKey(t)
   275  	apk := publicKey(akp, t)
   276  
   277  	account := NewAccountClaims(apk)
   278  	account.Expires = time.Now().Add(time.Hour * 24 * 365).Unix()
   279  	account.Limits.Conn = 10
   280  	account.Limits.Imports = 10
   281  	account.Limits.Exports = 10
   282  	account.Limits.WildcardExports = true
   283  	account.Exports = Exports{
   284  		&Export{Subject: "foo", Type: Stream},
   285  		&Export{Subject: "bar.*", Type: Stream},
   286  	}
   287  
   288  	vr := CreateValidationResults()
   289  	account.Validate(vr)
   290  
   291  	if !vr.IsEmpty() {
   292  		t.Fatal("valid account should have no validation issues")
   293  	}
   294  
   295  	account.Limits.WildcardExports = false
   296  	vr = CreateValidationResults()
   297  	account.Validate(vr)
   298  
   299  	if vr.IsEmpty() || !vr.IsBlocking(true) {
   300  		t.Fatal("invalid account should have validation issues")
   301  	}
   302  
   303  	account.Limits.WildcardExports = true
   304  	account.Limits.Exports = 1
   305  	vr = CreateValidationResults()
   306  	account.Validate(vr)
   307  
   308  	if vr.IsEmpty() || !vr.IsBlocking(true) {
   309  		t.Fatal("invalid account should have validation issues")
   310  	}
   311  }
   312  
   313  func TestJetstreamLimits(t *testing.T) {
   314  	akp := createAccountNKey(t)
   315  	apk := publicKey(akp, t)
   316  	acc1 := NewAccountClaims(apk)
   317  	if acc1.Limits.JetStreamLimits.DiskStorage != 0 ||
   318  		acc1.Limits.JetStreamLimits.MemoryStorage != 0 ||
   319  		acc1.Limits.JetStreamLimits.Consumer != 0 ||
   320  		acc1.Limits.JetStreamLimits.Streams != 0 ||
   321  		acc1.Limits.JetStreamLimits.MaxBytesRequired != false ||
   322  		acc1.Limits.JetStreamLimits.MemoryMaxStreamBytes != 0 ||
   323  		acc1.Limits.JetStreamLimits.DiskMaxStreamBytes != 0 ||
   324  		acc1.Limits.JetStreamLimits.MaxAckPending != 0 {
   325  		t.Fatalf("Expected unlimited operator limits")
   326  	}
   327  	acc1.Limits.Consumer = 1
   328  	acc1.Limits.Streams = 2
   329  	acc1.Limits.MemoryStorage = 3
   330  	acc1.Limits.DiskStorage = 4
   331  	acc1.Limits.MemoryMaxStreamBytes = 1000
   332  	acc1.Limits.DiskMaxStreamBytes = 1000
   333  	acc1.Limits.MaxBytesRequired = true
   334  	acc1.Limits.MaxAckPending = 200
   335  	vr := CreateValidationResults()
   336  	acc1.Validate(vr)
   337  	if !vr.IsEmpty() {
   338  		t.Fatal("valid account should have no validation issues")
   339  	}
   340  	if token, err := acc1.Encode(akp); err != nil {
   341  		t.Fatal("valid account should have no validation issues")
   342  	} else if acc2, err := DecodeAccountClaims(token); err != nil {
   343  		t.Fatal("valid account should have no validation issues")
   344  	} else if acc1.Limits.JetStreamLimits != acc2.Limits.JetStreamLimits {
   345  		t.Fatal("account should have same properties")
   346  	}
   347  }
   348  
   349  func TestTieredLimits(t *testing.T) {
   350  	akp := createAccountNKey(t)
   351  	apk := publicKey(akp, t)
   352  	acc1 := NewAccountClaims(apk)
   353  	l := JetStreamLimits{
   354  		MemoryStorage:    1024,
   355  		DiskStorage:      1024,
   356  		Streams:          1,
   357  		Consumer:         1,
   358  		MaxBytesRequired: true,
   359  	}
   360  	acc1.Limits.JetStreamTieredLimits["R1"] = l
   361  	l.Streams = 2 // minor change so both tiers differ
   362  	acc1.Limits.JetStreamTieredLimits["R3"] = l
   363  
   364  	vr := CreateValidationResults()
   365  	acc1.Validate(vr)
   366  	if !vr.IsEmpty() {
   367  		t.Fatal("valid account should have validation issues")
   368  	}
   369  
   370  	if token, err := acc1.Encode(akp); err != nil {
   371  		t.Fatal("valid account should have no validation issues")
   372  	} else if acc2, err := DecodeAccountClaims(token); err != nil {
   373  		t.Fatal("valid account should have no validation issues")
   374  	} else if acc1.Limits.JetStreamTieredLimits["R1"] != acc2.Limits.JetStreamTieredLimits["R1"] {
   375  		t.Fatal("tier R1 should have same limits")
   376  	} else if acc1.Limits.JetStreamTieredLimits["R3"] != acc2.Limits.JetStreamTieredLimits["R3"] {
   377  		t.Fatal("tier R2 should have same limits")
   378  	}
   379  	// test tiers and js limits being mutual exclusive
   380  	acc1.Limits.JetStreamLimits = l
   381  	acc1.Validate(vr)
   382  	if vr.IsEmpty() {
   383  		t.Fatal("valid account should have validation issues")
   384  	}
   385  }
   386  
   387  func TestJetstreamLimitsDeEnCode(t *testing.T) {
   388  	// token (generated without this change) with js disabled
   389  	c1, err := DecodeAccountClaims(`eyJ0eXAiOiJKV1QiLCJhbGciOiJlZDI1NTE5LW5rZXkifQ.eyJqdGkiOiI3V0NYQkZKS0lIN1Y0SkdPR0FVTEtTS05aQUxVTUZMVExZWVgyNTdDSzZORk5OWTdGRVdBIiwiaWF0IjoxNjQ0Mjc5NDY3LCJpc3MiOiJPQk5UUVJFSEVJUFJFVE1BVlBWUVVDSUdFUktHWkIzRVJBVjVTNUdNM0lPRVFOSFJFQkpPVUFSRiIsIm5hbWUiOiJ0ZXN0Iiwic3ViIjoiQUM2SFFJMlVBTVVQREVQN1dTWVFZV1JDTEVZQkxZVlNQTDZBSExDVVBKVEdVMzJUNEtRQktZU0ciLCJuYXRzIjp7ImxpbWl0cyI6eyJzdWJzIjotMSwiZGF0YSI6LTEsInBheWxvYWQiOi0xLCJpbXBvcnRzIjotMSwiZXhwb3J0cyI6LTEsIndpbGRjYXJkcyI6dHJ1ZSwiY29ubiI6LTEsImxlYWYiOi0xfSwiZGVmYXVsdF9wZXJtaXNzaW9ucyI6eyJwdWIiOnt9LCJzdWIiOnt9fSwidHlwZSI6ImFjY291bnQiLCJ2ZXJzaW9uIjoyfX0.73vDu9osNeLKwQ-g1Uu1fAtszMNz_QRZXRJLp0kzZh-0eMBmt0nb2mMwBwg-fufJs1FqYe9WbWKeXAYStnVnBg`)
   390  	if err != nil {
   391  		t.Fatal(err)
   392  	} else if c1.Limits.IsJSEnabled() {
   393  		t.Fatal("JetStream expected to be disabled")
   394  	}
   395  	// token (generated without this change) with js enabled
   396  	c2, err := DecodeAccountClaims(`eyJ0eXAiOiJKV1QiLCJhbGciOiJlZDI1NTE5LW5rZXkifQ.eyJqdGkiOiJPVFFXVEQyVkFMWkRQQTZYU1hLS09GRVFZR1VaVFBDNEtKV1BYMlAyWU1XMjVTMzRTVjNRIiwiaWF0IjoxNjQ0Mjc5MzM0LCJpc3MiOiJPQk5UUVJFSEVJUFJFVE1BVlBWUVVDSUdFUktHWkIzRVJBVjVTNUdNM0lPRVFOSFJFQkpPVUFSRiIsIm5hbWUiOiJ0ZXN0Iiwic3ViIjoiQUM2SFFJMlVBTVVQREVQN1dTWVFZV1JDTEVZQkxZVlNQTDZBSExDVVBKVEdVMzJUNEtRQktZU0ciLCJuYXRzIjp7ImxpbWl0cyI6eyJzdWJzIjotMSwiZGF0YSI6LTEsInBheWxvYWQiOi0xLCJpbXBvcnRzIjotMSwiZXhwb3J0cyI6LTEsIndpbGRjYXJkcyI6dHJ1ZSwiY29ubiI6LTEsImxlYWYiOi0xLCJkaXNrX3N0b3JhZ2UiOjEwMDAwMDB9LCJkZWZhdWx0X3Blcm1pc3Npb25zIjp7InB1YiI6e30sInN1YiI6e319LCJ0eXBlIjoiYWNjb3VudCIsInZlcnNpb24iOjJ9fQ.Xt5azhxOkC7nywz9Q8xVtzX8lZIqdOhpfGyQI30aNdd-nbVGX2O13OOfouIaTLyajZiS4bcJFXa29q6QCFRUDA`)
   397  	if err != nil {
   398  		t.Fatal(err)
   399  	} else if !c2.Limits.IsJSEnabled() {
   400  		t.Fatal("JetStream expected to be enabled")
   401  	}
   402  }
   403  
   404  func TestAccountSigningKeyValidation(t *testing.T) {
   405  	okp := createOperatorNKey(t)
   406  
   407  	akp1 := createAccountNKey(t)
   408  	apk1 := publicKey(akp1, t)
   409  	akp2 := createAccountNKey(t)
   410  	apk2 := publicKey(akp2, t)
   411  
   412  	ac := NewAccountClaims(apk1)
   413  	ac.SigningKeys.Add(apk2)
   414  
   415  	var vr ValidationResults
   416  	ac.Validate(&vr)
   417  	if len(vr.Issues) != 0 {
   418  		t.Fatal("expected no validation issues")
   419  	}
   420  
   421  	// try encoding/decoding
   422  	token, err := ac.Encode(okp)
   423  	if err != nil {
   424  		t.Fatal(err)
   425  	}
   426  
   427  	ac2, err := DecodeAccountClaims(token)
   428  	if err != nil {
   429  		t.Fatal(err)
   430  	}
   431  	if len(ac2.SigningKeys) != 1 {
   432  		t.Fatal("expected claim to have a signing key")
   433  	}
   434  	if !ac.SigningKeys.Contains(apk2) {
   435  		t.Fatalf("expected signing key %s", apk2)
   436  	}
   437  
   438  	bkp := createUserNKey(t)
   439  	ac.SigningKeys.Add(publicKey(bkp, t))
   440  	ac.Validate(&vr)
   441  	if len(vr.Issues) != 1 {
   442  		t.Fatal("expected 1 validation issue")
   443  	}
   444  }
   445  
   446  func TestAccountSignedBy(t *testing.T) {
   447  	okp := createOperatorNKey(t)
   448  
   449  	akp1 := createAccountNKey(t)
   450  	apk1 := publicKey(akp1, t)
   451  	akp2 := createAccountNKey(t)
   452  	apk2 := publicKey(akp2, t)
   453  
   454  	ac := NewAccountClaims(apk1)
   455  	ac.SigningKeys.Add(apk2)
   456  
   457  	token, err := ac.Encode(okp)
   458  	if err != nil {
   459  		t.Fatal(err)
   460  	}
   461  	ac2, err := DecodeAccountClaims(token)
   462  	if err != nil {
   463  		t.Fatal(err)
   464  	}
   465  	if len(ac2.SigningKeys) != 1 {
   466  		t.Fatal("expected claim to have a signing key")
   467  	}
   468  	if !ac.SigningKeys.Contains(apk2) {
   469  		t.Fatalf("expected signing key %s", apk2)
   470  	}
   471  
   472  	ukp := createUserNKey(t)
   473  	upk := publicKey(ukp, t)
   474  
   475  	// claim signed by alternate key
   476  	uc := NewUserClaims(upk)
   477  	uc.IssuerAccount = apk1
   478  	utoken, err := uc.Encode(akp2)
   479  	if err != nil {
   480  		t.Fatal(err)
   481  	}
   482  
   483  	uc2, err := DecodeUserClaims(utoken)
   484  	if err != nil {
   485  		t.Fatal(err)
   486  	}
   487  	if !ac2.DidSign(uc2) {
   488  		t.Fatal("failed to verify user claim")
   489  	}
   490  
   491  	// claim signed by the account pk
   492  	uc3 := NewUserClaims(upk)
   493  	utoken2, err := uc3.Encode(akp1)
   494  	if err != nil {
   495  		t.Fatal(err)
   496  	}
   497  	uc4, err := DecodeUserClaims(utoken2)
   498  	if err != nil {
   499  		t.Fatal(err)
   500  	}
   501  	if !ac2.DidSign(uc4) {
   502  		t.Fatal("failed to verify user claim")
   503  	}
   504  }
   505  
   506  func TestAddRemoveSigningKey(t *testing.T) {
   507  	akp1 := createAccountNKey(t)
   508  	apk1 := publicKey(akp1, t)
   509  	akp2 := createAccountNKey(t)
   510  	apk2 := publicKey(akp2, t)
   511  	akp3 := createAccountNKey(t)
   512  	apk3 := publicKey(akp3, t)
   513  
   514  	ac := NewAccountClaims(apk1)
   515  	ac.SigningKeys.Add(apk2, apk3)
   516  
   517  	if len(ac.SigningKeys) != 2 {
   518  		t.Fatal("expected 2 signing keys")
   519  	}
   520  
   521  	ac.SigningKeys.Remove(publicKey(createAccountNKey(t), t))
   522  	if len(ac.SigningKeys) != 2 {
   523  		t.Fatal("expected 2 signing keys")
   524  	}
   525  
   526  	ac.SigningKeys.Remove(apk2)
   527  	if len(ac.SigningKeys) != 1 {
   528  		t.Fatal("expected single signing keys")
   529  	}
   530  }
   531  
   532  func TestUserRevocation(t *testing.T) {
   533  	akp := createAccountNKey(t)
   534  	apk := publicKey(akp, t)
   535  	account := NewAccountClaims(apk)
   536  
   537  	ukp := createUserNKey(t)
   538  	pubKey := publicKey(ukp, t)
   539  	uc := NewUserClaims(pubKey)
   540  	uJwt, _ := uc.Encode(akp)
   541  	uc, err := DecodeUserClaims(uJwt)
   542  	if err != nil {
   543  		t.Errorf("Failed to decode user claim: %v", err)
   544  	}
   545  	now := time.Now()
   546  
   547  	// test that clear is safe before we add any
   548  	account.ClearRevocation(pubKey)
   549  
   550  	if account.isRevoked(pubKey, now) {
   551  		t.Errorf("no revocation was added so is revoked should be false")
   552  	}
   553  
   554  	account.RevokeAt(pubKey, now.Add(time.Second*100))
   555  
   556  	if !account.isRevoked(pubKey, now) {
   557  		t.Errorf("revocation should hold when timestamp is in the future")
   558  	}
   559  
   560  	if account.isRevoked(pubKey, now.Add(time.Second*150)) {
   561  		t.Errorf("revocation should time out")
   562  	}
   563  
   564  	account.RevokeAt(pubKey, now.Add(time.Second*50)) // shouldn't change the revocation, you can't move it in
   565  
   566  	if !account.isRevoked(pubKey, now.Add(time.Second*60)) {
   567  		t.Errorf("revocation should hold, 100 > 50")
   568  	}
   569  
   570  	encoded, _ := account.Encode(akp)
   571  	decoded, _ := DecodeAccountClaims(encoded)
   572  
   573  	if !decoded.isRevoked(pubKey, now.Add(time.Second*60)) {
   574  		t.Errorf("revocation should last across encoding")
   575  	}
   576  
   577  	account.ClearRevocation(pubKey)
   578  
   579  	if account.IsClaimRevoked(uc) {
   580  		t.Errorf("revocations should be cleared")
   581  	}
   582  
   583  	account.RevokeAt(pubKey, now.Add(time.Second*1000))
   584  
   585  	if !account.IsClaimRevoked(uc) {
   586  		t.Errorf("revocation be true we revoked in the future")
   587  	}
   588  }
   589  
   590  func TestAccountDefaultPermissions(t *testing.T) {
   591  	akp := createAccountNKey(t)
   592  	apk := publicKey(akp, t)
   593  
   594  	account := NewAccountClaims(apk)
   595  	account.DefaultPermissions.Sub = Permission{
   596  		Allow: []string{"foo.1", "bar.*"},
   597  		Deny:  []string{"foo.2", "baz.>"},
   598  	}
   599  	account.DefaultPermissions.Pub = Permission{
   600  		Allow: []string{"foo.4", "bar.>"},
   601  		Deny:  []string{"foo.4", "baz.*"},
   602  	}
   603  	account.DefaultPermissions.Resp = &ResponsePermission{
   604  		5,
   605  		5 * time.Second}
   606  
   607  	actJwt := encode(account, akp, t)
   608  
   609  	account2, err := DecodeAccountClaims(actJwt)
   610  	if err != nil {
   611  		t.Fatal("error decoding account jwt", err)
   612  	}
   613  
   614  	AssertEquals(account.String(), account2.String(), t)
   615  }
   616  
   617  func TestUserRevocationAll(t *testing.T) {
   618  	akp := createAccountNKey(t)
   619  	ukp := createUserNKey(t)
   620  	upk := publicKey(ukp, t)
   621  	user := NewUserClaims(upk)
   622  	token, err := user.Encode(akp)
   623  	if err != nil {
   624  		t.Fatal(err)
   625  	}
   626  
   627  	ud, err := DecodeUserClaims(token)
   628  	if err != nil {
   629  		t.Fatal(err)
   630  	}
   631  
   632  	apk := publicKey(akp, t)
   633  	account := NewAccountClaims(apk)
   634  	account.RevokeAt(All, time.Now().Add(time.Second))
   635  	if !account.IsClaimRevoked(ud) {
   636  		t.Fatal("user should have been revoked")
   637  	}
   638  
   639  	account.RevokeAt(All, time.Now().Add(time.Second*-10))
   640  	if !account.IsClaimRevoked(ud) {
   641  		t.Fatal("user should have not been revoked")
   642  	}
   643  }
   644  
   645  func TestInvalidAccountInfo(t *testing.T) {
   646  	a := NewAccountClaims(publicKey(createAccountNKey(t), t))
   647  	a.InfoURL = "/bad"
   648  	vr := CreateValidationResults()
   649  	a.Validate(vr)
   650  	if vr.IsEmpty() {
   651  		t.Errorf("export info should not validate cleanly")
   652  	}
   653  	if !vr.IsBlocking(true) {
   654  		t.Errorf("invalid info needs to be blocking")
   655  	}
   656  }
   657  
   658  func TestAccountMapping(t *testing.T) { // don't block encoding!!!
   659  	akp := createAccountNKey(t)
   660  	apk := publicKey(akp, t)
   661  
   662  	account := NewAccountClaims(apk)
   663  	vr := &ValidationResults{}
   664  
   665  	account.AddMapping("foo1", WeightedMapping{Subject: "to"})
   666  	account.Validate(vr)
   667  	if !vr.IsEmpty() {
   668  		t.Fatal("Expected no errors")
   669  	}
   670  	account.AddMapping("foo2",
   671  		WeightedMapping{Subject: "to1", Weight: 50},
   672  		WeightedMapping{Subject: "to2", Weight: 50})
   673  	account.Validate(vr)
   674  	if !vr.IsEmpty() {
   675  		t.Fatal("Expected no errors")
   676  	}
   677  	account.AddMapping("foo3",
   678  		WeightedMapping{Subject: "to1", Weight: 50},
   679  		WeightedMapping{Subject: "to2", Weight: 51})
   680  	account.Validate(vr)
   681  	if !vr.IsBlocking(false) {
   682  		t.Fatal("Expected blocking error as sum of weights is > 100")
   683  	}
   684  
   685  	vr = &ValidationResults{}
   686  	account.Mappings = Mapping{}
   687  	account.AddMapping("foo4",
   688  		WeightedMapping{Subject: "to1"}, // no weight means 100
   689  		WeightedMapping{Subject: "to2", Weight: 1})
   690  	account.Validate(vr)
   691  	if !vr.IsBlocking(false) {
   692  		t.Fatal("Expected blocking error as sum of weights is > 100")
   693  	}
   694  
   695  	vr = &ValidationResults{}
   696  	account.Mappings = Mapping{}
   697  	account.AddMapping("foo5.>", WeightedMapping{Subject: "to.*.>"})
   698  	account.Validate(vr)
   699  	if !vr.IsEmpty() {
   700  		t.Fatal("Expected no errors")
   701  	}
   702  
   703  	vr = &ValidationResults{}
   704  	account.Mappings = Mapping{}
   705  	account.AddMapping("foo6.>", WeightedMapping{Subject: "to.boo.>"})
   706  	account.Validate(vr)
   707  	if !vr.IsEmpty() {
   708  		t.Fatal("Expected no errors")
   709  	}
   710  }
   711  
   712  func TestAccountExternalAuthorization(t *testing.T) {
   713  	akp := createAccountNKey(t)
   714  	apk := publicKey(akp, t)
   715  
   716  	account := NewAccountClaims(apk)
   717  	vr := &ValidationResults{}
   718  
   719  	ukp := createUserNKey(t)
   720  	account.EnableExternalAuthorization(publicKey(ukp, t))
   721  	account.Validate(vr)
   722  	if !vr.IsEmpty() {
   723  		t.Fatal("Expected no errors")
   724  	}
   725  
   726  	akp2 := createAccountNKey(t)
   727  	account.Authorization.AllowedAccounts.Add(publicKey(akp2, t))
   728  	account.Validate(vr)
   729  	if !vr.IsEmpty() {
   730  		t.Fatal("Expected no errors")
   731  	}
   732  
   733  	if !account.HasExternalAuthorization() {
   734  		t.Fatalf("Expected to have authorization enabled")
   735  	}
   736  
   737  	vr = &ValidationResults{}
   738  	account.Authorization = ExternalAuthorization{}
   739  
   740  	account.Authorization.AuthUsers.Add("Z")
   741  	account.Validate(vr)
   742  	if vr.IsEmpty() || !vr.IsBlocking(false) {
   743  		t.Fatalf("Expected blocking error on bad auth user")
   744  	}
   745  
   746  	vr = &ValidationResults{}
   747  	account.Authorization = ExternalAuthorization{}
   748  	account.Authorization.AllowedAccounts.Add("Z")
   749  	account.Validate(vr)
   750  	if vr.IsEmpty() || !vr.IsBlocking(false) {
   751  		t.Fatalf("Expected blocking error on bad allowed account")
   752  	}
   753  
   754  	account.Authorization = ExternalAuthorization{}
   755  	if account.Authorization.IsEnabled() {
   756  		t.Fatalf("Expected not to have authorization enabled")
   757  	}
   758  }
   759  
   760  func TestAccountExternalAuthorizationRequiresOneUser(t *testing.T) {
   761  	akp := createAccountNKey(t)
   762  	apk := publicKey(akp, t)
   763  
   764  	account := NewAccountClaims(apk)
   765  	account.Authorization.AllowedAccounts.Add(publicKey(createAccountNKey(t), t))
   766  
   767  	vr := &ValidationResults{}
   768  	account.Validate(vr)
   769  
   770  	AssertEquals(len(vr.Errors()), 1, t)
   771  	AssertEquals("External authorization cannot have accounts without users specified",
   772  		vr.Errors()[0].Error(),
   773  		t)
   774  }
   775  
   776  func TestAccountExternalAuthorizationAnyAccount(t *testing.T) {
   777  	akp := createAccountNKey(t)
   778  	apk := publicKey(akp, t)
   779  	ukp := createUserNKey(t)
   780  	upk := publicKey(ukp, t)
   781  
   782  	account := NewAccountClaims(apk)
   783  	account.Authorization.AllowedAccounts.Add("*")
   784  	account.Authorization.AuthUsers.Add(upk)
   785  
   786  	vr := &ValidationResults{}
   787  	account.Validate(vr)
   788  	AssertEquals(len(vr.Errors()), 0, t)
   789  }
   790  
   791  func TestAccountExternalAuthorizationAnyAccountAndSpecificFails(t *testing.T) {
   792  	akp := createAccountNKey(t)
   793  	apk := publicKey(akp, t)
   794  	ukp := createUserNKey(t)
   795  	upk := publicKey(ukp, t)
   796  
   797  	account := NewAccountClaims(apk)
   798  	account.Authorization.AllowedAccounts.Add("*", apk)
   799  	account.Authorization.AuthUsers.Add(upk)
   800  
   801  	vr := &ValidationResults{}
   802  	account.Validate(vr)
   803  	AssertEquals(len(vr.Errors()), 1, t)
   804  	AssertEquals(vr.Errors()[0].Error(), fmt.Sprintf("AllowedAccounts can only be a list of accounts or %q", AnyAccount), t)
   805  }
   806  
   807  func TestAccountClaims_DidSign(t *testing.T) {
   808  	akp := createAccountNKey(t)
   809  	apk := publicKey(akp, t)
   810  	skp := createAccountNKey(t)
   811  	spk := publicKey(skp, t)
   812  
   813  	ac := NewAccountClaims(apk)
   814  	ac.SigningKeys.Add(spk)
   815  
   816  	upk := publicKey(createUserNKey(t), t)
   817  	uc := NewUserClaims(upk)
   818  	tok, err := uc.Encode(akp)
   819  	if err != nil {
   820  		t.Fatal("error encoding")
   821  	}
   822  	uc, err = DecodeUserClaims(tok)
   823  	if err != nil {
   824  		t.Fatal("error decoding")
   825  	}
   826  	if !ac.DidSign(uc) {
   827  		t.Fatal("expected account to have been issued")
   828  	}
   829  	uc = NewUserClaims(upk)
   830  	uc.IssuerAccount = publicKey(createAccountNKey(t), t)
   831  	tok, err = uc.Encode(skp)
   832  	if err != nil {
   833  		t.Fatalf("encode failed %v", err)
   834  	}
   835  	uc, err = DecodeUserClaims(tok)
   836  	if err != nil {
   837  		t.Fatalf("decode failed %v", err)
   838  	}
   839  	if ac.DidSign(uc) {
   840  		t.Fatal("this is not issued by account A")
   841  	}
   842  }
   843  
   844  func TestAccountClaims_GetTags(t *testing.T) {
   845  	akp := createAccountNKey(t)
   846  	apk := publicKey(akp, t)
   847  
   848  	ac := NewAccountClaims(apk)
   849  	ac.Account.Tags.Add("foo", "bar")
   850  	tags := ac.GetTags()
   851  	if len(tags) != 2 {
   852  		t.Fatal("expected 2 tags")
   853  	}
   854  	if tags[0] != "foo" {
   855  		t.Fatal("expected tag foo")
   856  	}
   857  	if tags[1] != "bar" {
   858  		t.Fatal("expected tag bar")
   859  	}
   860  
   861  	token, err := ac.Encode(akp)
   862  	if err != nil {
   863  		t.Fatal("error encoding")
   864  	}
   865  	ac, err = DecodeAccountClaims(token)
   866  	if err != nil {
   867  		t.Fatal("error decoding")
   868  	}
   869  	tags = ac.GetTags()
   870  	if len(tags) != 2 {
   871  		t.Fatal("expected 2 tags")
   872  	}
   873  	if tags[0] != "foo" {
   874  		t.Fatal("expected tag foo")
   875  	}
   876  	if tags[1] != "bar" {
   877  		t.Fatal("expected tag bar")
   878  	}
   879  }
   880  
   881  func TestAccountClaimsTraceDest(t *testing.T) {
   882  	akp := createAccountNKey(t)
   883  	apk := publicKey(akp, t)
   884  
   885  	account := NewAccountClaims(apk)
   886  	for i, test := range []struct {
   887  		name        string
   888  		invalidSubj Subject
   889  		expectErr   bool
   890  	}{
   891  		{"trace not specified", "", false},
   892  		{"trace created but with empty destination", "", true},
   893  		{"trace dest has spaces", "invalid dest", true},
   894  		{"trace dest start with a dot", ".invalid.dest", true},
   895  		{"trace dest ends with a dot", "invalid.dest.", true},
   896  		{"trace dest has consecutive dots", "invalid..dest", true},
   897  		{"trace dest invalid publish dest", "invalid.publish.*.dest", true},
   898  	} {
   899  		t.Run(test.name, func(t *testing.T) {
   900  			if i > 0 {
   901  				account.Trace = &MsgTrace{Destination: test.invalidSubj}
   902  			}
   903  			vr := CreateValidationResults()
   904  			account.Validate(vr)
   905  
   906  			if test.expectErr && vr.IsEmpty() {
   907  				t.Fatal("account validation should have failed")
   908  			} else if !test.expectErr && !vr.IsEmpty() {
   909  				t.Fatalf("account validation should not have failed, got %+v", vr.Issues)
   910  			}
   911  		})
   912  	}
   913  }
   914  
   915  func TestAccountClaimsTraceDestSampling(t *testing.T) {
   916  	akp := createAccountNKey(t)
   917  	apk := publicKey(akp, t)
   918  
   919  	account := NewAccountClaims(apk)
   920  	for _, test := range []struct {
   921  		name      string
   922  		dest      string
   923  		sampling  int
   924  		expectErr string
   925  	}{
   926  		{"sampling without destination", "", 10, "subject cannot be empty"},
   927  		{"sampling negative", "dest", -1, "should be in the range [1..100]"},
   928  		{"sampling above 100", "dest", 101, "should be in the range [1..100]"},
   929  		{"sampling at 50", "dest", 50, ""},
   930  		{"sampling at zero sets to 100", "dest", 0, ""},
   931  	} {
   932  		t.Run(test.name, func(t *testing.T) {
   933  			account.Trace = &MsgTrace{Destination: Subject(test.dest), Sampling: test.sampling}
   934  			vr := CreateValidationResults()
   935  			account.Validate(vr)
   936  
   937  			if test.expectErr == "" {
   938  				if !vr.IsEmpty() {
   939  					t.Fatalf("account validation should not have failed, got %+v", vr.Issues)
   940  				}
   941  				if test.sampling == 0 {
   942  					if account.Trace.Sampling != 100 {
   943  						t.Fatalf("account sampling should have been set to 100 got %d", account.Trace.Sampling)
   944  					}
   945  				} else if test.sampling != account.Trace.Sampling {
   946  					t.Fatalf("account sampling should be %d, got %d", test.sampling, account.Trace.Sampling)
   947  				}
   948  			} else {
   949  				if vr.IsEmpty() {
   950  					t.Fatal("account validation should have failed")
   951  				}
   952  				if !strings.Contains(vr.Issues[0].Description, test.expectErr) {
   953  					t.Fatalf("account validation should have failed with error %q, got %q", test.expectErr, vr.Issues[0].Description)
   954  				}
   955  			}
   956  		})
   957  	}
   958  }