github.com/nats-io/nats-server/v2@v2.11.0-preview.2/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 ...any) {
  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]any)
  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, _ 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]any{}
  4996  			err = json.Unmarshal(m.Data, &obj)
  4997  			require_NoError(t, err)
  4998  			// test if shared is honored
  4999  			reqInfo := obj["requestor"].(map[string]any)
  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  
  5193  	createImportingAccountClaim := func(aImpKp nkeys.KeyPair, aExpPub string, ac *jwt.ActivationClaims) (string, string) {
  5194  		t.Helper()
  5195  		token, err := ac.Encode(aExpKp)
  5196  		require_NoError(t, err)
  5197  
  5198  		aImpPub, err := aImpKp.PublicKey()
  5199  		require_NoError(t, err)
  5200  		aImpClaim := jwt.NewAccountClaims(aImpPub)
  5201  		aImpClaim.Name = "Import"
  5202  		aImpClaim.Imports.Add(&jwt.Import{
  5203  			Subject: "$events.*.$in.*.>",
  5204  			Type:    jwt.Stream,
  5205  			Account: aExpPub,
  5206  			Token:   token,
  5207  		})
  5208  		aImpJwt := encodeClaim(t, aImpClaim, aImpPub)
  5209  		aImpCreds := newUser(t, aImpKp)
  5210  		return aImpJwt, aImpCreds
  5211  	}
  5212  
  5213  	testConnect := func(aExpPub, aExpJwt, aImpPub, aImpJwt, aImpCreds string) {
  5214  		t.Helper()
  5215  		ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  5216  			if r.URL.Path == "/A/" {
  5217  				// Server startup
  5218  				w.Write(nil)
  5219  			} else if r.URL.Path == "/A/"+aExpPub {
  5220  				w.Write([]byte(aExpJwt))
  5221  			} else if r.URL.Path == "/A/"+aImpPub {
  5222  				w.Write([]byte(aImpJwt))
  5223  			} else {
  5224  				t.Fatal("not expected")
  5225  			}
  5226  		}))
  5227  		defer ts.Close()
  5228  		cf := createConfFile(t, []byte(fmt.Sprintf(`
  5229  			listen: 127.0.0.1:-1
  5230  			operator: %s
  5231  			resolver: URL("%s/A/")
  5232  		`, ojwt, ts.URL)))
  5233  
  5234  		s, opts := RunServerWithConfig(cf)
  5235  		defer s.Shutdown()
  5236  
  5237  		ncImp, err := nats.Connect(fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port), nats.UserCredentials(aImpCreds))
  5238  		require_Error(t, err) // misuse needs to result in an error
  5239  		defer ncImp.Close()
  5240  	}
  5241  
  5242  	testNatsResolver := func(aImpJwt string) {
  5243  		t.Helper()
  5244  		dirSrv := t.TempDir()
  5245  		cf := createConfFile(t, []byte(fmt.Sprintf(`
  5246  			listen: 127.0.0.1:-1
  5247  			operator: %s
  5248  			system_account: %s
  5249  			resolver: {
  5250  				type: full
  5251  				dir: '%s'
  5252  			}
  5253  		`, ojwt, syspub, dirSrv)))
  5254  
  5255  		s, _ := RunServerWithConfig(cf)
  5256  		defer s.Shutdown()
  5257  
  5258  		require_True(t, updateJwt(t, s.ClientURL(), sysCreds, sysJwt, 1) == 1)
  5259  		require_True(t, updateJwt(t, s.ClientURL(), sysCreds, aExpJwt, 1) == 1)
  5260  		require_True(t, updateJwt(t, s.ClientURL(), sysCreds, aImpJwt, 1) == 0) // assure this did not succeed
  5261  	}
  5262  
  5263  	t.Run("wrong-account", func(t *testing.T) {
  5264  		aImpKp, aImpPub := createKey(t)
  5265  		ac := &jwt.ActivationClaims{}
  5266  		_, ac.Subject = createKey(t) // on purpose issue this token for another account
  5267  		ac.ImportSubject = "$events.*.$in.*.>"
  5268  		ac.ImportType = jwt.Stream
  5269  
  5270  		aImpJwt, aImpCreds := createImportingAccountClaim(aImpKp, aExpPub, ac)
  5271  		testConnect(aExpPub, aExpJwt, aImpPub, aImpJwt, aImpCreds)
  5272  		testNatsResolver(aImpJwt)
  5273  	})
  5274  
  5275  	t.Run("different-subject", func(t *testing.T) {
  5276  		aImpKp, aImpPub := createKey(t)
  5277  		ac := &jwt.ActivationClaims{}
  5278  		ac.Subject = aImpPub
  5279  		ac.ImportSubject = "foo" // on purpose use a subject from another export
  5280  		ac.ImportType = jwt.Stream
  5281  
  5282  		aImpJwt, aImpCreds := createImportingAccountClaim(aImpKp, aExpPub, ac)
  5283  		testConnect(aExpPub, aExpJwt, aImpPub, aImpJwt, aImpCreds)
  5284  		testNatsResolver(aImpJwt)
  5285  	})
  5286  
  5287  	t.Run("non-existing-subject", func(t *testing.T) {
  5288  		aImpKp, aImpPub := createKey(t)
  5289  		ac := &jwt.ActivationClaims{}
  5290  		ac.Subject = aImpPub
  5291  		ac.ImportSubject = "does-not-exist-or-from-different-export" // on purpose use a non exported subject
  5292  		ac.ImportType = jwt.Stream
  5293  
  5294  		aImpJwt, aImpCreds := createImportingAccountClaim(aImpKp, aExpPub, ac)
  5295  		testConnect(aExpPub, aExpJwt, aImpPub, aImpJwt, aImpCreds)
  5296  		testNatsResolver(aImpJwt)
  5297  	})
  5298  }
  5299  
  5300  func TestJWTResponseThreshold(t *testing.T) {
  5301  	respThresh := 20 * time.Millisecond
  5302  	aExpKp, aExpPub := createKey(t)
  5303  	aExpClaim := jwt.NewAccountClaims(aExpPub)
  5304  	aExpClaim.Name = "Export"
  5305  	aExpClaim.Exports.Add(&jwt.Export{
  5306  		Subject:           "srvc",
  5307  		Type:              jwt.Service,
  5308  		ResponseThreshold: respThresh,
  5309  	})
  5310  	aExpJwt := encodeClaim(t, aExpClaim, aExpPub)
  5311  	aExpCreds := newUser(t, aExpKp)
  5312  
  5313  	aImpKp, aImpPub := createKey(t)
  5314  	aImpClaim := jwt.NewAccountClaims(aImpPub)
  5315  	aImpClaim.Name = "Import"
  5316  	aImpClaim.Imports.Add(&jwt.Import{
  5317  		Subject: "srvc",
  5318  		Type:    jwt.Service,
  5319  		Account: aExpPub,
  5320  	})
  5321  	aImpJwt := encodeClaim(t, aImpClaim, aImpPub)
  5322  	aImpCreds := newUser(t, aImpKp)
  5323  
  5324  	cf := createConfFile(t, []byte(fmt.Sprintf(`
  5325  		port: -1
  5326  		operator = %s
  5327  		resolver = MEMORY
  5328  		resolver_preload = {
  5329  			%s : "%s"
  5330  			%s : "%s"
  5331  		}
  5332  		`, ojwt, aExpPub, aExpJwt, aImpPub, aImpJwt)))
  5333  
  5334  	s, opts := RunServerWithConfig(cf)
  5335  	defer s.Shutdown()
  5336  
  5337  	ncExp := natsConnect(t, fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port), nats.UserCredentials(aExpCreds))
  5338  	defer ncExp.Close()
  5339  
  5340  	ncImp := natsConnect(t, fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port), nats.UserCredentials(aImpCreds))
  5341  	defer ncImp.Close()
  5342  
  5343  	delayChan := make(chan time.Duration, 1)
  5344  
  5345  	// Create subscriber for the service endpoint in foo.
  5346  	_, err := ncExp.Subscribe("srvc", func(m *nats.Msg) {
  5347  		time.Sleep(<-delayChan)
  5348  		m.Respond([]byte("yes!"))
  5349  	})
  5350  	require_NoError(t, err)
  5351  	ncExp.Flush()
  5352  
  5353  	t.Run("No-Timeout", func(t *testing.T) {
  5354  		delayChan <- respThresh / 2
  5355  		if resp, err := ncImp.Request("srvc", []byte("yes?"), 4*respThresh); err != nil {
  5356  			t.Fatalf("Expected a response to request srvc got: %v", err)
  5357  		} else if string(resp.Data) != "yes!" {
  5358  			t.Fatalf("Expected a response of %q, got %q", "yes!", resp.Data)
  5359  		}
  5360  	})
  5361  	t.Run("Timeout", func(t *testing.T) {
  5362  		delayChan <- 2 * respThresh
  5363  		if _, err := ncImp.Request("srvc", []byte("yes?"), 4*respThresh); err == nil || err != nats.ErrTimeout {
  5364  			t.Fatalf("Expected a timeout")
  5365  		}
  5366  	})
  5367  }
  5368  
  5369  func TestJWTJetStreamTiers(t *testing.T) {
  5370  	sysKp, syspub := createKey(t)
  5371  	sysJwt := encodeClaim(t, jwt.NewAccountClaims(syspub), syspub)
  5372  	sysCreds := newUser(t, sysKp)
  5373  
  5374  	accKp, accPub := createKey(t)
  5375  	accClaim := jwt.NewAccountClaims(accPub)
  5376  	accClaim.Name = "acc"
  5377  	accClaim.Limits.JetStreamTieredLimits["R1"] = jwt.JetStreamLimits{
  5378  		DiskStorage: 1100, MemoryStorage: 0, Consumer: 2, Streams: 2}
  5379  	accJwt1 := encodeClaim(t, accClaim, accPub)
  5380  	accCreds := newUser(t, accKp)
  5381  
  5382  	start := time.Now()
  5383  
  5384  	storeDir := t.TempDir()
  5385  
  5386  	dirSrv := t.TempDir()
  5387  	cf := createConfFile(t, []byte(fmt.Sprintf(`
  5388  		listen: 127.0.0.1:-1
  5389  		server_name: s1
  5390  		jetstream: {max_mem_store: 256MB, max_file_store: 2GB, store_dir: '%s'}
  5391  		leaf {
  5392  			listen: 127.0.0.1:-1
  5393  		}
  5394  		operator: %s
  5395  		system_account: %s
  5396  		resolver: {
  5397  			type: full
  5398  			dir: '%s'
  5399  		}
  5400  	`, storeDir, ojwt, syspub, dirSrv)))
  5401  
  5402  	s, _ := RunServerWithConfig(cf)
  5403  	defer s.Shutdown()
  5404  
  5405  	updateJwt(t, s.ClientURL(), sysCreds, sysJwt, 1)
  5406  	updateJwt(t, s.ClientURL(), sysCreds, accJwt1, 1)
  5407  
  5408  	nc := natsConnect(t, s.ClientURL(), nats.UserCredentials(accCreds))
  5409  	defer nc.Close()
  5410  
  5411  	js, err := nc.JetStream()
  5412  	require_NoError(t, err)
  5413  
  5414  	// Test tiers up to stream limits
  5415  	_, err = js.AddStream(&nats.StreamConfig{Name: "testR1-1", Replicas: 1, Subjects: []string{"testR1-1"}})
  5416  	require_NoError(t, err)
  5417  	_, err = js.AddStream(&nats.StreamConfig{Name: "testR1-2", Replicas: 1, Subjects: []string{"testR1-2"}})
  5418  	require_NoError(t, err)
  5419  
  5420  	// Test exceeding tiered stream limit
  5421  	_, err = js.AddStream(&nats.StreamConfig{Name: "testR1-3", Replicas: 1, Subjects: []string{"testR1-3"}})
  5422  	require_Error(t, err)
  5423  	require_Equal(t, err.Error(), "nats: maximum number of streams reached")
  5424  
  5425  	// Test tiers up to consumer limits
  5426  	_, err = js.AddConsumer("testR1-1", &nats.ConsumerConfig{Durable: "dur1", AckPolicy: nats.AckExplicitPolicy})
  5427  	require_NoError(t, err)
  5428  	_, err = js.AddConsumer("testR1-1", &nats.ConsumerConfig{Durable: "dur3", AckPolicy: nats.AckExplicitPolicy})
  5429  	require_NoError(t, err)
  5430  
  5431  	// test exceeding tiered consumer limits
  5432  	_, err = js.AddConsumer("testR1-1", &nats.ConsumerConfig{Durable: "dur4", AckPolicy: nats.AckExplicitPolicy})
  5433  	require_Error(t, err)
  5434  	require_Equal(t, err.Error(), "nats: maximum consumers limit reached")
  5435  	_, err = js.AddConsumer("testR1-1", &nats.ConsumerConfig{Durable: "dur5", AckPolicy: nats.AckExplicitPolicy})
  5436  	require_Error(t, err)
  5437  	require_Equal(t, err.Error(), "nats: maximum consumers limit reached")
  5438  
  5439  	// test tiered storage limit
  5440  	msg := [512]byte{}
  5441  	_, err = js.Publish("testR1-1", msg[:])
  5442  	require_NoError(t, err)
  5443  	_, err = js.Publish("testR1-2", msg[:])
  5444  	require_NoError(t, err)
  5445  
  5446  	// test exceeding tiered storage limit
  5447  	_, err = js.Publish("testR1-1", []byte("1"))
  5448  	require_Error(t, err)
  5449  	require_Equal(t, err.Error(), "nats: resource limits exceeded for account")
  5450  
  5451  	time.Sleep(time.Second - time.Since(start)) // make sure the time stamp changes
  5452  	accClaim.Limits.JetStreamTieredLimits["R1"] = jwt.JetStreamLimits{
  5453  		DiskStorage: 1650, MemoryStorage: 0, Consumer: 1, Streams: 3}
  5454  	accJwt2 := encodeClaim(t, accClaim, accPub)
  5455  	updateJwt(t, s.ClientURL(), sysCreds, accJwt2, 1)
  5456  
  5457  	// test same sequence as before, add stream, fail add stream, add consumer, fail add consumer, publish, fail publish
  5458  	_, err = js.AddStream(&nats.StreamConfig{Name: "testR1-3", Replicas: 1, Subjects: []string{"testR1-3"}})
  5459  	require_NoError(t, err)
  5460  	_, err = js.AddStream(&nats.StreamConfig{Name: "testR1-4", Replicas: 1, Subjects: []string{"testR1-4"}})
  5461  	require_Error(t, err)
  5462  	require_Equal(t, err.Error(), "nats: maximum number of streams reached")
  5463  	_, err = js.AddConsumer("testR1-3", &nats.ConsumerConfig{Durable: "dur6", AckPolicy: nats.AckExplicitPolicy})
  5464  	require_NoError(t, err)
  5465  	_, err = js.AddConsumer("testR1-3", &nats.ConsumerConfig{Durable: "dur7", AckPolicy: nats.AckExplicitPolicy})
  5466  	require_Error(t, err)
  5467  	require_Equal(t, err.Error(), "nats: maximum consumers limit reached")
  5468  	_, err = js.Publish("testR1-3", msg[:])
  5469  	require_Error(t, err)
  5470  	require_Equal(t, err.Error(), "nats: resource limits exceeded for account")
  5471  }
  5472  
  5473  func TestJWTJetStreamMaxAckPending(t *testing.T) {
  5474  	sysKp, syspub := createKey(t)
  5475  	sysJwt := encodeClaim(t, jwt.NewAccountClaims(syspub), syspub)
  5476  	sysCreds := newUser(t, sysKp)
  5477  
  5478  	accKp, accPub := createKey(t)
  5479  	accClaim := jwt.NewAccountClaims(accPub)
  5480  	accClaim.Name = "acc"
  5481  	accClaim.Limits.JetStreamTieredLimits["R1"] = jwt.JetStreamLimits{
  5482  		DiskStorage: jwt.NoLimit, MemoryStorage: jwt.NoLimit,
  5483  		Consumer: jwt.NoLimit, Streams: jwt.NoLimit, MaxAckPending: int64(1000),
  5484  	}
  5485  	accJwt1 := encodeClaim(t, accClaim, accPub)
  5486  	accCreds := newUser(t, accKp)
  5487  
  5488  	start := time.Now()
  5489  
  5490  	storeDir := t.TempDir()
  5491  
  5492  	dirSrv := t.TempDir()
  5493  	cf := createConfFile(t, []byte(fmt.Sprintf(`
  5494  		listen: 127.0.0.1:-1
  5495  		server_name: s1
  5496  		jetstream: {max_mem_store: 256MB, max_file_store: 2GB, store_dir: '%s'}
  5497  		leaf {
  5498  			listen: 127.0.0.1:-1
  5499  		}
  5500  		operator: %s
  5501  		system_account: %s
  5502  		resolver: {
  5503  			type: full
  5504  			dir: '%s'
  5505  		}
  5506  	`, storeDir, ojwt, syspub, dirSrv)))
  5507  
  5508  	s, _ := RunServerWithConfig(cf)
  5509  	defer s.Shutdown()
  5510  
  5511  	updateJwt(t, s.ClientURL(), sysCreds, sysJwt, 1)
  5512  	updateJwt(t, s.ClientURL(), sysCreds, accJwt1, 1)
  5513  
  5514  	nc := natsConnect(t, s.ClientURL(), nats.UserCredentials(accCreds))
  5515  	defer nc.Close()
  5516  
  5517  	js, err := nc.JetStream()
  5518  	require_NoError(t, err)
  5519  
  5520  	_, err = js.AddStream(&nats.StreamConfig{Name: "foo", Replicas: 1})
  5521  	require_NoError(t, err)
  5522  
  5523  	_, err = js.AddConsumer("foo", &nats.ConsumerConfig{
  5524  		Durable: "dur1", AckPolicy: nats.AckAllPolicy, MaxAckPending: 2000})
  5525  	require_Error(t, err)
  5526  	require_Equal(t, err.Error(), "nats: consumer max ack pending exceeds system limit of 1000")
  5527  
  5528  	ci, err := js.AddConsumer("foo", &nats.ConsumerConfig{
  5529  		Durable: "dur2", AckPolicy: nats.AckAllPolicy, MaxAckPending: 500})
  5530  	require_NoError(t, err)
  5531  	require_True(t, ci.Config.MaxAckPending == 500)
  5532  
  5533  	_, err = js.UpdateConsumer("foo", &nats.ConsumerConfig{
  5534  		Durable: "dur2", AckPolicy: nats.AckAllPolicy, MaxAckPending: 2000})
  5535  	require_Error(t, err)
  5536  	require_Equal(t, err.Error(), "nats: consumer max ack pending exceeds system limit of 1000")
  5537  
  5538  	time.Sleep(time.Second - time.Since(start)) // make sure the time stamp changes
  5539  	accClaim.Limits.JetStreamTieredLimits["R1"] = jwt.JetStreamLimits{
  5540  		DiskStorage: jwt.NoLimit, MemoryStorage: jwt.NoLimit, Consumer: jwt.NoLimit,
  5541  		Streams: jwt.NoLimit, MaxAckPending: int64(2000)}
  5542  	accJwt2 := encodeClaim(t, accClaim, accPub)
  5543  	updateJwt(t, s.ClientURL(), sysCreds, accJwt2, 1)
  5544  
  5545  	ci, err = js.UpdateConsumer("foo", &nats.ConsumerConfig{
  5546  		Durable: "dur2", AckPolicy: nats.AckAllPolicy, MaxAckPending: 2000})
  5547  	require_NoError(t, err)
  5548  	require_True(t, ci.Config.MaxAckPending == 2000)
  5549  }
  5550  
  5551  func TestJWTJetStreamMaxStreamBytes(t *testing.T) {
  5552  	sysKp, syspub := createKey(t)
  5553  	sysJwt := encodeClaim(t, jwt.NewAccountClaims(syspub), syspub)
  5554  	sysCreds := newUser(t, sysKp)
  5555  
  5556  	accKp, accPub := createKey(t)
  5557  	accClaim := jwt.NewAccountClaims(accPub)
  5558  	accClaim.Name = "acc"
  5559  	accClaim.Limits.JetStreamTieredLimits["R1"] = jwt.JetStreamLimits{
  5560  		DiskStorage: jwt.NoLimit, MemoryStorage: jwt.NoLimit,
  5561  		Consumer: jwt.NoLimit, Streams: jwt.NoLimit,
  5562  		DiskMaxStreamBytes: 1024, MaxBytesRequired: false,
  5563  	}
  5564  	accJwt1 := encodeClaim(t, accClaim, accPub)
  5565  	accCreds := newUser(t, accKp)
  5566  
  5567  	start := time.Now()
  5568  
  5569  	storeDir := t.TempDir()
  5570  
  5571  	dirSrv := t.TempDir()
  5572  	cf := createConfFile(t, []byte(fmt.Sprintf(`
  5573  		listen: 127.0.0.1:-1
  5574  		server_name: s1
  5575  		jetstream: {max_mem_store: 256MB, max_file_store: 2GB, store_dir: '%s'}
  5576  		leaf {
  5577  			listen: 127.0.0.1:-1
  5578  		}
  5579  		operator: %s
  5580  		system_account: %s
  5581  		resolver: {
  5582  			type: full
  5583  			dir: '%s'
  5584  		}
  5585  	`, storeDir, ojwt, syspub, dirSrv)))
  5586  
  5587  	s, _ := RunServerWithConfig(cf)
  5588  	defer s.Shutdown()
  5589  
  5590  	updateJwt(t, s.ClientURL(), sysCreds, sysJwt, 1)
  5591  	updateJwt(t, s.ClientURL(), sysCreds, accJwt1, 1)
  5592  
  5593  	nc := natsConnect(t, s.ClientURL(), nats.UserCredentials(accCreds))
  5594  	defer nc.Close()
  5595  
  5596  	js, err := nc.JetStream()
  5597  	require_NoError(t, err)
  5598  
  5599  	_, err = js.AddStream(&nats.StreamConfig{Name: "foo", Replicas: 1, MaxBytes: 2048})
  5600  	require_Error(t, err)
  5601  	require_Equal(t, err.Error(), "nats: stream max bytes exceeds account limit max stream bytes")
  5602  	_, err = js.AddStream(&nats.StreamConfig{Name: "foo", Replicas: 1, MaxBytes: 1024})
  5603  	require_NoError(t, err)
  5604  
  5605  	msg := [900]byte{}
  5606  	_, err = js.AddStream(&nats.StreamConfig{Name: "baz", Replicas: 1})
  5607  	require_NoError(t, err)
  5608  	_, err = js.Publish("baz", msg[:])
  5609  	require_NoError(t, err)
  5610  	_, err = js.Publish("baz", msg[:]) // exceeds max stream bytes
  5611  	require_Error(t, err)
  5612  	require_Equal(t, err.Error(), "nats: resource limits exceeded for account")
  5613  
  5614  	time.Sleep(time.Second - time.Since(start)) // make sure the time stamp changes
  5615  	accClaim.Limits.JetStreamTieredLimits["R1"] = jwt.JetStreamLimits{
  5616  		DiskStorage: jwt.NoLimit, MemoryStorage: jwt.NoLimit, Consumer: jwt.NoLimit, Streams: jwt.NoLimit,
  5617  		DiskMaxStreamBytes: 2048, MaxBytesRequired: true}
  5618  	accJwt2 := encodeClaim(t, accClaim, accPub)
  5619  	updateJwt(t, s.ClientURL(), sysCreds, accJwt2, 1)
  5620  
  5621  	_, err = js.AddStream(&nats.StreamConfig{Name: "bar", Replicas: 1, MaxBytes: 3000})
  5622  	require_Error(t, err)
  5623  	require_Equal(t, err.Error(), "nats: stream max bytes exceeds account limit max stream bytes")
  5624  	_, err = js.AddStream(&nats.StreamConfig{Name: "bar", Replicas: 1, MaxBytes: 2048})
  5625  	require_NoError(t, err)
  5626  
  5627  	// test if we can push more messages into the stream
  5628  	_, err = js.Publish("baz", msg[:]) // exceeds max stream bytes
  5629  	require_Error(t, err)
  5630  	require_Equal(t, err.Error(), "nats: resource limits exceeded for account")
  5631  
  5632  	// test disabling max bytes required
  5633  	_, err = js.UpdateStream(&nats.StreamConfig{Name: "bar", Replicas: 1})
  5634  	require_Error(t, err)
  5635  	require_Equal(t, err.Error(), "nats: account requires a stream config to have max bytes set")
  5636  }
  5637  
  5638  func TestJWTQueuePermissions(t *testing.T) {
  5639  	aExpKp, aExpPub := createKey(t)
  5640  	aExpClaim := jwt.NewAccountClaims(aExpPub)
  5641  	aExpJwt := encodeClaim(t, aExpClaim, aExpPub)
  5642  	newUser := func(t *testing.T, permType string) string {
  5643  		ukp, _ := nkeys.CreateUser()
  5644  		seed, _ := ukp.Seed()
  5645  		upub, _ := ukp.PublicKey()
  5646  		uclaim := newJWTTestUserClaims()
  5647  		uclaim.Subject = upub
  5648  		switch permType {
  5649  		case "allow":
  5650  			uclaim.Permissions.Sub.Allow.Add("foo.> *.dev")
  5651  		case "deny":
  5652  			uclaim.Permissions.Sub.Deny.Add("foo.> *.dev")
  5653  		}
  5654  		ujwt, err := uclaim.Encode(aExpKp)
  5655  		require_NoError(t, err)
  5656  		return genCredsFile(t, ujwt, seed)
  5657  	}
  5658  	confFileName := createConfFile(t, []byte(fmt.Sprintf(`
  5659  		port: -1
  5660  		operator = %s
  5661  		resolver = MEMORY
  5662  		resolver_preload = {
  5663  			%s : %s
  5664  		}`, ojwt, aExpPub, aExpJwt)))
  5665  	opts, err := ProcessConfigFile(confFileName)
  5666  	if err != nil {
  5667  		t.Fatalf("Received unexpected error %s", err)
  5668  	}
  5669  	opts.NoLog, opts.NoSigs = true, true
  5670  	errChan := make(chan error, 1)
  5671  	defer close(errChan)
  5672  	s := RunServer(opts)
  5673  	defer s.Shutdown()
  5674  
  5675  	for _, test := range []struct {
  5676  		permType    string
  5677  		queue       string
  5678  		errExpected bool
  5679  	}{
  5680  		{"allow", "queue.dev", false},
  5681  		{"allow", "", true},
  5682  		{"allow", "bad", true},
  5683  		{"deny", "", false},
  5684  		{"deny", "queue.dev", true},
  5685  	} {
  5686  		t.Run(test.permType+test.queue, func(t *testing.T) {
  5687  			usrCreds := newUser(t, test.permType)
  5688  			nc, err := nats.Connect(fmt.Sprintf("nats://127.0.0.1:%d", opts.Port),
  5689  				nats.ErrorHandler(func(conn *nats.Conn, s *nats.Subscription, err error) {
  5690  					errChan <- err
  5691  				}),
  5692  				nats.UserCredentials(usrCreds))
  5693  			if err != nil {
  5694  				t.Fatalf("No error expected: %v", err)
  5695  			}
  5696  			defer nc.Close()
  5697  			if test.queue == "" {
  5698  				if _, err := nc.Subscribe("foo.bar", func(msg *nats.Msg) {}); err != nil {
  5699  					t.Fatalf("no error expected: %v", err)
  5700  				}
  5701  			} else {
  5702  				if _, err := nc.QueueSubscribe("foo.bar", test.queue, func(msg *nats.Msg) {}); err != nil {
  5703  					t.Fatalf("no error expected: %v", err)
  5704  				}
  5705  			}
  5706  			nc.Flush()
  5707  			select {
  5708  			case err := <-errChan:
  5709  				if !test.errExpected {
  5710  					t.Fatalf("Expected no error, got %v", err)
  5711  				}
  5712  				if !strings.Contains(err.Error(), `Permissions Violation for Subscription to "foo.bar"`) {
  5713  					t.Fatalf("error %v", err)
  5714  				}
  5715  			case <-time.After(150 * time.Millisecond):
  5716  				if test.errExpected {
  5717  					t.Fatal("Expected an error")
  5718  				}
  5719  			}
  5720  		})
  5721  
  5722  	}
  5723  }
  5724  
  5725  func TestJWScopedSigningKeys(t *testing.T) {
  5726  	sysKp, syspub := createKey(t)
  5727  	sysJwt := encodeClaim(t, jwt.NewAccountClaims(syspub), syspub)
  5728  	sysCreds := newUser(t, sysKp)
  5729  
  5730  	_, aExpPub := createKey(t)
  5731  	accClaim := jwt.NewAccountClaims(aExpPub)
  5732  	accClaim.Name = "acc"
  5733  
  5734  	aSignNonScopedKp, aSignNonScopedPub := createKey(t)
  5735  	accClaim.SigningKeys.Add(aSignNonScopedPub)
  5736  
  5737  	aSignScopedKp, aSignScopedPub := createKey(t)
  5738  	signer := jwt.NewUserScope()
  5739  	signer.Key = aSignScopedPub
  5740  	signer.Template.Pub.Deny.Add("denied")
  5741  	signer.Template.Payload = 5
  5742  	accClaim.SigningKeys.AddScopedSigner(signer)
  5743  	accJwt := encodeClaim(t, accClaim, aExpPub)
  5744  
  5745  	aNonScopedCreds := newUserEx(t, aSignNonScopedKp, false, aExpPub)
  5746  	aBadScopedCreds := newUserEx(t, aSignScopedKp, false, aExpPub)
  5747  	aScopedCreds := newUserEx(t, aSignScopedKp, true, aExpPub)
  5748  
  5749  	dirSrv := t.TempDir()
  5750  	cf := createConfFile(t, []byte(fmt.Sprintf(`
  5751  		listen: 127.0.0.1:-1
  5752  		operator: %s
  5753  		system_account: %s
  5754  		resolver: {
  5755  			type: full
  5756  			dir: '%s'
  5757  		}
  5758      `, ojwt, syspub, dirSrv)))
  5759  	s, opts := RunServerWithConfig(cf)
  5760  	defer s.Shutdown()
  5761  
  5762  	url := fmt.Sprintf("nats://%s:%d", opts.Host, opts.Port)
  5763  	errChan := make(chan error, 1)
  5764  	defer close(errChan)
  5765  	awaitError := func(expected bool) {
  5766  		t.Helper()
  5767  		select {
  5768  		case err := <-errChan:
  5769  			if !expected {
  5770  				t.Fatalf("Expected no error, got %v", err)
  5771  			}
  5772  		case <-time.After(150 * time.Millisecond):
  5773  			if expected {
  5774  				t.Fatal("Expected an error")
  5775  			}
  5776  		}
  5777  	}
  5778  	errHdlr := nats.ErrorHandler(func(conn *nats.Conn, s *nats.Subscription, err error) {
  5779  		errChan <- err
  5780  	})
  5781  	if updateJwt(t, url, sysCreds, sysJwt, 1) != 1 {
  5782  		t.Error("Expected update to pass")
  5783  	} else if updateJwt(t, url, sysCreds, accJwt, 1) != 1 {
  5784  		t.Error("Expected update to pass")
  5785  	}
  5786  	t.Run("bad-scoped-signing-key", func(t *testing.T) {
  5787  		_, err := nats.Connect(url, nats.UserCredentials(aBadScopedCreds))
  5788  		require_Error(t, err)
  5789  	})
  5790  	t.Run("regular-signing-key", func(t *testing.T) {
  5791  		nc := natsConnect(t, url, nats.UserCredentials(aNonScopedCreds), errHdlr)
  5792  		defer nc.Close()
  5793  		nc.Flush()
  5794  		err := nc.Publish("denied", nil)
  5795  		require_NoError(t, err)
  5796  		nc.Flush()
  5797  		awaitError(false)
  5798  	})
  5799  	t.Run("scoped-signing-key-client-side", func(t *testing.T) {
  5800  		nc := natsConnect(t, url, nats.UserCredentials(aScopedCreds), errHdlr)
  5801  		defer nc.Close()
  5802  		nc.Flush()
  5803  		err := nc.Publish("too-long", []byte("way.too.long.for.payload.limit"))
  5804  		require_Error(t, err)
  5805  		require_True(t, strings.Contains(err.Error(), ErrMaxPayload.Error()))
  5806  	})
  5807  	t.Run("scoped-signing-key-server-side", func(t *testing.T) {
  5808  		nc := natsConnect(t, url, nats.UserCredentials(aScopedCreds), errHdlr)
  5809  		defer nc.Close()
  5810  		nc.Flush()
  5811  		err := nc.Publish("denied", nil)
  5812  		require_NoError(t, err)
  5813  		nc.Flush()
  5814  		awaitError(true)
  5815  	})
  5816  	t.Run("scoped-signing-key-reload", func(t *testing.T) {
  5817  		reconChan := make(chan struct{}, 1)
  5818  		defer close(reconChan)
  5819  		msgChan := make(chan *nats.Msg, 2)
  5820  		defer close(msgChan)
  5821  		nc := natsConnect(t, url, nats.UserCredentials(aScopedCreds), errHdlr,
  5822  			nats.DisconnectErrHandler(func(conn *nats.Conn, err error) {
  5823  				if err != nil {
  5824  					errChan <- err
  5825  				}
  5826  			}),
  5827  			nats.ReconnectHandler(func(conn *nats.Conn) {
  5828  				reconChan <- struct{}{}
  5829  			}),
  5830  		)
  5831  		defer nc.Close()
  5832  		_, err := nc.ChanSubscribe("denied", msgChan)
  5833  		require_NoError(t, err)
  5834  		nc.Flush()
  5835  		err = nc.Publish("denied", nil)
  5836  		require_NoError(t, err)
  5837  		awaitError(true)
  5838  		require_Len(t, len(msgChan), 0)
  5839  		// Alter scoped permissions and update
  5840  		signer.Template.Payload = -1
  5841  		signer.Template.Pub.Deny.Remove("denied")
  5842  		accClaim.SigningKeys.AddScopedSigner(signer)
  5843  		accUpdatedJwt := encodeClaim(t, accClaim, aExpPub)
  5844  		if updateJwt(t, url, sysCreds, accUpdatedJwt, 1) != 1 {
  5845  			t.Error("Expected update to pass")
  5846  		}
  5847  		// disconnect triggered by update
  5848  		awaitError(true)
  5849  		<-reconChan
  5850  		nc.Flush()
  5851  		err = nc.Publish("denied", []byte("way.too.long.for.old.payload.limit"))
  5852  		require_NoError(t, err)
  5853  		awaitError(false)
  5854  		msg := <-msgChan
  5855  		require_Equal(t, string(msg.Data), "way.too.long.for.old.payload.limit")
  5856  		require_Len(t, len(msgChan), 0)
  5857  	})
  5858  	require_Len(t, len(errChan), 0)
  5859  }
  5860  
  5861  func TestJWTStrictSigningKeys(t *testing.T) {
  5862  	newAccount := func(opKp nkeys.KeyPair) (nkeys.KeyPair, nkeys.KeyPair, string, *jwt.AccountClaims, string) {
  5863  		accId, err := nkeys.CreateAccount()
  5864  		require_NoError(t, err)
  5865  		accIdPub, err := accId.PublicKey()
  5866  		require_NoError(t, err)
  5867  
  5868  		accSig, err := nkeys.CreateAccount()
  5869  		require_NoError(t, err)
  5870  		accSigPub, err := accSig.PublicKey()
  5871  		require_NoError(t, err)
  5872  
  5873  		aClaim := jwt.NewAccountClaims(accIdPub)
  5874  		aClaim.SigningKeys.Add(accSigPub)
  5875  		theJwt, err := aClaim.Encode(opKp)
  5876  		require_NoError(t, err)
  5877  		return accId, accSig, accIdPub, aClaim, theJwt
  5878  	}
  5879  
  5880  	opId, err := nkeys.CreateOperator()
  5881  	require_NoError(t, err)
  5882  	opIdPub, err := opId.PublicKey()
  5883  	require_NoError(t, err)
  5884  
  5885  	opSig, err := nkeys.CreateOperator()
  5886  	require_NoError(t, err)
  5887  	opSigPub, err := opSig.PublicKey()
  5888  	require_NoError(t, err)
  5889  
  5890  	aBadBadKp, aBadGoodKp, aBadPub, _, aBadJwt := newAccount(opId)
  5891  	aGoodBadKp, aGoodGoodKp, aGoodPub, _, aGoodJwt := newAccount(opSig)
  5892  	_, aSysKp, aSysPub, _, aSysJwt := newAccount(opSig)
  5893  
  5894  	oClaim := jwt.NewOperatorClaims(opIdPub)
  5895  	oClaim.StrictSigningKeyUsage = true
  5896  	oClaim.SigningKeys.Add(opSigPub)
  5897  	oClaim.SystemAccount = aSysPub
  5898  	oJwt, err := oClaim.Encode(opId)
  5899  	require_NoError(t, err)
  5900  
  5901  	uBadBadCreds := newUserEx(t, aBadBadKp, false, aBadPub)
  5902  	uBadGoodCreds := newUserEx(t, aBadGoodKp, false, aBadPub)
  5903  	uGoodBadCreds := newUserEx(t, aGoodBadKp, false, aGoodPub)
  5904  	uGoodGoodCreds := newUserEx(t, aGoodGoodKp, false, aGoodPub)
  5905  	uSysCreds := newUserEx(t, aSysKp, false, aSysPub)
  5906  
  5907  	connectTest := func(url string) {
  5908  		for _, test := range []struct {
  5909  			creds string
  5910  			fail  bool
  5911  		}{
  5912  			{uBadBadCreds, true},
  5913  			{uBadGoodCreds, true},
  5914  			{uGoodBadCreds, true},
  5915  			{uGoodGoodCreds, false},
  5916  		} {
  5917  			nc, err := nats.Connect(url, nats.UserCredentials(test.creds))
  5918  			nc.Close()
  5919  			if test.fail {
  5920  				require_Error(t, err)
  5921  			} else {
  5922  				require_NoError(t, err)
  5923  			}
  5924  		}
  5925  	}
  5926  
  5927  	t.Run("resolver", func(t *testing.T) {
  5928  		dirSrv := t.TempDir()
  5929  		cf := createConfFile(t, []byte(fmt.Sprintf(`
  5930  		port: -1
  5931  		operator = %s
  5932  		resolver: {
  5933  			type: full
  5934  			dir: '%s'
  5935  		}
  5936  		resolver_preload = {
  5937  			%s : "%s"
  5938  		}
  5939  		`, oJwt, dirSrv, aSysPub, aSysJwt)))
  5940  		s, _ := RunServerWithConfig(cf)
  5941  		defer s.Shutdown()
  5942  		url := s.ClientURL()
  5943  		if updateJwt(t, url, uSysCreds, aBadJwt, 1) != 0 {
  5944  			t.Fatal("Expected negative response")
  5945  		}
  5946  		if updateJwt(t, url, uSysCreds, aGoodJwt, 1) != 1 {
  5947  			t.Fatal("Expected positive response")
  5948  		}
  5949  		connectTest(url)
  5950  	})
  5951  
  5952  	t.Run("mem-resolver", func(t *testing.T) {
  5953  		cf := createConfFile(t, []byte(fmt.Sprintf(`
  5954  		port: -1
  5955  		operator = %s
  5956  		resolver: MEMORY
  5957  		resolver_preload = {
  5958  			%s : "%s"
  5959  			%s : "%s"
  5960  			%s : "%s"
  5961  		}
  5962  		`, oJwt, aSysPub, aSysJwt, aBadPub, aBadJwt, aGoodPub, aGoodJwt)))
  5963  		s, _ := RunServerWithConfig(cf)
  5964  		defer s.Shutdown()
  5965  		connectTest(s.ClientURL())
  5966  	})
  5967  }
  5968  
  5969  func TestJWTAccountProtectedImport(t *testing.T) {
  5970  	srvFmt := `
  5971  		port: -1
  5972  		operator = %s
  5973  		resolver: MEMORY
  5974  		resolver_preload = {
  5975  			%s : "%s"
  5976  			%s : "%s"
  5977  		} `
  5978  	setupAccounts := func(pass bool) (nkeys.KeyPair, string, string, string, nkeys.KeyPair, string, string, string, string) {
  5979  		// Create accounts and imports/exports.
  5980  		exportKP, _ := nkeys.CreateAccount()
  5981  		exportPub, _ := exportKP.PublicKey()
  5982  		exportAC := jwt.NewAccountClaims(exportPub)
  5983  		exportAC.Exports.Add(&jwt.Export{Subject: "service.*", Type: jwt.Service, AccountTokenPosition: 2})
  5984  		exportAC.Exports.Add(&jwt.Export{Subject: "stream.*", Type: jwt.Stream, AccountTokenPosition: 2})
  5985  		exportJWT, err := exportAC.Encode(oKp)
  5986  		require_NoError(t, err)
  5987  		// create alternative exporter jwt without account token pos set
  5988  		exportAC.Exports = jwt.Exports{}
  5989  		exportAC.Exports.Add(&jwt.Export{Subject: "service.*", Type: jwt.Service})
  5990  		exportAC.Exports.Add(&jwt.Export{Subject: "stream.*", Type: jwt.Stream})
  5991  		exportJWTNoPos, err := exportAC.Encode(oKp)
  5992  		require_NoError(t, err)
  5993  
  5994  		importKP, _ := nkeys.CreateAccount()
  5995  		importPub, _ := importKP.PublicKey()
  5996  		importAc := jwt.NewAccountClaims(importPub)
  5997  		srvcSub, strmSub := "service.foo", "stream.foo"
  5998  		if pass {
  5999  			srvcSub = fmt.Sprintf("service.%s", importPub)
  6000  			strmSub = fmt.Sprintf("stream.%s", importPub)
  6001  		}
  6002  		importAc.Imports.Add(&jwt.Import{Account: exportPub, Subject: jwt.Subject(srvcSub), Type: jwt.Service})
  6003  		importAc.Imports.Add(&jwt.Import{Account: exportPub, Subject: jwt.Subject(strmSub), Type: jwt.Stream})
  6004  		importJWT, err := importAc.Encode(oKp)
  6005  		require_NoError(t, err)
  6006  
  6007  		return exportKP, exportPub, exportJWT, exportJWTNoPos, importKP, importPub, importJWT, srvcSub, strmSub
  6008  	}
  6009  	t.Run("pass", func(t *testing.T) {
  6010  		exportKp, exportPub, exportJWT, _, importKp, importPub, importJWT, srvcSub, strmSub := setupAccounts(true)
  6011  		cf := createConfFile(t, []byte(fmt.Sprintf(srvFmt, ojwt, exportPub, exportJWT, importPub, importJWT)))
  6012  		s, _ := RunServerWithConfig(cf)
  6013  		defer s.Shutdown()
  6014  		ncExp := natsConnect(t, s.ClientURL(), createUserCreds(t, s, exportKp))
  6015  		defer ncExp.Close()
  6016  		ncImp := natsConnect(t, s.ClientURL(), createUserCreds(t, s, importKp))
  6017  		defer ncImp.Close()
  6018  		t.Run("service", func(t *testing.T) {
  6019  			sub, err := ncExp.Subscribe("service.*", func(msg *nats.Msg) {
  6020  				msg.Respond([]byte("world"))
  6021  			})
  6022  			defer sub.Unsubscribe()
  6023  			require_NoError(t, err)
  6024  			ncExp.Flush()
  6025  			msg, err := ncImp.Request(srvcSub, []byte("hello"), time.Second)
  6026  			require_NoError(t, err)
  6027  			require_Equal(t, string(msg.Data), "world")
  6028  		})
  6029  		t.Run("stream", func(t *testing.T) {
  6030  			msgChan := make(chan *nats.Msg, 4)
  6031  			defer close(msgChan)
  6032  			sub, err := ncImp.ChanSubscribe(strmSub, msgChan)
  6033  			defer sub.Unsubscribe()
  6034  			require_NoError(t, err)
  6035  			ncImp.Flush()
  6036  			err = ncExp.Publish("stream.foo", []byte("hello"))
  6037  			require_NoError(t, err)
  6038  			err = ncExp.Publish(strmSub, []byte("hello"))
  6039  			require_NoError(t, err)
  6040  			msg := <-msgChan
  6041  			require_Equal(t, string(msg.Data), "hello")
  6042  			require_True(t, len(msgChan) == 0)
  6043  		})
  6044  	})
  6045  	t.Run("fail", func(t *testing.T) {
  6046  		exportKp, exportPub, exportJWT, _, importKp, importPub, importJWT, srvcSub, strmSub := setupAccounts(false)
  6047  		cf := createConfFile(t, []byte(fmt.Sprintf(srvFmt, ojwt, exportPub, exportJWT, importPub, importJWT)))
  6048  		s, _ := RunServerWithConfig(cf)
  6049  		defer s.Shutdown()
  6050  		ncExp := natsConnect(t, s.ClientURL(), createUserCreds(t, s, exportKp))
  6051  		defer ncExp.Close()
  6052  		ncImp := natsConnect(t, s.ClientURL(), createUserCreds(t, s, importKp))
  6053  		defer ncImp.Close()
  6054  		t.Run("service", func(t *testing.T) {
  6055  			sub, err := ncExp.Subscribe("service.*", func(msg *nats.Msg) {
  6056  				msg.Respond([]byte("world"))
  6057  			})
  6058  			defer sub.Unsubscribe()
  6059  			require_NoError(t, err)
  6060  			ncExp.Flush()
  6061  			_, err = ncImp.Request(srvcSub, []byte("hello"), time.Second)
  6062  			require_Error(t, err)
  6063  			require_Contains(t, err.Error(), "no responders available for request")
  6064  		})
  6065  		t.Run("stream", func(t *testing.T) {
  6066  			msgChan := make(chan *nats.Msg, 4)
  6067  			defer close(msgChan)
  6068  			_, err := ncImp.ChanSubscribe(strmSub, msgChan)
  6069  			require_NoError(t, err)
  6070  			ncImp.Flush()
  6071  			err = ncExp.Publish("stream.foo", []byte("hello"))
  6072  			require_NoError(t, err)
  6073  			err = ncExp.Publish(strmSub, []byte("hello"))
  6074  			require_NoError(t, err)
  6075  			select {
  6076  			case <-msgChan:
  6077  				t.Fatal("did not expect a message")
  6078  			case <-time.After(250 * time.Millisecond):
  6079  			}
  6080  			require_True(t, len(msgChan) == 0)
  6081  		})
  6082  	})
  6083  	t.Run("reload-off-2-on", func(t *testing.T) {
  6084  		exportKp, exportPub, exportJWTOn, exportJWTOff, importKp, _, importJWT, srvcSub, strmSub := setupAccounts(false)
  6085  		dirSrv := t.TempDir()
  6086  		// set up system account. Relying bootstrapping system account to not create JWT
  6087  		sysAcc, err := nkeys.CreateAccount()
  6088  		require_NoError(t, err)
  6089  		sysPub, err := sysAcc.PublicKey()
  6090  		require_NoError(t, err)
  6091  		sysUsrCreds := newUserEx(t, sysAcc, false, sysPub)
  6092  		cf := createConfFile(t, []byte(fmt.Sprintf(`
  6093  		port: -1
  6094  		operator = %s
  6095  		system_account = %s
  6096  		resolver: {
  6097  			type: full
  6098  			dir: '%s'
  6099  		}`, ojwt, sysPub, dirSrv)))
  6100  		s, _ := RunServerWithConfig(cf)
  6101  		defer s.Shutdown()
  6102  		updateJwt(t, s.ClientURL(), sysUsrCreds, importJWT, 1)
  6103  		updateJwt(t, s.ClientURL(), sysUsrCreds, exportJWTOff, 1)
  6104  		ncExp := natsConnect(t, s.ClientURL(), createUserCreds(t, s, exportKp))
  6105  		defer ncExp.Close()
  6106  		ncImp := natsConnect(t, s.ClientURL(), createUserCreds(t, s, importKp))
  6107  		defer ncImp.Close()
  6108  		msgChan := make(chan *nats.Msg, 4)
  6109  		defer close(msgChan)
  6110  		// ensure service passes
  6111  		subSrvc, err := ncExp.Subscribe("service.*", func(msg *nats.Msg) {
  6112  			msg.Respond([]byte("world"))
  6113  		})
  6114  		defer subSrvc.Unsubscribe()
  6115  		require_NoError(t, err)
  6116  		ncExp.Flush()
  6117  		respMst, err := ncImp.Request(srvcSub, []byte("hello"), time.Second)
  6118  		require_NoError(t, err)
  6119  		require_Equal(t, string(respMst.Data), "world")
  6120  		// ensure stream passes
  6121  		subStrm, err := ncImp.ChanSubscribe(strmSub, msgChan)
  6122  		defer subStrm.Unsubscribe()
  6123  		require_NoError(t, err)
  6124  		ncImp.Flush()
  6125  		err = ncExp.Publish(strmSub, []byte("hello"))
  6126  		require_NoError(t, err)
  6127  		msg := <-msgChan
  6128  		require_Equal(t, string(msg.Data), "hello")
  6129  		require_True(t, len(msgChan) == 0)
  6130  
  6131  		updateJwt(t, s.ClientURL(), sysUsrCreds, exportJWTOn, 1)
  6132  
  6133  		// ensure service fails
  6134  		_, err = ncImp.Request(srvcSub, []byte("hello"), time.Second)
  6135  		require_Error(t, err)
  6136  		require_Contains(t, err.Error(), "timeout")
  6137  		s.AccountResolver().Store(exportPub, exportJWTOn)
  6138  		// ensure stream fails
  6139  		err = ncExp.Publish(strmSub, []byte("hello"))
  6140  		require_NoError(t, err)
  6141  		select {
  6142  		case <-msgChan:
  6143  			t.Fatal("did not expect a message")
  6144  		case <-time.After(250 * time.Millisecond):
  6145  		}
  6146  		require_True(t, len(msgChan) == 0)
  6147  	})
  6148  }
  6149  
  6150  // Headers are ignored in claims update, but passing them should not cause error.
  6151  func TestJWTClaimsUpdateWithHeaders(t *testing.T) {
  6152  	skp, spub := createKey(t)
  6153  	newUser(t, skp)
  6154  
  6155  	sclaim := jwt.NewAccountClaims(spub)
  6156  	encodeClaim(t, sclaim, spub)
  6157  
  6158  	akp, apub := createKey(t)
  6159  	newUser(t, akp)
  6160  	claim := jwt.NewAccountClaims(apub)
  6161  	jwtClaim := encodeClaim(t, claim, apub)
  6162  
  6163  	dirSrv := t.TempDir()
  6164  
  6165  	conf := createConfFile(t, []byte(fmt.Sprintf(`
  6166  		listen: 127.0.0.1:-1
  6167  		operator: %s
  6168  		system_account: %s
  6169  		resolver: {
  6170  			type: full
  6171  			dir: '%s'
  6172  		}
  6173      `, ojwt, spub, dirSrv)))
  6174  
  6175  	s, _ := RunServerWithConfig(conf)
  6176  	defer s.Shutdown()
  6177  
  6178  	type zapi struct {
  6179  		Server *ServerInfo
  6180  		Data   *Connz
  6181  		Error  *ApiError
  6182  	}
  6183  
  6184  	sc := natsConnect(t, s.ClientURL(), createUserCreds(t, s, skp))
  6185  	defer sc.Close()
  6186  	// Pass claims update with headers.
  6187  	msg := &nats.Msg{
  6188  		Subject: "$SYS.REQ.CLAIMS.UPDATE",
  6189  		Data:    []byte(jwtClaim),
  6190  		Header:  map[string][]string{"key": {"value"}},
  6191  	}
  6192  	resp, err := sc.RequestMsg(msg, time.Second)
  6193  	if err != nil {
  6194  		t.Fatalf("Unexpected error: %v", err)
  6195  	}
  6196  	var cz zapi
  6197  	if err := json.Unmarshal(resp.Data, &cz); err != nil {
  6198  		t.Fatalf("Unexpected error: %v", err)
  6199  	}
  6200  	if cz.Error != nil {
  6201  		t.Fatalf("Unexpected error: %+v", cz.Error)
  6202  	}
  6203  }
  6204  
  6205  func TestJWTMappings(t *testing.T) {
  6206  	sysKp, syspub := createKey(t)
  6207  	sysJwt := encodeClaim(t, jwt.NewAccountClaims(syspub), syspub)
  6208  	sysCreds := newUser(t, sysKp)
  6209  
  6210  	// create two jwt, one with and one without mapping
  6211  	aKp, aPub := createKey(t)
  6212  	aClaim := jwt.NewAccountClaims(aPub)
  6213  	aJwtNoM := encodeClaim(t, aClaim, aPub)
  6214  	aClaim.AddMapping("foo1", jwt.WeightedMapping{Subject: "bar1"})
  6215  	aJwtMap1 := encodeClaim(t, aClaim, aPub)
  6216  
  6217  	aClaim.Mappings = map[jwt.Subject][]jwt.WeightedMapping{}
  6218  	aClaim.AddMapping("foo2", jwt.WeightedMapping{Subject: "bar2"})
  6219  	aJwtMap2 := encodeClaim(t, aClaim, aPub)
  6220  
  6221  	dirSrv := t.TempDir()
  6222  	conf := createConfFile(t, []byte(fmt.Sprintf(`
  6223  		listen: 127.0.0.1:-1
  6224  		operator: %s
  6225  		system_account: %s
  6226  		resolver: {
  6227  			type: full
  6228  			dir: '%s'
  6229  		}
  6230      `, ojwt, syspub, dirSrv)))
  6231  	srv, _ := RunServerWithConfig(conf)
  6232  	defer srv.Shutdown()
  6233  	updateJwt(t, srv.ClientURL(), sysCreds, sysJwt, 1) // update system account jwt
  6234  
  6235  	test := func(pub, sub string, fail bool) {
  6236  		t.Helper()
  6237  		nc := natsConnect(t, srv.ClientURL(), createUserCreds(t, srv, aKp))
  6238  		defer nc.Close()
  6239  		s, err := nc.SubscribeSync(sub)
  6240  		require_NoError(t, err)
  6241  		nc.Flush()
  6242  		err = nc.Publish(pub, nil)
  6243  		require_NoError(t, err)
  6244  		_, err = s.NextMsg(500 * time.Millisecond)
  6245  		switch {
  6246  		case fail && err == nil:
  6247  			t.Fatal("expected error, got none")
  6248  		case !fail && err != nil:
  6249  			t.Fatalf("expected no error, got %v", err)
  6250  		}
  6251  	}
  6252  
  6253  	// turn mappings on
  6254  	require_Len(t, 1, updateJwt(t, srv.ClientURL(), sysCreds, aJwtMap1, 1))
  6255  	test("foo1", "bar1", false)
  6256  	// alter mappings
  6257  	require_Len(t, 1, updateJwt(t, srv.ClientURL(), sysCreds, aJwtMap2, 1))
  6258  	test("foo1", "bar1", true)
  6259  	test("foo2", "bar2", false)
  6260  	// turn mappings off
  6261  	require_Len(t, 1, updateJwt(t, srv.ClientURL(), sysCreds, aJwtNoM, 1))
  6262  	test("foo2", "bar2", true)
  6263  }
  6264  
  6265  func TestJWTOperatorPinnedAccounts(t *testing.T) {
  6266  	kps, pubs, jwts := [4]nkeys.KeyPair{}, [4]string{}, [4]string{}
  6267  	for i := 0; i < 4; i++ {
  6268  		kps[i], pubs[i] = createKey(t)
  6269  		jwts[i] = encodeClaim(t, jwt.NewAccountClaims(pubs[i]), pubs[i])
  6270  	}
  6271  	// create system account user credentials, index 0 is handled as system account
  6272  	newUser(t, kps[0])
  6273  
  6274  	cfgCommon := fmt.Sprintf(`
  6275  		listen: 127.0.0.1:-1
  6276  		operator: %s
  6277  		system_account: %s
  6278  		resolver: MEM
  6279  		resolver_preload: {
  6280  			%s:%s
  6281  			%s:%s
  6282  			%s:%s
  6283  			%s:%s
  6284  		}`, ojwt, pubs[0], pubs[0], jwts[0], pubs[1], jwts[1], pubs[2], jwts[2], pubs[3], jwts[3])
  6285  	cfgFmt := cfgCommon + `
  6286  		resolver_pinned_accounts: [%s, %s]
  6287  	`
  6288  	conf := createConfFile(t, []byte(fmt.Sprintf(cfgFmt, pubs[1], pubs[2])))
  6289  	srv, _ := RunServerWithConfig(conf)
  6290  	defer srv.Shutdown()
  6291  
  6292  	connectPass := func(keys ...nkeys.KeyPair) {
  6293  		for _, kp := range keys {
  6294  			nc, err := nats.Connect(srv.ClientURL(), createUserCreds(t, srv, kp))
  6295  			require_NoError(t, err)
  6296  			defer nc.Close()
  6297  		}
  6298  	}
  6299  	var pinnedFail uint64
  6300  	connectFail := func(key nkeys.KeyPair) {
  6301  		_, err := nats.Connect(srv.ClientURL(), createUserCreds(t, srv, key))
  6302  		require_Error(t, err)
  6303  		require_Contains(t, err.Error(), "Authorization Violation")
  6304  		v, err := srv.Varz(&VarzOptions{})
  6305  		require_NoError(t, err)
  6306  		require_True(t, pinnedFail+1 == v.PinnedAccountFail)
  6307  		pinnedFail = v.PinnedAccountFail
  6308  	}
  6309  
  6310  	connectPass(kps[0], kps[1], kps[2]) // make sure user from accounts listed and system account (index 0) work
  6311  	connectFail(kps[3])                 // make sure the other user does not work
  6312  	// reload and test again
  6313  	reloadUpdateConfig(t, srv, conf, fmt.Sprintf(cfgFmt, pubs[2], pubs[3]))
  6314  	connectPass(kps[0], kps[2], kps[3]) // make sure user from accounts listed and system account (index 0) work
  6315  	connectFail(kps[1])                 // make sure the other user does not work
  6316  	// completely disable and test again
  6317  	reloadUpdateConfig(t, srv, conf, cfgCommon)
  6318  	connectPass(kps[0], kps[1], kps[2], kps[3]) // make sure every account and system account (index 0) can connect
  6319  	// re-enable and test again
  6320  	reloadUpdateConfig(t, srv, conf, fmt.Sprintf(cfgFmt, pubs[2], pubs[3]))
  6321  	connectPass(kps[0], kps[2], kps[3]) // make sure user from accounts listed and system account (index 0) work
  6322  	connectFail(kps[1])                 // make sure the other user does not work
  6323  }
  6324  
  6325  func TestJWTNoSystemAccountButNatsResolver(t *testing.T) {
  6326  	dirSrv := t.TempDir()
  6327  	for _, resType := range []string{"full", "cache"} {
  6328  		t.Run(resType, func(t *testing.T) {
  6329  			conf := createConfFile(t, []byte(fmt.Sprintf(`
  6330  			listen: 127.0.0.1:-1
  6331  			operator: %s
  6332  			resolver: {
  6333  				type: %s
  6334  				dir: '%s'
  6335  			}`, ojwt, resType, dirSrv)))
  6336  			opts := LoadConfig(conf)
  6337  			s, err := NewServer(opts)
  6338  			// Since the server cannot be stopped, since it did not start,
  6339  			// let's manually close the account resolver to avoid leaking go routines.
  6340  			opts.AccountResolver.Close()
  6341  			s.Shutdown()
  6342  			require_Error(t, err)
  6343  			require_Contains(t, err.Error(), "the system account needs to be specified in configuration or the operator jwt")
  6344  		})
  6345  	}
  6346  }
  6347  
  6348  func TestJWTAccountConnzAccessAfterClaimUpdate(t *testing.T) {
  6349  	skp, spub := createKey(t)
  6350  	newUser(t, skp)
  6351  
  6352  	sclaim := jwt.NewAccountClaims(spub)
  6353  	sclaim.AddMapping("foo.bar", jwt.WeightedMapping{Subject: "foo.baz"})
  6354  	sjwt := encodeClaim(t, sclaim, spub)
  6355  
  6356  	// create two jwt, one with and one without mapping
  6357  	akp, apub := createKey(t)
  6358  	newUser(t, akp)
  6359  	claim := jwt.NewAccountClaims(apub)
  6360  	jwt1 := encodeClaim(t, claim, apub)
  6361  	claim.AddMapping("foo.bar", jwt.WeightedMapping{Subject: "foo.baz"})
  6362  	jwt2 := encodeClaim(t, claim, apub)
  6363  
  6364  	dirSrv := t.TempDir()
  6365  
  6366  	conf := createConfFile(t, []byte(fmt.Sprintf(`
  6367  		listen: 127.0.0.1:-1
  6368  		operator: %s
  6369  		system_account: %s
  6370  		resolver: {
  6371  			type: full
  6372  			dir: '%s'
  6373  		}
  6374      `, ojwt, spub, dirSrv)))
  6375  
  6376  	s, _ := RunServerWithConfig(conf)
  6377  	defer s.Shutdown()
  6378  
  6379  	type zapi struct {
  6380  		Server *ServerInfo
  6381  		Data   *Connz
  6382  		Error  *ApiError
  6383  	}
  6384  
  6385  	updateJWT := func(jwt string) {
  6386  		t.Helper()
  6387  		sc := natsConnect(t, s.ClientURL(), createUserCreds(t, s, skp))
  6388  		defer sc.Close()
  6389  		resp, err := sc.Request("$SYS.REQ.CLAIMS.UPDATE", []byte(jwt), time.Second)
  6390  		if err != nil {
  6391  			t.Fatalf("Unexpected error: %v", err)
  6392  		}
  6393  		var cz zapi
  6394  		if err := json.Unmarshal(resp.Data, &cz); err != nil {
  6395  			t.Fatalf("Unexpected error: %v", err)
  6396  		}
  6397  		if cz.Error != nil {
  6398  			t.Fatalf("Unexpected error: %+v", cz.Error)
  6399  		}
  6400  	}
  6401  
  6402  	updateJWT(jwt1)
  6403  
  6404  	nc := natsConnect(t, s.ClientURL(), createUserCreds(t, s, akp))
  6405  	defer nc.Close()
  6406  
  6407  	doRequest := func() {
  6408  		t.Helper()
  6409  		resp, err := nc.Request("$SYS.REQ.SERVER.PING.CONNZ", nil, time.Second)
  6410  		if err != nil {
  6411  			t.Fatalf("Unexpected error: %v", err)
  6412  		}
  6413  		var cz zapi
  6414  		if err := json.Unmarshal(resp.Data, &cz); err != nil {
  6415  			t.Fatalf("Unexpected error: %v", err)
  6416  		}
  6417  		if cz.Error != nil {
  6418  			t.Fatalf("Unexpected error: %+v", cz.Error)
  6419  		}
  6420  	}
  6421  
  6422  	doRequest()
  6423  	updateJWT(jwt2)
  6424  	// If we accidentally wipe the system import this will fail with no responders.
  6425  	doRequest()
  6426  	// Now test updating system account.
  6427  	updateJWT(sjwt)
  6428  	// If export was wiped this would fail with timeout.
  6429  	doRequest()
  6430  }
  6431  
  6432  func TestAccountWeightedMappingInSuperCluster(t *testing.T) {
  6433  	skp, spub := createKey(t)
  6434  	sysClaim := jwt.NewAccountClaims(spub)
  6435  	sysClaim.Name = "SYS"
  6436  	sysCreds := newUser(t, skp)
  6437  
  6438  	akp, apub := createKey(t)
  6439  	aUsr := createUserCreds(t, nil, akp)
  6440  	claim := jwt.NewAccountClaims(apub)
  6441  	aJwtMap := encodeClaim(t, claim, apub)
  6442  
  6443  	// We are using the createJetStreamSuperClusterWithTemplateAndModHook()
  6444  	// helper, but this test is not about JetStream...
  6445  	tmpl := `
  6446  		listen: 127.0.0.1:-1
  6447  		server_name: %s
  6448  		jetstream: {max_mem_store: 256MB, max_file_store: 2GB, store_dir: '%s'}
  6449  		cluster {
  6450  			name: %s
  6451  			listen: 127.0.0.1:%d
  6452  			routes = [%s]
  6453  		}
  6454      `
  6455  
  6456  	sc := createJetStreamSuperClusterWithTemplateAndModHook(t, tmpl, 3, 3,
  6457  		func(serverName, clusterName, storeDir, conf string) string {
  6458  			dirSrv := t.TempDir()
  6459  			return fmt.Sprintf(`%s
  6460  				operator: %s
  6461  				system_account: %s
  6462  				resolver: {
  6463  					type: full
  6464  					dir: '%s'
  6465  				}
  6466  			`, conf, ojwt, spub, dirSrv)
  6467  		}, nil)
  6468  	defer sc.shutdown()
  6469  
  6470  	// Update from C2
  6471  	require_Len(t, 1, updateJwt(t, sc.clusterForName("C2").randomServer().ClientURL(), sysCreds, aJwtMap, 1))
  6472  
  6473  	// We will connect our services in the C3 cluster.
  6474  	nc1 := natsConnect(t, sc.clusterForName("C3").randomServer().ClientURL(), aUsr)
  6475  	defer nc1.Close()
  6476  	nc2 := natsConnect(t, sc.clusterForName("C3").randomServer().ClientURL(), aUsr)
  6477  	defer nc2.Close()
  6478  
  6479  	natsSub(t, nc1, "foo", func(m *nats.Msg) {
  6480  		m.Respond([]byte("foo"))
  6481  	})
  6482  	natsSub(t, nc1, "bar.v1", func(m *nats.Msg) {
  6483  		m.Respond([]byte("v1"))
  6484  	})
  6485  	natsSub(t, nc2, "bar.v2", func(m *nats.Msg) {
  6486  		m.Respond([]byte("v2"))
  6487  	})
  6488  	natsFlush(t, nc1)
  6489  	natsFlush(t, nc2)
  6490  
  6491  	// Now we will update the account to add weighted subject mapping
  6492  	claim.Mappings = map[jwt.Subject][]jwt.WeightedMapping{}
  6493  	// Start with foo->bar.v2 at 40%, the server will auto-add foo->foo at 60%.
  6494  	wm := []jwt.WeightedMapping{{Subject: "bar.v2", Weight: 40}}
  6495  	claim.AddMapping("foo", wm...)
  6496  	aJwtMap = encodeClaim(t, claim, apub)
  6497  
  6498  	// We will update from C2
  6499  	require_Len(t, 1, updateJwt(t, sc.clusterForName("C2").randomServer().ClientURL(), sysCreds, aJwtMap, 1))
  6500  
  6501  	time.Sleep(time.Second)
  6502  
  6503  	// And we will publish from C1
  6504  	nc := natsConnect(t, sc.clusterForName("C1").randomServer().ClientURL(), aUsr)
  6505  	defer nc.Close()
  6506  
  6507  	var foo, v1, v2 int
  6508  	pubAndCount := func() {
  6509  		for i := 0; i < 1000; i++ {
  6510  			msg, err := nc.Request("foo", []byte("req"), 500*time.Millisecond)
  6511  			if err != nil {
  6512  				continue
  6513  			}
  6514  			switch string(msg.Data) {
  6515  			case "foo":
  6516  				foo++
  6517  			case "v1":
  6518  				v1++
  6519  			case "v2":
  6520  				v2++
  6521  			}
  6522  		}
  6523  	}
  6524  	pubAndCount()
  6525  	if foo < 550 || foo > 650 {
  6526  		t.Fatalf("Expected foo to receive 60%%, got %v/1000", foo)
  6527  	}
  6528  	if v1 != 0 {
  6529  		t.Fatalf("Expected v1 to receive no message, got %v/1000", v1)
  6530  	}
  6531  	if v2 < 350 || v2 > 450 {
  6532  		t.Fatalf("Expected v2 to receive 40%%, got %v/1000", v2)
  6533  	}
  6534  
  6535  	// Now send a new update with foo-> bar.v2(40) and bar.v1(60).
  6536  	// The auto-add of "foo" should no longer be used by the server.
  6537  	wm = []jwt.WeightedMapping{
  6538  		{Subject: "bar.v2", Weight: 40},
  6539  		{Subject: "bar.v1", Weight: 60},
  6540  	}
  6541  	claim.AddMapping("foo", wm...)
  6542  	aJwtMap = encodeClaim(t, claim, apub)
  6543  
  6544  	// We will update from C2
  6545  	require_Len(t, 1, updateJwt(t, sc.clusterForName("C2").randomServer().ClientURL(), sysCreds, aJwtMap, 1))
  6546  
  6547  	time.Sleep(time.Second)
  6548  
  6549  	foo, v1, v2 = 0, 0, 0
  6550  	pubAndCount()
  6551  	if foo != 0 {
  6552  		t.Fatalf("Expected foo to receive no message, got %v/1000", foo)
  6553  	}
  6554  	if v1 < 550 || v1 > 650 {
  6555  		t.Fatalf("Expected v1 to receive 60%%, got %v/1000", v1)
  6556  	}
  6557  	if v2 < 350 || v2 > 450 {
  6558  		t.Fatalf("Expected v2 to receive 40%%, got %v/1000", v2)
  6559  	}
  6560  }
  6561  
  6562  func TestServerOperatorModeNoAuthRequired(t *testing.T) {
  6563  	_, spub := createKey(t)
  6564  	sysClaim := jwt.NewAccountClaims(spub)
  6565  	sysClaim.Name = "$SYS"
  6566  	sysJwt, err := sysClaim.Encode(oKp)
  6567  	require_NoError(t, err)
  6568  
  6569  	akp, apub := createKey(t)
  6570  	accClaim := jwt.NewAccountClaims(apub)
  6571  	accClaim.Name = "TEST"
  6572  	accJwt, err := accClaim.Encode(oKp)
  6573  	require_NoError(t, err)
  6574  
  6575  	ukp, _ := nkeys.CreateUser()
  6576  	seed, _ := ukp.Seed()
  6577  	upub, _ := ukp.PublicKey()
  6578  	nuc := jwt.NewUserClaims(upub)
  6579  	ujwt, err := nuc.Encode(akp)
  6580  	require_NoError(t, err)
  6581  	creds := genCredsFile(t, ujwt, seed)
  6582  
  6583  	dirSrv := t.TempDir()
  6584  
  6585  	conf := createConfFile(t, []byte(fmt.Sprintf(`
  6586  		listen: 127.0.0.1:-1
  6587  		server_name: srv-A
  6588  		operator: %s
  6589  		system_account: %s
  6590  		resolver: {
  6591  			type: full
  6592  			dir: '%s'
  6593  			interval: "200ms"
  6594  			limit: 4
  6595  		}
  6596  		resolver_preload: {
  6597  			%s: %s
  6598  			%s: %s
  6599  		}
  6600      `, ojwt, spub, dirSrv, spub, sysJwt, apub, accJwt)))
  6601  
  6602  	s, _ := RunServerWithConfig(conf)
  6603  	defer s.Shutdown()
  6604  
  6605  	nc := natsConnect(t, s.ClientURL(), nats.UserCredentials(creds))
  6606  	defer nc.Close()
  6607  
  6608  	require_True(t, nc.AuthRequired())
  6609  }
  6610  
  6611  func TestServerOperatorModeUserInfoExpiration(t *testing.T) {
  6612  	_, spub := createKey(t)
  6613  	sysClaim := jwt.NewAccountClaims(spub)
  6614  	sysClaim.Name = "$SYS"
  6615  	sysJwt, err := sysClaim.Encode(oKp)
  6616  	require_NoError(t, err)
  6617  
  6618  	akp, apub := createKey(t)
  6619  	accClaim := jwt.NewAccountClaims(apub)
  6620  	accClaim.Name = "TEST"
  6621  	accJwt, err := accClaim.Encode(oKp)
  6622  	require_NoError(t, err)
  6623  
  6624  	conf := createConfFile(t, []byte(fmt.Sprintf(`
  6625  				listen: 127.0.0.1:-1
  6626  				operator: %s
  6627  				system_account: %s
  6628  				resolver: MEM
  6629  				resolver_preload: {
  6630  					%s: %s
  6631  					%s: %s
  6632  				}
  6633  			`, ojwt, spub, apub, accJwt, spub, sysJwt)))
  6634  	defer removeFile(t, conf)
  6635  
  6636  	s, _ := RunServerWithConfig(conf)
  6637  	defer s.Shutdown()
  6638  
  6639  	expires := time.Now().Add(time.Minute)
  6640  	creds := createUserWithLimit(t, akp, expires, func(j *jwt.UserPermissionLimits) {})
  6641  
  6642  	nc := natsConnect(t, s.ClientURL(), nats.UserCredentials(creds))
  6643  	defer nc.Close()
  6644  
  6645  	resp, err := nc.Request("$SYS.REQ.USER.INFO", nil, time.Second)
  6646  	require_NoError(t, err)
  6647  	now := time.Now()
  6648  
  6649  	response := ServerAPIResponse{Data: &UserInfo{}}
  6650  	err = json.Unmarshal(resp.Data, &response)
  6651  	require_NoError(t, err)
  6652  
  6653  	userInfo := response.Data.(*UserInfo)
  6654  	require_True(t, userInfo.Expires != 0)
  6655  
  6656  	// We need to round the expiration time to the second because the server
  6657  	// will truncate the expiration time to the second.
  6658  	expiresDurRounded := expires.Sub(now).Truncate(time.Second)
  6659  
  6660  	// Checking range to avoid flaky tests where the expiration time is
  6661  	// off by a couple of seconds.
  6662  	require_True(t, expiresDurRounded >= userInfo.Expires-2*time.Second && expiresDurRounded <= userInfo.Expires+2*time.Second)
  6663  }
  6664  
  6665  func TestJWTAccountNATSResolverWrongCreds(t *testing.T) {
  6666  	require_NoLocalOrRemoteConnections := func(account string, srvs ...*Server) {
  6667  		t.Helper()
  6668  		for _, srv := range srvs {
  6669  			if acc, ok := srv.accounts.Load(account); ok {
  6670  				checkAccClientsCount(t, acc.(*Account), 0)
  6671  			}
  6672  		}
  6673  	}
  6674  	connect := func(url string, credsfile string, acc string, srvs ...*Server) {
  6675  		t.Helper()
  6676  		nc := natsConnect(t, url, nats.UserCredentials(credsfile), nats.Timeout(5*time.Second))
  6677  		nc.Close()
  6678  		require_NoLocalOrRemoteConnections(acc, srvs...)
  6679  	}
  6680  	createAccountAndUser := func(pubKey, jwt1, jwt2, creds *string) {
  6681  		t.Helper()
  6682  		kp, _ := nkeys.CreateAccount()
  6683  		*pubKey, _ = kp.PublicKey()
  6684  		claim := jwt.NewAccountClaims(*pubKey)
  6685  		var err error
  6686  		*jwt1, err = claim.Encode(oKp)
  6687  		require_NoError(t, err)
  6688  		*jwt2, err = claim.Encode(oKp)
  6689  		require_NoError(t, err)
  6690  		ukp, _ := nkeys.CreateUser()
  6691  		seed, _ := ukp.Seed()
  6692  		upub, _ := ukp.PublicKey()
  6693  		uclaim := newJWTTestUserClaims()
  6694  		uclaim.Subject = upub
  6695  		ujwt, err := uclaim.Encode(kp)
  6696  		require_NoError(t, err)
  6697  		*creds = genCredsFile(t, ujwt, seed)
  6698  	}
  6699  	// Create Accounts and corresponding user creds.
  6700  	var syspub, sysjwt, dummy1, sysCreds string
  6701  	createAccountAndUser(&syspub, &sysjwt, &dummy1, &sysCreds)
  6702  
  6703  	var apub, ajwt1, ajwt2, aCreds string
  6704  	createAccountAndUser(&apub, &ajwt1, &ajwt2, &aCreds)
  6705  
  6706  	var bpub, bjwt1, bjwt2, bCreds string
  6707  	createAccountAndUser(&bpub, &bjwt1, &bjwt2, &bCreds)
  6708  
  6709  	// The one that is going to be missing.
  6710  	var cpub, cjwt1, cjwt2, cCreds string
  6711  	createAccountAndUser(&cpub, &cjwt1, &cjwt2, &cCreds)
  6712  	// Create one directory for each server
  6713  	dirA := t.TempDir()
  6714  	dirB := t.TempDir()
  6715  	dirC := t.TempDir()
  6716  
  6717  	// Store accounts on servers A and B, then let C sync on its own.
  6718  	writeJWT(t, dirA, apub, ajwt1)
  6719  	writeJWT(t, dirB, bpub, bjwt1)
  6720  
  6721  	/////////////////////////////////////////
  6722  	//                                     //
  6723  	//   Server A: has creds from client A //
  6724  	//                                     //
  6725  	/////////////////////////////////////////
  6726  	confA := createConfFile(t, []byte(fmt.Sprintf(`
  6727  		listen: 127.0.0.1:-1
  6728  		server_name: srv-A
  6729  		operator: %s
  6730  		system_account: %s
  6731                  debug: true
  6732  		resolver: {
  6733  			type: full
  6734  			dir: '%s'
  6735  			allow_delete: true
  6736  			timeout: "1.5s"
  6737  			interval: "200ms"
  6738  		}
  6739  		resolver_preload: {
  6740  			%s: %s
  6741  		}
  6742  		cluster {
  6743  			name: clust
  6744  			listen: 127.0.0.1:-1
  6745  			no_advertise: true
  6746  		}
  6747         `, ojwt, syspub, dirA, apub, ajwt1)))
  6748  	sA, _ := RunServerWithConfig(confA)
  6749  	defer sA.Shutdown()
  6750  	require_JWTPresent(t, dirA, apub)
  6751  
  6752  	/////////////////////////////////////////
  6753  	//                                     //
  6754  	//   Server B: has creds from client B //
  6755  	//                                     //
  6756  	/////////////////////////////////////////
  6757  	confB := createConfFile(t, []byte(fmt.Sprintf(`
  6758  		listen: 127.0.0.1:-1
  6759  		server_name: srv-B
  6760  		operator: %s
  6761  		system_account: %s
  6762  		resolver: {
  6763  			type: full
  6764  			dir: '%s'
  6765  			allow_delete: true
  6766  			timeout: "1.5s"
  6767  			interval: "200ms"
  6768  		}
  6769  		cluster {
  6770  			name: clust
  6771  			listen: 127.0.0.1:-1
  6772  			no_advertise: true
  6773  			routes [
  6774  				nats-route://127.0.0.1:%d
  6775  			]
  6776  		}
  6777          `, ojwt, syspub, dirB, sA.opts.Cluster.Port)))
  6778  	sB, _ := RunServerWithConfig(confB)
  6779  	defer sB.Shutdown()
  6780  
  6781  	/////////////////////////////////////////
  6782  	//                                     //
  6783  	//   Server C: has no creds            //
  6784  	//                                     //
  6785  	/////////////////////////////////////////
  6786  	fmtC := `
  6787  		listen: 127.0.0.1:-1
  6788  		server_name: srv-C
  6789  		operator: %s
  6790  		system_account: %s
  6791  		resolver: {
  6792  			type: full
  6793  			dir: '%s'
  6794  			allow_delete: true
  6795  			timeout: "1.5s"
  6796  			interval: "200ms"
  6797  		}
  6798  		cluster {
  6799  			name: clust
  6800  			listen: 127.0.0.1:-1
  6801  			no_advertise: true
  6802  			routes [
  6803  				nats-route://127.0.0.1:%d
  6804  			]
  6805  		}
  6806      `
  6807  	confClongTTL := createConfFile(t, []byte(fmt.Sprintf(fmtC, ojwt, syspub, dirC, sA.opts.Cluster.Port)))
  6808  	sC, _ := RunServerWithConfig(confClongTTL) // use long ttl to assure it is not kicking
  6809  	defer sC.Shutdown()
  6810  
  6811  	// startup cluster
  6812  	checkClusterFormed(t, sA, sB, sC)
  6813  	time.Sleep(1 * time.Second) // wait for the protocol to converge
  6814  	// // Check all accounts
  6815  	require_JWTPresent(t, dirA, apub) // was already present on startup
  6816  	require_JWTPresent(t, dirB, apub) // was copied from server A
  6817  	require_JWTPresent(t, dirA, bpub) // was copied from server B
  6818  	require_JWTPresent(t, dirB, bpub) // was already present on startup
  6819  
  6820  	// There should be no state about the missing account.
  6821  	require_JWTAbsent(t, dirA, cpub)
  6822  	require_JWTAbsent(t, dirB, cpub)
  6823  	require_JWTAbsent(t, dirC, cpub)
  6824  
  6825  	// system account client can connect to every server
  6826  	connect(sA.ClientURL(), sysCreds, "")
  6827  	connect(sB.ClientURL(), sysCreds, "")
  6828  	connect(sC.ClientURL(), sysCreds, "")
  6829  
  6830  	// A and B clients can connect to any server.
  6831  	connect(sA.ClientURL(), aCreds, "")
  6832  	connect(sB.ClientURL(), aCreds, "")
  6833  	connect(sC.ClientURL(), aCreds, "")
  6834  	connect(sA.ClientURL(), bCreds, "")
  6835  	connect(sB.ClientURL(), bCreds, "")
  6836  	connect(sC.ClientURL(), bCreds, "")
  6837  
  6838  	// Check that trying to connect with bad credentials should not hang until the fetch timeout
  6839  	// and instead return a faster response when an account is not found.
  6840  	_, err := nats.Connect(sC.ClientURL(), nats.UserCredentials(cCreds), nats.Timeout(500*time.Second))
  6841  	if err != nil && !errors.Is(err, nats.ErrAuthorization) {
  6842  		t.Fatalf("Expected auth error: %v", err)
  6843  	}
  6844  }