get.pme.sh/pnats@v0.0.0-20240304004023-26bb5a137ed0/server/jwt_test.go (about)

     1  // Copyright 2018-2020 The NATS Authors
     2  // Licensed under the Apache License, Version 2.0 (the "License");
     3  // you may not use this file except in compliance with the License.
     4  // You may obtain a copy of the License at
     5  //
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package server
    15  
    16  import (
    17  	"bufio"
    18  	"encoding/base64"
    19  	"encoding/json"
    20  	"errors"
    21  	"fmt"
    22  	"io"
    23  	"net/http"
    24  	"net/http/httptest"
    25  	"os"
    26  	"path/filepath"
    27  	"strings"
    28  	"sync"
    29  	"sync/atomic"
    30  	"testing"
    31  	"time"
    32  
    33  	"github.com/nats-io/jwt/v2"
    34  	"github.com/nats-io/nats.go"
    35  	"github.com/nats-io/nkeys"
    36  )
    37  
    38  var (
    39  	// This matches ./configs/nkeys_jwts/test.seed
    40  	oSeed = []byte("SOAFYNORQLQFJYBYNUGC5D7SH2MXMUX5BFEWWGHN3EK4VGG5TPT5DZP7QU")
    41  	// This matches ./configs/nkeys/op.jwt
    42  	ojwt = "eyJ0eXAiOiJqd3QiLCJhbGciOiJlZDI1NTE5In0.eyJhdWQiOiJURVNUUyIsImV4cCI6MTg1OTEyMTI3NSwianRpIjoiWE5MWjZYWVBIVE1ESlFSTlFPSFVPSlFHV0NVN01JNVc1SlhDWk5YQllVS0VRVzY3STI1USIsImlhdCI6MTU0Mzc2MTI3NSwiaXNzIjoiT0NBVDMzTVRWVTJWVU9JTUdOR1VOWEo2NkFIMlJMU0RBRjNNVUJDWUFZNVFNSUw2NU5RTTZYUUciLCJuYW1lIjoiU3luYWRpYSBDb21tdW5pY2F0aW9ucyBJbmMuIiwibmJmIjoxNTQzNzYxMjc1LCJzdWIiOiJPQ0FUMzNNVFZVMlZVT0lNR05HVU5YSjY2QUgyUkxTREFGM01VQkNZQVk1UU1JTDY1TlFNNlhRRyIsInR5cGUiOiJvcGVyYXRvciIsIm5hdHMiOnsic2lnbmluZ19rZXlzIjpbIk9EU0tSN01ZRlFaNU1NQUo2RlBNRUVUQ1RFM1JJSE9GTFRZUEpSTUFWVk40T0xWMllZQU1IQ0FDIiwiT0RTS0FDU1JCV1A1MzdEWkRSVko2NTdKT0lHT1BPUTZLRzdUNEhONk9LNEY2SUVDR1hEQUhOUDIiLCJPRFNLSTM2TFpCNDRPWTVJVkNSNlA1MkZaSlpZTVlXWlZXTlVEVExFWjVUSzJQTjNPRU1SVEFCUiJdfX0.hyfz6E39BMUh0GLzovFfk3wT4OfualftjdJ_eYkLfPvu5tZubYQ_Pn9oFYGCV_6yKy3KMGhWGUCyCdHaPhalBw"
    43  	oKp  nkeys.KeyPair
    44  )
    45  
    46  func init() {
    47  	var err error
    48  	oKp, err = nkeys.FromSeed(oSeed)
    49  	if err != nil {
    50  		panic(fmt.Sprintf("Parsing oSeed failed with: %v", err))
    51  	}
    52  }
    53  
    54  func chanRecv(t *testing.T, recvChan <-chan struct{}, limit time.Duration) {
    55  	t.Helper()
    56  	select {
    57  	case <-recvChan:
    58  	case <-time.After(limit):
    59  		t.Fatal("Should have received from channel")
    60  	}
    61  }
    62  
    63  func opTrustBasicSetup() *Server {
    64  	kp, _ := nkeys.FromSeed(oSeed)
    65  	pub, _ := kp.PublicKey()
    66  	opts := defaultServerOptions
    67  	opts.TrustedKeys = []string{pub}
    68  	s, c, _, _ := rawSetup(opts)
    69  	c.close()
    70  	return s
    71  }
    72  
    73  func buildMemAccResolver(s *Server) {
    74  	mr := &MemAccResolver{}
    75  	s.SetAccountResolver(mr)
    76  }
    77  
    78  func addAccountToMemResolver(s *Server, pub, jwtclaim string) {
    79  	s.AccountResolver().Store(pub, jwtclaim)
    80  }
    81  
    82  func createClient(t *testing.T, s *Server, akp nkeys.KeyPair) (*testAsyncClient, *bufio.Reader, string) {
    83  	return createClientWithIssuer(t, s, akp, "")
    84  }
    85  
    86  func createClientWithIssuer(t *testing.T, s *Server, akp nkeys.KeyPair, optIssuerAccount string) (*testAsyncClient, *bufio.Reader, string) {
    87  	t.Helper()
    88  	nkp, _ := nkeys.CreateUser()
    89  	pub, _ := nkp.PublicKey()
    90  	nuc := jwt.NewUserClaims(pub)
    91  	if optIssuerAccount != "" {
    92  		nuc.IssuerAccount = optIssuerAccount
    93  	}
    94  	ujwt, err := nuc.Encode(akp)
    95  	if err != nil {
    96  		t.Fatalf("Error generating user JWT: %v", err)
    97  	}
    98  	c, cr, l := newClientForServer(s)
    99  
   100  	// Sign Nonce
   101  	var info nonceInfo
   102  	json.Unmarshal([]byte(l[5:]), &info)
   103  	sigraw, _ := nkp.Sign([]byte(info.Nonce))
   104  	sig := base64.RawURLEncoding.EncodeToString(sigraw)
   105  
   106  	cs := fmt.Sprintf("CONNECT {\"jwt\":%q,\"sig\":\"%s\"}\r\nPING\r\n", ujwt, sig)
   107  	return c, cr, cs
   108  }
   109  
   110  func setupJWTTestWithClaims(t *testing.T, nac *jwt.AccountClaims, nuc *jwt.UserClaims, expected string) (*Server, nkeys.KeyPair, *testAsyncClient, *bufio.Reader) {
   111  	t.Helper()
   112  
   113  	akp, _ := nkeys.CreateAccount()
   114  	apub, _ := akp.PublicKey()
   115  	if nac == nil {
   116  		nac = jwt.NewAccountClaims(apub)
   117  	} else {
   118  		nac.Subject = apub
   119  	}
   120  	ajwt, err := nac.Encode(oKp)
   121  	if err != nil {
   122  		t.Fatalf("Error generating account JWT: %v", err)
   123  	}
   124  
   125  	nkp, _ := nkeys.CreateUser()
   126  	pub, _ := nkp.PublicKey()
   127  	if nuc == nil {
   128  		nuc = jwt.NewUserClaims(pub)
   129  	} else {
   130  		nuc.Subject = pub
   131  	}
   132  	jwt, err := nuc.Encode(akp)
   133  	if err != nil {
   134  		t.Fatalf("Error generating user JWT: %v", err)
   135  	}
   136  
   137  	s := opTrustBasicSetup()
   138  	buildMemAccResolver(s)
   139  	addAccountToMemResolver(s, apub, ajwt)
   140  
   141  	c, cr, l := newClientForServer(s)
   142  
   143  	// Sign Nonce
   144  	var info nonceInfo
   145  	json.Unmarshal([]byte(l[5:]), &info)
   146  	sigraw, _ := nkp.Sign([]byte(info.Nonce))
   147  	sig := base64.RawURLEncoding.EncodeToString(sigraw)
   148  
   149  	// PING needed to flush the +OK/-ERR to us.
   150  	cs := fmt.Sprintf("CONNECT {\"jwt\":%q,\"sig\":\"%s\",\"verbose\":true,\"pedantic\":true}\r\nPING\r\n", jwt, sig)
   151  	wg := sync.WaitGroup{}
   152  	wg.Add(1)
   153  	go func() {
   154  		c.parse([]byte(cs))
   155  		wg.Done()
   156  	}()
   157  	l, _ = cr.ReadString('\n')
   158  	if !strings.HasPrefix(l, expected) {
   159  		t.Fatalf("Expected %q, got %q", expected, l)
   160  	}
   161  	wg.Wait()
   162  
   163  	return s, akp, c, cr
   164  }
   165  
   166  func setupJWTTestWitAccountClaims(t *testing.T, nac *jwt.AccountClaims, expected string) (*Server, nkeys.KeyPair, *testAsyncClient, *bufio.Reader) {
   167  	t.Helper()
   168  	return setupJWTTestWithClaims(t, nac, nil, expected)
   169  }
   170  
   171  // This is used in test to create account claims and pass it
   172  // to setupJWTTestWitAccountClaims.
   173  func newJWTTestAccountClaims() *jwt.AccountClaims {
   174  	// We call NewAccountClaims() because it sets some defaults.
   175  	// However, this call needs a subject, but the real subject will
   176  	// be set in setupJWTTestWitAccountClaims(). Use some temporary one
   177  	// here.
   178  	return jwt.NewAccountClaims("temp")
   179  }
   180  
   181  func setupJWTTestWithUserClaims(t *testing.T, nuc *jwt.UserClaims, expected string) (*Server, *testAsyncClient, *bufio.Reader) {
   182  	t.Helper()
   183  	s, _, c, cr := setupJWTTestWithClaims(t, nil, nuc, expected)
   184  	return s, c, cr
   185  }
   186  
   187  // This is used in test to create user claims and pass it
   188  // to setupJWTTestWithUserClaims.
   189  func newJWTTestUserClaims() *jwt.UserClaims {
   190  	// As of now, tests could simply do &jwt.UserClaims{}, but in
   191  	// case some defaults are later added, we call NewUserClaims().
   192  	// However, this call needs a subject, but the real subject will
   193  	// be set in setupJWTTestWithUserClaims(). Use some temporary one
   194  	// here.
   195  	return jwt.NewUserClaims("temp")
   196  }
   197  
   198  func TestJWTUser(t *testing.T) {
   199  	s := opTrustBasicSetup()
   200  	defer s.Shutdown()
   201  
   202  	// Check to make sure we would have an authTimer
   203  	if !s.info.AuthRequired {
   204  		t.Fatalf("Expect the server to require auth")
   205  	}
   206  
   207  	c, cr, _ := newClientForServer(s)
   208  	defer c.close()
   209  
   210  	// Don't send jwt field, should fail.
   211  	c.parseAsync("CONNECT {\"verbose\":true,\"pedantic\":true}\r\nPING\r\n")
   212  	l, _ := cr.ReadString('\n')
   213  	if !strings.HasPrefix(l, "-ERR ") {
   214  		t.Fatalf("Expected an error")
   215  	}
   216  
   217  	okp, _ := nkeys.FromSeed(oSeed)
   218  
   219  	// Create an account that will be expired.
   220  	akp, _ := nkeys.CreateAccount()
   221  	apub, _ := akp.PublicKey()
   222  	nac := jwt.NewAccountClaims(apub)
   223  	ajwt, err := nac.Encode(okp)
   224  	if err != nil {
   225  		t.Fatalf("Error generating account JWT: %v", err)
   226  	}
   227  
   228  	c, cr, cs := createClient(t, s, akp)
   229  	defer c.close()
   230  
   231  	// PING needed to flush the +OK/-ERR to us.
   232  	// This should fail too since no account resolver is defined.
   233  	c.parseAsync(cs)
   234  	l, _ = cr.ReadString('\n')
   235  	if !strings.HasPrefix(l, "-ERR ") {
   236  		t.Fatalf("Expected an error")
   237  	}
   238  
   239  	// Ok now let's walk through and make sure all is good.
   240  	// We will set the account resolver by hand to a memory resolver.
   241  	buildMemAccResolver(s)
   242  	addAccountToMemResolver(s, apub, ajwt)
   243  
   244  	c, cr, cs = createClient(t, s, akp)
   245  	defer c.close()
   246  
   247  	c.parseAsync(cs)
   248  	l, _ = cr.ReadString('\n')
   249  	if !strings.HasPrefix(l, "PONG") {
   250  		t.Fatalf("Expected a PONG, got %q", l)
   251  	}
   252  }
   253  
   254  func TestJWTUserBadTrusted(t *testing.T) {
   255  	s := opTrustBasicSetup()
   256  	defer s.Shutdown()
   257  
   258  	// Check to make sure we would have an authTimer
   259  	if !s.info.AuthRequired {
   260  		t.Fatalf("Expect the server to require auth")
   261  	}
   262  	// Now place bad trusted key
   263  	s.mu.Lock()
   264  	s.trustedKeys = []string{"bad"}
   265  	s.mu.Unlock()
   266  
   267  	buildMemAccResolver(s)
   268  
   269  	okp, _ := nkeys.FromSeed(oSeed)
   270  
   271  	// Create an account that will be expired.
   272  	akp, _ := nkeys.CreateAccount()
   273  	apub, _ := akp.PublicKey()
   274  	nac := jwt.NewAccountClaims(apub)
   275  	ajwt, err := nac.Encode(okp)
   276  	if err != nil {
   277  		t.Fatalf("Error generating account JWT: %v", err)
   278  	}
   279  	addAccountToMemResolver(s, apub, ajwt)
   280  
   281  	c, cr, cs := createClient(t, s, akp)
   282  	defer c.close()
   283  	c.parseAsync(cs)
   284  	l, _ := cr.ReadString('\n')
   285  	if !strings.HasPrefix(l, "-ERR ") {
   286  		t.Fatalf("Expected an error")
   287  	}
   288  }
   289  
   290  // Test that if a user tries to connect with an expired user JWT we do the right thing.
   291  func TestJWTUserExpired(t *testing.T) {
   292  	nuc := newJWTTestUserClaims()
   293  	nuc.IssuedAt = time.Now().Add(-10 * time.Second).Unix()
   294  	nuc.Expires = time.Now().Add(-2 * time.Second).Unix()
   295  	s, c, _ := setupJWTTestWithUserClaims(t, nuc, "-ERR ")
   296  	c.close()
   297  	s.Shutdown()
   298  }
   299  
   300  func TestJWTUserExpiresAfterConnect(t *testing.T) {
   301  	nuc := newJWTTestUserClaims()
   302  	nuc.IssuedAt = time.Now().Unix()
   303  	nuc.Expires = time.Now().Add(time.Second).Unix()
   304  	s, c, cr := setupJWTTestWithUserClaims(t, nuc, "+OK")
   305  	defer s.Shutdown()
   306  	defer c.close()
   307  	l, err := cr.ReadString('\n')
   308  	if err != nil {
   309  		t.Fatalf("Received %v", err)
   310  	}
   311  	if !strings.HasPrefix(l, "PONG") {
   312  		t.Fatalf("Expected a PONG")
   313  	}
   314  
   315  	// Now we should expire after 1 second or so.
   316  	time.Sleep(1250 * time.Millisecond)
   317  
   318  	l, err = cr.ReadString('\n')
   319  	if err != nil {
   320  		t.Fatalf("Received %v", err)
   321  	}
   322  	if !strings.HasPrefix(l, "-ERR ") {
   323  		t.Fatalf("Expected an error")
   324  	}
   325  	if !strings.Contains(l, "Expired") {
   326  		t.Fatalf("Expected 'Expired' to be in the error")
   327  	}
   328  }
   329  
   330  func TestJWTUserPermissionClaims(t *testing.T) {
   331  	nuc := newJWTTestUserClaims()
   332  	nuc.Permissions.Pub.Allow.Add("foo")
   333  	nuc.Permissions.Pub.Allow.Add("bar")
   334  	nuc.Permissions.Pub.Deny.Add("baz")
   335  	nuc.Permissions.Sub.Allow.Add("foo")
   336  	nuc.Permissions.Sub.Allow.Add("bar")
   337  	nuc.Permissions.Sub.Deny.Add("baz")
   338  
   339  	s, c, _ := setupJWTTestWithUserClaims(t, nuc, "+OK")
   340  	defer s.Shutdown()
   341  	defer c.close()
   342  
   343  	// Now check client to make sure permissions transferred.
   344  	c.mu.Lock()
   345  	defer c.mu.Unlock()
   346  
   347  	if c.perms == nil {
   348  		t.Fatalf("Expected client permissions to be set")
   349  	}
   350  
   351  	if lpa := c.perms.pub.allow.Count(); lpa != 2 {
   352  		t.Fatalf("Expected 2 publish allow subjects, got %d", lpa)
   353  	}
   354  	if lpd := c.perms.pub.deny.Count(); lpd != 1 {
   355  		t.Fatalf("Expected 1 publish deny subjects, got %d", lpd)
   356  	}
   357  	if lsa := c.perms.sub.allow.Count(); lsa != 2 {
   358  		t.Fatalf("Expected 2 subscribe allow subjects, got %d", lsa)
   359  	}
   360  	if lsd := c.perms.sub.deny.Count(); lsd != 1 {
   361  		t.Fatalf("Expected 1 subscribe deny subjects, got %d", lsd)
   362  	}
   363  }
   364  
   365  func TestJWTUserResponsePermissionClaims(t *testing.T) {
   366  	nuc := newJWTTestUserClaims()
   367  	nuc.Permissions.Resp = &jwt.ResponsePermission{
   368  		MaxMsgs: 22,
   369  		Expires: 100 * time.Millisecond,
   370  	}
   371  	s, c, _ := setupJWTTestWithUserClaims(t, nuc, "+OK")
   372  	defer s.Shutdown()
   373  	defer c.close()
   374  
   375  	// Now check client to make sure permissions transferred.
   376  	c.mu.Lock()
   377  	defer c.mu.Unlock()
   378  
   379  	if c.perms == nil {
   380  		t.Fatalf("Expected client permissions to be set")
   381  	}
   382  	if c.perms.pub.allow == nil {
   383  		t.Fatalf("Expected client perms for pub allow to be non-nil")
   384  	}
   385  	if lpa := c.perms.pub.allow.Count(); lpa != 0 {
   386  		t.Fatalf("Expected 0 publish allow subjects, got %d", lpa)
   387  	}
   388  	if c.perms.resp == nil {
   389  		t.Fatalf("Expected client perms for response permissions to be non-nil")
   390  	}
   391  	if c.perms.resp.MaxMsgs != nuc.Permissions.Resp.MaxMsgs {
   392  		t.Fatalf("Expected client perms for response permissions MaxMsgs to be same as jwt: %d vs %d",
   393  			c.perms.resp.MaxMsgs, nuc.Permissions.Resp.MaxMsgs)
   394  	}
   395  	if c.perms.resp.Expires != nuc.Permissions.Resp.Expires {
   396  		t.Fatalf("Expected client perms for response permissions Expires to be same as jwt: %v vs %v",
   397  			c.perms.resp.Expires, nuc.Permissions.Resp.Expires)
   398  	}
   399  }
   400  
   401  func TestJWTUserResponsePermissionClaimsDefaultValues(t *testing.T) {
   402  	nuc := newJWTTestUserClaims()
   403  	nuc.Permissions.Resp = &jwt.ResponsePermission{}
   404  	s, c, _ := setupJWTTestWithUserClaims(t, nuc, "+OK")
   405  	defer s.Shutdown()
   406  	defer c.close()
   407  
   408  	// Now check client to make sure permissions transferred
   409  	// and defaults are set.
   410  	c.mu.Lock()
   411  	defer c.mu.Unlock()
   412  
   413  	if c.perms == nil {
   414  		t.Fatalf("Expected client permissions to be set")
   415  	}
   416  	if c.perms.pub.allow == nil {
   417  		t.Fatalf("Expected client perms for pub allow to be non-nil")
   418  	}
   419  	if lpa := c.perms.pub.allow.Count(); lpa != 0 {
   420  		t.Fatalf("Expected 0 publish allow subjects, got %d", lpa)
   421  	}
   422  	if c.perms.resp == nil {
   423  		t.Fatalf("Expected client perms for response permissions to be non-nil")
   424  	}
   425  	if c.perms.resp.MaxMsgs != DEFAULT_ALLOW_RESPONSE_MAX_MSGS {
   426  		t.Fatalf("Expected client perms for response permissions MaxMsgs to be default %v, got %v",
   427  			DEFAULT_ALLOW_RESPONSE_MAX_MSGS, c.perms.resp.MaxMsgs)
   428  	}
   429  	if c.perms.resp.Expires != DEFAULT_ALLOW_RESPONSE_EXPIRATION {
   430  		t.Fatalf("Expected client perms for response permissions Expires to be default %v, got %v",
   431  			DEFAULT_ALLOW_RESPONSE_EXPIRATION, c.perms.resp.Expires)
   432  	}
   433  }
   434  
   435  func TestJWTUserResponsePermissionClaimsNegativeValues(t *testing.T) {
   436  	nuc := newJWTTestUserClaims()
   437  	nuc.Permissions.Resp = &jwt.ResponsePermission{
   438  		MaxMsgs: -1,
   439  		Expires: -1 * time.Second,
   440  	}
   441  	s, c, _ := setupJWTTestWithUserClaims(t, nuc, "+OK")
   442  	defer s.Shutdown()
   443  	defer c.close()
   444  
   445  	// Now check client to make sure permissions transferred
   446  	// and negative values are transferred.
   447  	c.mu.Lock()
   448  	defer c.mu.Unlock()
   449  
   450  	if c.perms == nil {
   451  		t.Fatalf("Expected client permissions to be set")
   452  	}
   453  	if c.perms.pub.allow == nil {
   454  		t.Fatalf("Expected client perms for pub allow to be non-nil")
   455  	}
   456  	if lpa := c.perms.pub.allow.Count(); lpa != 0 {
   457  		t.Fatalf("Expected 0 publish allow subjects, got %d", lpa)
   458  	}
   459  	if c.perms.resp == nil {
   460  		t.Fatalf("Expected client perms for response permissions to be non-nil")
   461  	}
   462  	if c.perms.resp.MaxMsgs != -1 {
   463  		t.Fatalf("Expected client perms for response permissions MaxMsgs to be %v, got %v",
   464  			-1, c.perms.resp.MaxMsgs)
   465  	}
   466  	if c.perms.resp.Expires != -1*time.Second {
   467  		t.Fatalf("Expected client perms for response permissions Expires to be %v, got %v",
   468  			-1*time.Second, c.perms.resp.Expires)
   469  	}
   470  }
   471  
   472  func TestJWTAccountExpired(t *testing.T) {
   473  	nac := newJWTTestAccountClaims()
   474  	nac.IssuedAt = time.Now().Add(-10 * time.Second).Unix()
   475  	nac.Expires = time.Now().Add(-2 * time.Second).Unix()
   476  	s, _, c, _ := setupJWTTestWitAccountClaims(t, nac, "-ERR ")
   477  	defer s.Shutdown()
   478  	defer c.close()
   479  }
   480  
   481  func TestJWTAccountExpiresAfterConnect(t *testing.T) {
   482  	nac := newJWTTestAccountClaims()
   483  	now := time.Now()
   484  	nac.IssuedAt = now.Add(-10 * time.Second).Unix()
   485  	nac.Expires = now.Round(time.Second).Add(time.Second).Unix()
   486  	s, akp, c, cr := setupJWTTestWitAccountClaims(t, nac, "+OK")
   487  	defer s.Shutdown()
   488  	defer c.close()
   489  
   490  	apub, _ := akp.PublicKey()
   491  	acc, err := s.LookupAccount(apub)
   492  	if acc == nil || err != nil {
   493  		t.Fatalf("Expected to retrieve the account")
   494  	}
   495  
   496  	if l, _ := cr.ReadString('\n'); !strings.HasPrefix(l, "PONG") {
   497  		t.Fatalf("Expected PONG, got %q", l)
   498  	}
   499  
   500  	// Wait for the account to be expired.
   501  	checkFor(t, 3*time.Second, 100*time.Millisecond, func() error {
   502  		if acc.IsExpired() {
   503  			return nil
   504  		}
   505  		return fmt.Errorf("Account not expired yet")
   506  	})
   507  
   508  	l, _ := cr.ReadString('\n')
   509  	if !strings.HasPrefix(l, "-ERR ") {
   510  		t.Fatalf("Expected an error, got %q", l)
   511  	}
   512  	if !strings.Contains(l, "Expired") {
   513  		t.Fatalf("Expected 'Expired' to be in the error")
   514  	}
   515  
   516  	// Now make sure that accounts that have expired return an error.
   517  	c, cr, cs := createClient(t, s, akp)
   518  	defer c.close()
   519  	c.parseAsync(cs)
   520  	l, _ = cr.ReadString('\n')
   521  	if !strings.HasPrefix(l, "-ERR ") {
   522  		t.Fatalf("Expected an error")
   523  	}
   524  }
   525  
   526  func TestJWTAccountRenew(t *testing.T) {
   527  	nac := newJWTTestAccountClaims()
   528  	// Create an account that has expired.
   529  	nac.IssuedAt = time.Now().Add(-10 * time.Second).Unix()
   530  	nac.Expires = time.Now().Add(-2 * time.Second).Unix()
   531  	// Expect an error
   532  	s, akp, c, _ := setupJWTTestWitAccountClaims(t, nac, "-ERR ")
   533  	defer s.Shutdown()
   534  	defer c.close()
   535  
   536  	okp, _ := nkeys.FromSeed(oSeed)
   537  	apub, _ := akp.PublicKey()
   538  
   539  	// Now update with new expiration
   540  	nac.IssuedAt = time.Now().Unix()
   541  	nac.Expires = time.Now().Add(5 * time.Second).Unix()
   542  	ajwt, err := nac.Encode(okp)
   543  	if err != nil {
   544  		t.Fatalf("Error generating account JWT: %v", err)
   545  	}
   546  
   547  	// Update the account
   548  	addAccountToMemResolver(s, apub, ajwt)
   549  	acc, _ := s.LookupAccount(apub)
   550  	if acc == nil {
   551  		t.Fatalf("Expected to retrieve the account")
   552  	}
   553  	s.UpdateAccountClaims(acc, nac)
   554  
   555  	// Now make sure we can connect.
   556  	c, cr, cs := createClient(t, s, akp)
   557  	defer c.close()
   558  	c.parseAsync(cs)
   559  	if l, _ := cr.ReadString('\n'); !strings.HasPrefix(l, "PONG") {
   560  		t.Fatalf("Expected a PONG, got: %q", l)
   561  	}
   562  }
   563  
   564  func TestJWTAccountRenewFromResolver(t *testing.T) {
   565  	s := opTrustBasicSetup()
   566  	defer s.Shutdown()
   567  	buildMemAccResolver(s)
   568  
   569  	okp, _ := nkeys.FromSeed(oSeed)
   570  
   571  	akp, _ := nkeys.CreateAccount()
   572  	apub, _ := akp.PublicKey()
   573  	nac := jwt.NewAccountClaims(apub)
   574  	nac.IssuedAt = time.Now().Add(-10 * time.Second).Unix()
   575  	nac.Expires = time.Now().Add(time.Second).Unix()
   576  	ajwt, err := nac.Encode(okp)
   577  	if err != nil {
   578  		t.Fatalf("Error generating account JWT: %v", err)
   579  	}
   580  
   581  	addAccountToMemResolver(s, apub, ajwt)
   582  	// Force it to be loaded by the server and start the expiration timer.
   583  	acc, _ := s.LookupAccount(apub)
   584  	if acc == nil {
   585  		t.Fatalf("Could not retrieve account for %q", apub)
   586  	}
   587  
   588  	// Create a new user
   589  	c, cr, cs := createClient(t, s, akp)
   590  	defer c.close()
   591  	// Wait for expiration.
   592  	time.Sleep(1250 * time.Millisecond)
   593  
   594  	c.parseAsync(cs)
   595  	l, _ := cr.ReadString('\n')
   596  	if !strings.HasPrefix(l, "-ERR ") {
   597  		t.Fatalf("Expected an error")
   598  	}
   599  
   600  	// Now update with new expiration
   601  	nac.IssuedAt = time.Now().Unix()
   602  	nac.Expires = time.Now().Add(5 * time.Second).Unix()
   603  	ajwt, err = nac.Encode(okp)
   604  	if err != nil {
   605  		t.Fatalf("Error generating account JWT: %v", err)
   606  	}
   607  
   608  	// Update the account
   609  	addAccountToMemResolver(s, apub, ajwt)
   610  	// Make sure the too quick update suppression does not bite us.
   611  	acc.mu.Lock()
   612  	acc.updated = time.Now().UTC().Add(-1 * time.Hour)
   613  	acc.mu.Unlock()
   614  
   615  	// Do not update the account directly. The resolver should
   616  	// happen automatically.
   617  
   618  	// Now make sure we can connect.
   619  	c, cr, cs = createClient(t, s, akp)
   620  	defer c.close()
   621  	c.parseAsync(cs)
   622  	l, _ = cr.ReadString('\n')
   623  	if !strings.HasPrefix(l, "PONG") {
   624  		t.Fatalf("Expected a PONG, got: %q", l)
   625  	}
   626  }
   627  
   628  func TestJWTAccountBasicImportExport(t *testing.T) {
   629  	s := opTrustBasicSetup()
   630  	defer s.Shutdown()
   631  	buildMemAccResolver(s)
   632  
   633  	okp, _ := nkeys.FromSeed(oSeed)
   634  
   635  	// Create accounts and imports/exports.
   636  	fooKP, _ := nkeys.CreateAccount()
   637  	fooPub, _ := fooKP.PublicKey()
   638  	fooAC := jwt.NewAccountClaims(fooPub)
   639  
   640  	// Now create Exports.
   641  	streamExport := &jwt.Export{Subject: "foo", Type: jwt.Stream}
   642  	streamExport2 := &jwt.Export{Subject: "private", Type: jwt.Stream, TokenReq: true}
   643  	serviceExport := &jwt.Export{Subject: "req.echo", Type: jwt.Service, TokenReq: true}
   644  	serviceExport2 := &jwt.Export{Subject: "req.add", Type: jwt.Service, TokenReq: true}
   645  
   646  	fooAC.Exports.Add(streamExport, streamExport2, serviceExport, serviceExport2)
   647  	fooJWT, err := fooAC.Encode(okp)
   648  	if err != nil {
   649  		t.Fatalf("Error generating account JWT: %v", err)
   650  	}
   651  
   652  	addAccountToMemResolver(s, fooPub, fooJWT)
   653  
   654  	acc, _ := s.LookupAccount(fooPub)
   655  	if acc == nil {
   656  		t.Fatalf("Expected to retrieve the account")
   657  	}
   658  
   659  	// Check to make sure exports transferred over.
   660  	if les := len(acc.exports.streams); les != 2 {
   661  		t.Fatalf("Expected exports streams len of 2, got %d", les)
   662  	}
   663  	if les := len(acc.exports.services); les != 2 {
   664  		t.Fatalf("Expected exports services len of 2, got %d", les)
   665  	}
   666  	_, ok := acc.exports.streams["foo"]
   667  	if !ok {
   668  		t.Fatalf("Expected to map a stream export")
   669  	}
   670  	se, ok := acc.exports.services["req.echo"]
   671  	if !ok || se == nil {
   672  		t.Fatalf("Expected to map a service export")
   673  	}
   674  	if !se.tokenReq {
   675  		t.Fatalf("Expected the service export to require tokens")
   676  	}
   677  
   678  	barKP, _ := nkeys.CreateAccount()
   679  	barPub, _ := barKP.PublicKey()
   680  	barAC := jwt.NewAccountClaims(barPub)
   681  
   682  	streamImport := &jwt.Import{Account: fooPub, Subject: "foo", To: "import.foo", Type: jwt.Stream}
   683  	serviceImport := &jwt.Import{Account: fooPub, Subject: "req.echo", Type: jwt.Service}
   684  	barAC.Imports.Add(streamImport, serviceImport)
   685  	barJWT, err := barAC.Encode(okp)
   686  	if err != nil {
   687  		t.Fatalf("Error generating account JWT: %v", err)
   688  	}
   689  	addAccountToMemResolver(s, barPub, barJWT)
   690  
   691  	acc, _ = s.LookupAccount(barPub)
   692  	if acc == nil {
   693  		t.Fatalf("Expected to retrieve the account")
   694  	}
   695  	if les := len(acc.imports.streams); les != 1 {
   696  		t.Fatalf("Expected imports streams len of 1, got %d", les)
   697  	}
   698  	// Our service import should have failed without a token.
   699  	if les := len(acc.imports.services); les != 0 {
   700  		t.Fatalf("Expected imports services len of 0, got %d", les)
   701  	}
   702  
   703  	// Now add in a bad activation token.
   704  	barAC = jwt.NewAccountClaims(barPub)
   705  	serviceImport = &jwt.Import{Account: fooPub, Subject: "req.echo", Token: "not a token", Type: jwt.Service}
   706  	barAC.Imports.Add(serviceImport)
   707  	barJWT, err = barAC.Encode(okp)
   708  	if err != nil {
   709  		t.Fatalf("Error generating account JWT: %v", err)
   710  	}
   711  	addAccountToMemResolver(s, barPub, barJWT)
   712  
   713  	s.UpdateAccountClaims(acc, barAC)
   714  
   715  	// Our service import should have failed with a bad token.
   716  	if les := len(acc.imports.services); les != 0 {
   717  		t.Fatalf("Expected imports services len of 0, got %d", les)
   718  	}
   719  
   720  	// Now make a correct one.
   721  	barAC = jwt.NewAccountClaims(barPub)
   722  	serviceImport = &jwt.Import{Account: fooPub, Subject: "req.echo", Type: jwt.Service}
   723  
   724  	activation := jwt.NewActivationClaims(barPub)
   725  	activation.ImportSubject = "req.echo"
   726  	activation.ImportType = jwt.Service
   727  	actJWT, err := activation.Encode(fooKP)
   728  	if err != nil {
   729  		t.Fatalf("Error generating activation token: %v", err)
   730  	}
   731  	serviceImport.Token = actJWT
   732  	barAC.Imports.Add(serviceImport)
   733  	barJWT, err = barAC.Encode(okp)
   734  	if err != nil {
   735  		t.Fatalf("Error generating account JWT: %v", err)
   736  	}
   737  
   738  	vr := jwt.ValidationResults{}
   739  	barAC.Validate(&vr)
   740  	if vr.IsBlocking(true) {
   741  		t.Fatalf("Error generating account JWT: %v", vr)
   742  	}
   743  
   744  	addAccountToMemResolver(s, barPub, barJWT)
   745  	s.UpdateAccountClaims(acc, barAC)
   746  	// Our service import should have succeeded.
   747  	if les := len(acc.imports.services); les != 1 {
   748  		t.Fatalf("Expected imports services len of 1, got %d", les)
   749  	}
   750  
   751  	// Now streams
   752  	barAC = jwt.NewAccountClaims(barPub)
   753  	streamImport = &jwt.Import{Account: fooPub, Subject: "private", To: "import.private", Type: jwt.Stream}
   754  
   755  	barAC.Imports.Add(streamImport)
   756  	barJWT, err = barAC.Encode(okp)
   757  	if err != nil {
   758  		t.Fatalf("Error generating account JWT: %v", err)
   759  	}
   760  	addAccountToMemResolver(s, barPub, barJWT)
   761  	s.UpdateAccountClaims(acc, barAC)
   762  	// Our stream import should have not succeeded.
   763  	if les := len(acc.imports.streams); les != 0 {
   764  		t.Fatalf("Expected imports services len of 0, got %d", les)
   765  	}
   766  
   767  	// Now add in activation.
   768  	barAC = jwt.NewAccountClaims(barPub)
   769  	streamImport = &jwt.Import{Account: fooPub, Subject: "private", To: "import.private", Type: jwt.Stream}
   770  
   771  	activation = jwt.NewActivationClaims(barPub)
   772  	activation.ImportSubject = "private"
   773  	activation.ImportType = jwt.Stream
   774  	actJWT, err = activation.Encode(fooKP)
   775  	if err != nil {
   776  		t.Fatalf("Error generating activation token: %v", err)
   777  	}
   778  	streamImport.Token = actJWT
   779  	barAC.Imports.Add(streamImport)
   780  	barJWT, err = barAC.Encode(okp)
   781  	if err != nil {
   782  		t.Fatalf("Error generating account JWT: %v", err)
   783  	}
   784  	addAccountToMemResolver(s, barPub, barJWT)
   785  	s.UpdateAccountClaims(acc, barAC)
   786  	// Our stream import should have not succeeded.
   787  	if les := len(acc.imports.streams); les != 1 {
   788  		t.Fatalf("Expected imports services len of 1, got %d", les)
   789  	}
   790  }
   791  
   792  func TestJWTAccountExportWithResponseType(t *testing.T) {
   793  	s := opTrustBasicSetup()
   794  	defer s.Shutdown()
   795  	buildMemAccResolver(s)
   796  
   797  	okp, _ := nkeys.FromSeed(oSeed)
   798  
   799  	// Create accounts and imports/exports.
   800  	fooKP, _ := nkeys.CreateAccount()
   801  	fooPub, _ := fooKP.PublicKey()
   802  	fooAC := jwt.NewAccountClaims(fooPub)
   803  
   804  	// Now create Exports.
   805  	serviceStreamExport := &jwt.Export{Subject: "test.stream", Type: jwt.Service, ResponseType: jwt.ResponseTypeStream, TokenReq: false}
   806  	serviceChunkExport := &jwt.Export{Subject: "test.chunk", Type: jwt.Service, ResponseType: jwt.ResponseTypeChunked, TokenReq: false}
   807  	serviceSingletonExport := &jwt.Export{Subject: "test.single", Type: jwt.Service, ResponseType: jwt.ResponseTypeSingleton, TokenReq: true}
   808  	serviceDefExport := &jwt.Export{Subject: "test.def", Type: jwt.Service, TokenReq: true}
   809  	serviceOldExport := &jwt.Export{Subject: "test.old", Type: jwt.Service, TokenReq: false}
   810  
   811  	fooAC.Exports.Add(serviceStreamExport, serviceSingletonExport, serviceChunkExport, serviceDefExport, serviceOldExport)
   812  	fooJWT, err := fooAC.Encode(okp)
   813  	if err != nil {
   814  		t.Fatalf("Error generating account JWT: %v", err)
   815  	}
   816  
   817  	addAccountToMemResolver(s, fooPub, fooJWT)
   818  
   819  	fooAcc, _ := s.LookupAccount(fooPub)
   820  	if fooAcc == nil {
   821  		t.Fatalf("Expected to retrieve the account")
   822  	}
   823  
   824  	services := fooAcc.exports.services
   825  
   826  	if len(services) != 5 {
   827  		t.Fatalf("Expected 4 services")
   828  	}
   829  
   830  	se, ok := services["test.stream"]
   831  	if !ok || se == nil {
   832  		t.Fatalf("Expected to map a service export")
   833  	}
   834  	if se.tokenReq {
   835  		t.Fatalf("Expected the service export to not require tokens")
   836  	}
   837  	if se.respType != Streamed {
   838  		t.Fatalf("Expected the service export to respond with a stream")
   839  	}
   840  
   841  	se, ok = services["test.chunk"]
   842  	if !ok || se == nil {
   843  		t.Fatalf("Expected to map a service export")
   844  	}
   845  	if se.tokenReq {
   846  		t.Fatalf("Expected the service export to not require tokens")
   847  	}
   848  	if se.respType != Chunked {
   849  		t.Fatalf("Expected the service export to respond with a stream")
   850  	}
   851  
   852  	se, ok = services["test.def"]
   853  	if !ok || se == nil {
   854  		t.Fatalf("Expected to map a service export")
   855  	}
   856  	if !se.tokenReq {
   857  		t.Fatalf("Expected the service export to not require tokens")
   858  	}
   859  	if se.respType != Singleton {
   860  		t.Fatalf("Expected the service export to respond with a stream")
   861  	}
   862  
   863  	se, ok = services["test.single"]
   864  	if !ok || se == nil {
   865  		t.Fatalf("Expected to map a service export")
   866  	}
   867  	if !se.tokenReq {
   868  		t.Fatalf("Expected the service export to not require tokens")
   869  	}
   870  	if se.respType != Singleton {
   871  		t.Fatalf("Expected the service export to respond with a stream")
   872  	}
   873  
   874  	se, ok = services["test.old"]
   875  	if !ok || se == nil || len(se.approved) > 0 {
   876  		t.Fatalf("Service with a singleton response and no tokens should not be nil and have no approvals")
   877  	}
   878  }
   879  
   880  func expectPong(t *testing.T, cr *bufio.Reader) {
   881  	t.Helper()
   882  	l, _ := cr.ReadString('\n')
   883  	if !strings.HasPrefix(l, "PONG") {
   884  		t.Fatalf("Expected a PONG, got %q", l)
   885  	}
   886  }
   887  
   888  func expectMsg(t *testing.T, cr *bufio.Reader, sub, payload string) {
   889  	t.Helper()
   890  	l, _ := cr.ReadString('\n')
   891  	expected := "MSG " + sub
   892  	if !strings.HasPrefix(l, expected) {
   893  		t.Fatalf("Expected %q, got %q", expected, l)
   894  	}
   895  	l, _ = cr.ReadString('\n')
   896  	if l != payload+"\r\n" {
   897  		t.Fatalf("Expected %q, got %q", payload, l)
   898  	}
   899  	expectPong(t, cr)
   900  }
   901  
   902  func TestJWTAccountImportExportUpdates(t *testing.T) {
   903  	s := opTrustBasicSetup()
   904  	defer s.Shutdown()
   905  	buildMemAccResolver(s)
   906  
   907  	okp, _ := nkeys.FromSeed(oSeed)
   908  
   909  	// Create accounts and imports/exports.
   910  	fooKP, _ := nkeys.CreateAccount()
   911  	fooPub, _ := fooKP.PublicKey()
   912  	fooAC := jwt.NewAccountClaims(fooPub)
   913  	streamExport := &jwt.Export{Subject: "foo", Type: jwt.Stream}
   914  
   915  	fooAC.Exports.Add(streamExport)
   916  	fooJWT, err := fooAC.Encode(okp)
   917  	if err != nil {
   918  		t.Fatalf("Error generating account JWT: %v", err)
   919  	}
   920  	addAccountToMemResolver(s, fooPub, fooJWT)
   921  
   922  	barKP, _ := nkeys.CreateAccount()
   923  	barPub, _ := barKP.PublicKey()
   924  	barAC := jwt.NewAccountClaims(barPub)
   925  	streamImport := &jwt.Import{Account: fooPub, Subject: "foo", To: "import", Type: jwt.Stream}
   926  
   927  	barAC.Imports.Add(streamImport)
   928  	barJWT, err := barAC.Encode(okp)
   929  	if err != nil {
   930  		t.Fatalf("Error generating account JWT: %v", err)
   931  	}
   932  	addAccountToMemResolver(s, barPub, barJWT)
   933  
   934  	// Create a client.
   935  	c, cr, cs := createClient(t, s, barKP)
   936  	defer c.close()
   937  
   938  	c.parseAsync(cs)
   939  	expectPong(t, cr)
   940  
   941  	c.parseAsync("SUB import.foo 1\r\nPING\r\n")
   942  	expectPong(t, cr)
   943  
   944  	checkShadow := func(expected int) {
   945  		t.Helper()
   946  		c.mu.Lock()
   947  		defer c.mu.Unlock()
   948  		sub := c.subs["1"]
   949  		if ls := len(sub.shadow); ls != expected {
   950  			t.Fatalf("Expected shadows to be %d, got %d", expected, ls)
   951  		}
   952  	}
   953  
   954  	// We created a SUB on foo which should create a shadow subscription.
   955  	checkShadow(1)
   956  
   957  	// Now update bar and remove the import which should make the shadow go away.
   958  	barAC = jwt.NewAccountClaims(barPub)
   959  	barJWT, _ = barAC.Encode(okp)
   960  	addAccountToMemResolver(s, barPub, barJWT)
   961  	acc, _ := s.LookupAccount(barPub)
   962  	s.UpdateAccountClaims(acc, barAC)
   963  
   964  	checkShadow(0)
   965  
   966  	// Now add it back and make sure the shadow comes back.
   967  	streamImport = &jwt.Import{Account: string(fooPub), Subject: "foo", To: "import", Type: jwt.Stream}
   968  	barAC.Imports.Add(streamImport)
   969  	barJWT, _ = barAC.Encode(okp)
   970  	addAccountToMemResolver(s, barPub, barJWT)
   971  	s.UpdateAccountClaims(acc, barAC)
   972  
   973  	checkShadow(1)
   974  
   975  	// Now change export and make sure it goes away as well. So no exports anymore.
   976  	fooAC = jwt.NewAccountClaims(fooPub)
   977  	fooJWT, _ = fooAC.Encode(okp)
   978  	addAccountToMemResolver(s, fooPub, fooJWT)
   979  	acc, _ = s.LookupAccount(fooPub)
   980  	s.UpdateAccountClaims(acc, fooAC)
   981  	checkShadow(0)
   982  
   983  	// Now add it in but with permission required.
   984  	streamExport = &jwt.Export{Subject: "foo", Type: jwt.Stream, TokenReq: true}
   985  	fooAC.Exports.Add(streamExport)
   986  	fooJWT, _ = fooAC.Encode(okp)
   987  	addAccountToMemResolver(s, fooPub, fooJWT)
   988  	s.UpdateAccountClaims(acc, fooAC)
   989  
   990  	checkShadow(0)
   991  
   992  	// Now put it back as normal.
   993  	fooAC = jwt.NewAccountClaims(fooPub)
   994  	streamExport = &jwt.Export{Subject: "foo", Type: jwt.Stream}
   995  	fooAC.Exports.Add(streamExport)
   996  	fooJWT, _ = fooAC.Encode(okp)
   997  	addAccountToMemResolver(s, fooPub, fooJWT)
   998  	s.UpdateAccountClaims(acc, fooAC)
   999  
  1000  	checkShadow(1)
  1001  }
  1002  
  1003  func TestJWTAccountImportActivationExpires(t *testing.T) {
  1004  	s := opTrustBasicSetup()
  1005  	defer s.Shutdown()
  1006  	buildMemAccResolver(s)
  1007  
  1008  	okp, _ := nkeys.FromSeed(oSeed)
  1009  
  1010  	// Create accounts and imports/exports.
  1011  	fooKP, _ := nkeys.CreateAccount()
  1012  	fooPub, _ := fooKP.PublicKey()
  1013  	fooAC := jwt.NewAccountClaims(fooPub)
  1014  	streamExport := &jwt.Export{Subject: "foo", Type: jwt.Stream, TokenReq: true}
  1015  	fooAC.Exports.Add(streamExport)
  1016  
  1017  	fooJWT, err := fooAC.Encode(okp)
  1018  	if err != nil {
  1019  		t.Fatalf("Error generating account JWT: %v", err)
  1020  	}
  1021  
  1022  	addAccountToMemResolver(s, fooPub, fooJWT)
  1023  	acc, _ := s.LookupAccount(fooPub)
  1024  	if acc == nil {
  1025  		t.Fatalf("Expected to retrieve the account")
  1026  	}
  1027  
  1028  	barKP, _ := nkeys.CreateAccount()
  1029  	barPub, _ := barKP.PublicKey()
  1030  	barAC := jwt.NewAccountClaims(barPub)
  1031  	streamImport := &jwt.Import{Account: fooPub, Subject: "foo", To: "import.", Type: jwt.Stream}
  1032  
  1033  	activation := jwt.NewActivationClaims(barPub)
  1034  	activation.ImportSubject = "foo"
  1035  	activation.ImportType = jwt.Stream
  1036  	now := time.Now()
  1037  	activation.IssuedAt = now.Add(-10 * time.Second).Unix()
  1038  	// These are second resolution. So round up before adding a second.
  1039  	activation.Expires = now.Round(time.Second).Add(time.Second).Unix()
  1040  	actJWT, err := activation.Encode(fooKP)
  1041  	if err != nil {
  1042  		t.Fatalf("Error generating activation token: %v", err)
  1043  	}
  1044  	streamImport.Token = actJWT
  1045  	barAC.Imports.Add(streamImport)
  1046  	barJWT, err := barAC.Encode(okp)
  1047  	if err != nil {
  1048  		t.Fatalf("Error generating account JWT: %v", err)
  1049  	}
  1050  	addAccountToMemResolver(s, barPub, barJWT)
  1051  	if acc, _ := s.LookupAccount(barPub); acc == nil {
  1052  		t.Fatalf("Expected to retrieve the account")
  1053  	}
  1054  
  1055  	// Create a client.
  1056  	c, cr, cs := createClient(t, s, barKP)
  1057  	defer c.close()
  1058  
  1059  	c.parseAsync(cs)
  1060  	expectPong(t, cr)
  1061  
  1062  	c.parseAsync("SUB import.foo 1\r\nPING\r\n")
  1063  	expectPong(t, cr)
  1064  
  1065  	checkShadow := func(t *testing.T, expected int) {
  1066  		t.Helper()
  1067  		checkFor(t, 3*time.Second, 15*time.Millisecond, func() error {
  1068  			c.mu.Lock()
  1069  			defer c.mu.Unlock()
  1070  			sub := c.subs["1"]
  1071  			if ls := len(sub.shadow); ls != expected {
  1072  				return fmt.Errorf("Expected shadows to be %d, got %d", expected, ls)
  1073  			}
  1074  			return nil
  1075  		})
  1076  	}
  1077  
  1078  	// We created a SUB on foo which should create a shadow subscription.
  1079  	checkShadow(t, 1)
  1080  
  1081  	time.Sleep(1250 * time.Millisecond)
  1082  
  1083  	// Should have expired and been removed.
  1084  	checkShadow(t, 0)
  1085  }
  1086  
  1087  func TestJWTAccountLimitsSubs(t *testing.T) {
  1088  	fooAC := newJWTTestAccountClaims()
  1089  	fooAC.Limits.Subs = 10
  1090  	s, fooKP, c, _ := setupJWTTestWitAccountClaims(t, fooAC, "+OK")
  1091  	defer s.Shutdown()
  1092  	defer c.close()
  1093  
  1094  	okp, _ := nkeys.FromSeed(oSeed)
  1095  	fooPub, _ := fooKP.PublicKey()
  1096  
  1097  	// Create a client.
  1098  	c, cr, cs := createClient(t, s, fooKP)
  1099  	defer c.close()
  1100  
  1101  	c.parseAsync(cs)
  1102  	expectPong(t, cr)
  1103  
  1104  	// Check to make sure we have the limit set.
  1105  	// Account first
  1106  	fooAcc, _ := s.LookupAccount(fooPub)
  1107  	fooAcc.mu.RLock()
  1108  	if fooAcc.msubs != 10 {
  1109  		fooAcc.mu.RUnlock()
  1110  		t.Fatalf("Expected account to have msubs of 10, got %d", fooAcc.msubs)
  1111  	}
  1112  	fooAcc.mu.RUnlock()
  1113  	// Now test that the client has limits too.
  1114  	c.mu.Lock()
  1115  	if c.msubs != 10 {
  1116  		c.mu.Unlock()
  1117  		t.Fatalf("Expected client msubs to be 10, got %d", c.msubs)
  1118  	}
  1119  	c.mu.Unlock()
  1120  
  1121  	// Now make sure its enforced.
  1122  	/// These should all work ok.
  1123  	for i := 0; i < 10; i++ {
  1124  		c.parseAsync(fmt.Sprintf("SUB foo %d\r\nPING\r\n", i))
  1125  		expectPong(t, cr)
  1126  	}
  1127  
  1128  	// This one should fail.
  1129  	c.parseAsync("SUB foo 22\r\n")
  1130  	l, _ := cr.ReadString('\n')
  1131  	if !strings.HasPrefix(l, "-ERR") {
  1132  		t.Fatalf("Expected an ERR, got: %v", l)
  1133  	}
  1134  	if !strings.Contains(l, "maximum subscriptions exceeded") {
  1135  		t.Fatalf("Expected an ERR for max subscriptions exceeded, got: %v", l)
  1136  	}
  1137  
  1138  	// Now update the claims and expect if max is lower to be disconnected.
  1139  	fooAC.Limits.Subs = 5
  1140  	fooJWT, err := fooAC.Encode(okp)
  1141  	if err != nil {
  1142  		t.Fatalf("Error generating account JWT: %v", err)
  1143  	}
  1144  	addAccountToMemResolver(s, fooPub, fooJWT)
  1145  	s.UpdateAccountClaims(fooAcc, fooAC)
  1146  	l, _ = cr.ReadString('\n')
  1147  	if !strings.HasPrefix(l, "-ERR") {
  1148  		t.Fatalf("Expected an ERR, got: %v", l)
  1149  	}
  1150  	if !strings.Contains(l, "maximum subscriptions exceeded") {
  1151  		t.Fatalf("Expected an ERR for max subscriptions exceeded, got: %v", l)
  1152  	}
  1153  }
  1154  
  1155  func TestJWTAccountLimitsSubsButServerOverrides(t *testing.T) {
  1156  	s := opTrustBasicSetup()
  1157  	defer s.Shutdown()
  1158  	buildMemAccResolver(s)
  1159  
  1160  	// override with server setting of 2.
  1161  	opts := s.getOpts()
  1162  	opts.MaxSubs = 2
  1163  
  1164  	okp, _ := nkeys.FromSeed(oSeed)
  1165  
  1166  	// Create accounts and imports/exports.
  1167  	fooKP, _ := nkeys.CreateAccount()
  1168  	fooPub, _ := fooKP.PublicKey()
  1169  	fooAC := jwt.NewAccountClaims(fooPub)
  1170  	fooAC.Limits.Subs = 10
  1171  	fooJWT, err := fooAC.Encode(okp)
  1172  	if err != nil {
  1173  		t.Fatalf("Error generating account JWT: %v", err)
  1174  	}
  1175  	addAccountToMemResolver(s, fooPub, fooJWT)
  1176  	fooAcc, _ := s.LookupAccount(fooPub)
  1177  	fooAcc.mu.RLock()
  1178  	if fooAcc.msubs != 10 {
  1179  		fooAcc.mu.RUnlock()
  1180  		t.Fatalf("Expected account to have msubs of 10, got %d", fooAcc.msubs)
  1181  	}
  1182  	fooAcc.mu.RUnlock()
  1183  
  1184  	// Create a client.
  1185  	c, cr, cs := createClient(t, s, fooKP)
  1186  	defer c.close()
  1187  
  1188  	c.parseAsync(cs)
  1189  	expectPong(t, cr)
  1190  
  1191  	c.parseAsync("SUB foo 1\r\nSUB bar 2\r\nSUB baz 3\r\nPING\r\n")
  1192  	l, _ := cr.ReadString('\n')
  1193  
  1194  	if !strings.HasPrefix(l, "-ERR ") {
  1195  		t.Fatalf("Expected an error")
  1196  	}
  1197  	if !strings.Contains(l, "maximum subscriptions exceeded") {
  1198  		t.Fatalf("Expected an ERR for max subscriptions exceeded, got: %v", l)
  1199  	}
  1200  	// Read last PONG so does not hold up test.
  1201  	cr.ReadString('\n')
  1202  }
  1203  
  1204  func TestJWTAccountLimitsMaxPayload(t *testing.T) {
  1205  	fooAC := newJWTTestAccountClaims()
  1206  	fooAC.Limits.Payload = 8
  1207  	s, fooKP, c, _ := setupJWTTestWitAccountClaims(t, fooAC, "+OK")
  1208  	defer s.Shutdown()
  1209  	defer c.close()
  1210  
  1211  	fooPub, _ := fooKP.PublicKey()
  1212  
  1213  	// Create a client.
  1214  	c, cr, cs := createClient(t, s, fooKP)
  1215  	defer c.close()
  1216  
  1217  	c.parseAsync(cs)
  1218  	expectPong(t, cr)
  1219  
  1220  	// Check to make sure we have the limit set.
  1221  	// Account first
  1222  	fooAcc, _ := s.LookupAccount(fooPub)
  1223  	fooAcc.mu.RLock()
  1224  	if fooAcc.mpay != 8 {
  1225  		fooAcc.mu.RUnlock()
  1226  		t.Fatalf("Expected account to have mpay of 8, got %d", fooAcc.mpay)
  1227  	}
  1228  	fooAcc.mu.RUnlock()
  1229  	// Now test that the client has limits too.
  1230  	c.mu.Lock()
  1231  	if c.mpay != 8 {
  1232  		c.mu.Unlock()
  1233  		t.Fatalf("Expected client to have mpay of 10, got %d", c.mpay)
  1234  	}
  1235  	c.mu.Unlock()
  1236  
  1237  	c.parseAsync("PUB foo 4\r\nXXXX\r\nPING\r\n")
  1238  	expectPong(t, cr)
  1239  
  1240  	c.parseAsync("PUB foo 10\r\nXXXXXXXXXX\r\nPING\r\n")
  1241  	l, _ := cr.ReadString('\n')
  1242  	if !strings.HasPrefix(l, "-ERR ") {
  1243  		t.Fatalf("Expected an error")
  1244  	}
  1245  	if !strings.Contains(l, "Maximum Payload") {
  1246  		t.Fatalf("Expected an ERR for max payload violation, got: %v", l)
  1247  	}
  1248  }
  1249  
  1250  func TestJWTAccountLimitsMaxPayloadButServerOverrides(t *testing.T) {
  1251  	s := opTrustBasicSetup()
  1252  	defer s.Shutdown()
  1253  	buildMemAccResolver(s)
  1254  
  1255  	// override with server setting of 4.
  1256  	opts := s.getOpts()
  1257  	opts.MaxPayload = 4
  1258  
  1259  	okp, _ := nkeys.FromSeed(oSeed)
  1260  
  1261  	// Create accounts and imports/exports.
  1262  	fooKP, _ := nkeys.CreateAccount()
  1263  	fooPub, _ := fooKP.PublicKey()
  1264  	fooAC := jwt.NewAccountClaims(fooPub)
  1265  	fooAC.Limits.Payload = 8
  1266  	fooJWT, err := fooAC.Encode(okp)
  1267  	if err != nil {
  1268  		t.Fatalf("Error generating account JWT: %v", err)
  1269  	}
  1270  	addAccountToMemResolver(s, fooPub, fooJWT)
  1271  
  1272  	// Create a client.
  1273  	c, cr, cs := createClient(t, s, fooKP)
  1274  	defer c.close()
  1275  
  1276  	c.parseAsync(cs)
  1277  	expectPong(t, cr)
  1278  
  1279  	c.parseAsync("PUB foo 6\r\nXXXXXX\r\nPING\r\n")
  1280  	l, _ := cr.ReadString('\n')
  1281  	if !strings.HasPrefix(l, "-ERR ") {
  1282  		t.Fatalf("Expected an error")
  1283  	}
  1284  	if !strings.Contains(l, "Maximum Payload") {
  1285  		t.Fatalf("Expected an ERR for max payload violation, got: %v", l)
  1286  	}
  1287  }
  1288  
  1289  func TestJWTAccountLimitsMaxConns(t *testing.T) {
  1290  	fooAC := newJWTTestAccountClaims()
  1291  	fooAC.Limits.Conn = 8
  1292  	s, fooKP, c, _ := setupJWTTestWitAccountClaims(t, fooAC, "+OK")
  1293  	defer s.Shutdown()
  1294  	defer c.close()
  1295  
  1296  	newClient := func(expPre string) *testAsyncClient {
  1297  		t.Helper()
  1298  		// Create a client.
  1299  		c, cr, cs := createClient(t, s, fooKP)
  1300  		c.parseAsync(cs)
  1301  		l, _ := cr.ReadString('\n')
  1302  		if !strings.HasPrefix(l, expPre) {
  1303  			t.Fatalf("Expected a response starting with %q, got %q", expPre, l)
  1304  		}
  1305  		return c
  1306  	}
  1307  
  1308  	// A connection is created in setupJWTTestWitAccountClaims(), so limit
  1309  	// to 7 here (8 total).
  1310  	for i := 0; i < 7; i++ {
  1311  		c := newClient("PONG")
  1312  		defer c.close()
  1313  	}
  1314  	// Now this one should fail.
  1315  	c = newClient("-ERR ")
  1316  	c.close()
  1317  }
  1318  
  1319  // This will test that we can switch from a public export to a private
  1320  // one and back with export claims to make sure the claim update mechanism
  1321  // is working properly.
  1322  func TestJWTAccountServiceImportAuthSwitch(t *testing.T) {
  1323  	s := opTrustBasicSetup()
  1324  	defer s.Shutdown()
  1325  	buildMemAccResolver(s)
  1326  
  1327  	okp, _ := nkeys.FromSeed(oSeed)
  1328  
  1329  	// Create accounts and imports/exports.
  1330  	fooKP, _ := nkeys.CreateAccount()
  1331  	fooPub, _ := fooKP.PublicKey()
  1332  	fooAC := jwt.NewAccountClaims(fooPub)
  1333  	serviceExport := &jwt.Export{Subject: "ngs.usage.*", Type: jwt.Service}
  1334  	fooAC.Exports.Add(serviceExport)
  1335  	fooJWT, err := fooAC.Encode(okp)
  1336  	if err != nil {
  1337  		t.Fatalf("Error generating account JWT: %v", err)
  1338  	}
  1339  	addAccountToMemResolver(s, fooPub, fooJWT)
  1340  
  1341  	barKP, _ := nkeys.CreateAccount()
  1342  	barPub, _ := barKP.PublicKey()
  1343  	barAC := jwt.NewAccountClaims(barPub)
  1344  	serviceImport := &jwt.Import{Account: fooPub, Subject: "ngs.usage", To: "ngs.usage.DEREK", Type: jwt.Service}
  1345  	barAC.Imports.Add(serviceImport)
  1346  	barJWT, err := barAC.Encode(okp)
  1347  	if err != nil {
  1348  		t.Fatalf("Error generating account JWT: %v", err)
  1349  	}
  1350  	addAccountToMemResolver(s, barPub, barJWT)
  1351  
  1352  	// Create a client that will send the request
  1353  	ca, cra, csa := createClient(t, s, barKP)
  1354  	defer ca.close()
  1355  	ca.parseAsync(csa)
  1356  	expectPong(t, cra)
  1357  
  1358  	// Create the client that will respond to the requests.
  1359  	cb, crb, csb := createClient(t, s, fooKP)
  1360  	defer cb.close()
  1361  	cb.parseAsync(csb)
  1362  	expectPong(t, crb)
  1363  
  1364  	// Create Subscriber.
  1365  	cb.parseAsync("SUB ngs.usage.* 1\r\nPING\r\n")
  1366  	expectPong(t, crb)
  1367  
  1368  	// Send Request
  1369  	ca.parseAsync("PUB ngs.usage 2\r\nhi\r\nPING\r\n")
  1370  	expectPong(t, cra)
  1371  
  1372  	// We should receive the request mapped into our account. PING needed to flush.
  1373  	cb.parseAsync("PING\r\n")
  1374  	expectMsg(t, crb, "ngs.usage.DEREK", "hi")
  1375  
  1376  	// Now update to make the export private.
  1377  	fooACPrivate := jwt.NewAccountClaims(fooPub)
  1378  	serviceExport = &jwt.Export{Subject: "ngs.usage.*", Type: jwt.Service, TokenReq: true}
  1379  	fooACPrivate.Exports.Add(serviceExport)
  1380  	fooJWTPrivate, err := fooACPrivate.Encode(okp)
  1381  	if err != nil {
  1382  		t.Fatalf("Error generating account JWT: %v", err)
  1383  	}
  1384  	addAccountToMemResolver(s, fooPub, fooJWTPrivate)
  1385  	acc, _ := s.LookupAccount(fooPub)
  1386  	s.UpdateAccountClaims(acc, fooACPrivate)
  1387  
  1388  	// Send Another Request
  1389  	ca.parseAsync("PUB ngs.usage 2\r\nhi\r\nPING\r\n")
  1390  	expectPong(t, cra)
  1391  
  1392  	// We should not receive the request this time.
  1393  	cb.parseAsync("PING\r\n")
  1394  	expectPong(t, crb)
  1395  
  1396  	// Now put it back again to public and make sure it works again.
  1397  	addAccountToMemResolver(s, fooPub, fooJWT)
  1398  	s.UpdateAccountClaims(acc, fooAC)
  1399  
  1400  	// Send Request
  1401  	ca.parseAsync("PUB ngs.usage 2\r\nhi\r\nPING\r\n")
  1402  	expectPong(t, cra)
  1403  
  1404  	// We should receive the request mapped into our account. PING needed to flush.
  1405  	cb.parseAsync("PING\r\n")
  1406  	expectMsg(t, crb, "ngs.usage.DEREK", "hi")
  1407  }
  1408  
  1409  func TestJWTAccountServiceImportExpires(t *testing.T) {
  1410  	s := opTrustBasicSetup()
  1411  	defer s.Shutdown()
  1412  	buildMemAccResolver(s)
  1413  
  1414  	okp, _ := nkeys.FromSeed(oSeed)
  1415  
  1416  	// Create accounts and imports/exports.
  1417  	fooKP, _ := nkeys.CreateAccount()
  1418  	fooPub, _ := fooKP.PublicKey()
  1419  	fooAC := jwt.NewAccountClaims(fooPub)
  1420  	serviceExport := &jwt.Export{Subject: "foo", Type: jwt.Service}
  1421  
  1422  	fooAC.Exports.Add(serviceExport)
  1423  	fooJWT, err := fooAC.Encode(okp)
  1424  	if err != nil {
  1425  		t.Fatalf("Error generating account JWT: %v", err)
  1426  	}
  1427  	addAccountToMemResolver(s, fooPub, fooJWT)
  1428  
  1429  	barKP, _ := nkeys.CreateAccount()
  1430  	barPub, _ := barKP.PublicKey()
  1431  	barAC := jwt.NewAccountClaims(barPub)
  1432  	serviceImport := &jwt.Import{Account: fooPub, Subject: "foo", Type: jwt.Service}
  1433  
  1434  	barAC.Imports.Add(serviceImport)
  1435  	barJWT, err := barAC.Encode(okp)
  1436  	if err != nil {
  1437  		t.Fatalf("Error generating account JWT: %v", err)
  1438  	}
  1439  	addAccountToMemResolver(s, barPub, barJWT)
  1440  
  1441  	// Create a client that will send the request
  1442  	ca, cra, csa := createClient(t, s, barKP)
  1443  	defer ca.close()
  1444  	ca.parseAsync(csa)
  1445  	expectPong(t, cra)
  1446  
  1447  	// Create the client that will respond to the requests.
  1448  	cb, crb, csb := createClient(t, s, fooKP)
  1449  	defer cb.close()
  1450  	cb.parseAsync(csb)
  1451  	expectPong(t, crb)
  1452  
  1453  	// Create Subscriber.
  1454  	cb.parseAsync("SUB foo 1\r\nPING\r\n")
  1455  	expectPong(t, crb)
  1456  
  1457  	// Send Request
  1458  	ca.parseAsync("PUB foo 2\r\nhi\r\nPING\r\n")
  1459  	expectPong(t, cra)
  1460  
  1461  	// We should receive the request. PING needed to flush.
  1462  	cb.parseAsync("PING\r\n")
  1463  	expectMsg(t, crb, "foo", "hi")
  1464  
  1465  	// Now update the exported service to require auth.
  1466  	fooAC = jwt.NewAccountClaims(fooPub)
  1467  	serviceExport = &jwt.Export{Subject: "foo", Type: jwt.Service, TokenReq: true}
  1468  
  1469  	fooAC.Exports.Add(serviceExport)
  1470  	fooJWT, err = fooAC.Encode(okp)
  1471  	if err != nil {
  1472  		t.Fatalf("Error generating account JWT: %v", err)
  1473  	}
  1474  	addAccountToMemResolver(s, fooPub, fooJWT)
  1475  	acc, _ := s.LookupAccount(fooPub)
  1476  	s.UpdateAccountClaims(acc, fooAC)
  1477  
  1478  	// Send Another Request
  1479  	ca.parseAsync("PUB foo 2\r\nhi\r\nPING\r\n")
  1480  	expectPong(t, cra)
  1481  
  1482  	// We should not receive the request this time.
  1483  	cb.parseAsync("PING\r\n")
  1484  	expectPong(t, crb)
  1485  
  1486  	// Now get an activation token such that it will work, but will expire.
  1487  	barAC = jwt.NewAccountClaims(barPub)
  1488  	serviceImport = &jwt.Import{Account: fooPub, Subject: "foo", Type: jwt.Service}
  1489  
  1490  	now := time.Now()
  1491  	activation := jwt.NewActivationClaims(barPub)
  1492  	activation.ImportSubject = "foo"
  1493  	activation.ImportType = jwt.Service
  1494  	activation.IssuedAt = now.Add(-10 * time.Second).Unix()
  1495  	activation.Expires = now.Add(time.Second).Round(time.Second).Unix()
  1496  	actJWT, err := activation.Encode(fooKP)
  1497  	if err != nil {
  1498  		t.Fatalf("Error generating activation token: %v", err)
  1499  	}
  1500  	serviceImport.Token = actJWT
  1501  
  1502  	barAC.Imports.Add(serviceImport)
  1503  	barJWT, err = barAC.Encode(okp)
  1504  	if err != nil {
  1505  		t.Fatalf("Error generating account JWT: %v", err)
  1506  	}
  1507  	addAccountToMemResolver(s, barPub, barJWT)
  1508  	acc, _ = s.LookupAccount(barPub)
  1509  	s.UpdateAccountClaims(acc, barAC)
  1510  
  1511  	// Now it should work again.
  1512  	// Send Another Request
  1513  	ca.parseAsync("PUB foo 3\r\nhi2\r\nPING\r\n")
  1514  	expectPong(t, cra)
  1515  
  1516  	// We should receive the request. PING needed to flush.
  1517  	cb.parseAsync("PING\r\n")
  1518  	expectMsg(t, crb, "foo", "hi2")
  1519  
  1520  	// Now wait for it to expire, then retry.
  1521  	waitTime := time.Duration(activation.Expires-time.Now().Unix()) * time.Second
  1522  	time.Sleep(waitTime + 250*time.Millisecond)
  1523  
  1524  	// Send Another Request
  1525  	ca.parseAsync("PUB foo 3\r\nhi3\r\nPING\r\n")
  1526  	expectPong(t, cra)
  1527  
  1528  	// We should NOT receive the request. PING needed to flush.
  1529  	cb.parseAsync("PING\r\n")
  1530  	expectPong(t, crb)
  1531  }
  1532  
  1533  func TestJWTAccountURLResolver(t *testing.T) {
  1534  	for _, test := range []struct {
  1535  		name   string
  1536  		useTLS bool
  1537  	}{
  1538  		{"plain", false},
  1539  		{"tls", true},
  1540  	} {
  1541  		t.Run(test.name, func(t *testing.T) {
  1542  			kp, _ := nkeys.FromSeed(oSeed)
  1543  			akp, _ := nkeys.CreateAccount()
  1544  			apub, _ := akp.PublicKey()
  1545  			nac := jwt.NewAccountClaims(apub)
  1546  			ajwt, err := nac.Encode(kp)
  1547  			if err != nil {
  1548  				t.Fatalf("Error generating account JWT: %v", err)
  1549  			}
  1550  
  1551  			hf := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  1552  				w.Write([]byte(ajwt))
  1553  			})
  1554  			var ts *httptest.Server
  1555  			if test.useTLS {
  1556  				tc := &TLSConfigOpts{
  1557  					CertFile: "../test/configs/certs/server-cert.pem",
  1558  					KeyFile:  "../test/configs/certs/server-key.pem",
  1559  					CaFile:   "../test/configs/certs/ca.pem",
  1560  				}
  1561  				tlsConfig, err := GenTLSConfig(tc)
  1562  				if err != nil {
  1563  					t.Fatalf("Error generating tls config: %v", err)
  1564  				}
  1565  				ts = httptest.NewUnstartedServer(hf)
  1566  				ts.TLS = tlsConfig
  1567  				ts.StartTLS()
  1568  			} else {
  1569  				ts = httptest.NewServer(hf)
  1570  			}
  1571  			defer ts.Close()
  1572  
  1573  			confTemplate := `
  1574  				operator: %s
  1575  				listen: 127.0.0.1:-1
  1576  				resolver: URL("%s/ngs/v1/accounts/jwt/")
  1577  				resolver_tls {
  1578  					cert_file: "../test/configs/certs/client-cert.pem"
  1579  					key_file: "../test/configs/certs/client-key.pem"
  1580  					ca_file: "../test/configs/certs/ca.pem"
  1581  				}
  1582  			`
  1583  			conf := createConfFile(t, []byte(fmt.Sprintf(confTemplate, ojwt, ts.URL)))
  1584  
  1585  			s, opts := RunServerWithConfig(conf)
  1586  			pub, _ := kp.PublicKey()
  1587  			opts.TrustedKeys = []string{pub}
  1588  			defer s.Shutdown()
  1589  
  1590  			acc, _ := s.LookupAccount(apub)
  1591  			if acc == nil {
  1592  				t.Fatalf("Expected to receive an account")
  1593  			}
  1594  			if acc.Name != apub {
  1595  				t.Fatalf("Account name did not match claim key")
  1596  			}
  1597  		})
  1598  	}
  1599  }
  1600  
  1601  func TestJWTAccountURLResolverTimeout(t *testing.T) {
  1602  	kp, _ := nkeys.FromSeed(oSeed)
  1603  	akp, _ := nkeys.CreateAccount()
  1604  	apub, _ := akp.PublicKey()
  1605  	nac := jwt.NewAccountClaims(apub)
  1606  	ajwt, err := nac.Encode(kp)
  1607  	if err != nil {
  1608  		t.Fatalf("Error generating account JWT: %v", err)
  1609  	}
  1610  
  1611  	basePath := "/ngs/v1/accounts/jwt/"
  1612  
  1613  	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  1614  		if r.URL.Path == basePath {
  1615  			w.Write([]byte("ok"))
  1616  			return
  1617  		}
  1618  		// Purposely be slow on account lookup.
  1619  		time.Sleep(200 * time.Millisecond)
  1620  		w.Write([]byte(ajwt))
  1621  	}))
  1622  	defer ts.Close()
  1623  
  1624  	confTemplate := `
  1625  		listen: 127.0.0.1:-1
  1626  		resolver: URL("%s%s")
  1627      `
  1628  	conf := createConfFile(t, []byte(fmt.Sprintf(confTemplate, ts.URL, basePath)))
  1629  
  1630  	s, opts := RunServerWithConfig(conf)
  1631  	pub, _ := kp.PublicKey()
  1632  	opts.TrustedKeys = []string{pub}
  1633  	defer s.Shutdown()
  1634  
  1635  	// Lower default timeout to speed-up test
  1636  	s.AccountResolver().(*URLAccResolver).c.Timeout = 50 * time.Millisecond
  1637  
  1638  	acc, _ := s.LookupAccount(apub)
  1639  	if acc != nil {
  1640  		t.Fatalf("Expected to not receive an account due to timeout")
  1641  	}
  1642  }
  1643  
  1644  func TestJWTAccountURLResolverNoFetchOnReload(t *testing.T) {
  1645  	kp, _ := nkeys.FromSeed(oSeed)
  1646  	akp, _ := nkeys.CreateAccount()
  1647  	apub, _ := akp.PublicKey()
  1648  	nac := jwt.NewAccountClaims(apub)
  1649  	ajwt, err := nac.Encode(kp)
  1650  	if err != nil {
  1651  		t.Fatalf("Error generating account JWT: %v", err)
  1652  	}
  1653  
  1654  	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  1655  		w.Write([]byte(ajwt))
  1656  	}))
  1657  	defer ts.Close()
  1658  
  1659  	confTemplate := `
  1660  		operator: %s
  1661  		listen: 127.0.0.1:-1
  1662  		resolver: URL("%s/ngs/v1/accounts/jwt/")
  1663      `
  1664  	conf := createConfFile(t, []byte(fmt.Sprintf(confTemplate, ojwt, ts.URL)))
  1665  
  1666  	s, _ := RunServerWithConfig(conf)
  1667  	defer s.Shutdown()
  1668  
  1669  	acc, _ := s.LookupAccount(apub)
  1670  	if acc == nil {
  1671  		t.Fatalf("Expected to receive an account")
  1672  	}
  1673  
  1674  	// Reload would produce a DATA race during the DeepEqual check for the account resolver,
  1675  	// so close the current one and we will create a new one that keeps track of fetch calls.
  1676  	ts.Close()
  1677  
  1678  	fetch := int32(0)
  1679  	ts = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  1680  		atomic.AddInt32(&fetch, 1)
  1681  		w.Write([]byte(ajwt))
  1682  	}))
  1683  	defer ts.Close()
  1684  
  1685  	changeCurrentConfigContentWithNewContent(t, conf, []byte(fmt.Sprintf(confTemplate, ojwt, ts.URL)))
  1686  
  1687  	if err := s.Reload(); err != nil {
  1688  		t.Fatalf("Error on reload: %v", err)
  1689  	}
  1690  	if atomic.LoadInt32(&fetch) != 0 {
  1691  		t.Fatalf("Fetch invoked during reload")
  1692  	}
  1693  
  1694  	// Now stop the resolver and make sure that on startup, we report URL resolver failure
  1695  	s.Shutdown()
  1696  	s = nil
  1697  	ts.Close()
  1698  
  1699  	opts := LoadConfig(conf)
  1700  	if s, err := NewServer(opts); err == nil || !strings.Contains(err.Error(), "could not fetch") {
  1701  		if s != nil {
  1702  			s.Shutdown()
  1703  		}
  1704  		t.Fatalf("Expected error regarding account resolver, got %v", err)
  1705  	}
  1706  }
  1707  
  1708  func TestJWTAccountURLResolverFetchFailureInServer1(t *testing.T) {
  1709  	const subj = "test"
  1710  	const crossAccSubj = "test"
  1711  	// Create Exporting Account
  1712  	expkp, _ := nkeys.CreateAccount()
  1713  	exppub, _ := expkp.PublicKey()
  1714  	expac := jwt.NewAccountClaims(exppub)
  1715  	expac.Exports.Add(&jwt.Export{
  1716  		Subject: crossAccSubj,
  1717  		Type:    jwt.Stream,
  1718  	})
  1719  	expjwt, err := expac.Encode(oKp)
  1720  	if err != nil {
  1721  		t.Fatalf("Error generating account JWT: %v", err)
  1722  	}
  1723  	// Create importing Account
  1724  	impkp, _ := nkeys.CreateAccount()
  1725  	imppub, _ := impkp.PublicKey()
  1726  	impac := jwt.NewAccountClaims(imppub)
  1727  	impac.Imports.Add(&jwt.Import{
  1728  		Account: exppub,
  1729  		Subject: crossAccSubj,
  1730  		Type:    jwt.Stream,
  1731  	})
  1732  	impjwt, err := impac.Encode(oKp)
  1733  	if err != nil {
  1734  		t.Fatalf("Error generating account JWT: %v", err)
  1735  	}
  1736  	// Simulate an account server that drops the first request to exppub
  1737  	chanImpA := make(chan struct{}, 10)
  1738  	defer close(chanImpA)
  1739  	chanExpS := make(chan struct{}, 10)
  1740  	defer close(chanExpS)
  1741  	chanExpF := make(chan struct{}, 1)
  1742  	defer close(chanExpF)
  1743  	failureCnt := int32(0)
  1744  	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  1745  		if r.URL.Path == "/A/" {
  1746  			// Server startup
  1747  			w.Write(nil)
  1748  			chanImpA <- struct{}{}
  1749  		} else if r.URL.Path == "/A/"+imppub {
  1750  			w.Write([]byte(impjwt))
  1751  			chanImpA <- struct{}{}
  1752  		} else if r.URL.Path == "/A/"+exppub {
  1753  			if atomic.AddInt32(&failureCnt, 1) <= 1 {
  1754  				// skip the write to simulate the failure
  1755  				chanExpF <- struct{}{}
  1756  			} else {
  1757  				w.Write([]byte(expjwt))
  1758  				chanExpS <- struct{}{}
  1759  			}
  1760  		} else {
  1761  			t.Fatal("not expected")
  1762  		}
  1763  	}))
  1764  	defer ts.Close()
  1765  	// Create server
  1766  	confA := createConfFile(t, []byte(fmt.Sprintf(`
  1767  		listen: 127.0.0.1:-1
  1768  		operator: %s
  1769  		resolver: URL("%s/A/")
  1770      `, ojwt, ts.URL)))
  1771  	sA := RunServer(LoadConfig(confA))
  1772  	defer sA.Shutdown()
  1773  	// server observed one fetch on startup
  1774  	chanRecv(t, chanImpA, 10*time.Second)
  1775  	// Create first client
  1776  	ncA := natsConnect(t, sA.ClientURL(), createUserCreds(t, nil, impkp))
  1777  	defer ncA.Close()
  1778  	// create a test subscription
  1779  	subA, err := ncA.SubscribeSync(subj)
  1780  	if err != nil {
  1781  		t.Fatalf("Expected no error during subscribe: %v", err)
  1782  	}
  1783  	defer subA.Unsubscribe()
  1784  	// Connect of client triggered a fetch of both accounts
  1785  	// the fetch for the imported account will fail
  1786  	chanRecv(t, chanImpA, 10*time.Second)
  1787  	chanRecv(t, chanExpF, 10*time.Second)
  1788  	// create second client for user exporting
  1789  	ncB := natsConnect(t, sA.ClientURL(), createUserCreds(t, nil, expkp))
  1790  	defer ncB.Close()
  1791  	chanRecv(t, chanExpS, 10*time.Second)
  1792  	// Connect of client triggered another fetch, this time passing
  1793  	checkSubInterest(t, sA, imppub, subj, 10*time.Second)
  1794  	checkSubInterest(t, sA, exppub, crossAccSubj, 10*time.Second) // Will fail as a result of this issue
  1795  }
  1796  
  1797  func TestJWTAccountURLResolverFetchFailurePushReorder(t *testing.T) {
  1798  	const subj = "test"
  1799  	const crossAccSubj = "test"
  1800  	// Create System Account
  1801  	syskp, _ := nkeys.CreateAccount()
  1802  	syspub, _ := syskp.PublicKey()
  1803  	sysAc := jwt.NewAccountClaims(syspub)
  1804  	sysjwt, err := sysAc.Encode(oKp)
  1805  	if err != nil {
  1806  		t.Fatalf("Error generating account JWT: %v", err)
  1807  	}
  1808  	// Create Exporting Account
  1809  	expkp, _ := nkeys.CreateAccount()
  1810  	exppub, _ := expkp.PublicKey()
  1811  	expac := jwt.NewAccountClaims(exppub)
  1812  	expjwt1, err := expac.Encode(oKp)
  1813  	if err != nil {
  1814  		t.Fatalf("Error generating account JWT: %v", err)
  1815  	}
  1816  	expac.Exports.Add(&jwt.Export{
  1817  		Subject: crossAccSubj,
  1818  		Type:    jwt.Stream,
  1819  	})
  1820  	expjwt2, err := expac.Encode(oKp)
  1821  	if err != nil {
  1822  		t.Fatalf("Error generating account JWT: %v", err)
  1823  	}
  1824  	// Create importing Account
  1825  	impkp, _ := nkeys.CreateAccount()
  1826  	imppub, _ := impkp.PublicKey()
  1827  	impac := jwt.NewAccountClaims(imppub)
  1828  	impac.Imports.Add(&jwt.Import{
  1829  		Account: exppub,
  1830  		Subject: crossAccSubj,
  1831  		Type:    jwt.Stream,
  1832  	})
  1833  	impjwt, err := impac.Encode(oKp)
  1834  	if err != nil {
  1835  		t.Fatalf("Error generating account JWT: %v", err)
  1836  	}
  1837  	// Simulate an account server that does not serve the updated jwt for exppub
  1838  	chanImpA := make(chan struct{}, 10)
  1839  	defer close(chanImpA)
  1840  	chanExpS := make(chan struct{}, 10)
  1841  	defer close(chanExpS)
  1842  	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  1843  		if r.URL.Path == "/A/" {
  1844  			// Server startup
  1845  			w.Write(nil)
  1846  			chanImpA <- struct{}{}
  1847  		} else if r.URL.Path == "/A/"+imppub {
  1848  			w.Write([]byte(impjwt))
  1849  			chanImpA <- struct{}{}
  1850  		} else if r.URL.Path == "/A/"+exppub {
  1851  			// respond with jwt that does not have the export
  1852  			// this simulates an ordering issue
  1853  			w.Write([]byte(expjwt1))
  1854  			chanExpS <- struct{}{}
  1855  		} else if r.URL.Path == "/A/"+syspub {
  1856  			w.Write([]byte(sysjwt))
  1857  		} else {
  1858  			t.Fatal("not expected")
  1859  		}
  1860  	}))
  1861  	defer ts.Close()
  1862  	confA := createConfFile(t, []byte(fmt.Sprintf(`
  1863  		listen: 127.0.0.1:-1
  1864  		operator: %s
  1865  		resolver: URL("%s/A/")
  1866  		system_account: %s
  1867      `, ojwt, ts.URL, syspub)))
  1868  	sA := RunServer(LoadConfig(confA))
  1869  	defer sA.Shutdown()
  1870  	// server observed one fetch on startup
  1871  	chanRecv(t, chanImpA, 10*time.Second)
  1872  	// Create first client
  1873  	ncA := natsConnect(t, sA.ClientURL(), createUserCreds(t, nil, impkp))
  1874  	defer ncA.Close()
  1875  	// create a test subscription
  1876  	subA, err := ncA.SubscribeSync(subj)
  1877  	if err != nil {
  1878  		t.Fatalf("Expected no error during subscribe: %v", err)
  1879  	}
  1880  	defer subA.Unsubscribe()
  1881  	// Connect of client triggered a fetch of both accounts
  1882  	// the fetch for the imported account will fail
  1883  	chanRecv(t, chanImpA, 10*time.Second)
  1884  	chanRecv(t, chanExpS, 10*time.Second)
  1885  	// create second client for user exporting
  1886  	ncB := natsConnect(t, sA.ClientURL(), createUserCreds(t, nil, expkp))
  1887  	defer ncB.Close()
  1888  	// update expjwt2, this will correct the import issue
  1889  	sysc := natsConnect(t, sA.ClientURL(), createUserCreds(t, nil, syskp))
  1890  	defer sysc.Close()
  1891  	natsPub(t, sysc, fmt.Sprintf(accUpdateEventSubjNew, exppub), []byte(expjwt2))
  1892  	sysc.Flush()
  1893  	// updating expjwt should cause this to pass
  1894  	checkSubInterest(t, sA, imppub, subj, 10*time.Second)
  1895  	checkSubInterest(t, sA, exppub, crossAccSubj, 10*time.Second) // Will fail as a result of this issue
  1896  }
  1897  
  1898  type captureDebugLogger struct {
  1899  	DummyLogger
  1900  	dbgCh chan string
  1901  }
  1902  
  1903  func (l *captureDebugLogger) Debugf(format string, v ...interface{}) {
  1904  	select {
  1905  	case l.dbgCh <- fmt.Sprintf(format, v...):
  1906  	default:
  1907  	}
  1908  }
  1909  
  1910  func TestJWTAccountURLResolverPermanentFetchFailure(t *testing.T) {
  1911  	const crossAccSubj = "test"
  1912  	expkp, _ := nkeys.CreateAccount()
  1913  	exppub, _ := expkp.PublicKey()
  1914  	impkp, _ := nkeys.CreateAccount()
  1915  	imppub, _ := impkp.PublicKey()
  1916  	// Create System Account
  1917  	syskp, _ := nkeys.CreateAccount()
  1918  	syspub, _ := syskp.PublicKey()
  1919  	sysAc := jwt.NewAccountClaims(syspub)
  1920  	sysjwt, err := sysAc.Encode(oKp)
  1921  	if err != nil {
  1922  		t.Fatalf("Error generating account JWT: %v", err)
  1923  	}
  1924  	// Create 2 Accounts. Each importing from the other, but NO matching export
  1925  	expac := jwt.NewAccountClaims(exppub)
  1926  	expac.Imports.Add(&jwt.Import{
  1927  		Account: imppub,
  1928  		Subject: crossAccSubj,
  1929  		Type:    jwt.Stream,
  1930  	})
  1931  	expjwt, err := expac.Encode(oKp)
  1932  	if err != nil {
  1933  		t.Fatalf("Error generating account JWT: %v", err)
  1934  	}
  1935  	// Create importing Account
  1936  	impac := jwt.NewAccountClaims(imppub)
  1937  	impac.Imports.Add(&jwt.Import{
  1938  		Account: exppub,
  1939  		Subject: crossAccSubj,
  1940  		Type:    jwt.Stream,
  1941  	})
  1942  	impjwt, err := impac.Encode(oKp)
  1943  	if err != nil {
  1944  		t.Fatalf("Error generating account JWT: %v", err)
  1945  	}
  1946  	// Simulate an account server that does not serve the updated jwt for exppub
  1947  	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  1948  		if r.URL.Path == "/A/" {
  1949  			// Server startup
  1950  			w.Write(nil)
  1951  		} else if r.URL.Path == "/A/"+imppub {
  1952  			w.Write([]byte(impjwt))
  1953  		} else if r.URL.Path == "/A/"+exppub {
  1954  			w.Write([]byte(expjwt))
  1955  		} else if r.URL.Path == "/A/"+syspub {
  1956  			w.Write([]byte(sysjwt))
  1957  		} else {
  1958  			t.Fatal("not expected")
  1959  		}
  1960  	}))
  1961  	defer ts.Close()
  1962  	confA := createConfFile(t, []byte(fmt.Sprintf(`
  1963  		listen: 127.0.0.1:-1
  1964  		operator: %s
  1965  		resolver: URL("%s/A/")
  1966  		system_account: %s
  1967      `, ojwt, ts.URL, syspub)))
  1968  	o := LoadConfig(confA)
  1969  	sA := RunServer(o)
  1970  	defer sA.Shutdown()
  1971  	l := &captureDebugLogger{dbgCh: make(chan string, 100)} // has enough space to not block
  1972  	sA.SetLogger(l, true, false)
  1973  	// Create clients
  1974  	ncA := natsConnect(t, sA.ClientURL(), createUserCreds(t, nil, impkp))
  1975  	defer ncA.Close()
  1976  	ncB := natsConnect(t, sA.ClientURL(), createUserCreds(t, nil, expkp))
  1977  	defer ncB.Close()
  1978  	sysc := natsConnect(t, sA.ClientURL(), createUserCreds(t, nil, syskp))
  1979  	defer sysc.Close()
  1980  	// push accounts
  1981  	natsPub(t, sysc, fmt.Sprintf(accUpdateEventSubjNew, imppub), []byte(impjwt))
  1982  	natsPub(t, sysc, fmt.Sprintf(accUpdateEventSubjOld, exppub), []byte(expjwt))
  1983  	sysc.Flush()
  1984  	importErrCnt := 0
  1985  	tmr := time.NewTimer(500 * time.Millisecond)
  1986  	defer tmr.Stop()
  1987  	for {
  1988  		select {
  1989  		case line := <-l.dbgCh:
  1990  			if strings.HasPrefix(line, "Error adding stream import to account") {
  1991  				importErrCnt++
  1992  			}
  1993  		case <-tmr.C:
  1994  			// connecting and updating, each cause 3 traces (2 + 1 on iteration)
  1995  			if importErrCnt != 6 {
  1996  				t.Fatalf("Expected 6 debug traces, got %d", importErrCnt)
  1997  			}
  1998  			return
  1999  		}
  2000  	}
  2001  }
  2002  
  2003  func TestJWTAccountURLResolverFetchFailureInCluster(t *testing.T) {
  2004  	assertChanLen := func(x int, chans ...chan struct{}) {
  2005  		t.Helper()
  2006  		for _, c := range chans {
  2007  			if len(c) != x {
  2008  				t.Fatalf("length of channel is not %d", x)
  2009  			}
  2010  		}
  2011  	}
  2012  	const subj = ">"
  2013  	const crossAccSubj = "test"
  2014  	// Create Exporting Account
  2015  	expkp, _ := nkeys.CreateAccount()
  2016  	exppub, _ := expkp.PublicKey()
  2017  	expac := jwt.NewAccountClaims(exppub)
  2018  	expac.Exports.Add(&jwt.Export{
  2019  		Subject: crossAccSubj,
  2020  		Type:    jwt.Stream,
  2021  	})
  2022  	expjwt, err := expac.Encode(oKp)
  2023  	if err != nil {
  2024  		t.Fatalf("Error generating account JWT: %v", err)
  2025  	}
  2026  	// Create importing Account
  2027  	impkp, _ := nkeys.CreateAccount()
  2028  	imppub, _ := impkp.PublicKey()
  2029  	impac := jwt.NewAccountClaims(imppub)
  2030  	impac.Imports.Add(&jwt.Import{
  2031  		Account: exppub,
  2032  		Subject: crossAccSubj,
  2033  		Type:    jwt.Stream,
  2034  	})
  2035  	impac.Exports.Add(&jwt.Export{
  2036  		Subject: "srvc",
  2037  		Type:    jwt.Service,
  2038  	})
  2039  	impjwt, err := impac.Encode(oKp)
  2040  	if err != nil {
  2041  		t.Fatalf("Error generating account JWT: %v", err)
  2042  	}
  2043  	// Create User
  2044  	nkp, _ := nkeys.CreateUser()
  2045  	uSeed, _ := nkp.Seed()
  2046  	upub, _ := nkp.PublicKey()
  2047  	nuc := newJWTTestUserClaims()
  2048  	nuc.Subject = upub
  2049  	uJwt, err := nuc.Encode(impkp)
  2050  	if err != nil {
  2051  		t.Fatalf("Error generating user JWT: %v", err)
  2052  	}
  2053  	creds := genCredsFile(t, uJwt, uSeed)
  2054  	// Simulate an account server that drops the first request to /B/acc
  2055  	chanImpA := make(chan struct{}, 4)
  2056  	defer close(chanImpA)
  2057  	chanImpB := make(chan struct{}, 4)
  2058  	defer close(chanImpB)
  2059  	chanExpA := make(chan struct{}, 4)
  2060  	defer close(chanExpA)
  2061  	chanExpB := make(chan struct{}, 4)
  2062  	defer close(chanExpB)
  2063  	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  2064  		if r.URL.Path == "/A/" {
  2065  			// Server A startup
  2066  			w.Write(nil)
  2067  			chanImpA <- struct{}{}
  2068  		} else if r.URL.Path == "/B/" {
  2069  			// Server B startup
  2070  			w.Write(nil)
  2071  			chanImpB <- struct{}{}
  2072  		} else if r.URL.Path == "/A/"+imppub {
  2073  			// First Client connecting to Server A
  2074  			w.Write([]byte(impjwt))
  2075  			chanImpA <- struct{}{}
  2076  		} else if r.URL.Path == "/B/"+imppub {
  2077  			// Second Client connecting to Server B
  2078  			w.Write([]byte(impjwt))
  2079  			chanImpB <- struct{}{}
  2080  		} else if r.URL.Path == "/A/"+exppub {
  2081  			// First Client connecting to Server A
  2082  			w.Write([]byte(expjwt))
  2083  			chanExpA <- struct{}{}
  2084  		} else if r.URL.Path == "/B/"+exppub {
  2085  			// Second Client connecting to Server B
  2086  			w.Write([]byte(expjwt))
  2087  			chanExpB <- struct{}{}
  2088  		} else {
  2089  			t.Fatal("not expected")
  2090  		}
  2091  	}))
  2092  	defer ts.Close()
  2093  	// Create seed server A
  2094  	confA := createConfFile(t, []byte(fmt.Sprintf(`
  2095  		listen: 127.0.0.1:-1
  2096  		operator: %s
  2097  		resolver: URL("%s/A/")
  2098  		cluster {
  2099  			name: clust
  2100  			no_advertise: true
  2101  			listen: 127.0.0.1:-1
  2102  		}
  2103      `, ojwt, ts.URL)))
  2104  	sA := RunServer(LoadConfig(confA))
  2105  	defer sA.Shutdown()
  2106  	// Create Server B (using no_advertise to prevent failover)
  2107  	confB := createConfFile(t, []byte(fmt.Sprintf(`
  2108  		listen: 127.0.0.1:-1
  2109  		operator: %s
  2110  		resolver: URL("%s/B/")
  2111  		cluster {
  2112  			name: clust
  2113  			no_advertise: true
  2114  			listen: 127.0.0.1:-1
  2115  			routes [
  2116  				nats-route://127.0.0.1:%d
  2117  			]
  2118  		}
  2119      `, ojwt, ts.URL, sA.opts.Cluster.Port)))
  2120  	sB := RunServer(LoadConfig(confB))
  2121  	defer sB.Shutdown()
  2122  	// startup cluster
  2123  	checkClusterFormed(t, sA, sB)
  2124  	// Both server observed one fetch on startup
  2125  	chanRecv(t, chanImpA, 10*time.Second)
  2126  	chanRecv(t, chanImpB, 10*time.Second)
  2127  	assertChanLen(0, chanImpA, chanImpB, chanExpA, chanExpB)
  2128  	// Create first client, directly connects to A
  2129  	urlA := fmt.Sprintf("nats://%s:%d", sA.opts.Host, sA.opts.Port)
  2130  	ncA, err := nats.Connect(urlA, nats.UserCredentials(creds),
  2131  		nats.DisconnectErrHandler(func(_ *nats.Conn, err error) {
  2132  			if err != nil {
  2133  				t.Fatal("error not expected in this test", err)
  2134  			}
  2135  		}),
  2136  		nats.ErrorHandler(func(_ *nats.Conn, _ *nats.Subscription, err error) {
  2137  			t.Fatal("error not expected in this test", err)
  2138  		}),
  2139  	)
  2140  	if err != nil {
  2141  		t.Fatalf("Expected to connect, got %v %s", err, urlA)
  2142  	}
  2143  	defer ncA.Close()
  2144  	// create a test subscription
  2145  	subA, err := ncA.SubscribeSync(subj)
  2146  	if err != nil {
  2147  		t.Fatalf("Expected no error during subscribe: %v", err)
  2148  	}
  2149  	defer subA.Unsubscribe()
  2150  	// Connect of client triggered a fetch by Server A
  2151  	chanRecv(t, chanImpA, 10*time.Second)
  2152  	chanRecv(t, chanExpA, 10*time.Second)
  2153  	assertChanLen(0, chanImpA, chanImpB, chanExpA, chanExpB)
  2154  	//time.Sleep(10 * time.Second)
  2155  	// create second client, directly connect to B
  2156  	urlB := fmt.Sprintf("nats://%s:%d", sB.opts.Host, sB.opts.Port)
  2157  	ncB, err := nats.Connect(urlB, nats.UserCredentials(creds), nats.NoReconnect())
  2158  	if err != nil {
  2159  		t.Fatalf("Expected to connect, got %v %s", err, urlB)
  2160  	}
  2161  	defer ncB.Close()
  2162  	// Connect of client triggered a fetch by Server B
  2163  	chanRecv(t, chanImpB, 10*time.Second)
  2164  	chanRecv(t, chanExpB, 10*time.Second)
  2165  	assertChanLen(0, chanImpA, chanImpB, chanExpA, chanExpB)
  2166  	checkClusterFormed(t, sA, sB)
  2167  	// the route subscription was lost due to the failed fetch
  2168  	// Now we test if some recover mechanism is in play
  2169  	checkSubInterest(t, sB, imppub, subj, 10*time.Second)         // Will fail as a result of this issue
  2170  	checkSubInterest(t, sB, exppub, crossAccSubj, 10*time.Second) // Will fail as a result of this issue
  2171  	if err := ncB.Publish(subj, []byte("msg")); err != nil {
  2172  		t.Fatalf("Expected to publish %v", err)
  2173  	}
  2174  	// expect the message from B to flow to A
  2175  	if m, err := subA.NextMsg(10 * time.Second); err != nil {
  2176  		t.Fatalf("Expected to receive a message %v", err)
  2177  	} else if string(m.Data) != "msg" {
  2178  		t.Fatalf("Expected to receive 'msg', got: %s", string(m.Data))
  2179  	}
  2180  	assertChanLen(0, chanImpA, chanImpB, chanExpA, chanExpB)
  2181  }
  2182  
  2183  func TestJWTAccountURLResolverReturnDifferentOperator(t *testing.T) {
  2184  	// Create a valid chain of op/acc/usr using a different operator
  2185  	// This is so we can test if the server rejects this chain.
  2186  	// Create Operator
  2187  	op, _ := nkeys.CreateOperator()
  2188  	// Create Account, this account is the one returned by the resolver
  2189  	akp, _ := nkeys.CreateAccount()
  2190  	apub, _ := akp.PublicKey()
  2191  	nac := jwt.NewAccountClaims(apub)
  2192  	ajwt, err := nac.Encode(op)
  2193  	if err != nil {
  2194  		t.Fatalf("Error generating account JWT: %v", err)
  2195  	}
  2196  	// Create User
  2197  	nkp, _ := nkeys.CreateUser()
  2198  	uSeed, _ := nkp.Seed()
  2199  	upub, _ := nkp.PublicKey()
  2200  	nuc := newJWTTestUserClaims()
  2201  	nuc.Subject = upub
  2202  	uJwt, err := nuc.Encode(akp)
  2203  	if err != nil {
  2204  		t.Fatalf("Error generating user JWT: %v", err)
  2205  	}
  2206  	creds := genCredsFile(t, uJwt, uSeed)
  2207  	// Simulate an account server that was hijacked/mis configured
  2208  	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  2209  		w.Write([]byte(ajwt))
  2210  	}))
  2211  	defer ts.Close()
  2212  	// Create Server
  2213  	confA := createConfFile(t, []byte(fmt.Sprintf(`
  2214  		listen: 127.0.0.1:-1
  2215  		operator: %s
  2216  		resolver: URL("%s/A/")
  2217      `, ojwt, ts.URL)))
  2218  	sA, _ := RunServerWithConfig(confA)
  2219  	defer sA.Shutdown()
  2220  	// Create first client, directly connects to A
  2221  	urlA := fmt.Sprintf("nats://%s:%d", sA.opts.Host, sA.opts.Port)
  2222  	if _, err := nats.Connect(urlA, nats.UserCredentials(creds),
  2223  		nats.DisconnectErrHandler(func(_ *nats.Conn, err error) {
  2224  			if err != nil {
  2225  				t.Fatal("error not expected in this test", err)
  2226  			}
  2227  		}),
  2228  		nats.ErrorHandler(func(_ *nats.Conn, _ *nats.Subscription, err error) {
  2229  			t.Fatal("error not expected in this test", err)
  2230  		}),
  2231  	); err == nil {
  2232  		t.Fatal("Expected connect to fail")
  2233  	}
  2234  	// Test if the server has the account in memory. (shouldn't)
  2235  	if v, ok := sA.accounts.Load(apub); ok {
  2236  		t.Fatalf("Expected account to NOT be in memory: %v", v.(*Account))
  2237  	}
  2238  }
  2239  
  2240  func TestJWTUserSigningKey(t *testing.T) {
  2241  	s := opTrustBasicSetup()
  2242  	defer s.Shutdown()
  2243  
  2244  	// Check to make sure we would have an authTimer
  2245  	if !s.info.AuthRequired {
  2246  		t.Fatalf("Expect the server to require auth")
  2247  	}
  2248  
  2249  	c, cr, _ := newClientForServer(s)
  2250  	defer c.close()
  2251  	// Don't send jwt field, should fail.
  2252  	c.parseAsync("CONNECT {\"verbose\":true,\"pedantic\":true}\r\nPING\r\n")
  2253  	l, _ := cr.ReadString('\n')
  2254  	if !strings.HasPrefix(l, "-ERR ") {
  2255  		t.Fatalf("Expected an error")
  2256  	}
  2257  
  2258  	okp, _ := nkeys.FromSeed(oSeed)
  2259  
  2260  	// Create an account
  2261  	akp, _ := nkeys.CreateAccount()
  2262  	apub, _ := akp.PublicKey()
  2263  
  2264  	// Create a signing key for the account
  2265  	askp, _ := nkeys.CreateAccount()
  2266  	aspub, _ := askp.PublicKey()
  2267  
  2268  	nac := jwt.NewAccountClaims(apub)
  2269  	ajwt, err := nac.Encode(okp)
  2270  	if err != nil {
  2271  		t.Fatalf("Error generating account JWT: %v", err)
  2272  	}
  2273  
  2274  	// Create a client with the account signing key
  2275  	c, cr, cs := createClientWithIssuer(t, s, askp, apub)
  2276  	defer c.close()
  2277  
  2278  	// PING needed to flush the +OK/-ERR to us.
  2279  	// This should fail too since no account resolver is defined.
  2280  	c.parseAsync(cs)
  2281  	l, _ = cr.ReadString('\n')
  2282  	if !strings.HasPrefix(l, "-ERR ") {
  2283  		t.Fatalf("Expected an error")
  2284  	}
  2285  
  2286  	// Ok now let's walk through and make sure all is good.
  2287  	// We will set the account resolver by hand to a memory resolver.
  2288  	buildMemAccResolver(s)
  2289  	addAccountToMemResolver(s, apub, ajwt)
  2290  
  2291  	// Create a client with a signing key
  2292  	c, cr, cs = createClientWithIssuer(t, s, askp, apub)
  2293  	defer c.close()
  2294  	// should fail because the signing key is not known
  2295  	c.parseAsync(cs)
  2296  	l, _ = cr.ReadString('\n')
  2297  	if !strings.HasPrefix(l, "-ERR ") {
  2298  		t.Fatalf("Expected an error: %v", l)
  2299  	}
  2300  
  2301  	// add a signing key
  2302  	nac.SigningKeys.Add(aspub)
  2303  	// update the memory resolver
  2304  	acc, _ := s.LookupAccount(apub)
  2305  	s.UpdateAccountClaims(acc, nac)
  2306  
  2307  	// Create a client with a signing key
  2308  	c, cr, cs = createClientWithIssuer(t, s, askp, apub)
  2309  	defer c.close()
  2310  
  2311  	// expect this to work
  2312  	c.parseAsync(cs)
  2313  	l, _ = cr.ReadString('\n')
  2314  	if !strings.HasPrefix(l, "PONG") {
  2315  		t.Fatalf("Expected a PONG, got %q", l)
  2316  	}
  2317  
  2318  	isClosed := func() bool {
  2319  		c.mu.Lock()
  2320  		defer c.mu.Unlock()
  2321  		return c.isClosed()
  2322  	}
  2323  
  2324  	if isClosed() {
  2325  		t.Fatal("expected client to be alive")
  2326  	}
  2327  	// remove the signing key should bounce client
  2328  	nac.SigningKeys = nil
  2329  	acc, _ = s.LookupAccount(apub)
  2330  	s.UpdateAccountClaims(acc, nac)
  2331  
  2332  	if !isClosed() {
  2333  		t.Fatal("expected client to be gone")
  2334  	}
  2335  }
  2336  
  2337  func TestJWTAccountImportSignerRemoved(t *testing.T) {
  2338  	s := opTrustBasicSetup()
  2339  	defer s.Shutdown()
  2340  	buildMemAccResolver(s)
  2341  
  2342  	okp, _ := nkeys.FromSeed(oSeed)
  2343  
  2344  	// Exporter keys
  2345  	srvKP, _ := nkeys.CreateAccount()
  2346  	srvPK, _ := srvKP.PublicKey()
  2347  	srvSignerKP, _ := nkeys.CreateAccount()
  2348  	srvSignerPK, _ := srvSignerKP.PublicKey()
  2349  
  2350  	// Importer keys
  2351  	clientKP, _ := nkeys.CreateAccount()
  2352  	clientPK, _ := clientKP.PublicKey()
  2353  
  2354  	createSrvJwt := func(signingKeys ...string) (string, *jwt.AccountClaims) {
  2355  		ac := jwt.NewAccountClaims(srvPK)
  2356  		ac.SigningKeys.Add(signingKeys...)
  2357  		ac.Exports.Add(&jwt.Export{Subject: "foo", Type: jwt.Service, TokenReq: true})
  2358  		ac.Exports.Add(&jwt.Export{Subject: "bar", Type: jwt.Stream, TokenReq: true})
  2359  		token, err := ac.Encode(okp)
  2360  		if err != nil {
  2361  			t.Fatalf("Error generating exporter JWT: %v", err)
  2362  		}
  2363  		return token, ac
  2364  	}
  2365  
  2366  	createImportToken := func(sub string, kind jwt.ExportType) string {
  2367  		actC := jwt.NewActivationClaims(clientPK)
  2368  		actC.IssuerAccount = srvPK
  2369  		actC.ImportType = kind
  2370  		actC.ImportSubject = jwt.Subject(sub)
  2371  		token, err := actC.Encode(srvSignerKP)
  2372  		if err != nil {
  2373  			t.Fatal(err)
  2374  		}
  2375  		return token
  2376  	}
  2377  
  2378  	createClientJwt := func() string {
  2379  		ac := jwt.NewAccountClaims(clientPK)
  2380  		ac.Imports.Add(&jwt.Import{Account: srvPK, Subject: "foo", Type: jwt.Service, Token: createImportToken("foo", jwt.Service)})
  2381  		ac.Imports.Add(&jwt.Import{Account: srvPK, Subject: "bar", Type: jwt.Stream, Token: createImportToken("bar", jwt.Stream)})
  2382  		token, err := ac.Encode(okp)
  2383  		if err != nil {
  2384  			t.Fatalf("Error generating importer JWT: %v", err)
  2385  		}
  2386  		return token
  2387  	}
  2388  
  2389  	srvJWT, _ := createSrvJwt(srvSignerPK)
  2390  	addAccountToMemResolver(s, srvPK, srvJWT)
  2391  
  2392  	clientJWT := createClientJwt()
  2393  	addAccountToMemResolver(s, clientPK, clientJWT)
  2394  
  2395  	// Create a client that will send the request
  2396  	client, clientReader, clientCS := createClient(t, s, clientKP)
  2397  	defer client.close()
  2398  	client.parseAsync(clientCS)
  2399  	expectPong(t, clientReader)
  2400  
  2401  	checkShadow := func(expected int) {
  2402  		t.Helper()
  2403  		client.mu.Lock()
  2404  		defer client.mu.Unlock()
  2405  		sub := client.subs["1"]
  2406  		count := 0
  2407  		if sub != nil {
  2408  			count = len(sub.shadow)
  2409  		}
  2410  		if count != expected {
  2411  			t.Fatalf("Expected shadows to be %d, got %d", expected, count)
  2412  		}
  2413  	}
  2414  
  2415  	checkShadow(0)
  2416  	// Create the client that will respond to the requests.
  2417  	srv, srvReader, srvCS := createClient(t, s, srvKP)
  2418  	defer srv.close()
  2419  	srv.parseAsync(srvCS)
  2420  	expectPong(t, srvReader)
  2421  
  2422  	// Create Subscriber.
  2423  	srv.parseAsync("SUB foo 1\r\nPING\r\n")
  2424  	expectPong(t, srvReader)
  2425  
  2426  	// Send Request
  2427  	client.parseAsync("PUB foo 2\r\nhi\r\nPING\r\n")
  2428  	expectPong(t, clientReader)
  2429  
  2430  	// We should receive the request. PING needed to flush.
  2431  	srv.parseAsync("PING\r\n")
  2432  	expectMsg(t, srvReader, "foo", "hi")
  2433  
  2434  	client.parseAsync("SUB bar 1\r\nPING\r\n")
  2435  	expectPong(t, clientReader)
  2436  	checkShadow(1)
  2437  
  2438  	srv.parseAsync("PUB bar 2\r\nhi\r\nPING\r\n")
  2439  	expectPong(t, srvReader)
  2440  
  2441  	// We should receive from stream. PING needed to flush.
  2442  	client.parseAsync("PING\r\n")
  2443  	expectMsg(t, clientReader, "bar", "hi")
  2444  
  2445  	// Now update the exported service no signer
  2446  	srvJWT, srvAC := createSrvJwt()
  2447  	addAccountToMemResolver(s, srvPK, srvJWT)
  2448  	acc, _ := s.LookupAccount(srvPK)
  2449  	s.UpdateAccountClaims(acc, srvAC)
  2450  
  2451  	// Send Another Request
  2452  	client.parseAsync("PUB foo 2\r\nhi\r\nPING\r\n")
  2453  	expectPong(t, clientReader)
  2454  
  2455  	// We should not receive the request this time.
  2456  	srv.parseAsync("PING\r\n")
  2457  	expectPong(t, srvReader)
  2458  
  2459  	// Publish on the stream
  2460  	srv.parseAsync("PUB bar 2\r\nhi\r\nPING\r\n")
  2461  	expectPong(t, srvReader)
  2462  
  2463  	// We should not receive from the stream this time
  2464  	client.parseAsync("PING\r\n")
  2465  	expectPong(t, clientReader)
  2466  	checkShadow(0)
  2467  }
  2468  
  2469  func TestJWTAccountImportSignerDeadlock(t *testing.T) {
  2470  	s := opTrustBasicSetup()
  2471  	defer s.Shutdown()
  2472  	buildMemAccResolver(s)
  2473  
  2474  	okp, _ := nkeys.FromSeed(oSeed)
  2475  
  2476  	// Exporter keys
  2477  	srvKP, _ := nkeys.CreateAccount()
  2478  	srvPK, _ := srvKP.PublicKey()
  2479  	srvSignerKP, _ := nkeys.CreateAccount()
  2480  	srvSignerPK, _ := srvSignerKP.PublicKey()
  2481  
  2482  	// Importer keys
  2483  	clientKP, _ := nkeys.CreateAccount()
  2484  	clientPK, _ := clientKP.PublicKey()
  2485  
  2486  	createSrvJwt := func(signingKeys ...string) (string, *jwt.AccountClaims) {
  2487  		ac := jwt.NewAccountClaims(srvPK)
  2488  		ac.SigningKeys.Add(signingKeys...)
  2489  		ac.Exports.Add(&jwt.Export{Subject: "foo", Type: jwt.Service, TokenReq: true})
  2490  		ac.Exports.Add(&jwt.Export{Subject: "bar", Type: jwt.Stream, TokenReq: true})
  2491  		token, err := ac.Encode(okp)
  2492  		if err != nil {
  2493  			t.Fatalf("Error generating exporter JWT: %v", err)
  2494  		}
  2495  		return token, ac
  2496  	}
  2497  
  2498  	createImportToken := func(sub string, kind jwt.ExportType) string {
  2499  		actC := jwt.NewActivationClaims(clientPK)
  2500  		actC.IssuerAccount = srvPK
  2501  		actC.ImportType = kind
  2502  		actC.ImportSubject = jwt.Subject(sub)
  2503  		token, err := actC.Encode(srvSignerKP)
  2504  		if err != nil {
  2505  			t.Fatal(err)
  2506  		}
  2507  		return token
  2508  	}
  2509  
  2510  	createClientJwt := func() string {
  2511  		ac := jwt.NewAccountClaims(clientPK)
  2512  		ac.Imports.Add(&jwt.Import{Account: srvPK, Subject: "foo", Type: jwt.Service, Token: createImportToken("foo", jwt.Service)})
  2513  		ac.Imports.Add(&jwt.Import{Account: srvPK, Subject: "bar", Type: jwt.Stream, Token: createImportToken("bar", jwt.Stream)})
  2514  		token, err := ac.Encode(okp)
  2515  		if err != nil {
  2516  			t.Fatalf("Error generating importer JWT: %v", err)
  2517  		}
  2518  		return token
  2519  	}
  2520  
  2521  	srvJWT, _ := createSrvJwt(srvSignerPK)
  2522  	addAccountToMemResolver(s, srvPK, srvJWT)
  2523  
  2524  	clientJWT := createClientJwt()
  2525  	addAccountToMemResolver(s, clientPK, clientJWT)
  2526  
  2527  	acc, _ := s.LookupAccount(srvPK)
  2528  	// Have a go routine that constantly gets/releases the acc's write lock.
  2529  	// There was a bug that could cause AddServiceImportWithClaim to deadlock.
  2530  	ch := make(chan bool, 1)
  2531  	wg := sync.WaitGroup{}
  2532  	wg.Add(1)
  2533  	go func() {
  2534  		defer wg.Done()
  2535  		for {
  2536  			select {
  2537  			case <-ch:
  2538  				return
  2539  			default:
  2540  				acc.mu.Lock()
  2541  				acc.mu.Unlock()
  2542  				time.Sleep(time.Millisecond)
  2543  			}
  2544  		}
  2545  	}()
  2546  
  2547  	// Create a client that will send the request
  2548  	client, clientReader, clientCS := createClient(t, s, clientKP)
  2549  	defer client.close()
  2550  	client.parseAsync(clientCS)
  2551  	expectPong(t, clientReader)
  2552  
  2553  	close(ch)
  2554  	wg.Wait()
  2555  }
  2556  
  2557  func TestJWTAccountImportWrongIssuerAccount(t *testing.T) {
  2558  	s := opTrustBasicSetup()
  2559  	defer s.Shutdown()
  2560  	buildMemAccResolver(s)
  2561  
  2562  	l := &captureErrorLogger{errCh: make(chan string, 2)}
  2563  	s.SetLogger(l, false, false)
  2564  
  2565  	okp, _ := nkeys.FromSeed(oSeed)
  2566  
  2567  	// Exporter keys
  2568  	srvKP, _ := nkeys.CreateAccount()
  2569  	srvPK, _ := srvKP.PublicKey()
  2570  	srvSignerKP, _ := nkeys.CreateAccount()
  2571  	srvSignerPK, _ := srvSignerKP.PublicKey()
  2572  
  2573  	// Importer keys
  2574  	clientKP, _ := nkeys.CreateAccount()
  2575  	clientPK, _ := clientKP.PublicKey()
  2576  
  2577  	createSrvJwt := func(signingKeys ...string) (string, *jwt.AccountClaims) {
  2578  		ac := jwt.NewAccountClaims(srvPK)
  2579  		ac.SigningKeys.Add(signingKeys...)
  2580  		ac.Exports.Add(&jwt.Export{Subject: "foo", Type: jwt.Service, TokenReq: true})
  2581  		ac.Exports.Add(&jwt.Export{Subject: "bar", Type: jwt.Stream, TokenReq: true})
  2582  		token, err := ac.Encode(okp)
  2583  		if err != nil {
  2584  			t.Fatalf("Error generating exporter JWT: %v", err)
  2585  		}
  2586  		return token, ac
  2587  	}
  2588  
  2589  	createImportToken := func(sub string, kind jwt.ExportType) string {
  2590  		actC := jwt.NewActivationClaims(clientPK)
  2591  		// Reference ourselves, which is wrong.
  2592  		actC.IssuerAccount = clientPK
  2593  		actC.ImportType = kind
  2594  		actC.ImportSubject = jwt.Subject(sub)
  2595  		token, err := actC.Encode(srvSignerKP)
  2596  		if err != nil {
  2597  			t.Fatal(err)
  2598  		}
  2599  		return token
  2600  	}
  2601  
  2602  	createClientJwt := func() string {
  2603  		ac := jwt.NewAccountClaims(clientPK)
  2604  		ac.Imports.Add(&jwt.Import{Account: srvPK, Subject: "foo", Type: jwt.Service, Token: createImportToken("foo", jwt.Service)})
  2605  		ac.Imports.Add(&jwt.Import{Account: srvPK, Subject: "bar", Type: jwt.Stream, Token: createImportToken("bar", jwt.Stream)})
  2606  		token, err := ac.Encode(okp)
  2607  		if err != nil {
  2608  			t.Fatalf("Error generating importer JWT: %v", err)
  2609  		}
  2610  		return token
  2611  	}
  2612  
  2613  	srvJWT, _ := createSrvJwt(srvSignerPK)
  2614  	addAccountToMemResolver(s, srvPK, srvJWT)
  2615  
  2616  	clientJWT := createClientJwt()
  2617  	addAccountToMemResolver(s, clientPK, clientJWT)
  2618  
  2619  	// Create a client that will send the request
  2620  	client, clientReader, clientCS := createClient(t, s, clientKP)
  2621  	defer client.close()
  2622  	client.parseAsync(clientCS)
  2623  	if l, _, err := clientReader.ReadLine(); err != nil {
  2624  		t.Fatalf("Expected no Error, got: %v", err)
  2625  	} else if !strings.Contains(string(l), "-ERR 'Authorization Violation'") {
  2626  		t.Fatalf("Expected Error, got: %v", l)
  2627  	}
  2628  }
  2629  
  2630  func TestJWTUserRevokedOnAccountUpdate(t *testing.T) {
  2631  	nac := newJWTTestAccountClaims()
  2632  	s, akp, c, cr := setupJWTTestWitAccountClaims(t, nac, "+OK")
  2633  	defer s.Shutdown()
  2634  	defer c.close()
  2635  
  2636  	expectPong(t, cr)
  2637  
  2638  	okp, _ := nkeys.FromSeed(oSeed)
  2639  	apub, _ := akp.PublicKey()
  2640  
  2641  	c.mu.Lock()
  2642  	pub := c.user.Nkey
  2643  	c.mu.Unlock()
  2644  
  2645  	// Now revoke the user.
  2646  	nac.Revoke(pub)
  2647  
  2648  	ajwt, err := nac.Encode(okp)
  2649  	if err != nil {
  2650  		t.Fatalf("Error generating account JWT: %v", err)
  2651  	}
  2652  
  2653  	// Update the account on the server.
  2654  	addAccountToMemResolver(s, apub, ajwt)
  2655  	acc, err := s.LookupAccount(apub)
  2656  	if err != nil {
  2657  		t.Fatalf("Error looking up the account: %v", err)
  2658  	}
  2659  
  2660  	// This is simulating a system update for the account claims.
  2661  	go s.updateAccountWithClaimJWT(acc, ajwt)
  2662  
  2663  	l, _ := cr.ReadString('\n')
  2664  	if !strings.HasPrefix(l, "-ERR ") {
  2665  		t.Fatalf("Expected an error")
  2666  	}
  2667  	if !strings.Contains(l, "Revoked") {
  2668  		t.Fatalf("Expected 'Revoked' to be in the error")
  2669  	}
  2670  }
  2671  
  2672  func TestJWTUserRevoked(t *testing.T) {
  2673  	okp, _ := nkeys.FromSeed(oSeed)
  2674  
  2675  	// Create a new user that we will make sure has been revoked.
  2676  	nkp, _ := nkeys.CreateUser()
  2677  	pub, _ := nkp.PublicKey()
  2678  	nuc := jwt.NewUserClaims(pub)
  2679  
  2680  	akp, _ := nkeys.CreateAccount()
  2681  	apub, _ := akp.PublicKey()
  2682  	nac := jwt.NewAccountClaims(apub)
  2683  	// Revoke the user right away.
  2684  	nac.Revoke(pub)
  2685  	ajwt, err := nac.Encode(okp)
  2686  	if err != nil {
  2687  		t.Fatalf("Error generating account JWT: %v", err)
  2688  	}
  2689  
  2690  	// Sign for the user.
  2691  	jwt, err := nuc.Encode(akp)
  2692  	if err != nil {
  2693  		t.Fatalf("Error generating user JWT: %v", err)
  2694  	}
  2695  
  2696  	s := opTrustBasicSetup()
  2697  	defer s.Shutdown()
  2698  	buildMemAccResolver(s)
  2699  	addAccountToMemResolver(s, apub, ajwt)
  2700  
  2701  	c, cr, l := newClientForServer(s)
  2702  	defer c.close()
  2703  
  2704  	// Sign Nonce
  2705  	var info nonceInfo
  2706  	json.Unmarshal([]byte(l[5:]), &info)
  2707  	sigraw, _ := nkp.Sign([]byte(info.Nonce))
  2708  	sig := base64.RawURLEncoding.EncodeToString(sigraw)
  2709  
  2710  	// PING needed to flush the +OK/-ERR to us.
  2711  	cs := fmt.Sprintf("CONNECT {\"jwt\":%q,\"sig\":\"%s\"}\r\nPING\r\n", jwt, sig)
  2712  
  2713  	c.parseAsync(cs)
  2714  
  2715  	l, _ = cr.ReadString('\n')
  2716  	if !strings.HasPrefix(l, "-ERR ") {
  2717  		t.Fatalf("Expected an error")
  2718  	}
  2719  	if !strings.Contains(l, "Authorization") {
  2720  		t.Fatalf("Expected 'Revoked' to be in the error")
  2721  	}
  2722  }
  2723  
  2724  // Test that an account update that revokes an import authorization cancels the import.
  2725  func TestJWTImportTokenRevokedAfter(t *testing.T) {
  2726  	s := opTrustBasicSetup()
  2727  	defer s.Shutdown()
  2728  	buildMemAccResolver(s)
  2729  
  2730  	okp, _ := nkeys.FromSeed(oSeed)
  2731  
  2732  	// Create accounts and imports/exports.
  2733  	fooKP, _ := nkeys.CreateAccount()
  2734  	fooPub, _ := fooKP.PublicKey()
  2735  	fooAC := jwt.NewAccountClaims(fooPub)
  2736  
  2737  	// Now create Exports.
  2738  	export := &jwt.Export{Subject: "foo.private", Type: jwt.Stream, TokenReq: true}
  2739  
  2740  	fooAC.Exports.Add(export)
  2741  	fooJWT, err := fooAC.Encode(okp)
  2742  	if err != nil {
  2743  		t.Fatalf("Error generating account JWT: %v", err)
  2744  	}
  2745  
  2746  	addAccountToMemResolver(s, fooPub, fooJWT)
  2747  
  2748  	barKP, _ := nkeys.CreateAccount()
  2749  	barPub, _ := barKP.PublicKey()
  2750  	barAC := jwt.NewAccountClaims(barPub)
  2751  	simport := &jwt.Import{Account: fooPub, Subject: "foo.private", Type: jwt.Stream}
  2752  
  2753  	activation := jwt.NewActivationClaims(barPub)
  2754  	activation.ImportSubject = "foo.private"
  2755  	activation.ImportType = jwt.Stream
  2756  	actJWT, err := activation.Encode(fooKP)
  2757  	if err != nil {
  2758  		t.Fatalf("Error generating activation token: %v", err)
  2759  	}
  2760  
  2761  	simport.Token = actJWT
  2762  	barAC.Imports.Add(simport)
  2763  	barJWT, err := barAC.Encode(okp)
  2764  	if err != nil {
  2765  		t.Fatalf("Error generating account JWT: %v", err)
  2766  	}
  2767  	addAccountToMemResolver(s, barPub, barJWT)
  2768  
  2769  	// Now revoke the export.
  2770  	decoded, _ := jwt.DecodeActivationClaims(actJWT)
  2771  	export.Revoke(decoded.Subject)
  2772  
  2773  	fooJWT, err = fooAC.Encode(okp)
  2774  	if err != nil {
  2775  		t.Fatalf("Error generating account JWT: %v", err)
  2776  	}
  2777  
  2778  	addAccountToMemResolver(s, fooPub, fooJWT)
  2779  
  2780  	fooAcc, _ := s.LookupAccount(fooPub)
  2781  	if fooAcc == nil {
  2782  		t.Fatalf("Expected to retrieve the account")
  2783  	}
  2784  
  2785  	// Now lookup bar account and make sure it was revoked.
  2786  	acc, _ := s.LookupAccount(barPub)
  2787  	if acc == nil {
  2788  		t.Fatalf("Expected to retrieve the account")
  2789  	}
  2790  	if les := len(acc.imports.streams); les != 0 {
  2791  		t.Fatalf("Expected imports streams len of 0, got %d", les)
  2792  	}
  2793  }
  2794  
  2795  // Test that an account update that revokes an import authorization cancels the import.
  2796  func TestJWTImportTokenRevokedBefore(t *testing.T) {
  2797  	s := opTrustBasicSetup()
  2798  	defer s.Shutdown()
  2799  	buildMemAccResolver(s)
  2800  
  2801  	okp, _ := nkeys.FromSeed(oSeed)
  2802  
  2803  	// Create accounts and imports/exports.
  2804  	fooKP, _ := nkeys.CreateAccount()
  2805  	fooPub, _ := fooKP.PublicKey()
  2806  	fooAC := jwt.NewAccountClaims(fooPub)
  2807  
  2808  	// Now create Exports.
  2809  	export := &jwt.Export{Subject: "foo.private", Type: jwt.Stream, TokenReq: true}
  2810  
  2811  	fooAC.Exports.Add(export)
  2812  
  2813  	// Import account
  2814  	barKP, _ := nkeys.CreateAccount()
  2815  	barPub, _ := barKP.PublicKey()
  2816  	barAC := jwt.NewAccountClaims(barPub)
  2817  	simport := &jwt.Import{Account: fooPub, Subject: "foo.private", Type: jwt.Stream}
  2818  
  2819  	activation := jwt.NewActivationClaims(barPub)
  2820  	activation.ImportSubject = "foo.private"
  2821  	activation.ImportType = jwt.Stream
  2822  	actJWT, err := activation.Encode(fooKP)
  2823  	if err != nil {
  2824  		t.Fatalf("Error generating activation token: %v", err)
  2825  	}
  2826  
  2827  	simport.Token = actJWT
  2828  	barAC.Imports.Add(simport)
  2829  
  2830  	// Now revoke the export.
  2831  	decoded, _ := jwt.DecodeActivationClaims(actJWT)
  2832  	export.Revoke(decoded.Subject)
  2833  
  2834  	fooJWT, err := fooAC.Encode(okp)
  2835  	if err != nil {
  2836  		t.Fatalf("Error generating account JWT: %v", err)
  2837  	}
  2838  
  2839  	addAccountToMemResolver(s, fooPub, fooJWT)
  2840  
  2841  	barJWT, err := barAC.Encode(okp)
  2842  	if err != nil {
  2843  		t.Fatalf("Error generating account JWT: %v", err)
  2844  	}
  2845  	addAccountToMemResolver(s, barPub, barJWT)
  2846  
  2847  	fooAcc, _ := s.LookupAccount(fooPub)
  2848  	if fooAcc == nil {
  2849  		t.Fatalf("Expected to retrieve the account")
  2850  	}
  2851  
  2852  	// Now lookup bar account and make sure it was revoked.
  2853  	acc, _ := s.LookupAccount(barPub)
  2854  	if acc == nil {
  2855  		t.Fatalf("Expected to retrieve the account")
  2856  	}
  2857  	if les := len(acc.imports.streams); les != 0 {
  2858  		t.Fatalf("Expected imports streams len of 0, got %d", les)
  2859  	}
  2860  }
  2861  
  2862  func TestJWTCircularAccountServiceImport(t *testing.T) {
  2863  	s := opTrustBasicSetup()
  2864  	defer s.Shutdown()
  2865  	buildMemAccResolver(s)
  2866  
  2867  	okp, _ := nkeys.FromSeed(oSeed)
  2868  
  2869  	// Create accounts
  2870  	fooKP, _ := nkeys.CreateAccount()
  2871  	fooPub, _ := fooKP.PublicKey()
  2872  	fooAC := jwt.NewAccountClaims(fooPub)
  2873  
  2874  	barKP, _ := nkeys.CreateAccount()
  2875  	barPub, _ := barKP.PublicKey()
  2876  	barAC := jwt.NewAccountClaims(barPub)
  2877  
  2878  	// Create service export/import for account foo
  2879  	serviceExport := &jwt.Export{Subject: "foo", Type: jwt.Service, TokenReq: true}
  2880  	serviceImport := &jwt.Import{Account: barPub, Subject: "bar", Type: jwt.Service}
  2881  
  2882  	fooAC.Exports.Add(serviceExport)
  2883  	fooAC.Imports.Add(serviceImport)
  2884  	fooJWT, err := fooAC.Encode(okp)
  2885  	if err != nil {
  2886  		t.Fatalf("Error generating account JWT: %v", err)
  2887  	}
  2888  
  2889  	addAccountToMemResolver(s, fooPub, fooJWT)
  2890  
  2891  	// Create service export/import for account bar
  2892  	serviceExport = &jwt.Export{Subject: "bar", Type: jwt.Service, TokenReq: true}
  2893  	serviceImport = &jwt.Import{Account: fooPub, Subject: "foo", Type: jwt.Service}
  2894  
  2895  	barAC.Exports.Add(serviceExport)
  2896  	barAC.Imports.Add(serviceImport)
  2897  	barJWT, err := barAC.Encode(okp)
  2898  	if err != nil {
  2899  		t.Fatalf("Error generating account JWT: %v", err)
  2900  	}
  2901  
  2902  	addAccountToMemResolver(s, barPub, barJWT)
  2903  
  2904  	c, cr, cs := createClient(t, s, fooKP)
  2905  	defer c.close()
  2906  
  2907  	c.parseAsync(cs)
  2908  	expectPong(t, cr)
  2909  
  2910  	c.parseAsync("SUB foo 1\r\nPING\r\n")
  2911  	expectPong(t, cr)
  2912  }
  2913  
  2914  // This test ensures that connected clients are properly evicted
  2915  // (no deadlock) if the max conns of an account has been lowered
  2916  // and the account is being updated (following expiration during
  2917  // a lookup).
  2918  func TestJWTAccountLimitsMaxConnsAfterExpired(t *testing.T) {
  2919  	s := opTrustBasicSetup()
  2920  	defer s.Shutdown()
  2921  	buildMemAccResolver(s)
  2922  
  2923  	okp, _ := nkeys.FromSeed(oSeed)
  2924  
  2925  	// Create accounts and imports/exports.
  2926  	fooKP, _ := nkeys.CreateAccount()
  2927  	fooPub, _ := fooKP.PublicKey()
  2928  	fooAC := jwt.NewAccountClaims(fooPub)
  2929  	fooAC.Limits.Conn = 10
  2930  	fooJWT, err := fooAC.Encode(okp)
  2931  	if err != nil {
  2932  		t.Fatalf("Error generating account JWT: %v", err)
  2933  	}
  2934  	addAccountToMemResolver(s, fooPub, fooJWT)
  2935  
  2936  	newClient := func(expPre string) *testAsyncClient {
  2937  		t.Helper()
  2938  		// Create a client.
  2939  		c, cr, cs := createClient(t, s, fooKP)
  2940  		c.parseAsync(cs)
  2941  		l, _ := cr.ReadString('\n')
  2942  		if !strings.HasPrefix(l, expPre) {
  2943  			t.Fatalf("Expected a response starting with %q, got %q", expPre, l)
  2944  		}
  2945  		go func() {
  2946  			for {
  2947  				if _, _, err := cr.ReadLine(); err != nil {
  2948  					return
  2949  				}
  2950  			}
  2951  		}()
  2952  		return c
  2953  	}
  2954  
  2955  	for i := 0; i < 4; i++ {
  2956  		c := newClient("PONG")
  2957  		defer c.close()
  2958  	}
  2959  
  2960  	// We will simulate that the account has expired. When
  2961  	// a new client will connect, the server will do a lookup
  2962  	// and find the account expired, which then will cause
  2963  	// a fetch and a rebuild of the account. Since max conns
  2964  	// is now lower, some clients should have been removed.
  2965  	acc, _ := s.LookupAccount(fooPub)
  2966  	acc.mu.Lock()
  2967  	acc.expired = true
  2968  	acc.updated = time.Now().UTC().Add(-2 * time.Second) // work around updating to quickly
  2969  	acc.mu.Unlock()
  2970  
  2971  	// Now update with new expiration and max connections lowered to 2
  2972  	fooAC.Limits.Conn = 2
  2973  	fooJWT, err = fooAC.Encode(okp)
  2974  	if err != nil {
  2975  		t.Fatalf("Error generating account JWT: %v", err)
  2976  	}
  2977  	addAccountToMemResolver(s, fooPub, fooJWT)
  2978  
  2979  	// Cause the lookup that will detect that account was expired
  2980  	// and rebuild it, and kick clients out.
  2981  	c := newClient("-ERR ")
  2982  	defer c.close()
  2983  
  2984  	acc, _ = s.LookupAccount(fooPub)
  2985  	checkFor(t, 2*time.Second, 15*time.Millisecond, func() error {
  2986  		acc.mu.RLock()
  2987  		numClients := len(acc.clients)
  2988  		acc.mu.RUnlock()
  2989  		if numClients != 2 {
  2990  			return fmt.Errorf("Should have 2 clients, got %v", numClients)
  2991  		}
  2992  		return nil
  2993  	})
  2994  }
  2995  
  2996  func TestJWTBearerToken(t *testing.T) {
  2997  	okp, _ := nkeys.FromSeed(oSeed)
  2998  	akp, _ := nkeys.CreateAccount()
  2999  	apub, _ := akp.PublicKey()
  3000  	nac := jwt.NewAccountClaims(apub)
  3001  	ajwt, err := nac.Encode(okp)
  3002  	if err != nil {
  3003  		t.Fatalf("Error generating account JWT: %v", err)
  3004  	}
  3005  
  3006  	nkp, _ := nkeys.CreateUser()
  3007  	pub, _ := nkp.PublicKey()
  3008  	nuc := newJWTTestUserClaims()
  3009  	nuc.Subject = pub
  3010  	// Set bearer token.
  3011  	nuc.BearerToken = true
  3012  	jwt, err := nuc.Encode(akp)
  3013  	if err != nil {
  3014  		t.Fatalf("Error generating user JWT: %v", err)
  3015  	}
  3016  
  3017  	s := opTrustBasicSetup()
  3018  	defer s.Shutdown()
  3019  	buildMemAccResolver(s)
  3020  	addAccountToMemResolver(s, apub, ajwt)
  3021  
  3022  	c, cr, _ := newClientForServer(s)
  3023  	defer c.close()
  3024  
  3025  	// Skip nonce signature...
  3026  
  3027  	// PING needed to flush the +OK/-ERR to us.
  3028  	cs := fmt.Sprintf("CONNECT {\"jwt\":%q,\"verbose\":true,\"pedantic\":true}\r\nPING\r\n", jwt)
  3029  	wg := sync.WaitGroup{}
  3030  	wg.Add(1)
  3031  	go func() {
  3032  		c.parse([]byte(cs))
  3033  		wg.Done()
  3034  	}()
  3035  	l, _ := cr.ReadString('\n')
  3036  	if !strings.HasPrefix(l, "+OK") {
  3037  		t.Fatalf("Expected +OK, got %s", l)
  3038  	}
  3039  	wg.Wait()
  3040  }
  3041  
  3042  func TestJWTBearerWithIssuerSameAsAccountToken(t *testing.T) {
  3043  	okp, _ := nkeys.FromSeed(oSeed)
  3044  	akp, _ := nkeys.CreateAccount()
  3045  	apub, _ := akp.PublicKey()
  3046  	nac := jwt.NewAccountClaims(apub)
  3047  	ajwt, err := nac.Encode(okp)
  3048  	if err != nil {
  3049  		t.Fatalf("Error generating account JWT: %v", err)
  3050  	}
  3051  
  3052  	nkp, _ := nkeys.CreateUser()
  3053  	pub, _ := nkp.PublicKey()
  3054  	nuc := newJWTTestUserClaims()
  3055  	// we are setting the issuer account here to trigger verification
  3056  	// of the issuer - the account has no signing keys, but the issuer
  3057  	// account is set to the public key of the account which should be OK.
  3058  	nuc.IssuerAccount = apub
  3059  	nuc.Subject = pub
  3060  	// Set bearer token.
  3061  	nuc.BearerToken = true
  3062  	jwt, err := nuc.Encode(akp)
  3063  	if err != nil {
  3064  		t.Fatalf("Error generating user JWT: %v", err)
  3065  	}
  3066  
  3067  	s := opTrustBasicSetup()
  3068  	defer s.Shutdown()
  3069  	buildMemAccResolver(s)
  3070  	addAccountToMemResolver(s, apub, ajwt)
  3071  
  3072  	c, cr, _ := newClientForServer(s)
  3073  	defer c.close()
  3074  
  3075  	// Skip nonce signature...
  3076  
  3077  	// PING needed to flush the +OK/-ERR to us.
  3078  	cs := fmt.Sprintf("CONNECT {\"jwt\":%q,\"verbose\":true,\"pedantic\":true}\r\nPING\r\n", jwt)
  3079  	wg := sync.WaitGroup{}
  3080  	wg.Add(1)
  3081  	go func() {
  3082  		c.parse([]byte(cs))
  3083  		wg.Done()
  3084  	}()
  3085  	l, _ := cr.ReadString('\n')
  3086  	if !strings.HasPrefix(l, "+OK") {
  3087  		t.Fatalf("Expected +OK, got %s", l)
  3088  	}
  3089  	wg.Wait()
  3090  }
  3091  
  3092  func TestJWTBearerWithBadIssuerToken(t *testing.T) {
  3093  	okp, _ := nkeys.FromSeed(oSeed)
  3094  	akp, _ := nkeys.CreateAccount()
  3095  	apub, _ := akp.PublicKey()
  3096  	nac := jwt.NewAccountClaims(apub)
  3097  	ajwt, err := nac.Encode(okp)
  3098  	if err != nil {
  3099  		t.Fatalf("Error generating account JWT: %v", err)
  3100  	}
  3101  
  3102  	nkp, _ := nkeys.CreateUser()
  3103  	pub, _ := nkp.PublicKey()
  3104  	nuc := newJWTTestUserClaims()
  3105  	bakp, _ := nkeys.CreateAccount()
  3106  	bapub, _ := bakp.PublicKey()
  3107  	nuc.IssuerAccount = bapub
  3108  	nuc.Subject = pub
  3109  	// Set bearer token.
  3110  	nuc.BearerToken = true
  3111  	jwt, err := nuc.Encode(akp)
  3112  	if err != nil {
  3113  		t.Fatalf("Error generating user JWT: %v", err)
  3114  	}
  3115  
  3116  	s := opTrustBasicSetup()
  3117  	defer s.Shutdown()
  3118  	buildMemAccResolver(s)
  3119  	addAccountToMemResolver(s, apub, ajwt)
  3120  
  3121  	c, cr, _ := newClientForServer(s)
  3122  	defer c.close()
  3123  
  3124  	// Skip nonce signature...
  3125  
  3126  	// PING needed to flush the +OK/-ERR to us.
  3127  	cs := fmt.Sprintf("CONNECT {\"jwt\":%q,\"verbose\":true,\"pedantic\":true}\r\nPING\r\n", jwt)
  3128  	wg := sync.WaitGroup{}
  3129  	wg.Add(1)
  3130  	go func() {
  3131  		c.parse([]byte(cs))
  3132  		wg.Done()
  3133  	}()
  3134  	l, _ := cr.ReadString('\n')
  3135  	if !strings.HasPrefix(l, "-ERR") {
  3136  		t.Fatalf("Expected -ERR, got %s", l)
  3137  	}
  3138  	wg.Wait()
  3139  }
  3140  
  3141  func TestJWTExpiredUserCredentialsRenewal(t *testing.T) {
  3142  	createTmpFile := func(t *testing.T, content []byte) string {
  3143  		t.Helper()
  3144  		conf := createTempFile(t, _EMPTY_)
  3145  		fName := conf.Name()
  3146  		conf.Close()
  3147  		if err := os.WriteFile(fName, content, 0666); err != nil {
  3148  			t.Fatalf("Error writing conf file: %v", err)
  3149  		}
  3150  		return fName
  3151  	}
  3152  	waitTime := func(ch chan bool, timeout time.Duration) error {
  3153  		select {
  3154  		case <-ch:
  3155  			return nil
  3156  		case <-time.After(timeout):
  3157  		}
  3158  		return errors.New("timeout")
  3159  	}
  3160  
  3161  	okp, _ := nkeys.FromSeed(oSeed)
  3162  	akp, err := nkeys.CreateAccount()
  3163  	if err != nil {
  3164  		t.Fatalf("Error generating account")
  3165  	}
  3166  	aPub, _ := akp.PublicKey()
  3167  	nac := jwt.NewAccountClaims(aPub)
  3168  	aJwt, err := nac.Encode(okp)
  3169  	if err != nil {
  3170  		t.Fatalf("Error generating account JWT: %v", err)
  3171  	}
  3172  
  3173  	kp, _ := nkeys.FromSeed(oSeed)
  3174  	oPub, _ := kp.PublicKey()
  3175  	opts := defaultServerOptions
  3176  	opts.TrustedKeys = []string{oPub}
  3177  	s := RunServer(&opts)
  3178  	if s == nil {
  3179  		t.Fatal("Server did not start")
  3180  	}
  3181  	defer s.Shutdown()
  3182  	buildMemAccResolver(s)
  3183  	addAccountToMemResolver(s, aPub, aJwt)
  3184  
  3185  	nkp, _ := nkeys.CreateUser()
  3186  	pub, _ := nkp.PublicKey()
  3187  	uSeed, _ := nkp.Seed()
  3188  	nuc := newJWTTestUserClaims()
  3189  	nuc.Subject = pub
  3190  	nuc.Expires = time.Now().Add(time.Second).Unix()
  3191  	uJwt, err := nuc.Encode(akp)
  3192  	if err != nil {
  3193  		t.Fatalf("Error generating user JWT: %v", err)
  3194  	}
  3195  
  3196  	creds, err := jwt.FormatUserConfig(uJwt, uSeed)
  3197  	if err != nil {
  3198  		t.Fatalf("Error encoding credentials: %v", err)
  3199  	}
  3200  	chainedFile := createTmpFile(t, creds)
  3201  
  3202  	rch := make(chan bool)
  3203  
  3204  	url := fmt.Sprintf("nats://%s:%d", s.opts.Host, s.opts.Port)
  3205  	nc, err := nats.Connect(url,
  3206  		nats.UserCredentials(chainedFile),
  3207  		nats.ReconnectWait(25*time.Millisecond),
  3208  		nats.ReconnectJitter(0, 0),
  3209  		nats.MaxReconnects(2),
  3210  		nats.ErrorHandler(noOpErrHandler),
  3211  		nats.ReconnectHandler(func(nc *nats.Conn) {
  3212  			rch <- true
  3213  		}),
  3214  	)
  3215  	if err != nil {
  3216  		t.Fatalf("Expected to connect, got %v %s", err, url)
  3217  	}
  3218  	defer nc.Close()
  3219  
  3220  	// Place new credentials underneath.
  3221  	nuc.Expires = time.Now().Add(30 * time.Second).Unix()
  3222  	uJwt, err = nuc.Encode(akp)
  3223  	if err != nil {
  3224  		t.Fatalf("Error encoding user jwt: %v", err)
  3225  	}
  3226  	creds, err = jwt.FormatUserConfig(uJwt, uSeed)
  3227  	if err != nil {
  3228  		t.Fatalf("Error encoding credentials: %v", err)
  3229  	}
  3230  	if err := os.WriteFile(chainedFile, creds, 0666); err != nil {
  3231  		t.Fatalf("Error writing conf file: %v", err)
  3232  	}
  3233  
  3234  	// Make sure we get disconnected and reconnected first.
  3235  	if err := waitTime(rch, 2*time.Second); err != nil {
  3236  		t.Fatal("Should have reconnected.")
  3237  	}
  3238  
  3239  	// We should not have been closed.
  3240  	if nc.IsClosed() {
  3241  		t.Fatal("Got disconnected when we should have reconnected.")
  3242  	}
  3243  
  3244  	// Check that we clear the lastErr that can cause the disconnect.
  3245  	// Our reconnect CB will happen before the clear. So check after a bit.
  3246  	time.Sleep(50 * time.Millisecond)
  3247  	if nc.LastError() != nil {
  3248  		t.Fatalf("Expected lastErr to be cleared, got %q", nc.LastError())
  3249  	}
  3250  }
  3251  
  3252  func updateJwt(t *testing.T, url string, creds string, jwt string, respCnt int) int {
  3253  	t.Helper()
  3254  	require_NextMsg := func(sub *nats.Subscription) bool {
  3255  		t.Helper()
  3256  		msg := natsNexMsg(t, sub, time.Second)
  3257  		content := make(map[string]interface{})
  3258  		json.Unmarshal(msg.Data, &content)
  3259  		if _, ok := content["data"]; ok {
  3260  			return true
  3261  		}
  3262  		return false
  3263  	}
  3264  	c := natsConnect(t, url, nats.UserCredentials(creds),
  3265  		nats.DisconnectErrHandler(func(_ *nats.Conn, err error) {
  3266  			if err != nil {
  3267  				t.Fatal("error not expected in this test", err)
  3268  			}
  3269  		}),
  3270  		nats.ErrorHandler(func(_ *nats.Conn, _ *nats.Subscription, err error) {
  3271  			t.Fatal("error not expected in this test", err)
  3272  		}),
  3273  	)
  3274  	defer c.Close()
  3275  	resp := c.NewRespInbox()
  3276  	sub := natsSubSync(t, c, resp)
  3277  	err := sub.AutoUnsubscribe(respCnt)
  3278  	require_NoError(t, err)
  3279  	require_NoError(t, c.PublishRequest(accClaimsReqSubj, resp, []byte(jwt)))
  3280  	passCnt := 0
  3281  	for i := 0; i < respCnt; i++ {
  3282  		if require_NextMsg(sub) {
  3283  			passCnt++
  3284  		}
  3285  	}
  3286  	return passCnt
  3287  }
  3288  
  3289  func require_JWTAbsent(t *testing.T, dir string, pub string) {
  3290  	t.Helper()
  3291  	_, err := os.Stat(filepath.Join(dir, pub+".jwt"))
  3292  	require_Error(t, err)
  3293  	require_True(t, os.IsNotExist(err))
  3294  }
  3295  
  3296  func require_JWTPresent(t *testing.T, dir string, pub string) {
  3297  	t.Helper()
  3298  	_, err := os.Stat(filepath.Join(dir, pub+".jwt"))
  3299  	require_NoError(t, err)
  3300  }
  3301  
  3302  func require_JWTEqual(t *testing.T, dir string, pub string, jwt string) {
  3303  	t.Helper()
  3304  	content, err := os.ReadFile(filepath.Join(dir, pub+".jwt"))
  3305  	require_NoError(t, err)
  3306  	require_Equal(t, string(content), jwt)
  3307  }
  3308  
  3309  func createTempFile(t testing.TB, prefix string) *os.File {
  3310  	t.Helper()
  3311  	tempDir := t.TempDir()
  3312  	f, err := os.CreateTemp(tempDir, prefix)
  3313  	require_NoError(t, err)
  3314  	return f
  3315  }
  3316  
  3317  func removeDir(t testing.TB, dir string) {
  3318  	t.Helper()
  3319  	if err := os.RemoveAll(dir); err != nil {
  3320  		t.Fatal(err)
  3321  	}
  3322  }
  3323  
  3324  func removeFile(t testing.TB, p string) {
  3325  	t.Helper()
  3326  	if err := os.Remove(p); err != nil {
  3327  		t.Fatal(err)
  3328  	}
  3329  }
  3330  
  3331  func writeJWT(t *testing.T, dir string, pub string, jwt string) {
  3332  	t.Helper()
  3333  	err := os.WriteFile(filepath.Join(dir, pub+".jwt"), []byte(jwt), 0644)
  3334  	require_NoError(t, err)
  3335  }
  3336  
  3337  func TestJWTAccountNATSResolverFetch(t *testing.T) {
  3338  	origEventsHBInterval := eventsHBInterval
  3339  	eventsHBInterval = 50 * time.Millisecond // speed up eventing
  3340  	defer func() { eventsHBInterval = origEventsHBInterval }()
  3341  	require_NoLocalOrRemoteConnections := func(account string, srvs ...*Server) {
  3342  		t.Helper()
  3343  		for _, srv := range srvs {
  3344  			if acc, ok := srv.accounts.Load(account); ok {
  3345  				checkAccClientsCount(t, acc.(*Account), 0)
  3346  			}
  3347  		}
  3348  	}
  3349  	// After each connection check, require_XConnection and connect assures that
  3350  	// listed server have no connections for the account used
  3351  	require_1Connection := func(url, creds, acc string, srvs ...*Server) {
  3352  		t.Helper()
  3353  		func() {
  3354  			t.Helper()
  3355  			c := natsConnect(t, url, nats.UserCredentials(creds))
  3356  			defer c.Close()
  3357  			if _, err := nats.Connect(url, nats.UserCredentials(creds)); err == nil {
  3358  				t.Fatal("Second connection was supposed to fail due to limits")
  3359  			} else if !strings.Contains(err.Error(), ErrTooManyAccountConnections.Error()) {
  3360  				t.Fatal("Second connection was supposed to fail with too many conns")
  3361  			}
  3362  		}()
  3363  		require_NoLocalOrRemoteConnections(acc, srvs...)
  3364  	}
  3365  	require_2Connection := func(url, creds, acc string, srvs ...*Server) {
  3366  		t.Helper()
  3367  		func() {
  3368  			t.Helper()
  3369  			c1 := natsConnect(t, url, nats.UserCredentials(creds))
  3370  			defer c1.Close()
  3371  			c2 := natsConnect(t, url, nats.UserCredentials(creds))
  3372  			defer c2.Close()
  3373  			if _, err := nats.Connect(url, nats.UserCredentials(creds)); err == nil {
  3374  				t.Fatal("Third connection was supposed to fail due to limits")
  3375  			} else if !strings.Contains(err.Error(), ErrTooManyAccountConnections.Error()) {
  3376  				t.Fatal("Third connection was supposed to fail with too many conns")
  3377  			}
  3378  		}()
  3379  		require_NoLocalOrRemoteConnections(acc, srvs...)
  3380  	}
  3381  	connect := func(url string, credsfile string, acc string, srvs ...*Server) {
  3382  		t.Helper()
  3383  		nc := natsConnect(t, url, nats.UserCredentials(credsfile), nats.Timeout(5*time.Second))
  3384  		nc.Close()
  3385  		require_NoLocalOrRemoteConnections(acc, srvs...)
  3386  	}
  3387  	createAccountAndUser := func(limit bool, done chan struct{}, pubKey, jwt1, jwt2, creds *string) {
  3388  		t.Helper()
  3389  		kp, _ := nkeys.CreateAccount()
  3390  		*pubKey, _ = kp.PublicKey()
  3391  		claim := jwt.NewAccountClaims(*pubKey)
  3392  		if limit {
  3393  			claim.Limits.Conn = 1
  3394  		}
  3395  		var err error
  3396  		*jwt1, err = claim.Encode(oKp)
  3397  		require_NoError(t, err)
  3398  		// need to assure that create time differs (resolution is sec)
  3399  		time.Sleep(time.Millisecond * 1100)
  3400  		// create updated claim allowing more connections
  3401  		if limit {
  3402  			claim.Limits.Conn = 2
  3403  		}
  3404  		*jwt2, err = claim.Encode(oKp)
  3405  		require_NoError(t, err)
  3406  		ukp, _ := nkeys.CreateUser()
  3407  		seed, _ := ukp.Seed()
  3408  		upub, _ := ukp.PublicKey()
  3409  		uclaim := newJWTTestUserClaims()
  3410  		uclaim.Subject = upub
  3411  		ujwt, err := uclaim.Encode(kp)
  3412  		require_NoError(t, err)
  3413  		*creds = genCredsFile(t, ujwt, seed)
  3414  		done <- struct{}{}
  3415  	}
  3416  	// Create Accounts and corresponding user creds. Do so concurrently to speed up the test
  3417  	doneChan := make(chan struct{}, 5)
  3418  	defer close(doneChan)
  3419  	var syspub, sysjwt, dummy1, sysCreds string
  3420  	go createAccountAndUser(false, doneChan, &syspub, &sysjwt, &dummy1, &sysCreds)
  3421  	var apub, ajwt1, ajwt2, aCreds string
  3422  	go createAccountAndUser(true, doneChan, &apub, &ajwt1, &ajwt2, &aCreds)
  3423  	var bpub, bjwt1, bjwt2, bCreds string
  3424  	go createAccountAndUser(true, doneChan, &bpub, &bjwt1, &bjwt2, &bCreds)
  3425  	var cpub, cjwt1, cjwt2, cCreds string
  3426  	go createAccountAndUser(true, doneChan, &cpub, &cjwt1, &cjwt2, &cCreds)
  3427  	var dpub, djwt1, dummy2, dCreds string // extra user used later in the test in order to test limits
  3428  	go createAccountAndUser(true, doneChan, &dpub, &djwt1, &dummy2, &dCreds)
  3429  	for i := 0; i < cap(doneChan); i++ {
  3430  		<-doneChan
  3431  	}
  3432  	// Create one directory for each server
  3433  	dirA := t.TempDir()
  3434  	dirB := t.TempDir()
  3435  	dirC := t.TempDir()
  3436  	// simulate a restart of the server by storing files in them
  3437  	// Server A/B will completely sync, so after startup each server
  3438  	// will contain the union off all stored/configured jwt
  3439  	// Server C will send out lookup requests for jwt it does not store itself
  3440  	writeJWT(t, dirA, apub, ajwt1)
  3441  	writeJWT(t, dirB, bpub, bjwt1)
  3442  	writeJWT(t, dirC, cpub, cjwt1)
  3443  	// Create seed server A (using no_advertise to prevent fail over)
  3444  	confA := createConfFile(t, []byte(fmt.Sprintf(`
  3445  		listen: 127.0.0.1:-1
  3446  		server_name: srv-A
  3447  		operator: %s
  3448  		system_account: %s
  3449  		resolver: {
  3450  			type: full
  3451  			dir: '%s'
  3452  			interval: "200ms"
  3453  			limit: 4
  3454  		}
  3455  		resolver_preload: {
  3456  			%s: %s
  3457  		}
  3458  		cluster {
  3459  			name: clust
  3460  			listen: 127.0.0.1:-1
  3461  			no_advertise: true
  3462  		}
  3463      `, ojwt, syspub, dirA, cpub, cjwt1)))
  3464  	sA, _ := RunServerWithConfig(confA)
  3465  	defer sA.Shutdown()
  3466  	// during startup resolver_preload causes the directory to contain data
  3467  	require_JWTPresent(t, dirA, cpub)
  3468  	// Create Server B (using no_advertise to prevent fail over)
  3469  	confB := createConfFile(t, []byte(fmt.Sprintf(`
  3470  		listen: 127.0.0.1:-1
  3471  		server_name: srv-B
  3472  		operator: %s
  3473  		system_account: %s
  3474  		resolver: {
  3475  			type: full
  3476  
  3477  			dir: '%s'
  3478  			interval: "200ms"
  3479  			limit: 4
  3480  		}
  3481  		cluster {
  3482  			name: clust
  3483  			listen: 127.0.0.1:-1
  3484  			no_advertise: true
  3485  			routes [
  3486  				nats-route://127.0.0.1:%d
  3487  			]
  3488  		}
  3489      `, ojwt, syspub, dirB, sA.opts.Cluster.Port)))
  3490  	sB, _ := RunServerWithConfig(confB)
  3491  	defer sB.Shutdown()
  3492  	// Create Server C (using no_advertise to prevent fail over)
  3493  	fmtC := `
  3494  		listen: 127.0.0.1:-1
  3495  		server_name: srv-C
  3496  		operator: %s
  3497  		system_account: %s
  3498  		resolver: {
  3499  			type: cache
  3500  			dir: '%s'
  3501  			ttl: "%dms"
  3502  			limit: 4
  3503  		}
  3504  		cluster {
  3505  			name: clust
  3506  			listen: 127.0.0.1:-1
  3507  			no_advertise: true
  3508  			routes [
  3509  				nats-route://127.0.0.1:%d
  3510  			]
  3511  		}
  3512      `
  3513  	confClongTTL := createConfFile(t, []byte(fmt.Sprintf(fmtC, ojwt, syspub, dirC, 10000, sA.opts.Cluster.Port)))
  3514  	confCshortTTL := createConfFile(t, []byte(fmt.Sprintf(fmtC, ojwt, syspub, dirC, 1000, sA.opts.Cluster.Port)))
  3515  	sC, _ := RunServerWithConfig(confClongTTL) // use long ttl to assure it is not kicking
  3516  	defer sC.Shutdown()
  3517  	// startup cluster
  3518  	checkClusterFormed(t, sA, sB, sC)
  3519  	time.Sleep(500 * time.Millisecond) // wait for the protocol to converge
  3520  	// Check all accounts
  3521  	require_JWTPresent(t, dirA, apub) // was already present on startup
  3522  	require_JWTPresent(t, dirB, apub) // was copied from server A
  3523  	require_JWTAbsent(t, dirC, apub)
  3524  	require_JWTPresent(t, dirA, bpub) // was copied from server B
  3525  	require_JWTPresent(t, dirB, bpub) // was already present on startup
  3526  	require_JWTAbsent(t, dirC, bpub)
  3527  	require_JWTPresent(t, dirA, cpub) // was present in preload
  3528  	require_JWTPresent(t, dirB, cpub) // was copied from server A
  3529  	require_JWTPresent(t, dirC, cpub) // was already present on startup
  3530  	// This is to test that connecting to it still works
  3531  	require_JWTAbsent(t, dirA, syspub)
  3532  	require_JWTAbsent(t, dirB, syspub)
  3533  	require_JWTAbsent(t, dirC, syspub)
  3534  	// system account client can connect to every server
  3535  	connect(sA.ClientURL(), sysCreds, "")
  3536  	connect(sB.ClientURL(), sysCreds, "")
  3537  	connect(sC.ClientURL(), sysCreds, "")
  3538  	checkClusterFormed(t, sA, sB, sC)
  3539  	// upload system account and require a response from each server
  3540  	passCnt := updateJwt(t, sA.ClientURL(), sysCreds, sysjwt, 3)
  3541  	require_True(t, passCnt == 3)
  3542  	require_JWTPresent(t, dirA, syspub) // was just received
  3543  	require_JWTPresent(t, dirB, syspub) // was just received
  3544  	require_JWTPresent(t, dirC, syspub) // was just received
  3545  	// Only files missing are in C, which is only caching
  3546  	connect(sC.ClientURL(), aCreds, apub, sA, sB, sC)
  3547  	connect(sC.ClientURL(), bCreds, bpub, sA, sB, sC)
  3548  	require_JWTPresent(t, dirC, apub) // was looked up form A or B
  3549  	require_JWTPresent(t, dirC, bpub) // was looked up from A or B
  3550  	// Check limits and update jwt B connecting to server A
  3551  	for port, v := range map[string]struct{ pub, jwt, creds string }{
  3552  		sB.ClientURL(): {bpub, bjwt2, bCreds},
  3553  		sC.ClientURL(): {cpub, cjwt2, cCreds},
  3554  	} {
  3555  		require_1Connection(sA.ClientURL(), v.creds, v.pub, sA, sB, sC)
  3556  		require_1Connection(sB.ClientURL(), v.creds, v.pub, sA, sB, sC)
  3557  		require_1Connection(sC.ClientURL(), v.creds, v.pub, sA, sB, sC)
  3558  		passCnt := updateJwt(t, port, sysCreds, v.jwt, 3)
  3559  		require_True(t, passCnt == 3)
  3560  		require_2Connection(sA.ClientURL(), v.creds, v.pub, sA, sB, sC)
  3561  		require_2Connection(sB.ClientURL(), v.creds, v.pub, sA, sB, sC)
  3562  		require_2Connection(sC.ClientURL(), v.creds, v.pub, sA, sB, sC)
  3563  		require_JWTEqual(t, dirA, v.pub, v.jwt)
  3564  		require_JWTEqual(t, dirB, v.pub, v.jwt)
  3565  		require_JWTEqual(t, dirC, v.pub, v.jwt)
  3566  	}
  3567  	// Simulates A having missed an update
  3568  	// shutting B down as it has it will directly connect to A and connect right away
  3569  	sB.Shutdown()
  3570  	writeJWT(t, dirB, apub, ajwt2) // this will be copied to server A
  3571  	sB, _ = RunServerWithConfig(confB)
  3572  	defer sB.Shutdown()
  3573  	checkClusterFormed(t, sA, sB, sC)
  3574  	time.Sleep(500 * time.Millisecond) // wait for the protocol to converge
  3575  	// Restart server C. this is a workaround to force C to do a lookup in the absence of account cleanup
  3576  	sC.Shutdown()
  3577  	sC, _ = RunServerWithConfig(confClongTTL) //TODO remove this once we clean up accounts
  3578  	defer sC.Shutdown()
  3579  	require_JWTEqual(t, dirA, apub, ajwt2) // was copied from server B
  3580  	require_JWTEqual(t, dirB, apub, ajwt2) // was restarted with this
  3581  	require_JWTEqual(t, dirC, apub, ajwt1) // still contains old cached value
  3582  	require_2Connection(sA.ClientURL(), aCreds, apub, sA, sB, sC)
  3583  	require_2Connection(sB.ClientURL(), aCreds, apub, sA, sB, sC)
  3584  	require_1Connection(sC.ClientURL(), aCreds, apub, sA, sB, sC)
  3585  	// Restart server C. this is a workaround to force C to do a lookup in the absence of account cleanup
  3586  	sC.Shutdown()
  3587  	sC, _ = RunServerWithConfig(confCshortTTL) //TODO remove this once we clean up accounts
  3588  	defer sC.Shutdown()
  3589  	require_JWTEqual(t, dirC, apub, ajwt1) // still contains old cached value
  3590  	checkClusterFormed(t, sA, sB, sC)
  3591  	// Force next connect to do a lookup exceeds ttl
  3592  	fname := filepath.Join(dirC, apub+".jwt")
  3593  	checkFor(t, 2*time.Second, 100*time.Millisecond, func() error {
  3594  		_, err := os.Stat(fname)
  3595  		if os.IsNotExist(err) {
  3596  			return nil
  3597  		}
  3598  		return fmt.Errorf("File not removed in time")
  3599  	})
  3600  	connect(sC.ClientURL(), aCreds, apub, sA, sB, sC) // When lookup happens
  3601  	require_JWTEqual(t, dirC, apub, ajwt2)            // was looked up form A or B
  3602  	require_2Connection(sC.ClientURL(), aCreds, apub, sA, sB, sC)
  3603  	// Test exceeding limit. For the exclusive directory resolver, limit is a stop gap measure.
  3604  	// It is not expected to be hit. When hit the administrator is supposed to take action.
  3605  	passCnt = updateJwt(t, sA.ClientURL(), sysCreds, djwt1, 3)
  3606  	require_True(t, passCnt == 1) // Only Server C updated
  3607  	for _, srv := range []*Server{sA, sB, sC} {
  3608  		if a, ok := srv.accounts.Load(syspub); ok {
  3609  			acc := a.(*Account)
  3610  			checkFor(t, time.Second, 20*time.Millisecond, func() error {
  3611  				acc.mu.Lock()
  3612  				defer acc.mu.Unlock()
  3613  				if acc.ctmr != nil {
  3614  					return fmt.Errorf("Timer still exists")
  3615  				}
  3616  				return nil
  3617  			})
  3618  		}
  3619  	}
  3620  }
  3621  
  3622  func TestJWTAccountNATSResolverCrossClusterFetch(t *testing.T) {
  3623  	connect := func(url string, credsfile string) {
  3624  		t.Helper()
  3625  		nc := natsConnect(t, url, nats.UserCredentials(credsfile))
  3626  		nc.Close()
  3627  	}
  3628  	createAccountAndUser := func(done chan struct{}, pubKey, jwt1, jwt2, creds *string) {
  3629  		t.Helper()
  3630  		kp, _ := nkeys.CreateAccount()
  3631  		*pubKey, _ = kp.PublicKey()
  3632  		claim := jwt.NewAccountClaims(*pubKey)
  3633  		var err error
  3634  		*jwt1, err = claim.Encode(oKp)
  3635  		require_NoError(t, err)
  3636  		// need to assure that create time differs (resolution is sec)
  3637  		time.Sleep(time.Millisecond * 1100)
  3638  		// create updated claim
  3639  		claim.Tags.Add("tag")
  3640  		*jwt2, err = claim.Encode(oKp)
  3641  		require_NoError(t, err)
  3642  		ukp, _ := nkeys.CreateUser()
  3643  		seed, _ := ukp.Seed()
  3644  		upub, _ := ukp.PublicKey()
  3645  		uclaim := newJWTTestUserClaims()
  3646  		uclaim.Subject = upub
  3647  		ujwt, err := uclaim.Encode(kp)
  3648  		require_NoError(t, err)
  3649  		*creds = genCredsFile(t, ujwt, seed)
  3650  		done <- struct{}{}
  3651  	}
  3652  	// Create Accounts and corresponding user creds. Do so concurrently to speed up the test
  3653  	doneChan := make(chan struct{}, 3)
  3654  	defer close(doneChan)
  3655  	var syspub, sysjwt, dummy1, sysCreds string
  3656  	go createAccountAndUser(doneChan, &syspub, &sysjwt, &dummy1, &sysCreds)
  3657  	var apub, ajwt1, ajwt2, aCreds string
  3658  	go createAccountAndUser(doneChan, &apub, &ajwt1, &ajwt2, &aCreds)
  3659  	var bpub, bjwt1, bjwt2, bCreds string
  3660  	go createAccountAndUser(doneChan, &bpub, &bjwt1, &bjwt2, &bCreds)
  3661  	for i := 0; i < cap(doneChan); i++ {
  3662  		<-doneChan
  3663  	}
  3664  	// Create one directory for each server
  3665  	dirAA := t.TempDir()
  3666  	dirAB := t.TempDir()
  3667  	dirBA := t.TempDir()
  3668  	dirBB := t.TempDir()
  3669  	// simulate a restart of the server by storing files in them
  3670  	// Server AA & AB will completely sync
  3671  	// Server BA & BB will completely sync
  3672  	// Be aware that no syncing will occur between cluster
  3673  	writeJWT(t, dirAA, apub, ajwt1)
  3674  	writeJWT(t, dirBA, bpub, bjwt1)
  3675  	// Create seed server A (using no_advertise to prevent fail over)
  3676  	confAA := createConfFile(t, []byte(fmt.Sprintf(`
  3677  		listen: 127.0.0.1:-1
  3678  		server_name: srv-A-A
  3679  		operator: %s
  3680  		system_account: %s
  3681  		resolver: {
  3682  			type: full
  3683  			dir: '%s'
  3684  			interval: "200ms"
  3685  		}
  3686  		gateway: {
  3687  			name: "clust-A"
  3688  			listen: 127.0.0.1:-1
  3689  		}
  3690  		cluster {
  3691  			name: clust-A
  3692  			listen: 127.0.0.1:-1
  3693  			no_advertise: true
  3694  		}
  3695         `, ojwt, syspub, dirAA)))
  3696  	sAA, _ := RunServerWithConfig(confAA)
  3697  	defer sAA.Shutdown()
  3698  	// Create Server B (using no_advertise to prevent fail over)
  3699  	confAB := createConfFile(t, []byte(fmt.Sprintf(`
  3700  		listen: 127.0.0.1:-1
  3701  		server_name: srv-A-B
  3702  		operator: %s
  3703  		system_account: %s
  3704  		resolver: {
  3705  			type: full
  3706  			dir: '%s'
  3707  			interval: "200ms"
  3708  		}
  3709  		gateway: {
  3710  			name: "clust-A"
  3711  			listen: 127.0.0.1:-1
  3712  		}
  3713  		cluster {
  3714  			name: clust-A
  3715  			listen: 127.0.0.1:-1
  3716  			no_advertise: true
  3717  			routes [
  3718  				nats-route://127.0.0.1:%d
  3719  			]
  3720  		}
  3721         `, ojwt, syspub, dirAB, sAA.opts.Cluster.Port)))
  3722  	sAB, _ := RunServerWithConfig(confAB)
  3723  	defer sAB.Shutdown()
  3724  	// Create Server C (using no_advertise to prevent fail over)
  3725  	confBA := createConfFile(t, []byte(fmt.Sprintf(`
  3726  		listen: 127.0.0.1:-1
  3727  		server_name: srv-B-A
  3728  		operator: %s
  3729  		system_account: %s
  3730  		resolver: {
  3731  			type: full
  3732  			dir: '%s'
  3733  			interval: "200ms"
  3734  		}
  3735  		gateway: {
  3736  			name: "clust-B"
  3737  			listen: 127.0.0.1:-1
  3738  			gateways: [
  3739  				{name: "clust-A", url: "nats://127.0.0.1:%d"},
  3740  			]
  3741  		}
  3742  		cluster {
  3743  			name: clust-B
  3744  			listen: 127.0.0.1:-1
  3745  			no_advertise: true
  3746  		}
  3747         `, ojwt, syspub, dirBA, sAA.opts.Gateway.Port)))
  3748  	sBA, _ := RunServerWithConfig(confBA)
  3749  	defer sBA.Shutdown()
  3750  	// Create Server BA (using no_advertise to prevent fail over)
  3751  	confBB := createConfFile(t, []byte(fmt.Sprintf(`
  3752  		listen: 127.0.0.1:-1
  3753  		server_name: srv-B-B
  3754  		operator: %s
  3755  		system_account: %s
  3756  		resolver: {
  3757  			type: full
  3758  			dir: '%s'
  3759  			interval: "200ms"
  3760  		}
  3761  		cluster {
  3762  			name: clust-B
  3763  			listen: 127.0.0.1:-1
  3764  			no_advertise: true
  3765  			routes [
  3766  				nats-route://127.0.0.1:%d
  3767  			]
  3768  		}
  3769  		gateway: {
  3770  			name: "clust-B"
  3771  			listen: 127.0.0.1:-1
  3772  			gateways: [
  3773  				{name: "clust-A", url: "nats://127.0.0.1:%d"},
  3774  			]
  3775  		}
  3776         `, ojwt, syspub, dirBB, sBA.opts.Cluster.Port, sAA.opts.Cluster.Port)))
  3777  	sBB, _ := RunServerWithConfig(confBB)
  3778  	defer sBB.Shutdown()
  3779  	// Assert topology
  3780  	checkClusterFormed(t, sAA, sAB)
  3781  	checkClusterFormed(t, sBA, sBB)
  3782  	waitForOutboundGateways(t, sAA, 1, 5*time.Second)
  3783  	waitForOutboundGateways(t, sAB, 1, 5*time.Second)
  3784  	waitForOutboundGateways(t, sBA, 1, 5*time.Second)
  3785  	waitForOutboundGateways(t, sBB, 1, 5*time.Second)
  3786  	time.Sleep(500 * time.Millisecond)                 // wait for the protocol to converge
  3787  	updateJwt(t, sAA.ClientURL(), sysCreds, sysjwt, 4) // update system account jwt on all server
  3788  	require_JWTEqual(t, dirAA, syspub, sysjwt)         // assure this update made it to every server
  3789  	require_JWTEqual(t, dirAB, syspub, sysjwt)         // assure this update made it to every server
  3790  	require_JWTEqual(t, dirBA, syspub, sysjwt)         // assure this update made it to every server
  3791  	require_JWTEqual(t, dirBB, syspub, sysjwt)         // assure this update made it to every server
  3792  	require_JWTAbsent(t, dirAA, bpub)                  // assure that jwt are not synced across cluster
  3793  	require_JWTAbsent(t, dirAB, bpub)                  // assure that jwt are not synced across cluster
  3794  	require_JWTAbsent(t, dirBA, apub)                  // assure that jwt are not synced across cluster
  3795  	require_JWTAbsent(t, dirBB, apub)                  // assure that jwt are not synced across cluster
  3796  	connect(sAA.ClientURL(), aCreds)                   // connect to cluster where jwt was initially stored
  3797  	connect(sAB.ClientURL(), aCreds)                   // connect to cluster where jwt was initially stored
  3798  	connect(sBA.ClientURL(), bCreds)                   // connect to cluster where jwt was initially stored
  3799  	connect(sBB.ClientURL(), bCreds)                   // connect to cluster where jwt was initially stored
  3800  	time.Sleep(500 * time.Millisecond)                 // wait for the protocol to (NOT) converge
  3801  	require_JWTAbsent(t, dirAA, bpub)                  // assure that jwt are still not synced across cluster
  3802  	require_JWTAbsent(t, dirAB, bpub)                  // assure that jwt are still not synced across cluster
  3803  	require_JWTAbsent(t, dirBA, apub)                  // assure that jwt are still not synced across cluster
  3804  	require_JWTAbsent(t, dirBB, apub)                  // assure that jwt are still not synced across cluster
  3805  	// We have verified that account B does not exist in cluster A, neither does account A in cluster B
  3806  	// Despite that clients from account B can connect to server A, same for account A in cluster B
  3807  	connect(sAA.ClientURL(), bCreds)                  // connect to cluster where jwt was not initially stored
  3808  	connect(sAB.ClientURL(), bCreds)                  // connect to cluster where jwt was not initially stored
  3809  	connect(sBA.ClientURL(), aCreds)                  // connect to cluster where jwt was not initially stored
  3810  	connect(sBB.ClientURL(), aCreds)                  // connect to cluster where jwt was not initially stored
  3811  	require_JWTEqual(t, dirAA, bpub, bjwt1)           // assure that now jwt used in connect is stored
  3812  	require_JWTEqual(t, dirAB, bpub, bjwt1)           // assure that now jwt used in connect is stored
  3813  	require_JWTEqual(t, dirBA, apub, ajwt1)           // assure that now jwt used in connect is stored
  3814  	require_JWTEqual(t, dirBB, apub, ajwt1)           // assure that now jwt used in connect is stored
  3815  	updateJwt(t, sAA.ClientURL(), sysCreds, bjwt2, 4) // update bjwt, expect updates from everywhere
  3816  	updateJwt(t, sBA.ClientURL(), sysCreds, ajwt2, 4) // update ajwt, expect updates from everywhere
  3817  	require_JWTEqual(t, dirAA, bpub, bjwt2)           // assure that jwt got updated accordingly
  3818  	require_JWTEqual(t, dirAB, bpub, bjwt2)           // assure that jwt got updated accordingly
  3819  	require_JWTEqual(t, dirBA, apub, ajwt2)           // assure that jwt got updated accordingly
  3820  	require_JWTEqual(t, dirBB, apub, ajwt2)           // assure that jwt got updated accordingly
  3821  }
  3822  
  3823  func newTimeRange(start time.Time, dur time.Duration) jwt.TimeRange {
  3824  	return jwt.TimeRange{Start: start.Format("15:04:05"), End: start.Add(dur).Format("15:04:05")}
  3825  }
  3826  
  3827  func createUserWithLimit(t *testing.T, accKp nkeys.KeyPair, expiration time.Time, limits func(*jwt.UserPermissionLimits)) string {
  3828  	t.Helper()
  3829  	ukp, _ := nkeys.CreateUser()
  3830  	seed, _ := ukp.Seed()
  3831  	upub, _ := ukp.PublicKey()
  3832  	uclaim := newJWTTestUserClaims()
  3833  	uclaim.Subject = upub
  3834  	if limits != nil {
  3835  		limits(&uclaim.UserPermissionLimits)
  3836  	}
  3837  	if !expiration.IsZero() {
  3838  		uclaim.Expires = expiration.Unix()
  3839  	}
  3840  	vr := jwt.ValidationResults{}
  3841  	uclaim.Validate(&vr)
  3842  	require_Len(t, len(vr.Errors()), 0)
  3843  	ujwt, err := uclaim.Encode(accKp)
  3844  	require_NoError(t, err)
  3845  	return genCredsFile(t, ujwt, seed)
  3846  }
  3847  
  3848  func TestJWTUserLimits(t *testing.T) {
  3849  	// helper for time
  3850  	inAnHour := time.Now().Add(time.Hour)
  3851  	inTwoHours := time.Now().Add(2 * time.Hour)
  3852  	doNotExpire := time.Now().AddDate(1, 0, 0)
  3853  	// create account
  3854  	kp, _ := nkeys.CreateAccount()
  3855  	aPub, _ := kp.PublicKey()
  3856  	claim := jwt.NewAccountClaims(aPub)
  3857  	aJwt, err := claim.Encode(oKp)
  3858  	require_NoError(t, err)
  3859  	conf := createConfFile(t, []byte(fmt.Sprintf(`
  3860  		listen: 127.0.0.1:-1
  3861  		operator: %s
  3862  		resolver: MEM
  3863  		resolver_preload: {
  3864  			%s: %s
  3865  		}
  3866      `, ojwt, aPub, aJwt)))
  3867  	sA, _ := RunServerWithConfig(conf)
  3868  	defer sA.Shutdown()
  3869  	for _, v := range []struct {
  3870  		pass bool
  3871  		f    func(*jwt.UserPermissionLimits)
  3872  	}{
  3873  		{true, nil},
  3874  		{false, func(j *jwt.UserPermissionLimits) { j.Src.Set("8.8.8.8/8") }},
  3875  		{true, func(j *jwt.UserPermissionLimits) { j.Src.Set("8.8.8.8/0") }},
  3876  		{true, func(j *jwt.UserPermissionLimits) { j.Src.Set("127.0.0.1/8") }},
  3877  		{true, func(j *jwt.UserPermissionLimits) { j.Src.Set("8.8.8.8/8,127.0.0.1/8") }},
  3878  		{false, func(j *jwt.UserPermissionLimits) { j.Src.Set("8.8.8.8/8,9.9.9.9/8") }},
  3879  		{true, func(j *jwt.UserPermissionLimits) { j.Times = append(j.Times, newTimeRange(time.Now(), time.Hour)) }},
  3880  		{false, func(j *jwt.UserPermissionLimits) {
  3881  			j.Times = append(j.Times, newTimeRange(time.Now().Add(time.Hour), time.Hour))
  3882  		}},
  3883  		{true, func(j *jwt.UserPermissionLimits) {
  3884  			j.Times = append(j.Times, newTimeRange(inAnHour, time.Hour), newTimeRange(time.Now(), time.Hour))
  3885  		}}, // last one is within range
  3886  		{false, func(j *jwt.UserPermissionLimits) {
  3887  			j.Times = append(j.Times, newTimeRange(inAnHour, time.Hour), newTimeRange(inTwoHours, time.Hour))
  3888  		}}, // out of range
  3889  		{false, func(j *jwt.UserPermissionLimits) {
  3890  			j.Times = append(j.Times, newTimeRange(inAnHour, 3*time.Hour), newTimeRange(inTwoHours, 2*time.Hour))
  3891  		}}, // overlapping [a[]b] out of range*/
  3892  		{false, func(j *jwt.UserPermissionLimits) {
  3893  			j.Times = append(j.Times, newTimeRange(inAnHour, 3*time.Hour), newTimeRange(inTwoHours, time.Hour))
  3894  		}}, // overlapping [a[b]] out of range
  3895  		// next day tests where end < begin
  3896  		{true, func(j *jwt.UserPermissionLimits) { j.Times = append(j.Times, newTimeRange(time.Now(), 25*time.Hour)) }},
  3897  		{true, func(j *jwt.UserPermissionLimits) { j.Times = append(j.Times, newTimeRange(time.Now(), -time.Hour)) }},
  3898  	} {
  3899  		t.Run("", func(t *testing.T) {
  3900  			creds := createUserWithLimit(t, kp, doNotExpire, v.f)
  3901  			if c, err := nats.Connect(sA.ClientURL(), nats.UserCredentials(creds)); err == nil {
  3902  				c.Close()
  3903  				if !v.pass {
  3904  					t.Fatalf("Expected failure got none")
  3905  				}
  3906  			} else if v.pass {
  3907  				t.Fatalf("Expected success got %v", err)
  3908  			} else if !strings.Contains(err.Error(), "Authorization Violation") {
  3909  				t.Fatalf("Expected error other than %v", err)
  3910  			}
  3911  		})
  3912  	}
  3913  }
  3914  
  3915  func TestJWTTimeExpiration(t *testing.T) {
  3916  	validFor := 1500 * time.Millisecond
  3917  	validRange := 500 * time.Millisecond
  3918  	doNotExpire := time.Now().AddDate(1, 0, 0)
  3919  	// create account
  3920  	kp, _ := nkeys.CreateAccount()
  3921  	aPub, _ := kp.PublicKey()
  3922  	claim := jwt.NewAccountClaims(aPub)
  3923  	aJwt, err := claim.Encode(oKp)
  3924  	require_NoError(t, err)
  3925  	conf := createConfFile(t, []byte(fmt.Sprintf(`
  3926  		listen: 127.0.0.1:-1
  3927  		operator: %s
  3928  		resolver: MEM
  3929  		resolver_preload: {
  3930  			%s: %s
  3931  		}
  3932      `, ojwt, aPub, aJwt)))
  3933  	sA, _ := RunServerWithConfig(conf)
  3934  	defer sA.Shutdown()
  3935  	for _, l := range []string{"", "Europe/Berlin", "America/New_York"} {
  3936  		t.Run("simple expiration "+l, func(t *testing.T) {
  3937  			start := time.Now()
  3938  			creds := createUserWithLimit(t, kp, doNotExpire, func(j *jwt.UserPermissionLimits) {
  3939  				if l == _EMPTY_ {
  3940  					j.Times = []jwt.TimeRange{newTimeRange(start, validFor)}
  3941  				} else {
  3942  					loc, err := time.LoadLocation(l)
  3943  					require_NoError(t, err)
  3944  					j.Times = []jwt.TimeRange{newTimeRange(start.In(loc), validFor)}
  3945  					j.Locale = l
  3946  				}
  3947  			})
  3948  			disconnectChan := make(chan struct{})
  3949  			defer close(disconnectChan)
  3950  			errChan := make(chan struct{})
  3951  			defer close(errChan)
  3952  			c := natsConnect(t, sA.ClientURL(),
  3953  				nats.UserCredentials(creds),
  3954  				nats.DisconnectErrHandler(func(conn *nats.Conn, err error) {
  3955  					if err != io.EOF {
  3956  						return
  3957  					}
  3958  					disconnectChan <- struct{}{}
  3959  				}),
  3960  				nats.ErrorHandler(func(conn *nats.Conn, s *nats.Subscription, err error) {
  3961  					if err != nats.ErrAuthExpired {
  3962  						return
  3963  					}
  3964  					now := time.Now()
  3965  					stop := start.Add(validFor)
  3966  					// assure event happens within a second of stop
  3967  					if stop.Add(-validRange).Before(stop) && now.Before(stop.Add(validRange)) {
  3968  						errChan <- struct{}{}
  3969  					}
  3970  				}))
  3971  			defer c.Close()
  3972  			chanRecv(t, errChan, 10*time.Second)
  3973  			chanRecv(t, disconnectChan, 10*time.Second)
  3974  			require_True(t, c.IsReconnecting())
  3975  			require_False(t, c.IsConnected())
  3976  		})
  3977  	}
  3978  	t.Run("double expiration", func(t *testing.T) {
  3979  		start1 := time.Now()
  3980  		start2 := start1.Add(2 * validFor)
  3981  		creds := createUserWithLimit(t, kp, doNotExpire, func(j *jwt.UserPermissionLimits) {
  3982  			j.Times = []jwt.TimeRange{newTimeRange(start1, validFor), newTimeRange(start2, validFor)}
  3983  		})
  3984  		errChan := make(chan struct{})
  3985  		defer close(errChan)
  3986  		reConnectChan := make(chan struct{})
  3987  		defer close(reConnectChan)
  3988  		c := natsConnect(t, sA.ClientURL(),
  3989  			nats.UserCredentials(creds),
  3990  			nats.ReconnectHandler(func(conn *nats.Conn) {
  3991  				reConnectChan <- struct{}{}
  3992  			}),
  3993  			nats.ErrorHandler(func(conn *nats.Conn, s *nats.Subscription, err error) {
  3994  				if err != nats.ErrAuthExpired {
  3995  					return
  3996  				}
  3997  				now := time.Now()
  3998  				stop := start1.Add(validFor)
  3999  				// assure event happens within a second of stop
  4000  				if stop.Add(-validRange).Before(stop) && now.Before(stop.Add(validRange)) {
  4001  					errChan <- struct{}{}
  4002  					return
  4003  				}
  4004  				stop = start2.Add(validFor)
  4005  				// assure event happens within a second of stop
  4006  				if stop.Add(-validRange).Before(stop) && now.Before(stop.Add(validRange)) {
  4007  					errChan <- struct{}{}
  4008  				}
  4009  			}))
  4010  		defer c.Close()
  4011  		chanRecv(t, errChan, 10*time.Second)
  4012  		chanRecv(t, reConnectChan, 10*time.Second)
  4013  		require_False(t, c.IsReconnecting())
  4014  		require_True(t, c.IsConnected())
  4015  		chanRecv(t, errChan, 10*time.Second)
  4016  	})
  4017  	t.Run("lower jwt expiration overwrites time", func(t *testing.T) {
  4018  		start := time.Now()
  4019  		creds := createUserWithLimit(t, kp, start.Add(validFor), func(j *jwt.UserPermissionLimits) { j.Times = []jwt.TimeRange{newTimeRange(start, 2*validFor)} })
  4020  		disconnectChan := make(chan struct{})
  4021  		defer close(disconnectChan)
  4022  		errChan := make(chan struct{})
  4023  		defer close(errChan)
  4024  		c := natsConnect(t, sA.ClientURL(),
  4025  			nats.UserCredentials(creds),
  4026  			nats.DisconnectErrHandler(func(conn *nats.Conn, err error) {
  4027  				if err != io.EOF {
  4028  					return
  4029  				}
  4030  				disconnectChan <- struct{}{}
  4031  			}),
  4032  			nats.ErrorHandler(func(conn *nats.Conn, s *nats.Subscription, err error) {
  4033  				if err != nats.ErrAuthExpired {
  4034  					return
  4035  				}
  4036  				now := time.Now()
  4037  				stop := start.Add(validFor)
  4038  				// assure event happens within a second of stop
  4039  				if stop.Add(-validRange).Before(stop) && now.Before(stop.Add(validRange)) {
  4040  					errChan <- struct{}{}
  4041  				}
  4042  			}))
  4043  		defer c.Close()
  4044  		chanRecv(t, errChan, 10*time.Second)
  4045  		chanRecv(t, disconnectChan, 10*time.Second)
  4046  		require_True(t, c.IsReconnecting())
  4047  		require_False(t, c.IsConnected())
  4048  	})
  4049  }
  4050  
  4051  func NewJwtAccountClaim(name string) (nkeys.KeyPair, string, *jwt.AccountClaims) {
  4052  	sysKp, _ := nkeys.CreateAccount()
  4053  	sysPub, _ := sysKp.PublicKey()
  4054  	claim := jwt.NewAccountClaims(sysPub)
  4055  	claim.Name = name
  4056  	return sysKp, sysPub, claim
  4057  }
  4058  
  4059  func TestJWTSysImportForDifferentAccount(t *testing.T) {
  4060  	_, sysPub, sysClaim := NewJwtAccountClaim("SYS")
  4061  	sysClaim.Exports.Add(&jwt.Export{
  4062  		Type:    jwt.Service,
  4063  		Subject: "$SYS.REQ.ACCOUNT.*.INFO",
  4064  	})
  4065  	sysJwt, err := sysClaim.Encode(oKp)
  4066  	require_NoError(t, err)
  4067  
  4068  	// create account
  4069  	aKp, aPub, claim := NewJwtAccountClaim("A")
  4070  	claim.Imports.Add(&jwt.Import{
  4071  		Type:         jwt.Service,
  4072  		Subject:      "$SYS.REQ.ACCOUNT.*.INFO",
  4073  		LocalSubject: "COMMON.ADVISORY.SYS.REQ.ACCOUNT.*.INFO",
  4074  		Account:      sysPub,
  4075  	})
  4076  	aJwt, err := claim.Encode(oKp)
  4077  	require_NoError(t, err)
  4078  
  4079  	conf := createConfFile(t, []byte(fmt.Sprintf(`
  4080  		listen: 127.0.0.1:-1
  4081  		operator: %s
  4082  		system_account: %s
  4083  		resolver: MEM
  4084  		resolver_preload: {
  4085  			%s: %s
  4086  			%s: %s
  4087  		}
  4088      `, ojwt, sysPub, sysPub, sysJwt, aPub, aJwt)))
  4089  	sA, _ := RunServerWithConfig(conf)
  4090  	defer sA.Shutdown()
  4091  
  4092  	nc := natsConnect(t, sA.ClientURL(), createUserCreds(t, nil, aKp))
  4093  	defer nc.Close()
  4094  	// user for account a requests for a different account, the system account
  4095  	m, err := nc.Request(fmt.Sprintf("COMMON.ADVISORY.SYS.REQ.ACCOUNT.%s.INFO", sysPub), nil, time.Second)
  4096  	require_NoError(t, err)
  4097  	resp := &ServerAPIResponse{}
  4098  	require_NoError(t, json.Unmarshal(m.Data, resp))
  4099  	require_True(t, resp.Error == nil)
  4100  }
  4101  
  4102  func TestJWTSysImportFromNothing(t *testing.T) {
  4103  	_, sysPub, sysClaim := NewJwtAccountClaim("SYS")
  4104  	sysJwt, err := sysClaim.Encode(oKp)
  4105  	require_NoError(t, err)
  4106  
  4107  	// create account
  4108  	aKp, aPub, claim := NewJwtAccountClaim("A")
  4109  	claim.Imports.Add(&jwt.Import{
  4110  		Type: jwt.Service,
  4111  		// fails as it's not for own account, but system account
  4112  		Subject:      jwt.Subject(fmt.Sprintf("$SYS.REQ.ACCOUNT.%s.CONNZ", sysPub)),
  4113  		LocalSubject: "fail1",
  4114  		Account:      sysPub,
  4115  	})
  4116  	claim.Imports.Add(&jwt.Import{
  4117  		Type: jwt.Service,
  4118  		// fails as it's not for own account but all accounts
  4119  		Subject:      "$SYS.REQ.ACCOUNT.*.CONNZ",
  4120  		LocalSubject: "fail2.*",
  4121  		Account:      sysPub,
  4122  	})
  4123  	claim.Imports.Add(&jwt.Import{
  4124  		Type:         jwt.Service,
  4125  		Subject:      jwt.Subject(fmt.Sprintf("$SYS.REQ.ACCOUNT.%s.CONNZ", aPub)),
  4126  		LocalSubject: "pass",
  4127  		Account:      sysPub,
  4128  	})
  4129  	aJwt, err := claim.Encode(oKp)
  4130  	require_NoError(t, err)
  4131  
  4132  	conf := createConfFile(t, []byte(fmt.Sprintf(`
  4133  		listen: 127.0.0.1:-1
  4134  		operator: %s
  4135  		system_account: %s
  4136  		resolver: MEM
  4137  		resolver_preload: {
  4138  			%s: %s
  4139  			%s: %s
  4140  		}
  4141      `, ojwt, sysPub, sysPub, sysJwt, aPub, aJwt)))
  4142  	sA, _ := RunServerWithConfig(conf)
  4143  	defer sA.Shutdown()
  4144  
  4145  	nc := natsConnect(t, sA.ClientURL(), createUserCreds(t, nil, aKp))
  4146  	defer nc.Close()
  4147  	// user for account a requests for a different account, the system account
  4148  	_, err = nc.Request("pass", nil, time.Second)
  4149  	require_NoError(t, err)
  4150  	// default import
  4151  	_, err = nc.Request("$SYS.REQ.ACCOUNT.PING.CONNZ", nil, time.Second)
  4152  	require_NoError(t, err)
  4153  	_, err = nc.Request("fail1", nil, time.Second)
  4154  	require_Error(t, err)
  4155  	require_Contains(t, err.Error(), "no responders")
  4156  	// fails even for own account, as the import itself is bad
  4157  	_, err = nc.Request("fail2."+aPub, nil, time.Second)
  4158  	require_Error(t, err)
  4159  	require_Contains(t, err.Error(), "no responders")
  4160  }
  4161  
  4162  func TestJWTSysImportOverwritePublic(t *testing.T) {
  4163  	_, sysPub, sysClaim := NewJwtAccountClaim("SYS")
  4164  	// this changes the export permissions to allow for requests for every account
  4165  	sysClaim.Exports.Add(&jwt.Export{
  4166  		Type:    jwt.Service,
  4167  		Subject: "$SYS.REQ.ACCOUNT.*.>",
  4168  	})
  4169  	sysJwt, err := sysClaim.Encode(oKp)
  4170  	require_NoError(t, err)
  4171  
  4172  	// create account
  4173  	aKp, aPub, claim := NewJwtAccountClaim("A")
  4174  	claim.Imports.Add(&jwt.Import{
  4175  		Type:         jwt.Service,
  4176  		Subject:      jwt.Subject(fmt.Sprintf("$SYS.REQ.ACCOUNT.%s.CONNZ", sysPub)),
  4177  		LocalSubject: "pass1",
  4178  		Account:      sysPub,
  4179  	})
  4180  	claim.Imports.Add(&jwt.Import{
  4181  		Type:         jwt.Service,
  4182  		Subject:      jwt.Subject(fmt.Sprintf("$SYS.REQ.ACCOUNT.%s.CONNZ", aPub)),
  4183  		LocalSubject: "pass2",
  4184  		Account:      sysPub,
  4185  	})
  4186  	claim.Imports.Add(&jwt.Import{
  4187  		Type:         jwt.Service,
  4188  		Subject:      "$SYS.REQ.ACCOUNT.*.CONNZ",
  4189  		LocalSubject: "pass3.*",
  4190  		Account:      sysPub,
  4191  	})
  4192  	aJwt, err := claim.Encode(oKp)
  4193  	require_NoError(t, err)
  4194  
  4195  	conf := createConfFile(t, []byte(fmt.Sprintf(`
  4196  		listen: 127.0.0.1:-1
  4197  		operator: %s
  4198  		system_account: %s
  4199  		resolver: MEM
  4200  		resolver_preload: {
  4201  			%s: %s
  4202  			%s: %s
  4203  		}
  4204      `, ojwt, sysPub, sysPub, sysJwt, aPub, aJwt)))
  4205  	sA, _ := RunServerWithConfig(conf)
  4206  	defer sA.Shutdown()
  4207  
  4208  	nc := natsConnect(t, sA.ClientURL(), createUserCreds(t, nil, aKp))
  4209  	defer nc.Close()
  4210  	// user for account a requests for a different account, the system account
  4211  	_, err = nc.Request("pass1", nil, time.Second)
  4212  	require_NoError(t, err)
  4213  	_, err = nc.Request("pass2", nil, time.Second)
  4214  	require_NoError(t, err)
  4215  	_, err = nc.Request("pass3."+sysPub, nil, time.Second)
  4216  	require_NoError(t, err)
  4217  	_, err = nc.Request("pass3."+aPub, nil, time.Second)
  4218  	require_NoError(t, err)
  4219  	_, err = nc.Request("pass3.PING", nil, time.Second)
  4220  	require_NoError(t, err)
  4221  }
  4222  
  4223  func TestJWTSysImportOverwriteToken(t *testing.T) {
  4224  	_, sysPub, sysClaim := NewJwtAccountClaim("SYS")
  4225  	// this changes the export permissions in a way that the internal imports can't satisfy
  4226  	sysClaim.Exports.Add(&jwt.Export{
  4227  		Type:     jwt.Service,
  4228  		Subject:  "$SYS.REQ.>",
  4229  		TokenReq: true,
  4230  	})
  4231  
  4232  	sysJwt, err := sysClaim.Encode(oKp)
  4233  	require_NoError(t, err)
  4234  
  4235  	// create account
  4236  	aKp, aPub, claim := NewJwtAccountClaim("A")
  4237  	aJwt, err := claim.Encode(oKp)
  4238  	require_NoError(t, err)
  4239  
  4240  	conf := createConfFile(t, []byte(fmt.Sprintf(`
  4241  		listen: 127.0.0.1:-1
  4242  		operator: %s
  4243  		system_account: %s
  4244  		resolver: MEM
  4245  		resolver_preload: {
  4246  			%s: %s
  4247  			%s: %s
  4248  		}
  4249      `, ojwt, sysPub, sysPub, sysJwt, aPub, aJwt)))
  4250  	sA, _ := RunServerWithConfig(conf)
  4251  	defer sA.Shutdown()
  4252  
  4253  	nc := natsConnect(t, sA.ClientURL(), createUserCreds(t, nil, aKp))
  4254  	defer nc.Close()
  4255  	// make sure the internal import still got added
  4256  	_, err = nc.Request("$SYS.REQ.ACCOUNT.PING.CONNZ", nil, time.Second)
  4257  	require_NoError(t, err)
  4258  }
  4259  
  4260  func TestJWTLimits(t *testing.T) {
  4261  	doNotExpire := time.Now().AddDate(1, 0, 0)
  4262  	// create account
  4263  	kp, _ := nkeys.CreateAccount()
  4264  	aPub, _ := kp.PublicKey()
  4265  	claim := jwt.NewAccountClaims(aPub)
  4266  	aJwt, err := claim.Encode(oKp)
  4267  	require_NoError(t, err)
  4268  	conf := createConfFile(t, []byte(fmt.Sprintf(`
  4269  		listen: 127.0.0.1:-1
  4270  		operator: %s
  4271  		resolver: MEM
  4272  		resolver_preload: {
  4273  			%s: %s
  4274  		}
  4275      `, ojwt, aPub, aJwt)))
  4276  	sA, _ := RunServerWithConfig(conf)
  4277  	defer sA.Shutdown()
  4278  	errChan := make(chan struct{})
  4279  	defer close(errChan)
  4280  	t.Run("subs", func(t *testing.T) {
  4281  		creds := createUserWithLimit(t, kp, doNotExpire, func(j *jwt.UserPermissionLimits) { j.Subs = 1 })
  4282  		c := natsConnect(t, sA.ClientURL(), nats.UserCredentials(creds),
  4283  			nats.DisconnectErrHandler(func(conn *nats.Conn, err error) {
  4284  				if e := conn.LastError(); e != nil && strings.Contains(e.Error(), "maximum subscriptions exceeded") {
  4285  					errChan <- struct{}{}
  4286  				}
  4287  			}),
  4288  		)
  4289  		defer c.Close()
  4290  		if _, err := c.Subscribe("foo", func(msg *nats.Msg) {}); err != nil {
  4291  			t.Fatalf("couldn't subscribe: %v", err)
  4292  		}
  4293  		if _, err = c.Subscribe("bar", func(msg *nats.Msg) {}); err != nil {
  4294  			t.Fatalf("expected error got: %v", err)
  4295  		}
  4296  		chanRecv(t, errChan, time.Second)
  4297  	})
  4298  	t.Run("payload", func(t *testing.T) {
  4299  		creds := createUserWithLimit(t, kp, doNotExpire, func(j *jwt.UserPermissionLimits) { j.Payload = 5 })
  4300  		c := natsConnect(t, sA.ClientURL(), nats.UserCredentials(creds))
  4301  		defer c.Close()
  4302  		if err := c.Flush(); err != nil {
  4303  			t.Fatalf("flush failed %v", err)
  4304  		}
  4305  		if err := c.Publish("foo", []byte("world")); err != nil {
  4306  			t.Fatalf("couldn't publish: %v", err)
  4307  		}
  4308  		if err := c.Publish("foo", []byte("worldX")); err != nats.ErrMaxPayload {
  4309  			t.Fatalf("couldn't publish: %v", err)
  4310  		}
  4311  	})
  4312  }
  4313  
  4314  func TestJwtTemplates(t *testing.T) {
  4315  	kp, _ := nkeys.CreateAccount()
  4316  	aPub, _ := kp.PublicKey()
  4317  	ukp, _ := nkeys.CreateUser()
  4318  	upub, _ := ukp.PublicKey()
  4319  	uclaim := newJWTTestUserClaims()
  4320  	uclaim.Name = "myname"
  4321  	uclaim.Subject = upub
  4322  	uclaim.SetScoped(true)
  4323  	uclaim.IssuerAccount = aPub
  4324  	uclaim.Tags.Add("foo:foo1")
  4325  	uclaim.Tags.Add("foo:foo2")
  4326  	uclaim.Tags.Add("bar:bar1")
  4327  	uclaim.Tags.Add("bar:bar2")
  4328  	uclaim.Tags.Add("bar:bar3")
  4329  
  4330  	lim := jwt.UserPermissionLimits{}
  4331  	lim.Pub.Allow.Add("{{tag(foo)}}.none.{{tag(bar)}}")
  4332  	lim.Pub.Deny.Add("{{tag(foo)}}.{{account-tag(acc)}}")
  4333  	lim.Sub.Allow.Add("{{tag(NOT_THERE)}}") // expect to not emit this
  4334  	lim.Sub.Deny.Add("foo.{{name()}}.{{subject()}}.{{account-name()}}.{{account-subject()}}.bar")
  4335  	acc := &Account{nameTag: "accname", tags: []string{"acc:acc1", "acc:acc2"}}
  4336  
  4337  	resLim, err := processUserPermissionsTemplate(lim, uclaim, acc)
  4338  	require_NoError(t, err)
  4339  
  4340  	test := func(expectedSubjects []string, res jwt.StringList) {
  4341  		t.Helper()
  4342  		require_True(t, len(res) == len(expectedSubjects))
  4343  		for _, expetedSubj := range expectedSubjects {
  4344  			require_True(t, res.Contains(expetedSubj))
  4345  		}
  4346  	}
  4347  
  4348  	test(resLim.Pub.Allow, []string{"foo1.none.bar1", "foo1.none.bar2", "foo1.none.bar3",
  4349  		"foo2.none.bar1", "foo2.none.bar2", "foo2.none.bar3"})
  4350  
  4351  	test(resLim.Pub.Deny, []string{"foo1.acc1", "foo1.acc2", "foo2.acc1", "foo2.acc2"})
  4352  
  4353  	require_True(t, len(resLim.Sub.Allow) == 0)
  4354  	require_True(t, len(resLim.Sub.Deny) == 2)
  4355  	require_Contains(t, resLim.Sub.Deny[0], fmt.Sprintf("foo.myname.%s.accname.%s.bar", upub, aPub))
  4356  	// added in to compensate for sub allow not resolving
  4357  	require_Contains(t, resLim.Sub.Deny[1], ">")
  4358  
  4359  	lim.Pub.Deny.Add("{{tag(NOT_THERE)}}")
  4360  	_, err = processUserPermissionsTemplate(lim, uclaim, acc)
  4361  	require_Error(t, err)
  4362  	require_Contains(t, err.Error(), "generated invalid subject")
  4363  }
  4364  
  4365  func TestJwtTemplateGoodTagAfterBadTag(t *testing.T) {
  4366  	kp, _ := nkeys.CreateAccount()
  4367  	aPub, _ := kp.PublicKey()
  4368  	ukp, _ := nkeys.CreateUser()
  4369  	upub, _ := ukp.PublicKey()
  4370  	uclaim := newJWTTestUserClaims()
  4371  	uclaim.Name = "myname"
  4372  	uclaim.Subject = upub
  4373  	uclaim.SetScoped(true)
  4374  	uclaim.IssuerAccount = aPub
  4375  	uclaim.Tags.Add("foo:foo1")
  4376  
  4377  	lim := jwt.UserPermissionLimits{}
  4378  	lim.Pub.Deny.Add("{{tag(NOT_THERE)}}.{{tag(foo)}}")
  4379  	acc := &Account{nameTag: "accname", tags: []string{"acc:acc1", "acc:acc2"}}
  4380  
  4381  	_, err := processUserPermissionsTemplate(lim, uclaim, acc)
  4382  	require_Error(t, err)
  4383  	require_Contains(t, err.Error(), "generated invalid subject")
  4384  }
  4385  
  4386  func TestJWTLimitsTemplate(t *testing.T) {
  4387  	kp, _ := nkeys.CreateAccount()
  4388  	aPub, _ := kp.PublicKey()
  4389  	claim := jwt.NewAccountClaims(aPub)
  4390  	aSignScopedKp, aSignScopedPub := createKey(t)
  4391  	signer := jwt.NewUserScope()
  4392  	signer.Key = aSignScopedPub
  4393  	signer.Template.Pub.Deny.Add("denied")
  4394  	signer.Template.Pub.Allow.Add("foo.{{name()}}")
  4395  	signer.Template.Sub.Allow.Add("foo.{{name()}}")
  4396  	claim.SigningKeys.AddScopedSigner(signer)
  4397  	aJwt, err := claim.Encode(oKp)
  4398  	require_NoError(t, err)
  4399  	conf := createConfFile(t, []byte(fmt.Sprintf(`
  4400  		listen: 127.0.0.1:-1
  4401  		operator: %s
  4402  		resolver: MEM
  4403  		resolver_preload: {
  4404  			%s: %s
  4405  		}
  4406      `, ojwt, aPub, aJwt)))
  4407  	sA, _ := RunServerWithConfig(conf)
  4408  	defer sA.Shutdown()
  4409  	errChan := make(chan struct{})
  4410  	defer close(errChan)
  4411  
  4412  	ukp, _ := nkeys.CreateUser()
  4413  	seed, _ := ukp.Seed()
  4414  	upub, _ := ukp.PublicKey()
  4415  	uclaim := newJWTTestUserClaims()
  4416  	uclaim.Name = "myname"
  4417  	uclaim.Subject = upub
  4418  	uclaim.SetScoped(true)
  4419  	uclaim.IssuerAccount = aPub
  4420  
  4421  	ujwt, err := uclaim.Encode(aSignScopedKp)
  4422  	require_NoError(t, err)
  4423  	creds := genCredsFile(t, ujwt, seed)
  4424  
  4425  	t.Run("pass", func(t *testing.T) {
  4426  		c := natsConnect(t, sA.ClientURL(), nats.UserCredentials(creds))
  4427  		defer c.Close()
  4428  		sub, err := c.SubscribeSync("foo.myname")
  4429  		require_NoError(t, err)
  4430  		require_NoError(t, c.Flush())
  4431  		require_NoError(t, c.Publish("foo.myname", nil))
  4432  		_, err = sub.NextMsg(time.Second)
  4433  		require_NoError(t, err)
  4434  	})
  4435  	t.Run("fail", func(t *testing.T) {
  4436  		c := natsConnect(t, sA.ClientURL(), nats.UserCredentials(creds),
  4437  			nats.ErrorHandler(func(_ *nats.Conn, _ *nats.Subscription, err error) {
  4438  				if strings.Contains(err.Error(), `nats: Permissions Violation for Publish to "foo.othername"`) {
  4439  					errChan <- struct{}{}
  4440  				}
  4441  			}))
  4442  		defer c.Close()
  4443  		require_NoError(t, c.Publish("foo.othername", nil))
  4444  		select {
  4445  		case <-errChan:
  4446  		case <-time.After(time.Second * 2):
  4447  			require_True(t, false)
  4448  		}
  4449  	})
  4450  }
  4451  
  4452  func TestJWTNoOperatorMode(t *testing.T) {
  4453  	for _, login := range []bool{true, false} {
  4454  		t.Run("", func(t *testing.T) {
  4455  			opts := DefaultOptions()
  4456  			if login {
  4457  				opts.Users = append(opts.Users, &User{Username: "u", Password: "pwd"})
  4458  			}
  4459  			sA := RunServer(opts)
  4460  			defer sA.Shutdown()
  4461  			kp, _ := nkeys.CreateAccount()
  4462  			creds := createUserWithLimit(t, kp, time.Now().Add(time.Hour), nil)
  4463  			url := sA.ClientURL()
  4464  			if login {
  4465  				url = fmt.Sprintf("nats://u:pwd@%s:%d", sA.opts.Host, sA.opts.Port)
  4466  			}
  4467  			c := natsConnect(t, url, nats.UserCredentials(creds))
  4468  			defer c.Close()
  4469  			sA.mu.Lock()
  4470  			defer sA.mu.Unlock()
  4471  			if len(sA.clients) != 1 {
  4472  				t.Fatalf("Expected exactly one client")
  4473  			}
  4474  			for _, v := range sA.clients {
  4475  				if v.opts.JWT != "" {
  4476  					t.Fatalf("Expected no jwt %v", v.opts.JWT)
  4477  				}
  4478  			}
  4479  		})
  4480  	}
  4481  }
  4482  
  4483  func TestJWTUserRevocation(t *testing.T) {
  4484  	test := func(all bool) {
  4485  		createAccountAndUser := func(done chan struct{}, pubKey, jwt1, jwt2, creds1, creds2 *string) {
  4486  			t.Helper()
  4487  			kp, _ := nkeys.CreateAccount()
  4488  			*pubKey, _ = kp.PublicKey()
  4489  			claim := jwt.NewAccountClaims(*pubKey)
  4490  			var err error
  4491  			*jwt1, err = claim.Encode(oKp)
  4492  			require_NoError(t, err)
  4493  
  4494  			ukp, _ := nkeys.CreateUser()
  4495  			seed, _ := ukp.Seed()
  4496  			upub, _ := ukp.PublicKey()
  4497  			uclaim := newJWTTestUserClaims()
  4498  			uclaim.Subject = upub
  4499  
  4500  			ujwt1, err := uclaim.Encode(kp)
  4501  			require_NoError(t, err)
  4502  			*creds1 = genCredsFile(t, ujwt1, seed)
  4503  
  4504  			// create updated claim need to assure that issue time differs
  4505  			if all {
  4506  				claim.Revoke(jwt.All) // revokes all jwt from now on
  4507  			} else {
  4508  				claim.Revoke(upub) // revokes this jwt from now on
  4509  			}
  4510  			time.Sleep(time.Millisecond * 1100)
  4511  			*jwt2, err = claim.Encode(oKp)
  4512  			require_NoError(t, err)
  4513  
  4514  			ujwt2, err := uclaim.Encode(kp)
  4515  			require_NoError(t, err)
  4516  			*creds2 = genCredsFile(t, ujwt2, seed)
  4517  
  4518  			done <- struct{}{}
  4519  		}
  4520  		// Create Accounts and corresponding revoked and non revoked user creds. Do so concurrently to speed up the test
  4521  		doneChan := make(chan struct{}, 2)
  4522  		defer close(doneChan)
  4523  		var syspub, sysjwt, dummy1, sysCreds, dummyCreds string
  4524  		go createAccountAndUser(doneChan, &syspub, &sysjwt, &dummy1, &sysCreds, &dummyCreds)
  4525  		var apub, ajwt1, ajwt2, aCreds1, aCreds2 string
  4526  		go createAccountAndUser(doneChan, &apub, &ajwt1, &ajwt2, &aCreds1, &aCreds2)
  4527  		for i := 0; i < cap(doneChan); i++ {
  4528  			<-doneChan
  4529  		}
  4530  		dirSrv := t.TempDir()
  4531  		conf := createConfFile(t, []byte(fmt.Sprintf(`
  4532  		listen: 127.0.0.1:-1
  4533  		operator: %s
  4534  		system_account: %s
  4535  		resolver: {
  4536  			type: full
  4537  			dir: '%s'
  4538  		}
  4539      `, ojwt, syspub, dirSrv)))
  4540  		srv, _ := RunServerWithConfig(conf)
  4541  		defer srv.Shutdown()
  4542  		updateJwt(t, srv.ClientURL(), sysCreds, sysjwt, 1) // update system account jwt
  4543  		updateJwt(t, srv.ClientURL(), sysCreds, ajwt1, 1)  // set account jwt without revocation
  4544  		ncSys := natsConnect(t, srv.ClientURL(), nats.UserCredentials(sysCreds), nats.Name("conn name"))
  4545  		defer ncSys.Close()
  4546  		ncChan := make(chan *nats.Msg, 10)
  4547  		defer close(ncChan)
  4548  		sub, _ := ncSys.ChanSubscribe(fmt.Sprintf(disconnectEventSubj, apub), ncChan) // observe disconnect message
  4549  		defer sub.Unsubscribe()
  4550  		// use credentials that will be revoked ans assure that the connection will be disconnected
  4551  		nc := natsConnect(t, srv.ClientURL(), nats.UserCredentials(aCreds1),
  4552  			nats.ErrorHandler(func(_ *nats.Conn, _ *nats.Subscription, err error) {
  4553  				if err != nil && strings.Contains(err.Error(), "authentication revoked") {
  4554  					doneChan <- struct{}{}
  4555  				}
  4556  			}),
  4557  		)
  4558  		defer nc.Close()
  4559  		// update account jwt to contain revocation
  4560  		if updateJwt(t, srv.ClientURL(), sysCreds, ajwt2, 1) != 1 {
  4561  			t.Fatalf("Expected jwt update to pass")
  4562  		}
  4563  		// assure that nc got disconnected due to the revocation
  4564  		select {
  4565  		case <-doneChan:
  4566  		case <-time.After(time.Second):
  4567  			t.Fatalf("Expected connection to have failed")
  4568  		}
  4569  		m := <-ncChan
  4570  		require_Len(t, strings.Count(string(m.Data), apub), 2)
  4571  		require_True(t, strings.Contains(string(m.Data), `"jwt":"eyJ0`))
  4572  		// try again with old credentials. Expected to fail
  4573  		if nc1, err := nats.Connect(srv.ClientURL(), nats.UserCredentials(aCreds1)); err == nil {
  4574  			nc1.Close()
  4575  			t.Fatalf("Expected revoked credentials to fail")
  4576  		}
  4577  		// Assure new creds pass
  4578  		nc2 := natsConnect(t, srv.ClientURL(), nats.UserCredentials(aCreds2))
  4579  		defer nc2.Close()
  4580  	}
  4581  	t.Run("specific-key", func(t *testing.T) {
  4582  		test(false)
  4583  	})
  4584  	t.Run("all-key", func(t *testing.T) {
  4585  		test(true)
  4586  	})
  4587  }
  4588  
  4589  func TestJWTActivationRevocation(t *testing.T) {
  4590  	test := func(all bool) {
  4591  		sysKp, syspub := createKey(t)
  4592  		sysJwt := encodeClaim(t, jwt.NewAccountClaims(syspub), syspub)
  4593  		sysCreds := newUser(t, sysKp)
  4594  
  4595  		aExpKp, aExpPub := createKey(t)
  4596  		aExpClaim := jwt.NewAccountClaims(aExpPub)
  4597  		aExpClaim.Name = "Export"
  4598  		aExpClaim.Exports.Add(&jwt.Export{
  4599  			Subject:  "foo",
  4600  			Type:     jwt.Stream,
  4601  			TokenReq: true,
  4602  		})
  4603  		aExp1Jwt := encodeClaim(t, aExpClaim, aExpPub)
  4604  		aExpCreds := newUser(t, aExpKp)
  4605  
  4606  		aImpKp, aImpPub := createKey(t)
  4607  
  4608  		ac := &jwt.ActivationClaims{}
  4609  		ac.Subject = aImpPub
  4610  		ac.ImportSubject = "foo"
  4611  		ac.ImportType = jwt.Stream
  4612  		token, err := ac.Encode(aExpKp)
  4613  		require_NoError(t, err)
  4614  
  4615  		revPubKey := aImpPub
  4616  		if all {
  4617  			revPubKey = jwt.All
  4618  		}
  4619  
  4620  		aExpClaim.Exports[0].RevokeAt(revPubKey, time.Now())
  4621  		aExp2Jwt := encodeClaim(t, aExpClaim, aExpPub)
  4622  
  4623  		aExpClaim.Exports[0].ClearRevocation(revPubKey)
  4624  		aExp3Jwt := encodeClaim(t, aExpClaim, aExpPub)
  4625  
  4626  		aImpClaim := jwt.NewAccountClaims(aImpPub)
  4627  		aImpClaim.Name = "Import"
  4628  		aImpClaim.Imports.Add(&jwt.Import{
  4629  			Subject: "foo",
  4630  			Type:    jwt.Stream,
  4631  			Account: aExpPub,
  4632  			Token:   token,
  4633  		})
  4634  		aImpJwt := encodeClaim(t, aImpClaim, aImpPub)
  4635  		aImpCreds := newUser(t, aImpKp)
  4636  
  4637  		dirSrv := t.TempDir()
  4638  		conf := createConfFile(t, []byte(fmt.Sprintf(`
  4639  		listen: 127.0.0.1:-1
  4640  		operator: %s
  4641  		system_account: %s
  4642  		resolver: {
  4643  			type: full
  4644  			dir: '%s'
  4645  		}
  4646      `, ojwt, syspub, dirSrv)))
  4647  
  4648  		t.Run("token-expired-on-connect", func(t *testing.T) {
  4649  			srv, _ := RunServerWithConfig(conf)
  4650  			defer srv.Shutdown()
  4651  			defer removeDir(t, dirSrv) // clean jwt directory
  4652  
  4653  			updateJwt(t, srv.ClientURL(), sysCreds, sysJwt, 1)   // update system account jwt
  4654  			updateJwt(t, srv.ClientURL(), sysCreds, aExp2Jwt, 1) // set account jwt without revocation
  4655  			updateJwt(t, srv.ClientURL(), sysCreds, aImpJwt, 1)
  4656  
  4657  			ncExp1 := natsConnect(t, srv.ClientURL(), nats.UserCredentials(aExpCreds))
  4658  			defer ncExp1.Close()
  4659  
  4660  			ncImp := natsConnect(t, srv.ClientURL(), nats.UserCredentials(aImpCreds))
  4661  			defer ncImp.Close()
  4662  
  4663  			sub, err := ncImp.SubscribeSync("foo")
  4664  			require_NoError(t, err)
  4665  			require_NoError(t, ncImp.Flush())
  4666  			require_NoError(t, ncExp1.Publish("foo", []byte("1")))
  4667  			_, err = sub.NextMsg(time.Second)
  4668  			require_Error(t, err)
  4669  			require_Equal(t, err.Error(), "nats: timeout")
  4670  		})
  4671  
  4672  		t.Run("token-expired-on-update", func(t *testing.T) {
  4673  			srv, _ := RunServerWithConfig(conf)
  4674  			defer srv.Shutdown()
  4675  			defer removeDir(t, dirSrv) // clean jwt directory
  4676  
  4677  			updateJwt(t, srv.ClientURL(), sysCreds, sysJwt, 1)   // update system account jwt
  4678  			updateJwt(t, srv.ClientURL(), sysCreds, aExp1Jwt, 1) // set account jwt without revocation
  4679  			updateJwt(t, srv.ClientURL(), sysCreds, aImpJwt, 1)
  4680  
  4681  			ncExp1 := natsConnect(t, srv.ClientURL(), nats.UserCredentials(aExpCreds))
  4682  			defer ncExp1.Close()
  4683  
  4684  			ncImp := natsConnect(t, srv.ClientURL(), nats.UserCredentials(aImpCreds))
  4685  			defer ncImp.Close()
  4686  
  4687  			sub, err := ncImp.SubscribeSync("foo")
  4688  			require_NoError(t, err)
  4689  			require_NoError(t, ncImp.Flush())
  4690  			require_NoError(t, ncExp1.Publish("foo", []byte("1")))
  4691  			m1, err := sub.NextMsg(time.Second)
  4692  			require_NoError(t, err)
  4693  			require_Equal(t, string(m1.Data), "1")
  4694  
  4695  			updateJwt(t, srv.ClientURL(), sysCreds, aExp2Jwt, 1) // set account jwt with revocation
  4696  
  4697  			require_NoError(t, ncExp1.Publish("foo", []byte("2")))
  4698  			_, err = sub.NextMsg(time.Second)
  4699  			require_Error(t, err)
  4700  			require_Equal(t, err.Error(), "nats: timeout")
  4701  
  4702  			updateJwt(t, srv.ClientURL(), sysCreds, aExp3Jwt, 1) // set account with revocation cleared
  4703  
  4704  			require_NoError(t, ncExp1.Publish("foo", []byte("3")))
  4705  			m2, err := sub.NextMsg(time.Second)
  4706  			require_NoError(t, err)
  4707  			require_Equal(t, string(m2.Data), "3")
  4708  		})
  4709  	}
  4710  	t.Run("specific-key", func(t *testing.T) {
  4711  		test(false)
  4712  	})
  4713  	t.Run("all-key", func(t *testing.T) {
  4714  		test(true)
  4715  	})
  4716  }
  4717  
  4718  func TestJWTAccountFetchTimeout(t *testing.T) {
  4719  	createAccountAndUser := func(pubKey, jwt1, creds1 *string) {
  4720  		t.Helper()
  4721  		kp, _ := nkeys.CreateAccount()
  4722  		*pubKey, _ = kp.PublicKey()
  4723  		claim := jwt.NewAccountClaims(*pubKey)
  4724  		var err error
  4725  		*jwt1, err = claim.Encode(oKp)
  4726  		require_NoError(t, err)
  4727  		ukp, _ := nkeys.CreateUser()
  4728  		seed, _ := ukp.Seed()
  4729  		upub, _ := ukp.PublicKey()
  4730  		uclaim := newJWTTestUserClaims()
  4731  		uclaim.Subject = upub
  4732  		ujwt1, err := uclaim.Encode(kp)
  4733  		require_NoError(t, err)
  4734  		*creds1 = genCredsFile(t, ujwt1, seed)
  4735  	}
  4736  	for _, cfg := range []string{
  4737  		`type: full`,
  4738  		`type: cache`,
  4739  	} {
  4740  		t.Run("", func(t *testing.T) {
  4741  			var syspub, sysjwt, sysCreds string
  4742  			createAccountAndUser(&syspub, &sysjwt, &sysCreds)
  4743  			var apub, ajwt1, aCreds1 string
  4744  			createAccountAndUser(&apub, &ajwt1, &aCreds1)
  4745  			dirSrv := t.TempDir()
  4746  			conf := createConfFile(t, []byte(fmt.Sprintf(`
  4747  		listen: 127.0.0.1:-1
  4748  		operator: %s
  4749  		system_account: %s
  4750  		resolver: {
  4751  			%s
  4752  			timeout: "100ms"
  4753  			dir: '%s'
  4754  		}
  4755      `, ojwt, syspub, cfg, dirSrv)))
  4756  			srv, _ := RunServerWithConfig(conf)
  4757  			defer srv.Shutdown()
  4758  			updateJwt(t, srv.ClientURL(), sysCreds, sysjwt, 1) // update system account jwt
  4759  			start := time.Now()
  4760  			nc, err := nats.Connect(srv.ClientURL(), nats.UserCredentials(aCreds1))
  4761  			if err == nil {
  4762  				t.Fatal("expected an error, got none")
  4763  			} else if !strings.Contains(err.Error(), "Authorization Violation") {
  4764  				t.Fatalf("expected an authorization violation, got: %v", err)
  4765  			}
  4766  			if time.Since(start) > 300*time.Millisecond {
  4767  				t.Fatal("expected timeout earlier")
  4768  			}
  4769  			defer nc.Close()
  4770  		})
  4771  	}
  4772  }
  4773  
  4774  func TestJWTAccountOps(t *testing.T) {
  4775  	op, _ := nkeys.CreateOperator()
  4776  	opPk, _ := op.PublicKey()
  4777  	sk, _ := nkeys.CreateOperator()
  4778  	skPk, _ := sk.PublicKey()
  4779  	opClaim := jwt.NewOperatorClaims(opPk)
  4780  	opClaim.SigningKeys.Add(skPk)
  4781  	opJwt, err := opClaim.Encode(op)
  4782  	require_NoError(t, err)
  4783  	createAccountAndUser := func(pubKey, jwt1, creds1 *string) {
  4784  		t.Helper()
  4785  		kp, _ := nkeys.CreateAccount()
  4786  		*pubKey, _ = kp.PublicKey()
  4787  		claim := jwt.NewAccountClaims(*pubKey)
  4788  		var err error
  4789  		*jwt1, err = claim.Encode(sk)
  4790  		require_NoError(t, err)
  4791  
  4792  		ukp, _ := nkeys.CreateUser()
  4793  		seed, _ := ukp.Seed()
  4794  		upub, _ := ukp.PublicKey()
  4795  		uclaim := newJWTTestUserClaims()
  4796  		uclaim.Subject = upub
  4797  
  4798  		ujwt1, err := uclaim.Encode(kp)
  4799  		require_NoError(t, err)
  4800  		*creds1 = genCredsFile(t, ujwt1, seed)
  4801  	}
  4802  	generateRequest := func(accs []string, kp nkeys.KeyPair) []byte {
  4803  		t.Helper()
  4804  		opk, _ := kp.PublicKey()
  4805  		c := jwt.NewGenericClaims(opk)
  4806  		c.Data["accounts"] = accs
  4807  		cJwt, err := c.Encode(kp)
  4808  		if err != nil {
  4809  			t.Fatalf("Expected no error %v", err)
  4810  		}
  4811  		return []byte(cJwt)
  4812  	}
  4813  	for _, cfg := range []string{
  4814  		`type: full
  4815   		allow_delete: true`,
  4816  		`type: cache`,
  4817  	} {
  4818  		t.Run("", func(t *testing.T) {
  4819  			var syspub, sysjwt, sysCreds string
  4820  			createAccountAndUser(&syspub, &sysjwt, &sysCreds)
  4821  			var apub, ajwt1, aCreds1 string
  4822  			createAccountAndUser(&apub, &ajwt1, &aCreds1)
  4823  			dirSrv := t.TempDir()
  4824  			conf := createConfFile(t, []byte(fmt.Sprintf(`
  4825  		listen: 127.0.0.1:-1
  4826  		operator: %s
  4827  		system_account: %s
  4828  		resolver: {
  4829  			%s
  4830  			dir: '%s'
  4831  		}
  4832      `, opJwt, syspub, cfg, dirSrv)))
  4833  			disconnectErrChan := make(chan struct{}, 1)
  4834  			defer close(disconnectErrChan)
  4835  			srv, _ := RunServerWithConfig(conf)
  4836  			defer srv.Shutdown()
  4837  			updateJwt(t, srv.ClientURL(), sysCreds, sysjwt, 1) // update system account jwt
  4838  			// push jwt (for full resolver)
  4839  			updateJwt(t, srv.ClientURL(), sysCreds, ajwt1, 1) // set jwt
  4840  			nc := natsConnect(t, srv.ClientURL(), nats.UserCredentials(sysCreds))
  4841  			defer nc.Close()
  4842  			// simulate nas resolver in case of a lookup request (cache)
  4843  			nc.Subscribe(fmt.Sprintf(accLookupReqSubj, apub), func(msg *nats.Msg) {
  4844  				msg.Respond([]byte(ajwt1))
  4845  			})
  4846  			// connect so there is a reason to cache the request and so disconnect can be observed
  4847  			ncA := natsConnect(t, srv.ClientURL(), nats.UserCredentials(aCreds1), nats.NoReconnect(),
  4848  				nats.ErrorHandler(func(_ *nats.Conn, _ *nats.Subscription, err error) {
  4849  					if err != nil && strings.Contains(err.Error(), "account authentication expired") {
  4850  						disconnectErrChan <- struct{}{}
  4851  					}
  4852  				}))
  4853  			defer ncA.Close()
  4854  			resp, err := nc.Request(accListReqSubj, nil, time.Second)
  4855  			require_NoError(t, err)
  4856  			require_True(t, strings.Contains(string(resp.Data), apub))
  4857  			require_True(t, strings.Contains(string(resp.Data), syspub))
  4858  			// delete nothing
  4859  			resp, err = nc.Request(accDeleteReqSubj, generateRequest([]string{}, op), time.Second)
  4860  			require_NoError(t, err)
  4861  			require_True(t, strings.Contains(string(resp.Data), `"message":"deleted 0 accounts"`))
  4862  			// issue delete, twice to also delete a non existing account
  4863  			// also switch which key used to sign the request
  4864  			for i := 0; i < 2; i++ {
  4865  				resp, err = nc.Request(accDeleteReqSubj, generateRequest([]string{apub}, sk), time.Second)
  4866  				require_NoError(t, err)
  4867  				require_True(t, strings.Contains(string(resp.Data), `"message":"deleted 1 accounts"`))
  4868  				resp, err = nc.Request(accListReqSubj, nil, time.Second)
  4869  				require_False(t, strings.Contains(string(resp.Data), apub))
  4870  				require_True(t, strings.Contains(string(resp.Data), syspub))
  4871  				require_NoError(t, err)
  4872  				if i > 0 {
  4873  					continue
  4874  				}
  4875  				select {
  4876  				case <-disconnectErrChan:
  4877  				case <-time.After(time.Second):
  4878  					t.Fatal("Callback not executed")
  4879  				}
  4880  			}
  4881  		})
  4882  	}
  4883  }
  4884  
  4885  func createKey(t *testing.T) (nkeys.KeyPair, string) {
  4886  	t.Helper()
  4887  	kp, _ := nkeys.CreateAccount()
  4888  	syspub, _ := kp.PublicKey()
  4889  	return kp, syspub
  4890  }
  4891  
  4892  func encodeClaim(t *testing.T, claim *jwt.AccountClaims, pub string) string {
  4893  	t.Helper()
  4894  	theJWT, err := claim.Encode(oKp)
  4895  	require_NoError(t, err)
  4896  	return theJWT
  4897  }
  4898  
  4899  // returns user creds
  4900  func newUserEx(t *testing.T, accKp nkeys.KeyPair, scoped bool, issuerAccount string) string {
  4901  	ukp, _ := nkeys.CreateUser()
  4902  	seed, _ := ukp.Seed()
  4903  	upub, _ := ukp.PublicKey()
  4904  	uclaim := newJWTTestUserClaims()
  4905  	uclaim.Subject = upub
  4906  	uclaim.SetScoped(scoped)
  4907  	if issuerAccount != _EMPTY_ {
  4908  		uclaim.IssuerAccount = issuerAccount
  4909  	}
  4910  	ujwt, err := uclaim.Encode(accKp)
  4911  	require_NoError(t, err)
  4912  	return genCredsFile(t, ujwt, seed)
  4913  }
  4914  
  4915  // returns user creds
  4916  func newUser(t *testing.T, accKp nkeys.KeyPair) string {
  4917  	return newUserEx(t, accKp, false, "")
  4918  }
  4919  
  4920  func TestJWTHeader(t *testing.T) {
  4921  	sysKp, syspub := createKey(t)
  4922  	sysJwt := encodeClaim(t, jwt.NewAccountClaims(syspub), syspub)
  4923  	sysCreds := newUser(t, sysKp)
  4924  
  4925  	test := func(share bool) {
  4926  		aExpKp, aExpPub := createKey(t)
  4927  		aExpClaim := jwt.NewAccountClaims(aExpPub)
  4928  		aExpClaim.Exports.Add(&jwt.Export{
  4929  			Name:     "test",
  4930  			Subject:  "srvc",
  4931  			Type:     jwt.Service,
  4932  			TokenReq: false,
  4933  			Latency: &jwt.ServiceLatency{
  4934  				Sampling: jwt.Headers,
  4935  				Results:  "res",
  4936  			},
  4937  		})
  4938  		aExpJwt := encodeClaim(t, aExpClaim, aExpPub)
  4939  		aExpCreds := newUser(t, aExpKp)
  4940  
  4941  		aImpKp, aImpPub := createKey(t)
  4942  		aImpClaim := jwt.NewAccountClaims(aImpPub)
  4943  		aImpClaim.Imports.Add(&jwt.Import{
  4944  			Name:    "test",
  4945  			Subject: "srvc",
  4946  			Account: aExpPub,
  4947  			Type:    jwt.Service,
  4948  			Share:   share,
  4949  		})
  4950  		aImpJwt := encodeClaim(t, aImpClaim, aImpPub)
  4951  		aImpCreds := newUser(t, aImpKp)
  4952  
  4953  		dirSrv := t.TempDir()
  4954  		conf := createConfFile(t, []byte(fmt.Sprintf(`
  4955  		listen: 127.0.0.1:-1
  4956  		operator: %s
  4957  		system_account: %s
  4958  		resolver: {
  4959  			type: full
  4960  			dir: '%s'
  4961  		}
  4962      `, ojwt, syspub, dirSrv)))
  4963  		srv, _ := RunServerWithConfig(conf)
  4964  		defer srv.Shutdown()
  4965  		updateJwt(t, srv.ClientURL(), sysCreds, sysJwt, 1) // update system account jwt
  4966  		updateJwt(t, srv.ClientURL(), sysCreds, aExpJwt, 1)
  4967  		updateJwt(t, srv.ClientURL(), sysCreds, aImpJwt, 1)
  4968  
  4969  		expNc := natsConnect(t, srv.ClientURL(), nats.UserCredentials(aExpCreds))
  4970  		defer expNc.Close()
  4971  		resChan := make(chan *nats.Msg, 1)
  4972  		expNc.ChanSubscribe("res", resChan)
  4973  		sub, err := expNc.Subscribe("srvc", func(msg *nats.Msg) {
  4974  			msg.Respond(nil)
  4975  		})
  4976  		require_NoError(t, err)
  4977  		defer sub.Unsubscribe()
  4978  
  4979  		impNc := natsConnect(t, srv.ClientURL(), nats.UserCredentials(aImpCreds))
  4980  		defer impNc.Close()
  4981  		// send request w/o header
  4982  		_, err = impNc.Request("srvc", []byte("msg1"), time.Second)
  4983  		require_NoError(t, err)
  4984  		require_True(t, len(resChan) == 0)
  4985  
  4986  		_, err = impNc.RequestMsg(&nats.Msg{
  4987  			Subject: "srvc", Data: []byte("msg2"), Header: nats.Header{
  4988  				"X-B3-Sampled": []string{"1"},
  4989  				"Share":        []string{"Me"}}}, time.Second)
  4990  		require_NoError(t, err)
  4991  		select {
  4992  		case <-time.After(time.Second):
  4993  			t.Fatalf("should have received a response")
  4994  		case m := <-resChan:
  4995  			obj := map[string]interface{}{}
  4996  			err = json.Unmarshal(m.Data, &obj)
  4997  			require_NoError(t, err)
  4998  			// test if shared is honored
  4999  			reqInfo := obj["requestor"].(map[string]interface{})
  5000  			// fields always set
  5001  			require_True(t, reqInfo["acc"] != nil)
  5002  			require_True(t, reqInfo["rtt"] != nil)
  5003  
  5004  			// fields only set when shared
  5005  			_, ok1 := reqInfo["lang"]
  5006  			_, ok2 := reqInfo["ver"]
  5007  			_, ok3 := reqInfo["host"]
  5008  			_, ok4 := reqInfo["start"]
  5009  			if !share {
  5010  				ok1 = !ok1
  5011  				ok2 = !ok2
  5012  				ok3 = !ok3
  5013  				ok4 = !ok4
  5014  			}
  5015  			require_True(t, ok1)
  5016  			require_True(t, ok2)
  5017  			require_True(t, ok3)
  5018  			require_True(t, ok4)
  5019  
  5020  		}
  5021  		require_True(t, len(resChan) == 0)
  5022  	}
  5023  	test(true)
  5024  	test(false)
  5025  }
  5026  
  5027  func TestJWTAccountImportsWithWildcardSupport(t *testing.T) {
  5028  	test := func(aExpPub, aExpJwt, aExpCreds, aImpPub, aImpJwt, aImpCreds string, jsEnabled bool, exSubExpect, exPub, imReq, imSubExpect string) {
  5029  		t.Helper()
  5030  
  5031  		var jsSetting string
  5032  		if jsEnabled {
  5033  			jsSetting = "jetstream: {max_mem_store: 10Mb, max_file_store: 10Mb}"
  5034  		}
  5035  
  5036  		_, aSysPub := createKey(t)
  5037  		aSysClaim := jwt.NewAccountClaims(aSysPub)
  5038  		aSysJwt := encodeClaim(t, aSysClaim, aSysPub)
  5039  		cf := createConfFile(t, []byte(fmt.Sprintf(`
  5040  		port: -1
  5041  		operator = %s
  5042  		resolver = MEMORY
  5043  		resolver_preload = {
  5044  			%s : "%s"
  5045  			%s : "%s"
  5046  			%s : "%s"
  5047  		}
  5048  		system_account: %s
  5049  		%s
  5050  		`, ojwt, aExpPub, aExpJwt, aImpPub, aImpJwt, aSysPub, aSysJwt, aSysPub, jsSetting)))
  5051  
  5052  		s, opts := RunServerWithConfig(cf)
  5053  		defer s.Shutdown()
  5054  
  5055  		ncExp := natsConnect(t, fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port), nats.UserCredentials(aExpCreds))
  5056  		defer ncExp.Close()
  5057  
  5058  		ncImp := natsConnect(t, fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port), nats.UserCredentials(aImpCreds))
  5059  		defer ncImp.Close()
  5060  
  5061  		// Create subscriber for the service endpoint in foo.
  5062  		_, err := ncExp.Subscribe(exSubExpect, func(m *nats.Msg) {
  5063  			m.Respond([]byte("yes!"))
  5064  		})
  5065  		require_NoError(t, err)
  5066  		ncExp.Flush()
  5067  
  5068  		// Now test service import.
  5069  		if resp, err := ncImp.Request(imReq, []byte("yes?"), time.Second); err != nil {
  5070  			t.Fatalf("Expected a response to request %s got: %v", imReq, err)
  5071  		} else if string(resp.Data) != "yes!" {
  5072  			t.Fatalf("Expected a response of %q, got %q", "yes!", resp.Data)
  5073  		}
  5074  		subBar, err := ncImp.SubscribeSync(imSubExpect)
  5075  		require_NoError(t, err)
  5076  		ncImp.Flush()
  5077  
  5078  		ncExp.Publish(exPub, []byte("event!"))
  5079  
  5080  		if m, err := subBar.NextMsg(time.Second); err != nil {
  5081  			t.Fatalf("Expected a stream message got %v", err)
  5082  		} else if string(m.Data) != "event!" {
  5083  			t.Fatalf("Expected a response of %q, got %q", "event!", m.Data)
  5084  		}
  5085  	}
  5086  	createExporter := func() (string, string, string) {
  5087  		t.Helper()
  5088  		aExpKp, aExpPub := createKey(t)
  5089  		aExpClaim := jwt.NewAccountClaims(aExpPub)
  5090  		aExpClaim.Name = "Export"
  5091  		aExpClaim.Exports.Add(&jwt.Export{
  5092  			Subject: "$request.*.$in.*.>",
  5093  			Type:    jwt.Service,
  5094  		}, &jwt.Export{
  5095  			Subject: "$events.*.$in.*.>",
  5096  			Type:    jwt.Stream,
  5097  		})
  5098  		aExpJwt := encodeClaim(t, aExpClaim, aExpPub)
  5099  		aExpCreds := newUser(t, aExpKp)
  5100  		return aExpPub, aExpJwt, aExpCreds
  5101  	}
  5102  	t.Run("To", func(t *testing.T) {
  5103  		aExpPub, aExpJwt, aExpCreds := createExporter()
  5104  		aImpKp, aImpPub := createKey(t)
  5105  		aImpClaim := jwt.NewAccountClaims(aImpPub)
  5106  		aImpClaim.Name = "Import"
  5107  		aImpClaim.Imports.Add(&jwt.Import{
  5108  			Subject: "my.request.*.*.>",
  5109  			Type:    jwt.Service,
  5110  			To:      "$request.*.$in.*.>", // services have local and remote switched between Subject and To
  5111  			Account: aExpPub,
  5112  		}, &jwt.Import{
  5113  			Subject: "$events.*.$in.*.>",
  5114  			Type:    jwt.Stream,
  5115  			To:      "prefix",
  5116  			Account: aExpPub,
  5117  		})
  5118  		aImpJwt := encodeClaim(t, aImpClaim, aImpPub)
  5119  		aImpCreds := newUser(t, aImpKp)
  5120  		test(aExpPub, aExpJwt, aExpCreds, aImpPub, aImpJwt, aImpCreds, false,
  5121  			"$request.1.$in.2.bar", "$events.1.$in.2.bar",
  5122  			"my.request.1.2.bar", "prefix.$events.1.$in.2.bar")
  5123  	})
  5124  	t.Run("LocalSubject-No-Reorder", func(t *testing.T) {
  5125  		aExpPub, aExpJwt, aExpCreds := createExporter()
  5126  		aImpKp, aImpPub := createKey(t)
  5127  		aImpClaim := jwt.NewAccountClaims(aImpPub)
  5128  		aImpClaim.Name = "Import"
  5129  		aImpClaim.Imports.Add(&jwt.Import{
  5130  			Subject:      "$request.*.$in.*.>",
  5131  			Type:         jwt.Service,
  5132  			LocalSubject: "my.request.*.*.>",
  5133  			Account:      aExpPub,
  5134  		}, &jwt.Import{
  5135  			Subject:      "$events.*.$in.*.>",
  5136  			Type:         jwt.Stream,
  5137  			LocalSubject: "my.events.*.*.>",
  5138  			Account:      aExpPub,
  5139  		})
  5140  		aImpJwt := encodeClaim(t, aImpClaim, aImpPub)
  5141  		aImpCreds := newUser(t, aImpKp)
  5142  		test(aExpPub, aExpJwt, aExpCreds, aImpPub, aImpJwt, aImpCreds, false,
  5143  			"$request.1.$in.2.bar", "$events.1.$in.2.bar",
  5144  			"my.request.1.2.bar", "my.events.1.2.bar")
  5145  	})
  5146  	t.Run("LocalSubject-Reorder", func(t *testing.T) {
  5147  		for _, jsEnabled := range []bool{false, true} {
  5148  			t.Run(fmt.Sprintf("%t", jsEnabled), func(t *testing.T) {
  5149  				aExpPub, aExpJwt, aExpCreds := createExporter()
  5150  				aImpKp, aImpPub := createKey(t)
  5151  				aImpClaim := jwt.NewAccountClaims(aImpPub)
  5152  				aImpClaim.Name = "Import"
  5153  				aImpClaim.Imports.Add(&jwt.Import{
  5154  					Subject:      "$request.*.$in.*.>",
  5155  					Type:         jwt.Service,
  5156  					LocalSubject: "my.request.$2.$1.>",
  5157  					Account:      aExpPub,
  5158  				}, &jwt.Import{
  5159  					Subject:      "$events.*.$in.*.>",
  5160  					Type:         jwt.Stream,
  5161  					LocalSubject: "my.events.$2.$1.>",
  5162  					Account:      aExpPub,
  5163  				})
  5164  				aImpJwt := encodeClaim(t, aImpClaim, aImpPub)
  5165  				aImpCreds := newUser(t, aImpKp)
  5166  				test(aExpPub, aExpJwt, aExpCreds, aImpPub, aImpJwt, aImpCreds, jsEnabled,
  5167  					"$request.2.$in.1.bar", "$events.1.$in.2.bar",
  5168  					"my.request.1.2.bar", "my.events.2.1.bar")
  5169  			})
  5170  		}
  5171  	})
  5172  }
  5173  
  5174  func TestJWTAccountTokenImportMisuse(t *testing.T) {
  5175  	sysKp, syspub := createKey(t)
  5176  	sysJwt := encodeClaim(t, jwt.NewAccountClaims(syspub), syspub)
  5177  	sysCreds := newUser(t, sysKp)
  5178  
  5179  	aExpKp, aExpPub := createKey(t)
  5180  	aExpClaim := jwt.NewAccountClaims(aExpPub)
  5181  	aExpClaim.Name = "Export"
  5182  	aExpClaim.Exports.Add(&jwt.Export{
  5183  		Subject:  "$events.*.$in.*.>",
  5184  		Type:     jwt.Stream,
  5185  		TokenReq: true,
  5186  	}, &jwt.Export{
  5187  		Subject:  "foo",
  5188  		Type:     jwt.Stream,
  5189  		TokenReq: true,
  5190  	})
  5191  	aExpJwt := encodeClaim(t, aExpClaim, aExpPub)
  5192  	aExpCreds := newUser(t, aExpKp)
  5193  
  5194  	createImportingAccountClaim := func(aImpKp nkeys.KeyPair, aExpPub string, ac *jwt.ActivationClaims) (string, string) {
  5195  		t.Helper()
  5196  		token, err := ac.Encode(aExpKp)
  5197  		require_NoError(t, err)
  5198  
  5199  		aImpPub, err := aImpKp.PublicKey()
  5200  		require_NoError(t, err)
  5201  		aImpClaim := jwt.NewAccountClaims(aImpPub)
  5202  		aImpClaim.Name = "Import"
  5203  		aImpClaim.Imports.Add(&jwt.Import{
  5204  			Subject: "$events.*.$in.*.>",
  5205  			Type:    jwt.Stream,
  5206  			Account: aExpPub,
  5207  			Token:   token,
  5208  		})
  5209  		aImpJwt := encodeClaim(t, aImpClaim, aImpPub)
  5210  		aImpCreds := newUser(t, aImpKp)
  5211  		return aImpJwt, aImpCreds
  5212  	}
  5213  
  5214  	testConnect := func(aExpPub, aExpJwt, aExpCreds, aImpPub, aImpJwt, aImpCreds string) {
  5215  		t.Helper()
  5216  		ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  5217  			if r.URL.Path == "/A/" {
  5218  				// Server startup
  5219  				w.Write(nil)
  5220  			} else if r.URL.Path == "/A/"+aExpPub {
  5221  				w.Write([]byte(aExpJwt))
  5222  			} else if r.URL.Path == "/A/"+aImpPub {
  5223  				w.Write([]byte(aImpJwt))
  5224  			} else {
  5225  				t.Fatal("not expected")
  5226  			}
  5227  		}))
  5228  		defer ts.Close()
  5229  		cf := createConfFile(t, []byte(fmt.Sprintf(`
  5230  			listen: 127.0.0.1:-1
  5231  			operator: %s
  5232  			resolver: URL("%s/A/")
  5233  		`, ojwt, ts.URL)))
  5234  
  5235  		s, opts := RunServerWithConfig(cf)
  5236  		defer s.Shutdown()
  5237  
  5238  		ncImp, err := nats.Connect(fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port), nats.UserCredentials(aImpCreds))
  5239  		require_Error(t, err) // misuse needs to result in an error
  5240  		defer ncImp.Close()
  5241  	}
  5242  
  5243  	testNatsResolver := func(aImpJwt string) {
  5244  		t.Helper()
  5245  		dirSrv := t.TempDir()
  5246  		cf := createConfFile(t, []byte(fmt.Sprintf(`
  5247  			listen: 127.0.0.1:-1
  5248  			operator: %s
  5249  			system_account: %s
  5250  			resolver: {
  5251  				type: full
  5252  				dir: '%s'
  5253  			}
  5254  		`, ojwt, syspub, dirSrv)))
  5255  
  5256  		s, _ := RunServerWithConfig(cf)
  5257  		defer s.Shutdown()
  5258  
  5259  		require_True(t, updateJwt(t, s.ClientURL(), sysCreds, sysJwt, 1) == 1)
  5260  		require_True(t, updateJwt(t, s.ClientURL(), sysCreds, aExpJwt, 1) == 1)
  5261  		require_True(t, updateJwt(t, s.ClientURL(), sysCreds, aImpJwt, 1) == 0) // assure this did not succeed
  5262  	}
  5263  
  5264  	t.Run("wrong-account", func(t *testing.T) {
  5265  		aImpKp, aImpPub := createKey(t)
  5266  		ac := &jwt.ActivationClaims{}
  5267  		_, ac.Subject = createKey(t) // on purpose issue this token for another account
  5268  		ac.ImportSubject = "$events.*.$in.*.>"
  5269  		ac.ImportType = jwt.Stream
  5270  
  5271  		aImpJwt, aImpCreds := createImportingAccountClaim(aImpKp, aExpPub, ac)
  5272  		testConnect(aExpPub, aExpJwt, aExpCreds, aImpPub, aImpJwt, aImpCreds)
  5273  		testNatsResolver(aImpJwt)
  5274  	})
  5275  
  5276  	t.Run("different-subject", func(t *testing.T) {
  5277  		aImpKp, aImpPub := createKey(t)
  5278  		ac := &jwt.ActivationClaims{}
  5279  		ac.Subject = aImpPub
  5280  		ac.ImportSubject = "foo" // on purpose use a subject from another export
  5281  		ac.ImportType = jwt.Stream
  5282  
  5283  		aImpJwt, aImpCreds := createImportingAccountClaim(aImpKp, aExpPub, ac)
  5284  		testConnect(aExpPub, aExpJwt, aExpCreds, aImpPub, aImpJwt, aImpCreds)
  5285  		testNatsResolver(aImpJwt)
  5286  	})
  5287  
  5288  	t.Run("non-existing-subject", func(t *testing.T) {
  5289  		aImpKp, aImpPub := createKey(t)
  5290  		ac := &jwt.ActivationClaims{}
  5291  		ac.Subject = aImpPub
  5292  		ac.ImportSubject = "does-not-exist-or-from-different-export" // on purpose use a non exported subject
  5293  		ac.ImportType = jwt.Stream
  5294  
  5295  		aImpJwt, aImpCreds := createImportingAccountClaim(aImpKp, aExpPub, ac)
  5296  		testConnect(aExpPub, aExpJwt, aExpCreds, aImpPub, aImpJwt, aImpCreds)
  5297  		testNatsResolver(aImpJwt)
  5298  	})
  5299  }
  5300  
  5301  func TestJWTResponseThreshold(t *testing.T) {
  5302  	respThresh := 20 * time.Millisecond
  5303  	aExpKp, aExpPub := createKey(t)
  5304  	aExpClaim := jwt.NewAccountClaims(aExpPub)
  5305  	aExpClaim.Name = "Export"
  5306  	aExpClaim.Exports.Add(&jwt.Export{
  5307  		Subject:           "srvc",
  5308  		Type:              jwt.Service,
  5309  		ResponseThreshold: respThresh,
  5310  	})
  5311  	aExpJwt := encodeClaim(t, aExpClaim, aExpPub)
  5312  	aExpCreds := newUser(t, aExpKp)
  5313  
  5314  	aImpKp, aImpPub := createKey(t)
  5315  	aImpClaim := jwt.NewAccountClaims(aImpPub)
  5316  	aImpClaim.Name = "Import"
  5317  	aImpClaim.Imports.Add(&jwt.Import{
  5318  		Subject: "srvc",
  5319  		Type:    jwt.Service,
  5320  		Account: aExpPub,
  5321  	})
  5322  	aImpJwt := encodeClaim(t, aImpClaim, aImpPub)
  5323  	aImpCreds := newUser(t, aImpKp)
  5324  
  5325  	cf := createConfFile(t, []byte(fmt.Sprintf(`
  5326  		port: -1
  5327  		operator = %s
  5328  		resolver = MEMORY
  5329  		resolver_preload = {
  5330  			%s : "%s"
  5331  			%s : "%s"
  5332  		}
  5333  		`, ojwt, aExpPub, aExpJwt, aImpPub, aImpJwt)))
  5334  
  5335  	s, opts := RunServerWithConfig(cf)
  5336  	defer s.Shutdown()
  5337  
  5338  	ncExp := natsConnect(t, fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port), nats.UserCredentials(aExpCreds))
  5339  	defer ncExp.Close()
  5340  
  5341  	ncImp := natsConnect(t, fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port), nats.UserCredentials(aImpCreds))
  5342  	defer ncImp.Close()
  5343  
  5344  	delayChan := make(chan time.Duration, 1)
  5345  
  5346  	// Create subscriber for the service endpoint in foo.
  5347  	_, err := ncExp.Subscribe("srvc", func(m *nats.Msg) {
  5348  		time.Sleep(<-delayChan)
  5349  		m.Respond([]byte("yes!"))
  5350  	})
  5351  	require_NoError(t, err)
  5352  	ncExp.Flush()
  5353  
  5354  	t.Run("No-Timeout", func(t *testing.T) {
  5355  		delayChan <- respThresh / 2
  5356  		if resp, err := ncImp.Request("srvc", []byte("yes?"), 4*respThresh); err != nil {
  5357  			t.Fatalf("Expected a response to request srvc got: %v", err)
  5358  		} else if string(resp.Data) != "yes!" {
  5359  			t.Fatalf("Expected a response of %q, got %q", "yes!", resp.Data)
  5360  		}
  5361  	})
  5362  	t.Run("Timeout", func(t *testing.T) {
  5363  		delayChan <- 2 * respThresh
  5364  		if _, err := ncImp.Request("srvc", []byte("yes?"), 4*respThresh); err == nil || err != nats.ErrTimeout {
  5365  			t.Fatalf("Expected a timeout")
  5366  		}
  5367  	})
  5368  }
  5369  
  5370  func TestJWTJetStreamTiers(t *testing.T) {
  5371  	sysKp, syspub := createKey(t)
  5372  	sysJwt := encodeClaim(t, jwt.NewAccountClaims(syspub), syspub)
  5373  	sysCreds := newUser(t, sysKp)
  5374  
  5375  	accKp, accPub := createKey(t)
  5376  	accClaim := jwt.NewAccountClaims(accPub)
  5377  	accClaim.Name = "acc"
  5378  	accClaim.Limits.JetStreamTieredLimits["R1"] = jwt.JetStreamLimits{
  5379  		DiskStorage: 1100, MemoryStorage: 0, Consumer: 2, Streams: 2}
  5380  	accJwt1 := encodeClaim(t, accClaim, accPub)
  5381  	accCreds := newUser(t, accKp)
  5382  
  5383  	start := time.Now()
  5384  
  5385  	storeDir := t.TempDir()
  5386  
  5387  	dirSrv := t.TempDir()
  5388  	cf := createConfFile(t, []byte(fmt.Sprintf(`
  5389  		listen: 127.0.0.1:-1
  5390  		server_name: s1
  5391  		jetstream: {max_mem_store: 256MB, max_file_store: 2GB, store_dir: '%s'}
  5392  		leaf {
  5393  			listen: 127.0.0.1:-1
  5394  		}
  5395  		operator: %s
  5396  		system_account: %s
  5397  		resolver: {
  5398  			type: full
  5399  			dir: '%s'
  5400  		}
  5401  	`, storeDir, ojwt, syspub, dirSrv)))
  5402  
  5403  	s, _ := RunServerWithConfig(cf)
  5404  	defer s.Shutdown()
  5405  
  5406  	updateJwt(t, s.ClientURL(), sysCreds, sysJwt, 1)
  5407  	updateJwt(t, s.ClientURL(), sysCreds, accJwt1, 1)
  5408  
  5409  	nc := natsConnect(t, s.ClientURL(), nats.UserCredentials(accCreds))
  5410  	defer nc.Close()
  5411  
  5412  	js, err := nc.JetStream()
  5413  	require_NoError(t, err)
  5414  
  5415  	// Test tiers up to stream limits
  5416  	_, err = js.AddStream(&nats.StreamConfig{Name: "testR1-1", Replicas: 1, Subjects: []string{"testR1-1"}})
  5417  	require_NoError(t, err)
  5418  	_, err = js.AddStream(&nats.StreamConfig{Name: "testR1-2", Replicas: 1, Subjects: []string{"testR1-2"}})
  5419  	require_NoError(t, err)
  5420  
  5421  	// Test exceeding tiered stream limit
  5422  	_, err = js.AddStream(&nats.StreamConfig{Name: "testR1-3", Replicas: 1, Subjects: []string{"testR1-3"}})
  5423  	require_Error(t, err)
  5424  	require_Equal(t, err.Error(), "nats: maximum number of streams reached")
  5425  
  5426  	// Test tiers up to consumer limits
  5427  	_, err = js.AddConsumer("testR1-1", &nats.ConsumerConfig{Durable: "dur1", AckPolicy: nats.AckExplicitPolicy})
  5428  	require_NoError(t, err)
  5429  	_, err = js.AddConsumer("testR1-1", &nats.ConsumerConfig{Durable: "dur3", AckPolicy: nats.AckExplicitPolicy})
  5430  	require_NoError(t, err)
  5431  
  5432  	// test exceeding tiered consumer limits
  5433  	_, err = js.AddConsumer("testR1-1", &nats.ConsumerConfig{Durable: "dur4", AckPolicy: nats.AckExplicitPolicy})
  5434  	require_Error(t, err)
  5435  	require_Equal(t, err.Error(), "nats: maximum consumers limit reached")
  5436  	_, err = js.AddConsumer("testR1-1", &nats.ConsumerConfig{Durable: "dur5", AckPolicy: nats.AckExplicitPolicy})
  5437  	require_Error(t, err)
  5438  	require_Equal(t, err.Error(), "nats: maximum consumers limit reached")
  5439  
  5440  	// test tiered storage limit
  5441  	msg := [512]byte{}
  5442  	_, err = js.Publish("testR1-1", msg[:])
  5443  	require_NoError(t, err)
  5444  	_, err = js.Publish("testR1-2", msg[:])
  5445  	require_NoError(t, err)
  5446  
  5447  	// test exceeding tiered storage limit
  5448  	_, err = js.Publish("testR1-1", []byte("1"))
  5449  	require_Error(t, err)
  5450  	require_Equal(t, err.Error(), "nats: resource limits exceeded for account")
  5451  
  5452  	time.Sleep(time.Second - time.Since(start)) // make sure the time stamp changes
  5453  	accClaim.Limits.JetStreamTieredLimits["R1"] = jwt.JetStreamLimits{
  5454  		DiskStorage: 1650, MemoryStorage: 0, Consumer: 1, Streams: 3}
  5455  	accJwt2 := encodeClaim(t, accClaim, accPub)
  5456  	updateJwt(t, s.ClientURL(), sysCreds, accJwt2, 1)
  5457  
  5458  	// test same sequence as before, add stream, fail add stream, add consumer, fail add consumer, publish, fail publish
  5459  	_, err = js.AddStream(&nats.StreamConfig{Name: "testR1-3", Replicas: 1, Subjects: []string{"testR1-3"}})
  5460  	require_NoError(t, err)
  5461  	_, err = js.AddStream(&nats.StreamConfig{Name: "testR1-4", Replicas: 1, Subjects: []string{"testR1-4"}})
  5462  	require_Error(t, err)
  5463  	require_Equal(t, err.Error(), "nats: maximum number of streams reached")
  5464  	_, err = js.AddConsumer("testR1-3", &nats.ConsumerConfig{Durable: "dur6", AckPolicy: nats.AckExplicitPolicy})
  5465  	require_NoError(t, err)
  5466  	_, err = js.AddConsumer("testR1-3", &nats.ConsumerConfig{Durable: "dur7", AckPolicy: nats.AckExplicitPolicy})
  5467  	require_Error(t, err)
  5468  	require_Equal(t, err.Error(), "nats: maximum consumers limit reached")
  5469  	_, err = js.Publish("testR1-3", msg[:])
  5470  	require_Error(t, err)
  5471  	require_Equal(t, err.Error(), "nats: resource limits exceeded for account")
  5472  }
  5473  
  5474  func TestJWTJetStreamMaxAckPending(t *testing.T) {
  5475  	sysKp, syspub := createKey(t)
  5476  	sysJwt := encodeClaim(t, jwt.NewAccountClaims(syspub), syspub)
  5477  	sysCreds := newUser(t, sysKp)
  5478  
  5479  	accKp, accPub := createKey(t)
  5480  	accClaim := jwt.NewAccountClaims(accPub)
  5481  	accClaim.Name = "acc"
  5482  	accClaim.Limits.JetStreamTieredLimits["R1"] = jwt.JetStreamLimits{
  5483  		DiskStorage: jwt.NoLimit, MemoryStorage: jwt.NoLimit,
  5484  		Consumer: jwt.NoLimit, Streams: jwt.NoLimit, MaxAckPending: int64(1000),
  5485  	}
  5486  	accJwt1 := encodeClaim(t, accClaim, accPub)
  5487  	accCreds := newUser(t, accKp)
  5488  
  5489  	start := time.Now()
  5490  
  5491  	storeDir := t.TempDir()
  5492  
  5493  	dirSrv := t.TempDir()
  5494  	cf := createConfFile(t, []byte(fmt.Sprintf(`
  5495  		listen: 127.0.0.1:-1
  5496  		server_name: s1
  5497  		jetstream: {max_mem_store: 256MB, max_file_store: 2GB, store_dir: '%s'}
  5498  		leaf {
  5499  			listen: 127.0.0.1:-1
  5500  		}
  5501  		operator: %s
  5502  		system_account: %s
  5503  		resolver: {
  5504  			type: full
  5505  			dir: '%s'
  5506  		}
  5507  	`, storeDir, ojwt, syspub, dirSrv)))
  5508  
  5509  	s, _ := RunServerWithConfig(cf)
  5510  	defer s.Shutdown()
  5511  
  5512  	updateJwt(t, s.ClientURL(), sysCreds, sysJwt, 1)
  5513  	updateJwt(t, s.ClientURL(), sysCreds, accJwt1, 1)
  5514  
  5515  	nc := natsConnect(t, s.ClientURL(), nats.UserCredentials(accCreds))
  5516  	defer nc.Close()
  5517  
  5518  	js, err := nc.JetStream()
  5519  	require_NoError(t, err)
  5520  
  5521  	_, err = js.AddStream(&nats.StreamConfig{Name: "foo", Replicas: 1})
  5522  	require_NoError(t, err)
  5523  
  5524  	_, err = js.AddConsumer("foo", &nats.ConsumerConfig{
  5525  		Durable: "dur1", AckPolicy: nats.AckAllPolicy, MaxAckPending: 2000})
  5526  	require_Error(t, err)
  5527  	require_Equal(t, err.Error(), "nats: consumer max ack pending exceeds system limit of 1000")
  5528  
  5529  	ci, err := js.AddConsumer("foo", &nats.ConsumerConfig{
  5530  		Durable: "dur2", AckPolicy: nats.AckAllPolicy, MaxAckPending: 500})
  5531  	require_NoError(t, err)
  5532  	require_True(t, ci.Config.MaxAckPending == 500)
  5533  
  5534  	_, err = js.UpdateConsumer("foo", &nats.ConsumerConfig{
  5535  		Durable: "dur2", AckPolicy: nats.AckAllPolicy, MaxAckPending: 2000})
  5536  	require_Error(t, err)
  5537  	require_Equal(t, err.Error(), "nats: consumer max ack pending exceeds system limit of 1000")
  5538  
  5539  	time.Sleep(time.Second - time.Since(start)) // make sure the time stamp changes
  5540  	accClaim.Limits.JetStreamTieredLimits["R1"] = jwt.JetStreamLimits{
  5541  		DiskStorage: jwt.NoLimit, MemoryStorage: jwt.NoLimit, Consumer: jwt.NoLimit,
  5542  		Streams: jwt.NoLimit, MaxAckPending: int64(2000)}
  5543  	accJwt2 := encodeClaim(t, accClaim, accPub)
  5544  	updateJwt(t, s.ClientURL(), sysCreds, accJwt2, 1)
  5545  
  5546  	ci, err = js.UpdateConsumer("foo", &nats.ConsumerConfig{
  5547  		Durable: "dur2", AckPolicy: nats.AckAllPolicy, MaxAckPending: 2000})
  5548  	require_NoError(t, err)
  5549  	require_True(t, ci.Config.MaxAckPending == 2000)
  5550  }
  5551  
  5552  func TestJWTJetStreamMaxStreamBytes(t *testing.T) {
  5553  	sysKp, syspub := createKey(t)
  5554  	sysJwt := encodeClaim(t, jwt.NewAccountClaims(syspub), syspub)
  5555  	sysCreds := newUser(t, sysKp)
  5556  
  5557  	accKp, accPub := createKey(t)
  5558  	accClaim := jwt.NewAccountClaims(accPub)
  5559  	accClaim.Name = "acc"
  5560  	accClaim.Limits.JetStreamTieredLimits["R1"] = jwt.JetStreamLimits{
  5561  		DiskStorage: jwt.NoLimit, MemoryStorage: jwt.NoLimit,
  5562  		Consumer: jwt.NoLimit, Streams: jwt.NoLimit,
  5563  		DiskMaxStreamBytes: 1024, MaxBytesRequired: false,
  5564  	}
  5565  	accJwt1 := encodeClaim(t, accClaim, accPub)
  5566  	accCreds := newUser(t, accKp)
  5567  
  5568  	start := time.Now()
  5569  
  5570  	storeDir := t.TempDir()
  5571  
  5572  	dirSrv := t.TempDir()
  5573  	cf := createConfFile(t, []byte(fmt.Sprintf(`
  5574  		listen: 127.0.0.1:-1
  5575  		server_name: s1
  5576  		jetstream: {max_mem_store: 256MB, max_file_store: 2GB, store_dir: '%s'}
  5577  		leaf {
  5578  			listen: 127.0.0.1:-1
  5579  		}
  5580  		operator: %s
  5581  		system_account: %s
  5582  		resolver: {
  5583  			type: full
  5584  			dir: '%s'
  5585  		}
  5586  	`, storeDir, ojwt, syspub, dirSrv)))
  5587  
  5588  	s, _ := RunServerWithConfig(cf)
  5589  	defer s.Shutdown()
  5590  
  5591  	updateJwt(t, s.ClientURL(), sysCreds, sysJwt, 1)
  5592  	updateJwt(t, s.ClientURL(), sysCreds, accJwt1, 1)
  5593  
  5594  	nc := natsConnect(t, s.ClientURL(), nats.UserCredentials(accCreds))
  5595  	defer nc.Close()
  5596  
  5597  	js, err := nc.JetStream()
  5598  	require_NoError(t, err)
  5599  
  5600  	_, err = js.AddStream(&nats.StreamConfig{Name: "foo", Replicas: 1, MaxBytes: 2048})
  5601  	require_Error(t, err)
  5602  	require_Equal(t, err.Error(), "nats: stream max bytes exceeds account limit max stream bytes")
  5603  	_, err = js.AddStream(&nats.StreamConfig{Name: "foo", Replicas: 1, MaxBytes: 1024})
  5604  	require_NoError(t, err)
  5605  
  5606  	msg := [900]byte{}
  5607  	_, err = js.AddStream(&nats.StreamConfig{Name: "baz", Replicas: 1})
  5608  	require_NoError(t, err)
  5609  	_, err = js.Publish("baz", msg[:])
  5610  	require_NoError(t, err)
  5611  	_, err = js.Publish("baz", msg[:]) // exceeds max stream bytes
  5612  	require_Error(t, err)
  5613  	require_Equal(t, err.Error(), "nats: resource limits exceeded for account")
  5614  
  5615  	time.Sleep(time.Second - time.Since(start)) // make sure the time stamp changes
  5616  	accClaim.Limits.JetStreamTieredLimits["R1"] = jwt.JetStreamLimits{
  5617  		DiskStorage: jwt.NoLimit, MemoryStorage: jwt.NoLimit, Consumer: jwt.NoLimit, Streams: jwt.NoLimit,
  5618  		DiskMaxStreamBytes: 2048, MaxBytesRequired: true}
  5619  	accJwt2 := encodeClaim(t, accClaim, accPub)
  5620  	updateJwt(t, s.ClientURL(), sysCreds, accJwt2, 1)
  5621  
  5622  	_, err = js.AddStream(&nats.StreamConfig{Name: "bar", Replicas: 1, MaxBytes: 3000})
  5623  	require_Error(t, err)
  5624  	require_Equal(t, err.Error(), "nats: stream max bytes exceeds account limit max stream bytes")
  5625  	_, err = js.AddStream(&nats.StreamConfig{Name: "bar", Replicas: 1, MaxBytes: 2048})
  5626  	require_NoError(t, err)
  5627  
  5628  	// test if we can push more messages into the stream
  5629  	_, err = js.Publish("baz", msg[:]) // exceeds max stream bytes
  5630  	require_Error(t, err)
  5631  	require_Equal(t, err.Error(), "nats: resource limits exceeded for account")
  5632  
  5633  	// test disabling max bytes required
  5634  	_, err = js.UpdateStream(&nats.StreamConfig{Name: "bar", Replicas: 1})
  5635  	require_Error(t, err)
  5636  	require_Equal(t, err.Error(), "nats: account requires a stream config to have max bytes set")
  5637  }
  5638  
  5639  func TestJWTQueuePermissions(t *testing.T) {
  5640  	aExpKp, aExpPub := createKey(t)
  5641  	aExpClaim := jwt.NewAccountClaims(aExpPub)
  5642  	aExpJwt := encodeClaim(t, aExpClaim, aExpPub)
  5643  	newUser := func(t *testing.T, permType string) string {
  5644  		ukp, _ := nkeys.CreateUser()
  5645  		seed, _ := ukp.Seed()
  5646  		upub, _ := ukp.PublicKey()
  5647  		uclaim := newJWTTestUserClaims()
  5648  		uclaim.Subject = upub
  5649  		switch permType {
  5650  		case "allow":
  5651  			uclaim.Permissions.Sub.Allow.Add("foo.> *.dev")
  5652  		case "deny":
  5653  			uclaim.Permissions.Sub.Deny.Add("foo.> *.dev")
  5654  		}
  5655  		ujwt, err := uclaim.Encode(aExpKp)
  5656  		require_NoError(t, err)
  5657  		return genCredsFile(t, ujwt, seed)
  5658  	}
  5659  	confFileName := createConfFile(t, []byte(fmt.Sprintf(`
  5660  		port: -1
  5661  		operator = %s
  5662  		resolver = MEMORY
  5663  		resolver_preload = {
  5664  			%s : %s
  5665  		}`, ojwt, aExpPub, aExpJwt)))
  5666  	opts, err := ProcessConfigFile(confFileName)
  5667  	if err != nil {
  5668  		t.Fatalf("Received unexpected error %s", err)
  5669  	}
  5670  	opts.NoLog, opts.NoSigs = true, true
  5671  	errChan := make(chan error, 1)
  5672  	defer close(errChan)
  5673  	s := RunServer(opts)
  5674  	defer s.Shutdown()
  5675  
  5676  	for _, test := range []struct {
  5677  		permType    string
  5678  		queue       string
  5679  		errExpected bool
  5680  	}{
  5681  		{"allow", "queue.dev", false},
  5682  		{"allow", "", true},
  5683  		{"allow", "bad", true},
  5684  		{"deny", "", false},
  5685  		{"deny", "queue.dev", true},
  5686  	} {
  5687  		t.Run(test.permType+test.queue, func(t *testing.T) {
  5688  			usrCreds := newUser(t, test.permType)
  5689  			nc, err := nats.Connect(fmt.Sprintf("nats://127.0.0.1:%d", opts.Port),
  5690  				nats.ErrorHandler(func(conn *nats.Conn, s *nats.Subscription, err error) {
  5691  					errChan <- err
  5692  				}),
  5693  				nats.UserCredentials(usrCreds))
  5694  			if err != nil {
  5695  				t.Fatalf("No error expected: %v", err)
  5696  			}
  5697  			defer nc.Close()
  5698  			if test.queue == "" {
  5699  				if _, err := nc.Subscribe("foo.bar", func(msg *nats.Msg) {}); err != nil {
  5700  					t.Fatalf("no error expected: %v", err)
  5701  				}
  5702  			} else {
  5703  				if _, err := nc.QueueSubscribe("foo.bar", test.queue, func(msg *nats.Msg) {}); err != nil {
  5704  					t.Fatalf("no error expected: %v", err)
  5705  				}
  5706  			}
  5707  			nc.Flush()
  5708  			select {
  5709  			case err := <-errChan:
  5710  				if !test.errExpected {
  5711  					t.Fatalf("Expected no error, got %v", err)
  5712  				}
  5713  				if !strings.Contains(err.Error(), `Permissions Violation for Subscription to "foo.bar"`) {
  5714  					t.Fatalf("error %v", err)
  5715  				}
  5716  			case <-time.After(150 * time.Millisecond):
  5717  				if test.errExpected {
  5718  					t.Fatal("Expected an error")
  5719  				}
  5720  			}
  5721  		})
  5722  
  5723  	}
  5724  }
  5725  
  5726  func TestJWScopedSigningKeys(t *testing.T) {
  5727  	sysKp, syspub := createKey(t)
  5728  	sysJwt := encodeClaim(t, jwt.NewAccountClaims(syspub), syspub)
  5729  	sysCreds := newUser(t, sysKp)
  5730  
  5731  	_, aExpPub := createKey(t)
  5732  	accClaim := jwt.NewAccountClaims(aExpPub)
  5733  	accClaim.Name = "acc"
  5734  
  5735  	aSignNonScopedKp, aSignNonScopedPub := createKey(t)
  5736  	accClaim.SigningKeys.Add(aSignNonScopedPub)
  5737  
  5738  	aSignScopedKp, aSignScopedPub := createKey(t)
  5739  	signer := jwt.NewUserScope()
  5740  	signer.Key = aSignScopedPub
  5741  	signer.Template.Pub.Deny.Add("denied")
  5742  	signer.Template.Payload = 5
  5743  	accClaim.SigningKeys.AddScopedSigner(signer)
  5744  	accJwt := encodeClaim(t, accClaim, aExpPub)
  5745  
  5746  	aNonScopedCreds := newUserEx(t, aSignNonScopedKp, false, aExpPub)
  5747  	aBadScopedCreds := newUserEx(t, aSignScopedKp, false, aExpPub)
  5748  	aScopedCreds := newUserEx(t, aSignScopedKp, true, aExpPub)
  5749  
  5750  	dirSrv := t.TempDir()
  5751  	cf := createConfFile(t, []byte(fmt.Sprintf(`
  5752  		listen: 127.0.0.1:-1
  5753  		operator: %s
  5754  		system_account: %s
  5755  		resolver: {
  5756  			type: full
  5757  			dir: '%s'
  5758  		}
  5759      `, ojwt, syspub, dirSrv)))
  5760  	s, opts := RunServerWithConfig(cf)
  5761  	defer s.Shutdown()
  5762  
  5763  	url := fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)
  5764  	errChan := make(chan error, 1)
  5765  	defer close(errChan)
  5766  	awaitError := func(expected bool) {
  5767  		t.Helper()
  5768  		select {
  5769  		case err := <-errChan:
  5770  			if !expected {
  5771  				t.Fatalf("Expected no error, got %v", err)
  5772  			}
  5773  		case <-time.After(150 * time.Millisecond):
  5774  			if expected {
  5775  				t.Fatal("Expected an error")
  5776  			}
  5777  		}
  5778  	}
  5779  	errHdlr := nats.ErrorHandler(func(conn *nats.Conn, s *nats.Subscription, err error) {
  5780  		errChan <- err
  5781  	})
  5782  	if updateJwt(t, url, sysCreds, sysJwt, 1) != 1 {
  5783  		t.Error("Expected update to pass")
  5784  	} else if updateJwt(t, url, sysCreds, accJwt, 1) != 1 {
  5785  		t.Error("Expected update to pass")
  5786  	}
  5787  	t.Run("bad-scoped-signing-key", func(t *testing.T) {
  5788  		_, err := nats.Connect(url, nats.UserCredentials(aBadScopedCreds))
  5789  		require_Error(t, err)
  5790  	})
  5791  	t.Run("regular-signing-key", func(t *testing.T) {
  5792  		nc := natsConnect(t, url, nats.UserCredentials(aNonScopedCreds), errHdlr)
  5793  		defer nc.Close()
  5794  		nc.Flush()
  5795  		err := nc.Publish("denied", nil)
  5796  		require_NoError(t, err)
  5797  		nc.Flush()
  5798  		awaitError(false)
  5799  	})
  5800  	t.Run("scoped-signing-key-client-side", func(t *testing.T) {
  5801  		nc := natsConnect(t, url, nats.UserCredentials(aScopedCreds), errHdlr)
  5802  		defer nc.Close()
  5803  		nc.Flush()
  5804  		err := nc.Publish("too-long", []byte("way.too.long.for.payload.limit"))
  5805  		require_Error(t, err)
  5806  		require_True(t, strings.Contains(err.Error(), ErrMaxPayload.Error()))
  5807  	})
  5808  	t.Run("scoped-signing-key-server-side", func(t *testing.T) {
  5809  		nc := natsConnect(t, url, nats.UserCredentials(aScopedCreds), errHdlr)
  5810  		defer nc.Close()
  5811  		nc.Flush()
  5812  		err := nc.Publish("denied", nil)
  5813  		require_NoError(t, err)
  5814  		nc.Flush()
  5815  		awaitError(true)
  5816  	})
  5817  	t.Run("scoped-signing-key-reload", func(t *testing.T) {
  5818  		reconChan := make(chan struct{}, 1)
  5819  		defer close(reconChan)
  5820  		msgChan := make(chan *nats.Msg, 2)
  5821  		defer close(msgChan)
  5822  		nc := natsConnect(t, url, nats.UserCredentials(aScopedCreds), errHdlr,
  5823  			nats.DisconnectErrHandler(func(conn *nats.Conn, err error) {
  5824  				if err != nil {
  5825  					errChan <- err
  5826  				}
  5827  			}),
  5828  			nats.ReconnectHandler(func(conn *nats.Conn) {
  5829  				reconChan <- struct{}{}
  5830  			}),
  5831  		)
  5832  		defer nc.Close()
  5833  		_, err := nc.ChanSubscribe("denied", msgChan)
  5834  		require_NoError(t, err)
  5835  		nc.Flush()
  5836  		err = nc.Publish("denied", nil)
  5837  		require_NoError(t, err)
  5838  		awaitError(true)
  5839  		require_Len(t, len(msgChan), 0)
  5840  		// Alter scoped permissions and update
  5841  		signer.Template.Payload = -1
  5842  		signer.Template.Pub.Deny.Remove("denied")
  5843  		accClaim.SigningKeys.AddScopedSigner(signer)
  5844  		accUpdatedJwt := encodeClaim(t, accClaim, aExpPub)
  5845  		if updateJwt(t, url, sysCreds, accUpdatedJwt, 1) != 1 {
  5846  			t.Error("Expected update to pass")
  5847  		}
  5848  		// disconnect triggered by update
  5849  		awaitError(true)
  5850  		<-reconChan
  5851  		nc.Flush()
  5852  		err = nc.Publish("denied", []byte("way.too.long.for.old.payload.limit"))
  5853  		require_NoError(t, err)
  5854  		awaitError(false)
  5855  		msg := <-msgChan
  5856  		require_Equal(t, string(msg.Data), "way.too.long.for.old.payload.limit")
  5857  		require_Len(t, len(msgChan), 0)
  5858  	})
  5859  	require_Len(t, len(errChan), 0)
  5860  }
  5861  
  5862  func TestJWTStrictSigningKeys(t *testing.T) {
  5863  	newAccount := func(opKp nkeys.KeyPair) (nkeys.KeyPair, nkeys.KeyPair, string, *jwt.AccountClaims, string) {
  5864  		accId, err := nkeys.CreateAccount()
  5865  		require_NoError(t, err)
  5866  		accIdPub, err := accId.PublicKey()
  5867  		require_NoError(t, err)
  5868  
  5869  		accSig, err := nkeys.CreateAccount()
  5870  		require_NoError(t, err)
  5871  		accSigPub, err := accSig.PublicKey()
  5872  		require_NoError(t, err)
  5873  
  5874  		aClaim := jwt.NewAccountClaims(accIdPub)
  5875  		aClaim.SigningKeys.Add(accSigPub)
  5876  		theJwt, err := aClaim.Encode(opKp)
  5877  		require_NoError(t, err)
  5878  		return accId, accSig, accIdPub, aClaim, theJwt
  5879  	}
  5880  
  5881  	opId, err := nkeys.CreateOperator()
  5882  	require_NoError(t, err)
  5883  	opIdPub, err := opId.PublicKey()
  5884  	require_NoError(t, err)
  5885  
  5886  	opSig, err := nkeys.CreateOperator()
  5887  	require_NoError(t, err)
  5888  	opSigPub, err := opSig.PublicKey()
  5889  	require_NoError(t, err)
  5890  
  5891  	aBadBadKp, aBadGoodKp, aBadPub, _, aBadJwt := newAccount(opId)
  5892  	aGoodBadKp, aGoodGoodKp, aGoodPub, _, aGoodJwt := newAccount(opSig)
  5893  	_, aSysKp, aSysPub, _, aSysJwt := newAccount(opSig)
  5894  
  5895  	oClaim := jwt.NewOperatorClaims(opIdPub)
  5896  	oClaim.StrictSigningKeyUsage = true
  5897  	oClaim.SigningKeys.Add(opSigPub)
  5898  	oClaim.SystemAccount = aSysPub
  5899  	oJwt, err := oClaim.Encode(opId)
  5900  	require_NoError(t, err)
  5901  
  5902  	uBadBadCreds := newUserEx(t, aBadBadKp, false, aBadPub)
  5903  	uBadGoodCreds := newUserEx(t, aBadGoodKp, false, aBadPub)
  5904  	uGoodBadCreds := newUserEx(t, aGoodBadKp, false, aGoodPub)
  5905  	uGoodGoodCreds := newUserEx(t, aGoodGoodKp, false, aGoodPub)
  5906  	uSysCreds := newUserEx(t, aSysKp, false, aSysPub)
  5907  
  5908  	connectTest := func(url string) {
  5909  		for _, test := range []struct {
  5910  			creds string
  5911  			fail  bool
  5912  		}{
  5913  			{uBadBadCreds, true},
  5914  			{uBadGoodCreds, true},
  5915  			{uGoodBadCreds, true},
  5916  			{uGoodGoodCreds, false},
  5917  		} {
  5918  			nc, err := nats.Connect(url, nats.UserCredentials(test.creds))
  5919  			nc.Close()
  5920  			if test.fail {
  5921  				require_Error(t, err)
  5922  			} else {
  5923  				require_NoError(t, err)
  5924  			}
  5925  		}
  5926  	}
  5927  
  5928  	t.Run("resolver", func(t *testing.T) {
  5929  		dirSrv := t.TempDir()
  5930  		cf := createConfFile(t, []byte(fmt.Sprintf(`
  5931  		port: -1
  5932  		operator = %s
  5933  		resolver: {
  5934  			type: full
  5935  			dir: '%s'
  5936  		}
  5937  		resolver_preload = {
  5938  			%s : "%s"
  5939  		}
  5940  		`, oJwt, dirSrv, aSysPub, aSysJwt)))
  5941  		s, _ := RunServerWithConfig(cf)
  5942  		defer s.Shutdown()
  5943  		url := s.ClientURL()
  5944  		if updateJwt(t, url, uSysCreds, aBadJwt, 1) != 0 {
  5945  			t.Fatal("Expected negative response")
  5946  		}
  5947  		if updateJwt(t, url, uSysCreds, aGoodJwt, 1) != 1 {
  5948  			t.Fatal("Expected positive response")
  5949  		}
  5950  		connectTest(url)
  5951  	})
  5952  
  5953  	t.Run("mem-resolver", func(t *testing.T) {
  5954  		cf := createConfFile(t, []byte(fmt.Sprintf(`
  5955  		port: -1
  5956  		operator = %s
  5957  		resolver: MEMORY
  5958  		resolver_preload = {
  5959  			%s : "%s"
  5960  			%s : "%s"
  5961  			%s : "%s"
  5962  		}
  5963  		`, oJwt, aSysPub, aSysJwt, aBadPub, aBadJwt, aGoodPub, aGoodJwt)))
  5964  		s, _ := RunServerWithConfig(cf)
  5965  		defer s.Shutdown()
  5966  		connectTest(s.ClientURL())
  5967  	})
  5968  }
  5969  
  5970  func TestJWTAccountProtectedImport(t *testing.T) {
  5971  	srvFmt := `
  5972  		port: -1
  5973  		operator = %s
  5974  		resolver: MEMORY
  5975  		resolver_preload = {
  5976  			%s : "%s"
  5977  			%s : "%s"
  5978  		} `
  5979  	setupAccounts := func(pass bool) (nkeys.KeyPair, string, string, string, nkeys.KeyPair, string, string, string, string) {
  5980  		// Create accounts and imports/exports.
  5981  		exportKP, _ := nkeys.CreateAccount()
  5982  		exportPub, _ := exportKP.PublicKey()
  5983  		exportAC := jwt.NewAccountClaims(exportPub)
  5984  		exportAC.Exports.Add(&jwt.Export{Subject: "service.*", Type: jwt.Service, AccountTokenPosition: 2})
  5985  		exportAC.Exports.Add(&jwt.Export{Subject: "stream.*", Type: jwt.Stream, AccountTokenPosition: 2})
  5986  		exportJWT, err := exportAC.Encode(oKp)
  5987  		require_NoError(t, err)
  5988  		// create alternative exporter jwt without account token pos set
  5989  		exportAC.Exports = jwt.Exports{}
  5990  		exportAC.Exports.Add(&jwt.Export{Subject: "service.*", Type: jwt.Service})
  5991  		exportAC.Exports.Add(&jwt.Export{Subject: "stream.*", Type: jwt.Stream})
  5992  		exportJWTNoPos, err := exportAC.Encode(oKp)
  5993  		require_NoError(t, err)
  5994  
  5995  		importKP, _ := nkeys.CreateAccount()
  5996  		importPub, _ := importKP.PublicKey()
  5997  		importAc := jwt.NewAccountClaims(importPub)
  5998  		srvcSub, strmSub := "service.foo", "stream.foo"
  5999  		if pass {
  6000  			srvcSub = fmt.Sprintf("service.%s", importPub)
  6001  			strmSub = fmt.Sprintf("stream.%s", importPub)
  6002  		}
  6003  		importAc.Imports.Add(&jwt.Import{Account: exportPub, Subject: jwt.Subject(srvcSub), Type: jwt.Service})
  6004  		importAc.Imports.Add(&jwt.Import{Account: exportPub, Subject: jwt.Subject(strmSub), Type: jwt.Stream})
  6005  		importJWT, err := importAc.Encode(oKp)
  6006  		require_NoError(t, err)
  6007  
  6008  		return exportKP, exportPub, exportJWT, exportJWTNoPos, importKP, importPub, importJWT, srvcSub, strmSub
  6009  	}
  6010  	t.Run("pass", func(t *testing.T) {
  6011  		exportKp, exportPub, exportJWT, _, importKp, importPub, importJWT, srvcSub, strmSub := setupAccounts(true)
  6012  		cf := createConfFile(t, []byte(fmt.Sprintf(srvFmt, ojwt, exportPub, exportJWT, importPub, importJWT)))
  6013  		s, _ := RunServerWithConfig(cf)
  6014  		defer s.Shutdown()
  6015  		ncExp := natsConnect(t, s.ClientURL(), createUserCreds(t, s, exportKp))
  6016  		defer ncExp.Close()
  6017  		ncImp := natsConnect(t, s.ClientURL(), createUserCreds(t, s, importKp))
  6018  		defer ncImp.Close()
  6019  		t.Run("service", func(t *testing.T) {
  6020  			sub, err := ncExp.Subscribe("service.*", func(msg *nats.Msg) {
  6021  				msg.Respond([]byte("world"))
  6022  			})
  6023  			defer sub.Unsubscribe()
  6024  			require_NoError(t, err)
  6025  			ncExp.Flush()
  6026  			msg, err := ncImp.Request(srvcSub, []byte("hello"), time.Second)
  6027  			require_NoError(t, err)
  6028  			require_Equal(t, string(msg.Data), "world")
  6029  		})
  6030  		t.Run("stream", func(t *testing.T) {
  6031  			msgChan := make(chan *nats.Msg, 4)
  6032  			defer close(msgChan)
  6033  			sub, err := ncImp.ChanSubscribe(strmSub, msgChan)
  6034  			defer sub.Unsubscribe()
  6035  			require_NoError(t, err)
  6036  			ncImp.Flush()
  6037  			err = ncExp.Publish("stream.foo", []byte("hello"))
  6038  			require_NoError(t, err)
  6039  			err = ncExp.Publish(strmSub, []byte("hello"))
  6040  			require_NoError(t, err)
  6041  			msg := <-msgChan
  6042  			require_Equal(t, string(msg.Data), "hello")
  6043  			require_True(t, len(msgChan) == 0)
  6044  		})
  6045  	})
  6046  	t.Run("fail", func(t *testing.T) {
  6047  		exportKp, exportPub, exportJWT, _, importKp, importPub, importJWT, srvcSub, strmSub := setupAccounts(false)
  6048  		cf := createConfFile(t, []byte(fmt.Sprintf(srvFmt, ojwt, exportPub, exportJWT, importPub, importJWT)))
  6049  		s, _ := RunServerWithConfig(cf)
  6050  		defer s.Shutdown()
  6051  		ncExp := natsConnect(t, s.ClientURL(), createUserCreds(t, s, exportKp))
  6052  		defer ncExp.Close()
  6053  		ncImp := natsConnect(t, s.ClientURL(), createUserCreds(t, s, importKp))
  6054  		defer ncImp.Close()
  6055  		t.Run("service", func(t *testing.T) {
  6056  			sub, err := ncExp.Subscribe("service.*", func(msg *nats.Msg) {
  6057  				msg.Respond([]byte("world"))
  6058  			})
  6059  			defer sub.Unsubscribe()
  6060  			require_NoError(t, err)
  6061  			ncExp.Flush()
  6062  			_, err = ncImp.Request(srvcSub, []byte("hello"), time.Second)
  6063  			require_Error(t, err)
  6064  			require_Contains(t, err.Error(), "no responders available for request")
  6065  		})
  6066  		t.Run("stream", func(t *testing.T) {
  6067  			msgChan := make(chan *nats.Msg, 4)
  6068  			defer close(msgChan)
  6069  			_, err := ncImp.ChanSubscribe(strmSub, msgChan)
  6070  			require_NoError(t, err)
  6071  			ncImp.Flush()
  6072  			err = ncExp.Publish("stream.foo", []byte("hello"))
  6073  			require_NoError(t, err)
  6074  			err = ncExp.Publish(strmSub, []byte("hello"))
  6075  			require_NoError(t, err)
  6076  			select {
  6077  			case <-msgChan:
  6078  				t.Fatal("did not expect a message")
  6079  			case <-time.After(250 * time.Millisecond):
  6080  			}
  6081  			require_True(t, len(msgChan) == 0)
  6082  		})
  6083  	})
  6084  	t.Run("reload-off-2-on", func(t *testing.T) {
  6085  		exportKp, exportPub, exportJWTOn, exportJWTOff, importKp, _, importJWT, srvcSub, strmSub := setupAccounts(false)
  6086  		dirSrv := t.TempDir()
  6087  		// set up system account. Relying bootstrapping system account to not create JWT
  6088  		sysAcc, err := nkeys.CreateAccount()
  6089  		require_NoError(t, err)
  6090  		sysPub, err := sysAcc.PublicKey()
  6091  		require_NoError(t, err)
  6092  		sysUsrCreds := newUserEx(t, sysAcc, false, sysPub)
  6093  		cf := createConfFile(t, []byte(fmt.Sprintf(`
  6094  		port: -1
  6095  		operator = %s
  6096  		system_account = %s
  6097  		resolver: {
  6098  			type: full
  6099  			dir: '%s'
  6100  		}`, ojwt, sysPub, dirSrv)))
  6101  		s, _ := RunServerWithConfig(cf)
  6102  		defer s.Shutdown()
  6103  		updateJwt(t, s.ClientURL(), sysUsrCreds, importJWT, 1)
  6104  		updateJwt(t, s.ClientURL(), sysUsrCreds, exportJWTOff, 1)
  6105  		ncExp := natsConnect(t, s.ClientURL(), createUserCreds(t, s, exportKp))
  6106  		defer ncExp.Close()
  6107  		ncImp := natsConnect(t, s.ClientURL(), createUserCreds(t, s, importKp))
  6108  		defer ncImp.Close()
  6109  		msgChan := make(chan *nats.Msg, 4)
  6110  		defer close(msgChan)
  6111  		// ensure service passes
  6112  		subSrvc, err := ncExp.Subscribe("service.*", func(msg *nats.Msg) {
  6113  			msg.Respond([]byte("world"))
  6114  		})
  6115  		defer subSrvc.Unsubscribe()
  6116  		require_NoError(t, err)
  6117  		ncExp.Flush()
  6118  		respMst, err := ncImp.Request(srvcSub, []byte("hello"), time.Second)
  6119  		require_NoError(t, err)
  6120  		require_Equal(t, string(respMst.Data), "world")
  6121  		// ensure stream passes
  6122  		subStrm, err := ncImp.ChanSubscribe(strmSub, msgChan)
  6123  		defer subStrm.Unsubscribe()
  6124  		require_NoError(t, err)
  6125  		ncImp.Flush()
  6126  		err = ncExp.Publish(strmSub, []byte("hello"))
  6127  		require_NoError(t, err)
  6128  		msg := <-msgChan
  6129  		require_Equal(t, string(msg.Data), "hello")
  6130  		require_True(t, len(msgChan) == 0)
  6131  
  6132  		updateJwt(t, s.ClientURL(), sysUsrCreds, exportJWTOn, 1)
  6133  
  6134  		// ensure service fails
  6135  		_, err = ncImp.Request(srvcSub, []byte("hello"), time.Second)
  6136  		require_Error(t, err)
  6137  		require_Contains(t, err.Error(), "timeout")
  6138  		s.AccountResolver().Store(exportPub, exportJWTOn)
  6139  		// ensure stream fails
  6140  		err = ncExp.Publish(strmSub, []byte("hello"))
  6141  		require_NoError(t, err)
  6142  		select {
  6143  		case <-msgChan:
  6144  			t.Fatal("did not expect a message")
  6145  		case <-time.After(250 * time.Millisecond):
  6146  		}
  6147  		require_True(t, len(msgChan) == 0)
  6148  	})
  6149  }
  6150  
  6151  // Headers are ignored in claims update, but passing them should not cause error.
  6152  func TestJWTClaimsUpdateWithHeaders(t *testing.T) {
  6153  	skp, spub := createKey(t)
  6154  	newUser(t, skp)
  6155  
  6156  	sclaim := jwt.NewAccountClaims(spub)
  6157  	encodeClaim(t, sclaim, spub)
  6158  
  6159  	akp, apub := createKey(t)
  6160  	newUser(t, akp)
  6161  	claim := jwt.NewAccountClaims(apub)
  6162  	jwtClaim := encodeClaim(t, claim, apub)
  6163  
  6164  	dirSrv := t.TempDir()
  6165  
  6166  	conf := createConfFile(t, []byte(fmt.Sprintf(`
  6167  		listen: 127.0.0.1:-1
  6168  		operator: %s
  6169  		system_account: %s
  6170  		resolver: {
  6171  			type: full
  6172  			dir: '%s'
  6173  		}
  6174      `, ojwt, spub, dirSrv)))
  6175  
  6176  	s, _ := RunServerWithConfig(conf)
  6177  	defer s.Shutdown()
  6178  
  6179  	type zapi struct {
  6180  		Server *ServerInfo
  6181  		Data   *Connz
  6182  		Error  *ApiError
  6183  	}
  6184  
  6185  	sc := natsConnect(t, s.ClientURL(), createUserCreds(t, s, skp))
  6186  	defer sc.Close()
  6187  	// Pass claims update with headers.
  6188  	msg := &nats.Msg{
  6189  		Subject: "$SYS.REQ.CLAIMS.UPDATE",
  6190  		Data:    []byte(jwtClaim),
  6191  		Header:  map[string][]string{"key": {"value"}},
  6192  	}
  6193  	resp, err := sc.RequestMsg(msg, time.Second)
  6194  	if err != nil {
  6195  		t.Fatalf("Unexpected error: %v", err)
  6196  	}
  6197  	var cz zapi
  6198  	if err := json.Unmarshal(resp.Data, &cz); err != nil {
  6199  		t.Fatalf("Unexpected error: %v", err)
  6200  	}
  6201  	if cz.Error != nil {
  6202  		t.Fatalf("Unexpected error: %+v", cz.Error)
  6203  	}
  6204  }
  6205  
  6206  func TestJWTMappings(t *testing.T) {
  6207  	sysKp, syspub := createKey(t)
  6208  	sysJwt := encodeClaim(t, jwt.NewAccountClaims(syspub), syspub)
  6209  	sysCreds := newUser(t, sysKp)
  6210  
  6211  	// create two jwt, one with and one without mapping
  6212  	aKp, aPub := createKey(t)
  6213  	aClaim := jwt.NewAccountClaims(aPub)
  6214  	aJwtNoM := encodeClaim(t, aClaim, aPub)
  6215  	aClaim.AddMapping("foo1", jwt.WeightedMapping{Subject: "bar1"})
  6216  	aJwtMap1 := encodeClaim(t, aClaim, aPub)
  6217  
  6218  	aClaim.Mappings = map[jwt.Subject][]jwt.WeightedMapping{}
  6219  	aClaim.AddMapping("foo2", jwt.WeightedMapping{Subject: "bar2"})
  6220  	aJwtMap2 := encodeClaim(t, aClaim, aPub)
  6221  
  6222  	dirSrv := t.TempDir()
  6223  	conf := createConfFile(t, []byte(fmt.Sprintf(`
  6224  		listen: 127.0.0.1:-1
  6225  		operator: %s
  6226  		system_account: %s
  6227  		resolver: {
  6228  			type: full
  6229  			dir: '%s'
  6230  		}
  6231      `, ojwt, syspub, dirSrv)))
  6232  	srv, _ := RunServerWithConfig(conf)
  6233  	defer srv.Shutdown()
  6234  	updateJwt(t, srv.ClientURL(), sysCreds, sysJwt, 1) // update system account jwt
  6235  
  6236  	test := func(pub, sub string, fail bool) {
  6237  		t.Helper()
  6238  		nc := natsConnect(t, srv.ClientURL(), createUserCreds(t, srv, aKp))
  6239  		defer nc.Close()
  6240  		s, err := nc.SubscribeSync(sub)
  6241  		require_NoError(t, err)
  6242  		nc.Flush()
  6243  		err = nc.Publish(pub, nil)
  6244  		require_NoError(t, err)
  6245  		_, err = s.NextMsg(500 * time.Millisecond)
  6246  		switch {
  6247  		case fail && err == nil:
  6248  			t.Fatal("expected error, got none")
  6249  		case !fail && err != nil:
  6250  			t.Fatalf("expected no error, got %v", err)
  6251  		}
  6252  	}
  6253  
  6254  	// turn mappings on
  6255  	require_Len(t, 1, updateJwt(t, srv.ClientURL(), sysCreds, aJwtMap1, 1))
  6256  	test("foo1", "bar1", false)
  6257  	// alter mappings
  6258  	require_Len(t, 1, updateJwt(t, srv.ClientURL(), sysCreds, aJwtMap2, 1))
  6259  	test("foo1", "bar1", true)
  6260  	test("foo2", "bar2", false)
  6261  	// turn mappings off
  6262  	require_Len(t, 1, updateJwt(t, srv.ClientURL(), sysCreds, aJwtNoM, 1))
  6263  	test("foo2", "bar2", true)
  6264  }
  6265  
  6266  func TestJWTOperatorPinnedAccounts(t *testing.T) {
  6267  	kps, pubs, jwts := [4]nkeys.KeyPair{}, [4]string{}, [4]string{}
  6268  	for i := 0; i < 4; i++ {
  6269  		kps[i], pubs[i] = createKey(t)
  6270  		jwts[i] = encodeClaim(t, jwt.NewAccountClaims(pubs[i]), pubs[i])
  6271  	}
  6272  	// create system account user credentials, index 0 is handled as system account
  6273  	newUser(t, kps[0])
  6274  
  6275  	cfgCommon := fmt.Sprintf(`
  6276  		listen: 127.0.0.1:-1
  6277  		operator: %s
  6278  		system_account: %s
  6279  		resolver: MEM
  6280  		resolver_preload: {
  6281  			%s:%s
  6282  			%s:%s
  6283  			%s:%s
  6284  			%s:%s
  6285  		}`, ojwt, pubs[0], pubs[0], jwts[0], pubs[1], jwts[1], pubs[2], jwts[2], pubs[3], jwts[3])
  6286  	cfgFmt := cfgCommon + `
  6287  		resolver_pinned_accounts: [%s, %s]
  6288  	`
  6289  	conf := createConfFile(t, []byte(fmt.Sprintf(cfgFmt, pubs[1], pubs[2])))
  6290  	srv, _ := RunServerWithConfig(conf)
  6291  	defer srv.Shutdown()
  6292  
  6293  	connectPass := func(keys ...nkeys.KeyPair) {
  6294  		for _, kp := range keys {
  6295  			nc, err := nats.Connect(srv.ClientURL(), createUserCreds(t, srv, kp))
  6296  			require_NoError(t, err)
  6297  			defer nc.Close()
  6298  		}
  6299  	}
  6300  	var pinnedFail uint64
  6301  	connectFail := func(key nkeys.KeyPair) {
  6302  		_, err := nats.Connect(srv.ClientURL(), createUserCreds(t, srv, key))
  6303  		require_Error(t, err)
  6304  		require_Contains(t, err.Error(), "Authorization Violation")
  6305  		v, err := srv.Varz(&VarzOptions{})
  6306  		require_NoError(t, err)
  6307  		require_True(t, pinnedFail+1 == v.PinnedAccountFail)
  6308  		pinnedFail = v.PinnedAccountFail
  6309  	}
  6310  
  6311  	connectPass(kps[0], kps[1], kps[2]) // make sure user from accounts listed and system account (index 0) work
  6312  	connectFail(kps[3])                 // make sure the other user does not work
  6313  	// reload and test again
  6314  	reloadUpdateConfig(t, srv, conf, fmt.Sprintf(cfgFmt, pubs[2], pubs[3]))
  6315  	connectPass(kps[0], kps[2], kps[3]) // make sure user from accounts listed and system account (index 0) work
  6316  	connectFail(kps[1])                 // make sure the other user does not work
  6317  	// completely disable and test again
  6318  	reloadUpdateConfig(t, srv, conf, cfgCommon)
  6319  	connectPass(kps[0], kps[1], kps[2], kps[3]) // make sure every account and system account (index 0) can connect
  6320  	// re-enable and test again
  6321  	reloadUpdateConfig(t, srv, conf, fmt.Sprintf(cfgFmt, pubs[2], pubs[3]))
  6322  	connectPass(kps[0], kps[2], kps[3]) // make sure user from accounts listed and system account (index 0) work
  6323  	connectFail(kps[1])                 // make sure the other user does not work
  6324  }
  6325  
  6326  func TestJWTNoSystemAccountButNatsResolver(t *testing.T) {
  6327  	dirSrv := t.TempDir()
  6328  	for _, resType := range []string{"full", "cache"} {
  6329  		t.Run(resType, func(t *testing.T) {
  6330  			conf := createConfFile(t, []byte(fmt.Sprintf(`
  6331  			listen: 127.0.0.1:-1
  6332  			operator: %s
  6333  			resolver: {
  6334  				type: %s
  6335  				dir: '%s'
  6336  			}`, ojwt, resType, dirSrv)))
  6337  			opts := LoadConfig(conf)
  6338  			s, err := NewServer(opts)
  6339  			// Since the server cannot be stopped, since it did not start,
  6340  			// let's manually close the account resolver to avoid leaking go routines.
  6341  			opts.AccountResolver.Close()
  6342  			s.Shutdown()
  6343  			require_Error(t, err)
  6344  			require_Contains(t, err.Error(), "the system account needs to be specified in configuration or the operator jwt")
  6345  		})
  6346  	}
  6347  }
  6348  
  6349  func TestJWTAccountConnzAccessAfterClaimUpdate(t *testing.T) {
  6350  	skp, spub := createKey(t)
  6351  	newUser(t, skp)
  6352  
  6353  	sclaim := jwt.NewAccountClaims(spub)
  6354  	sclaim.AddMapping("foo.bar", jwt.WeightedMapping{Subject: "foo.baz"})
  6355  	sjwt := encodeClaim(t, sclaim, spub)
  6356  
  6357  	// create two jwt, one with and one without mapping
  6358  	akp, apub := createKey(t)
  6359  	newUser(t, akp)
  6360  	claim := jwt.NewAccountClaims(apub)
  6361  	jwt1 := encodeClaim(t, claim, apub)
  6362  	claim.AddMapping("foo.bar", jwt.WeightedMapping{Subject: "foo.baz"})
  6363  	jwt2 := encodeClaim(t, claim, apub)
  6364  
  6365  	dirSrv := t.TempDir()
  6366  
  6367  	conf := createConfFile(t, []byte(fmt.Sprintf(`
  6368  		listen: 127.0.0.1:-1
  6369  		operator: %s
  6370  		system_account: %s
  6371  		resolver: {
  6372  			type: full
  6373  			dir: '%s'
  6374  		}
  6375      `, ojwt, spub, dirSrv)))
  6376  
  6377  	s, _ := RunServerWithConfig(conf)
  6378  	defer s.Shutdown()
  6379  
  6380  	type zapi struct {
  6381  		Server *ServerInfo
  6382  		Data   *Connz
  6383  		Error  *ApiError
  6384  	}
  6385  
  6386  	updateJWT := func(jwt string) {
  6387  		t.Helper()
  6388  		sc := natsConnect(t, s.ClientURL(), createUserCreds(t, s, skp))
  6389  		defer sc.Close()
  6390  		resp, err := sc.Request("$SYS.REQ.CLAIMS.UPDATE", []byte(jwt), time.Second)
  6391  		if err != nil {
  6392  			t.Fatalf("Unexpected error: %v", err)
  6393  		}
  6394  		var cz zapi
  6395  		if err := json.Unmarshal(resp.Data, &cz); err != nil {
  6396  			t.Fatalf("Unexpected error: %v", err)
  6397  		}
  6398  		if cz.Error != nil {
  6399  			t.Fatalf("Unexpected error: %+v", cz.Error)
  6400  		}
  6401  	}
  6402  
  6403  	updateJWT(jwt1)
  6404  
  6405  	nc := natsConnect(t, s.ClientURL(), createUserCreds(t, s, akp))
  6406  	defer nc.Close()
  6407  
  6408  	doRequest := func() {
  6409  		t.Helper()
  6410  		resp, err := nc.Request("$SYS.REQ.SERVER.PING.CONNZ", nil, time.Second)
  6411  		if err != nil {
  6412  			t.Fatalf("Unexpected error: %v", err)
  6413  		}
  6414  		var cz zapi
  6415  		if err := json.Unmarshal(resp.Data, &cz); err != nil {
  6416  			t.Fatalf("Unexpected error: %v", err)
  6417  		}
  6418  		if cz.Error != nil {
  6419  			t.Fatalf("Unexpected error: %+v", cz.Error)
  6420  		}
  6421  	}
  6422  
  6423  	doRequest()
  6424  	updateJWT(jwt2)
  6425  	// If we accidentally wipe the system import this will fail with no responders.
  6426  	doRequest()
  6427  	// Now test updating system account.
  6428  	updateJWT(sjwt)
  6429  	// If export was wiped this would fail with timeout.
  6430  	doRequest()
  6431  }
  6432  
  6433  func TestAccountWeightedMappingInSuperCluster(t *testing.T) {
  6434  	skp, spub := createKey(t)
  6435  	sysClaim := jwt.NewAccountClaims(spub)
  6436  	sysClaim.Name = "SYS"
  6437  	sysCreds := newUser(t, skp)
  6438  
  6439  	akp, apub := createKey(t)
  6440  	aUsr := createUserCreds(t, nil, akp)
  6441  	claim := jwt.NewAccountClaims(apub)
  6442  	aJwtMap := encodeClaim(t, claim, apub)
  6443  
  6444  	// We are using the createJetStreamSuperClusterWithTemplateAndModHook()
  6445  	// helper, but this test is not about JetStream...
  6446  	tmpl := `
  6447  		listen: 127.0.0.1:-1
  6448  		server_name: %s
  6449  		jetstream: {max_mem_store: 256MB, max_file_store: 2GB, store_dir: '%s'}
  6450  		cluster {
  6451  			name: %s
  6452  			listen: 127.0.0.1:%d
  6453  			routes = [%s]
  6454  		}
  6455      `
  6456  
  6457  	sc := createJetStreamSuperClusterWithTemplateAndModHook(t, tmpl, 3, 3,
  6458  		func(serverName, clusterName, storeDir, conf string) string {
  6459  			dirSrv := t.TempDir()
  6460  			return fmt.Sprintf(`%s
  6461  				operator: %s
  6462  				system_account: %s
  6463  				resolver: {
  6464  					type: full
  6465  					dir: '%s'
  6466  				}
  6467  			`, conf, ojwt, spub, dirSrv)
  6468  		}, nil)
  6469  	defer sc.shutdown()
  6470  
  6471  	// Update from C2
  6472  	require_Len(t, 1, updateJwt(t, sc.clusterForName("C2").randomServer().ClientURL(), sysCreds, aJwtMap, 1))
  6473  
  6474  	// We will connect our services in the C3 cluster.
  6475  	nc1 := natsConnect(t, sc.clusterForName("C3").randomServer().ClientURL(), aUsr)
  6476  	defer nc1.Close()
  6477  	nc2 := natsConnect(t, sc.clusterForName("C3").randomServer().ClientURL(), aUsr)
  6478  	defer nc2.Close()
  6479  
  6480  	natsSub(t, nc1, "foo", func(m *nats.Msg) {
  6481  		m.Respond([]byte("foo"))
  6482  	})
  6483  	natsSub(t, nc1, "bar.v1", func(m *nats.Msg) {
  6484  		m.Respond([]byte("v1"))
  6485  	})
  6486  	natsSub(t, nc2, "bar.v2", func(m *nats.Msg) {
  6487  		m.Respond([]byte("v2"))
  6488  	})
  6489  	natsFlush(t, nc1)
  6490  	natsFlush(t, nc2)
  6491  
  6492  	// Now we will update the account to add weighted subject mapping
  6493  	claim.Mappings = map[jwt.Subject][]jwt.WeightedMapping{}
  6494  	// Start with foo->bar.v2 at 40%, the server will auto-add foo->foo at 60%.
  6495  	wm := []jwt.WeightedMapping{{Subject: "bar.v2", Weight: 40}}
  6496  	claim.AddMapping("foo", wm...)
  6497  	aJwtMap = encodeClaim(t, claim, apub)
  6498  
  6499  	// We will update from C2
  6500  	require_Len(t, 1, updateJwt(t, sc.clusterForName("C2").randomServer().ClientURL(), sysCreds, aJwtMap, 1))
  6501  
  6502  	time.Sleep(time.Second)
  6503  
  6504  	// And we will publish from C1
  6505  	nc := natsConnect(t, sc.clusterForName("C1").randomServer().ClientURL(), aUsr)
  6506  	defer nc.Close()
  6507  
  6508  	var foo, v1, v2 int
  6509  	pubAndCount := func() {
  6510  		for i := 0; i < 1000; i++ {
  6511  			msg, err := nc.Request("foo", []byte("req"), 500*time.Millisecond)
  6512  			if err != nil {
  6513  				continue
  6514  			}
  6515  			switch string(msg.Data) {
  6516  			case "foo":
  6517  				foo++
  6518  			case "v1":
  6519  				v1++
  6520  			case "v2":
  6521  				v2++
  6522  			}
  6523  		}
  6524  	}
  6525  	pubAndCount()
  6526  	if foo < 550 || foo > 650 {
  6527  		t.Fatalf("Expected foo to receive 60%%, got %v/1000", foo)
  6528  	}
  6529  	if v1 != 0 {
  6530  		t.Fatalf("Expected v1 to receive no message, got %v/1000", v1)
  6531  	}
  6532  	if v2 < 350 || v2 > 450 {
  6533  		t.Fatalf("Expected v2 to receive 40%%, got %v/1000", v2)
  6534  	}
  6535  
  6536  	// Now send a new update with foo-> bar.v2(40) and bar.v1(60).
  6537  	// The auto-add of "foo" should no longer be used by the server.
  6538  	wm = []jwt.WeightedMapping{
  6539  		{Subject: "bar.v2", Weight: 40},
  6540  		{Subject: "bar.v1", Weight: 60},
  6541  	}
  6542  	claim.AddMapping("foo", wm...)
  6543  	aJwtMap = encodeClaim(t, claim, apub)
  6544  
  6545  	// We will update from C2
  6546  	require_Len(t, 1, updateJwt(t, sc.clusterForName("C2").randomServer().ClientURL(), sysCreds, aJwtMap, 1))
  6547  
  6548  	time.Sleep(time.Second)
  6549  
  6550  	foo, v1, v2 = 0, 0, 0
  6551  	pubAndCount()
  6552  	if foo != 0 {
  6553  		t.Fatalf("Expected foo to receive no message, got %v/1000", foo)
  6554  	}
  6555  	if v1 < 550 || v1 > 650 {
  6556  		t.Fatalf("Expected v1 to receive 60%%, got %v/1000", v1)
  6557  	}
  6558  	if v2 < 350 || v2 > 450 {
  6559  		t.Fatalf("Expected v2 to receive 40%%, got %v/1000", v2)
  6560  	}
  6561  }
  6562  
  6563  func TestServerOperatorModeNoAuthRequired(t *testing.T) {
  6564  	_, spub := createKey(t)
  6565  	sysClaim := jwt.NewAccountClaims(spub)
  6566  	sysClaim.Name = "$SYS"
  6567  	sysJwt, err := sysClaim.Encode(oKp)
  6568  	require_NoError(t, err)
  6569  
  6570  	akp, apub := createKey(t)
  6571  	accClaim := jwt.NewAccountClaims(apub)
  6572  	accClaim.Name = "TEST"
  6573  	accJwt, err := accClaim.Encode(oKp)
  6574  	require_NoError(t, err)
  6575  
  6576  	ukp, _ := nkeys.CreateUser()
  6577  	seed, _ := ukp.Seed()
  6578  	upub, _ := ukp.PublicKey()
  6579  	nuc := jwt.NewUserClaims(upub)
  6580  	ujwt, err := nuc.Encode(akp)
  6581  	require_NoError(t, err)
  6582  	creds := genCredsFile(t, ujwt, seed)
  6583  
  6584  	dirSrv := t.TempDir()
  6585  
  6586  	conf := createConfFile(t, []byte(fmt.Sprintf(`
  6587  		listen: 127.0.0.1:-1
  6588  		server_name: srv-A
  6589  		operator: %s
  6590  		system_account: %s
  6591  		resolver: {
  6592  			type: full
  6593  			dir: '%s'
  6594  			interval: "200ms"
  6595  			limit: 4
  6596  		}
  6597  		resolver_preload: {
  6598  			%s: %s
  6599  			%s: %s
  6600  		}
  6601      `, ojwt, spub, dirSrv, spub, sysJwt, apub, accJwt)))
  6602  
  6603  	s, _ := RunServerWithConfig(conf)
  6604  	defer s.Shutdown()
  6605  
  6606  	nc := natsConnect(t, s.ClientURL(), nats.UserCredentials(creds))
  6607  	defer nc.Close()
  6608  
  6609  	require_True(t, nc.AuthRequired())
  6610  }
  6611  
  6612  func TestServerOperatorModeUserInfoExpiration(t *testing.T) {
  6613  	_, spub := createKey(t)
  6614  	sysClaim := jwt.NewAccountClaims(spub)
  6615  	sysClaim.Name = "$SYS"
  6616  	sysJwt, err := sysClaim.Encode(oKp)
  6617  	require_NoError(t, err)
  6618  
  6619  	akp, apub := createKey(t)
  6620  	accClaim := jwt.NewAccountClaims(apub)
  6621  	accClaim.Name = "TEST"
  6622  	accJwt, err := accClaim.Encode(oKp)
  6623  	require_NoError(t, err)
  6624  
  6625  	conf := createConfFile(t, []byte(fmt.Sprintf(`
  6626  				listen: 127.0.0.1:-1
  6627  				operator: %s
  6628  				system_account: %s
  6629  				resolver: MEM
  6630  				resolver_preload: {
  6631  					%s: %s
  6632  					%s: %s
  6633  				}
  6634  			`, ojwt, spub, apub, accJwt, spub, sysJwt)))
  6635  	defer removeFile(t, conf)
  6636  
  6637  	s, _ := RunServerWithConfig(conf)
  6638  	defer s.Shutdown()
  6639  
  6640  	expires := time.Now().Add(time.Minute)
  6641  	creds := createUserWithLimit(t, akp, expires, func(j *jwt.UserPermissionLimits) {})
  6642  
  6643  	nc := natsConnect(t, s.ClientURL(), nats.UserCredentials(creds))
  6644  	defer nc.Close()
  6645  
  6646  	resp, err := nc.Request("$SYS.REQ.USER.INFO", nil, time.Second)
  6647  	require_NoError(t, err)
  6648  	now := time.Now()
  6649  
  6650  	response := ServerAPIResponse{Data: &UserInfo{}}
  6651  	err = json.Unmarshal(resp.Data, &response)
  6652  	require_NoError(t, err)
  6653  
  6654  	userInfo := response.Data.(*UserInfo)
  6655  	require_True(t, userInfo.Expires != 0)
  6656  
  6657  	// We need to round the expiration time to the second because the server
  6658  	// will truncate the expiration time to the second.
  6659  	expiresDurRounded := expires.Sub(now).Truncate(time.Second)
  6660  
  6661  	// Checking range to avoid flaky tests where the expiration time is
  6662  	// off by a couple of seconds.
  6663  	require_True(t, expiresDurRounded >= userInfo.Expires-2*time.Second && expiresDurRounded <= userInfo.Expires+2*time.Second)
  6664  }
  6665  
  6666  func TestJWTAccountNATSResolverWrongCreds(t *testing.T) {
  6667  	require_NoLocalOrRemoteConnections := func(account string, srvs ...*Server) {
  6668  		t.Helper()
  6669  		for _, srv := range srvs {
  6670  			if acc, ok := srv.accounts.Load(account); ok {
  6671  				checkAccClientsCount(t, acc.(*Account), 0)
  6672  			}
  6673  		}
  6674  	}
  6675  	connect := func(url string, credsfile string, acc string, srvs ...*Server) {
  6676  		t.Helper()
  6677  		nc := natsConnect(t, url, nats.UserCredentials(credsfile), nats.Timeout(5*time.Second))
  6678  		nc.Close()
  6679  		require_NoLocalOrRemoteConnections(acc, srvs...)
  6680  	}
  6681  	createAccountAndUser := func(limit bool, done chan struct{}, pubKey, jwt1, jwt2, creds *string) {
  6682  		t.Helper()
  6683  		kp, _ := nkeys.CreateAccount()
  6684  		*pubKey, _ = kp.PublicKey()
  6685  		claim := jwt.NewAccountClaims(*pubKey)
  6686  		var err error
  6687  		*jwt1, err = claim.Encode(oKp)
  6688  		require_NoError(t, err)
  6689  		*jwt2, err = claim.Encode(oKp)
  6690  		require_NoError(t, err)
  6691  		ukp, _ := nkeys.CreateUser()
  6692  		seed, _ := ukp.Seed()
  6693  		upub, _ := ukp.PublicKey()
  6694  		uclaim := newJWTTestUserClaims()
  6695  		uclaim.Subject = upub
  6696  		ujwt, err := uclaim.Encode(kp)
  6697  		require_NoError(t, err)
  6698  		*creds = genCredsFile(t, ujwt, seed)
  6699  		done <- struct{}{}
  6700  	}
  6701  	// Create Accounts and corresponding user creds.
  6702  	doneChan := make(chan struct{}, 4)
  6703  	defer close(doneChan)
  6704  	var syspub, sysjwt, dummy1, sysCreds string
  6705  	createAccountAndUser(false, doneChan, &syspub, &sysjwt, &dummy1, &sysCreds)
  6706  
  6707  	var apub, ajwt1, ajwt2, aCreds string
  6708  	createAccountAndUser(true, doneChan, &apub, &ajwt1, &ajwt2, &aCreds)
  6709  
  6710  	var bpub, bjwt1, bjwt2, bCreds string
  6711  	createAccountAndUser(true, doneChan, &bpub, &bjwt1, &bjwt2, &bCreds)
  6712  
  6713  	// The one that is going to be missing.
  6714  	var cpub, cjwt1, cjwt2, cCreds string
  6715  	createAccountAndUser(true, doneChan, &cpub, &cjwt1, &cjwt2, &cCreds)
  6716  	for i := 0; i < cap(doneChan); i++ {
  6717  		<-doneChan
  6718  	}
  6719  	// Create one directory for each server
  6720  	dirA := t.TempDir()
  6721  	dirB := t.TempDir()
  6722  	dirC := t.TempDir()
  6723  
  6724  	// Store accounts on servers A and B, then let C sync on its own.
  6725  	writeJWT(t, dirA, apub, ajwt1)
  6726  	writeJWT(t, dirB, bpub, bjwt1)
  6727  
  6728  	/////////////////////////////////////////
  6729  	//                                     //
  6730  	//   Server A: has creds from client A //
  6731  	//                                     //
  6732  	/////////////////////////////////////////
  6733  	confA := createConfFile(t, []byte(fmt.Sprintf(`
  6734  		listen: 127.0.0.1:-1
  6735  		server_name: srv-A
  6736  		operator: %s
  6737  		system_account: %s
  6738                  debug: true
  6739  		resolver: {
  6740  			type: full
  6741  			dir: '%s'
  6742  			allow_delete: true
  6743  			timeout: "1.5s"
  6744  			interval: "200ms"
  6745  		}
  6746  		resolver_preload: {
  6747  			%s: %s
  6748  		}
  6749  		cluster {
  6750  			name: clust
  6751  			listen: 127.0.0.1:-1
  6752  			no_advertise: true
  6753  		}
  6754         `, ojwt, syspub, dirA, apub, ajwt1)))
  6755  	sA, _ := RunServerWithConfig(confA)
  6756  	defer sA.Shutdown()
  6757  	require_JWTPresent(t, dirA, apub)
  6758  
  6759  	/////////////////////////////////////////
  6760  	//                                     //
  6761  	//   Server B: has creds from client B //
  6762  	//                                     //
  6763  	/////////////////////////////////////////
  6764  	confB := createConfFile(t, []byte(fmt.Sprintf(`
  6765  		listen: 127.0.0.1:-1
  6766  		server_name: srv-B
  6767  		operator: %s
  6768  		system_account: %s
  6769  		resolver: {
  6770  			type: full
  6771  			dir: '%s'
  6772  			allow_delete: true
  6773  			timeout: "1.5s"
  6774  			interval: "200ms"
  6775  		}
  6776  		cluster {
  6777  			name: clust
  6778  			listen: 127.0.0.1:-1
  6779  			no_advertise: true
  6780  			routes [
  6781  				nats-route://127.0.0.1:%d
  6782  			]
  6783  		}
  6784          `, ojwt, syspub, dirB, sA.opts.Cluster.Port)))
  6785  	sB, _ := RunServerWithConfig(confB)
  6786  	defer sB.Shutdown()
  6787  
  6788  	/////////////////////////////////////////
  6789  	//                                     //
  6790  	//   Server C: has no creds            //
  6791  	//                                     //
  6792  	/////////////////////////////////////////
  6793  	fmtC := `
  6794  		listen: 127.0.0.1:-1
  6795  		server_name: srv-C
  6796  		operator: %s
  6797  		system_account: %s
  6798  		resolver: {
  6799  			type: full
  6800  			dir: '%s'
  6801  			allow_delete: true
  6802  			timeout: "1.5s"
  6803  			interval: "200ms"
  6804  		}
  6805  		cluster {
  6806  			name: clust
  6807  			listen: 127.0.0.1:-1
  6808  			no_advertise: true
  6809  			routes [
  6810  				nats-route://127.0.0.1:%d
  6811  			]
  6812  		}
  6813      `
  6814  	confClongTTL := createConfFile(t, []byte(fmt.Sprintf(fmtC, ojwt, syspub, dirC, sA.opts.Cluster.Port)))
  6815  	sC, _ := RunServerWithConfig(confClongTTL) // use long ttl to assure it is not kicking
  6816  	defer sC.Shutdown()
  6817  
  6818  	// startup cluster
  6819  	checkClusterFormed(t, sA, sB, sC)
  6820  	time.Sleep(1 * time.Second) // wait for the protocol to converge
  6821  	// // Check all accounts
  6822  	require_JWTPresent(t, dirA, apub) // was already present on startup
  6823  	require_JWTPresent(t, dirB, apub) // was copied from server A
  6824  	require_JWTPresent(t, dirA, bpub) // was copied from server B
  6825  	require_JWTPresent(t, dirB, bpub) // was already present on startup
  6826  
  6827  	// There should be no state about the missing account.
  6828  	require_JWTAbsent(t, dirA, cpub)
  6829  	require_JWTAbsent(t, dirB, cpub)
  6830  	require_JWTAbsent(t, dirC, cpub)
  6831  
  6832  	// system account client can connect to every server
  6833  	connect(sA.ClientURL(), sysCreds, "")
  6834  	connect(sB.ClientURL(), sysCreds, "")
  6835  	connect(sC.ClientURL(), sysCreds, "")
  6836  
  6837  	// A and B clients can connect to any server.
  6838  	connect(sA.ClientURL(), aCreds, "")
  6839  	connect(sB.ClientURL(), aCreds, "")
  6840  	connect(sC.ClientURL(), aCreds, "")
  6841  	connect(sA.ClientURL(), bCreds, "")
  6842  	connect(sB.ClientURL(), bCreds, "")
  6843  	connect(sC.ClientURL(), bCreds, "")
  6844  
  6845  	// Check that trying to connect with bad credentials should not hang until the fetch timeout
  6846  	// and instead return a faster response when an account is not found.
  6847  	_, err := nats.Connect(sC.ClientURL(), nats.UserCredentials(cCreds), nats.Timeout(500*time.Second))
  6848  	if err != nil && !errors.Is(err, nats.ErrAuthorization) {
  6849  		t.Fatalf("Expected auth error: %v", err)
  6850  	}
  6851  }