github.com/nats-io/nats-server/v2@v2.11.0-preview.2/server/jetstream_jwt_test.go (about)

     1  // Copyright 2020-2023 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  //go:build !skip_js_tests
    15  // +build !skip_js_tests
    16  
    17  package server
    18  
    19  import (
    20  	"encoding/json"
    21  	"errors"
    22  	"fmt"
    23  	"net/http"
    24  	"net/http/httptest"
    25  	"strings"
    26  	"sync/atomic"
    27  	"testing"
    28  	"time"
    29  
    30  	jwt "github.com/nats-io/jwt/v2"
    31  	"github.com/nats-io/nats.go"
    32  	"github.com/nats-io/nkeys"
    33  )
    34  
    35  func TestJetStreamJWTLimits(t *testing.T) {
    36  	updateJwt := func(url string, creds string, pubKey string, jwt string) {
    37  		t.Helper()
    38  		c := natsConnect(t, url, nats.UserCredentials(creds))
    39  		defer c.Close()
    40  		if msg, err := c.Request(fmt.Sprintf(accUpdateEventSubjNew, pubKey), []byte(jwt), time.Second); err != nil {
    41  			t.Fatal("error not expected in this test", err)
    42  		} else {
    43  			content := make(map[string]any)
    44  			if err := json.Unmarshal(msg.Data, &content); err != nil {
    45  				t.Fatalf("%v", err)
    46  			} else if _, ok := content["data"]; !ok {
    47  				t.Fatalf("did not get an ok response got: %v", content)
    48  			}
    49  		}
    50  	}
    51  	require_IdenticalLimits := func(infoLim JetStreamAccountLimits, lim jwt.JetStreamLimits) {
    52  		t.Helper()
    53  		if int64(infoLim.MaxConsumers) != lim.Consumer || int64(infoLim.MaxStreams) != lim.Streams ||
    54  			infoLim.MaxMemory != lim.MemoryStorage || infoLim.MaxStore != lim.DiskStorage {
    55  			t.Fatalf("limits do not match %v != %v", infoLim, lim)
    56  		}
    57  	}
    58  	expect_JSDisabledForAccount := func(c *nats.Conn) {
    59  		t.Helper()
    60  		if _, err := c.Request("$JS.API.INFO", nil, time.Second); err != nats.ErrTimeout && err != nats.ErrNoResponders {
    61  			t.Fatalf("Unexpected error: %v", err)
    62  		}
    63  	}
    64  	expect_InfoError := func(c *nats.Conn) {
    65  		t.Helper()
    66  		var info JSApiAccountInfoResponse
    67  		if resp, err := c.Request("$JS.API.INFO", nil, time.Second); err != nil {
    68  			t.Fatalf("Unexpected error: %v", err)
    69  		} else if err = json.Unmarshal(resp.Data, &info); err != nil {
    70  			t.Fatalf("response1 %v got error %v", string(resp.Data), err)
    71  		} else if info.Error == nil {
    72  			t.Fatalf("expected error")
    73  		}
    74  	}
    75  	validate_limits := func(c *nats.Conn, expectedLimits jwt.JetStreamLimits) {
    76  		t.Helper()
    77  		var info JSApiAccountInfoResponse
    78  		if resp, err := c.Request("$JS.API.INFO", nil, time.Second); err != nil {
    79  			t.Fatalf("Unexpected error: %v", err)
    80  		} else if err = json.Unmarshal(resp.Data, &info); err != nil {
    81  			t.Fatalf("response1 %v got error %v", string(resp.Data), err)
    82  		} else {
    83  			require_IdenticalLimits(info.Limits, expectedLimits)
    84  		}
    85  	}
    86  	// create system account
    87  	sysKp, _ := nkeys.CreateAccount()
    88  	sysPub, _ := sysKp.PublicKey()
    89  	sysUKp, _ := nkeys.CreateUser()
    90  	sysUSeed, _ := sysUKp.Seed()
    91  	uclaim := newJWTTestUserClaims()
    92  	uclaim.Subject, _ = sysUKp.PublicKey()
    93  	sysUserJwt, err := uclaim.Encode(sysKp)
    94  	require_NoError(t, err)
    95  	sysKp.Seed()
    96  	sysCreds := genCredsFile(t, sysUserJwt, sysUSeed)
    97  	// limits to apply and check
    98  	limits1 := jwt.JetStreamLimits{MemoryStorage: 1024 * 1024, DiskStorage: 2048 * 1024, Streams: 1, Consumer: 2, MaxBytesRequired: true}
    99  	// has valid limits that would fail when incorrectly applied twice
   100  	limits2 := jwt.JetStreamLimits{MemoryStorage: 4096 * 1024, DiskStorage: 8192 * 1024, Streams: 3, Consumer: 4}
   101  	// limits exceeding actual configured value of DiskStorage
   102  	limitsExceeded := jwt.JetStreamLimits{MemoryStorage: 8192 * 1024, DiskStorage: 16384 * 1024, Streams: 5, Consumer: 6}
   103  	// create account using jetstream with both limits
   104  	akp, _ := nkeys.CreateAccount()
   105  	aPub, _ := akp.PublicKey()
   106  	claim := jwt.NewAccountClaims(aPub)
   107  	claim.Limits.JetStreamLimits = limits1
   108  	aJwt1, err := claim.Encode(oKp)
   109  	require_NoError(t, err)
   110  	claim.Limits.JetStreamLimits = limits2
   111  	aJwt2, err := claim.Encode(oKp)
   112  	require_NoError(t, err)
   113  	claim.Limits.JetStreamLimits = limitsExceeded
   114  	aJwtLimitsExceeded, err := claim.Encode(oKp)
   115  	require_NoError(t, err)
   116  	claim.Limits.JetStreamLimits = jwt.JetStreamLimits{} // disabled
   117  	aJwt4, err := claim.Encode(oKp)
   118  	require_NoError(t, err)
   119  	// account user
   120  	uKp, _ := nkeys.CreateUser()
   121  	uSeed, _ := uKp.Seed()
   122  	uclaim = newJWTTestUserClaims()
   123  	uclaim.Subject, _ = uKp.PublicKey()
   124  	userJwt, err := uclaim.Encode(akp)
   125  	require_NoError(t, err)
   126  	userCreds := genCredsFile(t, userJwt, uSeed)
   127  	dir := t.TempDir()
   128  	conf := createConfFile(t, []byte(fmt.Sprintf(`
   129  		listen: 127.0.0.1:-1
   130  		jetstream: {max_mem_store: 10Mb, max_file_store: 10Mb, store_dir: "%s"}
   131  		operator: %s
   132  		resolver: {
   133  			type: full
   134  			dir: '%s'
   135  		}
   136  		system_account: %s
   137      `, dir, ojwt, dir, sysPub)))
   138  	s, opts := RunServerWithConfig(conf)
   139  	defer s.Shutdown()
   140  	port := opts.Port
   141  	updateJwt(s.ClientURL(), sysCreds, aPub, aJwt1)
   142  	c := natsConnect(t, s.ClientURL(), nats.UserCredentials(userCreds), nats.ReconnectWait(200*time.Millisecond))
   143  	defer c.Close()
   144  	validate_limits(c, limits1)
   145  	// keep using the same connection
   146  	updateJwt(s.ClientURL(), sysCreds, aPub, aJwt2)
   147  	validate_limits(c, limits2)
   148  	// keep using the same connection but do NOT CHANGE anything.
   149  	// This tests if the jwt is applied a second time (would fail)
   150  	updateJwt(s.ClientURL(), sysCreds, aPub, aJwt2)
   151  	validate_limits(c, limits2)
   152  	// keep using the same connection. This update EXCEEDS LIMITS
   153  	updateJwt(s.ClientURL(), sysCreds, aPub, aJwtLimitsExceeded)
   154  	validate_limits(c, limits2)
   155  	// disable test after failure
   156  	updateJwt(s.ClientURL(), sysCreds, aPub, aJwt4)
   157  	expect_InfoError(c)
   158  	// re enable, again testing with a value that can't be applied twice
   159  	updateJwt(s.ClientURL(), sysCreds, aPub, aJwt2)
   160  	validate_limits(c, limits2)
   161  	// disable test no prior failure
   162  	updateJwt(s.ClientURL(), sysCreds, aPub, aJwt4)
   163  	expect_InfoError(c)
   164  	// Wrong limits form start
   165  	updateJwt(s.ClientURL(), sysCreds, aPub, aJwtLimitsExceeded)
   166  	expect_JSDisabledForAccount(c)
   167  	// enable js but exceed limits. Followed by fix via restart
   168  	updateJwt(s.ClientURL(), sysCreds, aPub, aJwt2)
   169  	validate_limits(c, limits2)
   170  	updateJwt(s.ClientURL(), sysCreds, aPub, aJwtLimitsExceeded)
   171  	validate_limits(c, limits2)
   172  	s.Shutdown()
   173  	conf = createConfFile(t, []byte(fmt.Sprintf(`
   174  		listen: 127.0.0.1:%d
   175  		jetstream: {max_mem_store: 20Mb, max_file_store: 20Mb, store_dir: "%s"}
   176  		operator: %s
   177  		resolver: {
   178  			type: full
   179  			dir: '%s'
   180  		}
   181  		system_account: %s
   182      `, port, dir, ojwt, dir, sysPub)))
   183  	s, _ = RunServerWithConfig(conf)
   184  	defer s.Shutdown()
   185  	c.Flush() // force client to discover the disconnect
   186  	checkClientsCount(t, s, 1)
   187  	validate_limits(c, limitsExceeded)
   188  	s.Shutdown()
   189  	// disable jetstream test
   190  	conf = createConfFile(t, []byte(fmt.Sprintf(`
   191  		listen: 127.0.0.1:%d
   192  		operator: %s
   193  		resolver: {
   194  			type: full
   195  			dir: '%s'
   196  		}
   197  		system_account: %s
   198      `, port, ojwt, dir, sysPub)))
   199  	s, _ = RunServerWithConfig(conf)
   200  	defer s.Shutdown()
   201  	c.Flush() // force client to discover the disconnect
   202  	checkClientsCount(t, s, 1)
   203  	expect_JSDisabledForAccount(c)
   204  	// test that it stays disabled
   205  	updateJwt(s.ClientURL(), sysCreds, aPub, aJwt2)
   206  	expect_JSDisabledForAccount(c)
   207  	c.Close()
   208  }
   209  
   210  func TestJetStreamJWTDisallowBearer(t *testing.T) {
   211  	sysKp, syspub := createKey(t)
   212  	sysJwt := encodeClaim(t, jwt.NewAccountClaims(syspub), syspub)
   213  	sysCreds := newUser(t, sysKp)
   214  
   215  	accKp, err := nkeys.CreateAccount()
   216  	require_NoError(t, err)
   217  	accIdPub, err := accKp.PublicKey()
   218  	require_NoError(t, err)
   219  	aClaim := jwt.NewAccountClaims(accIdPub)
   220  	accJwt1, err := aClaim.Encode(oKp)
   221  	require_NoError(t, err)
   222  	aClaim.Limits.DisallowBearer = true
   223  	accJwt2, err := aClaim.Encode(oKp)
   224  	require_NoError(t, err)
   225  
   226  	uc := jwt.NewUserClaims("dummy")
   227  	uc.BearerToken = true
   228  	uOpt1 := createUserCredsEx(t, uc, accKp)
   229  	uc.BearerToken = false
   230  	uOpt2 := createUserCredsEx(t, uc, accKp)
   231  
   232  	dir := t.TempDir()
   233  	cf := createConfFile(t, []byte(fmt.Sprintf(`
   234  		port: -1
   235  		operator = %s
   236  		system_account: %s
   237  		resolver: {
   238  			type: full
   239  			dir: '%s/jwt'
   240  		}
   241  		resolver_preload = {
   242  			%s : "%s"
   243  		}
   244  		`, ojwt, syspub, dir, syspub, sysJwt)))
   245  	s, _ := RunServerWithConfig(cf)
   246  	defer s.Shutdown()
   247  
   248  	updateJwt(t, s.ClientURL(), sysCreds, accJwt1, 1)
   249  	disconnectErrCh := make(chan error, 10)
   250  	defer close(disconnectErrCh)
   251  	nc1, err := nats.Connect(s.ClientURL(), uOpt1,
   252  		nats.NoReconnect(),
   253  		nats.ErrorHandler(func(conn *nats.Conn, s *nats.Subscription, err error) {
   254  			disconnectErrCh <- err
   255  		}))
   256  	require_NoError(t, err)
   257  	defer nc1.Close()
   258  
   259  	// update jwt and observe bearer token get disconnected
   260  	updateJwt(t, s.ClientURL(), sysCreds, accJwt2, 1)
   261  	select {
   262  	case err := <-disconnectErrCh:
   263  		require_Contains(t, err.Error(), "authorization violation")
   264  	case <-time.After(time.Second):
   265  		t.Fatalf("expected error on disconnect")
   266  	}
   267  
   268  	// assure bearer token is not allowed to connect
   269  	_, err = nats.Connect(s.ClientURL(), uOpt1)
   270  	require_Error(t, err)
   271  
   272  	// assure non bearer token can connect
   273  	nc2, err := nats.Connect(s.ClientURL(), uOpt2)
   274  	require_NoError(t, err)
   275  	defer nc2.Close()
   276  }
   277  
   278  func TestJetStreamJWTMove(t *testing.T) {
   279  	sysKp, syspub := createKey(t)
   280  	sysJwt := encodeClaim(t, jwt.NewAccountClaims(syspub), syspub)
   281  	sysCreds := newUser(t, sysKp)
   282  
   283  	accKp, aExpPub := createKey(t)
   284  
   285  	test := func(t *testing.T, replicas int, accClaim *jwt.AccountClaims) {
   286  		accClaim.Name = "acc"
   287  		accJwt := encodeClaim(t, accClaim, aExpPub)
   288  		accCreds := newUser(t, accKp)
   289  
   290  		tmlp := `
   291  			listen: 127.0.0.1:-1
   292  			server_name: %s
   293  			jetstream: {max_mem_store: 256MB, max_file_store: 2GB, store_dir: '%s'}
   294  			leaf {
   295  				listen: 127.0.0.1:-1
   296  			}
   297  			cluster {
   298  				name: %s
   299  				listen: 127.0.0.1:%d
   300  				routes = [%s]
   301  			}
   302  		`
   303  		sc := createJetStreamSuperClusterWithTemplateAndModHook(t, tmlp, 5, 2,
   304  			func(serverName, clustername, storeDir, conf string) string {
   305  				switch sname := serverName[strings.Index(serverName, "-")+1:]; sname {
   306  				case "S1", "S2":
   307  					conf = strings.ReplaceAll(conf, "jetstream", "#jetstream")
   308  				}
   309  				return conf + fmt.Sprintf(`
   310  					server_tags: [cloud:%s-tag]
   311  					operator: %s
   312  					system_account: %s
   313  					resolver: {
   314  						type: full
   315  						dir: '%s/jwt'
   316  					}
   317  					resolver_preload = {
   318  						%s : %s
   319  					}
   320  				`, clustername, ojwt, syspub, storeDir, syspub, sysJwt)
   321  			}, nil)
   322  		defer sc.shutdown()
   323  
   324  		s := sc.serverByName("C1-S1")
   325  		require_False(t, s.JetStreamEnabled())
   326  		updateJwt(t, s.ClientURL(), sysCreds, accJwt, 10)
   327  
   328  		s = sc.serverByName("C2-S1")
   329  		require_False(t, s.JetStreamEnabled())
   330  
   331  		nc := natsConnect(t, s.ClientURL(), nats.UserCredentials(accCreds))
   332  		defer nc.Close()
   333  
   334  		js, err := nc.JetStream()
   335  		require_NoError(t, err)
   336  
   337  		ci, err := js.AddStream(&nats.StreamConfig{Name: "MOVE-ME", Replicas: replicas,
   338  			Placement: &nats.Placement{Tags: []string{"cloud:C1-tag"}}})
   339  		require_NoError(t, err)
   340  		require_Equal(t, ci.Cluster.Name, "C1")
   341  
   342  		_, err = js.AddConsumer("MOVE-ME", &nats.ConsumerConfig{Durable: "dur", AckPolicy: nats.AckExplicitPolicy})
   343  		require_NoError(t, err)
   344  		_, err = js.Publish("MOVE-ME", []byte("hello world"))
   345  		require_NoError(t, err)
   346  
   347  		// Perform actual move
   348  		ci, err = js.UpdateStream(&nats.StreamConfig{Name: "MOVE-ME", Replicas: replicas,
   349  			Placement: &nats.Placement{Tags: []string{"cloud:C2-tag"}}})
   350  		require_NoError(t, err)
   351  		require_Equal(t, ci.Cluster.Name, "C1")
   352  
   353  		sc.clusterForName("C2").waitOnStreamLeader(aExpPub, "MOVE-ME")
   354  
   355  		checkFor(t, 30*time.Second, 250*time.Millisecond, func() error {
   356  			if si, err := js.StreamInfo("MOVE-ME"); err != nil {
   357  				return fmt.Errorf("stream: %v", err)
   358  			} else if si.Cluster.Name != "C2" {
   359  				return fmt.Errorf("Wrong cluster: %q", si.Cluster.Name)
   360  			} else if !strings.HasPrefix(si.Cluster.Leader, "C2-") {
   361  				return fmt.Errorf("Wrong leader: %q", si.Cluster.Leader)
   362  			} else if len(si.Cluster.Replicas) != replicas-1 {
   363  				return fmt.Errorf("Expected %d replicas, got %d", replicas-1, len(si.Cluster.Replicas))
   364  			} else if si.State.Msgs != 1 {
   365  				return fmt.Errorf("expected one message")
   366  			}
   367  			// Now make sure consumer has leader etc..
   368  			if ci, err := js.ConsumerInfo("MOVE-ME", "dur"); err != nil {
   369  				return fmt.Errorf("stream: %v", err)
   370  			} else if ci.Cluster.Name != "C2" {
   371  				return fmt.Errorf("Wrong cluster: %q", ci.Cluster.Name)
   372  			} else if ci.Cluster.Leader == _EMPTY_ {
   373  				return fmt.Errorf("No leader yet")
   374  			}
   375  			return nil
   376  		})
   377  
   378  		sub, err := js.PullSubscribe("", "dur", nats.BindStream("MOVE-ME"))
   379  		require_NoError(t, err)
   380  		m, err := sub.Fetch(1)
   381  		require_NoError(t, err)
   382  		require_NoError(t, m[0].AckSync())
   383  	}
   384  
   385  	t.Run("tiered", func(t *testing.T) {
   386  		accClaim := jwt.NewAccountClaims(aExpPub)
   387  		accClaim.Limits.JetStreamTieredLimits["R1"] = jwt.JetStreamLimits{
   388  			DiskStorage: 1100, Consumer: 1, Streams: 1}
   389  		accClaim.Limits.JetStreamTieredLimits["R3"] = jwt.JetStreamLimits{
   390  			DiskStorage: 3300, Consumer: 1, Streams: 1}
   391  
   392  		t.Run("R3", func(t *testing.T) {
   393  			test(t, 3, accClaim)
   394  		})
   395  		t.Run("R1", func(t *testing.T) {
   396  			test(t, 1, accClaim)
   397  		})
   398  	})
   399  
   400  	t.Run("non-tiered", func(t *testing.T) {
   401  		accClaim := jwt.NewAccountClaims(aExpPub)
   402  		accClaim.Limits.JetStreamLimits = jwt.JetStreamLimits{
   403  			DiskStorage: 4400, Consumer: 2, Streams: 2}
   404  
   405  		t.Run("R3", func(t *testing.T) {
   406  			test(t, 3, accClaim)
   407  		})
   408  		t.Run("R1", func(t *testing.T) {
   409  			test(t, 1, accClaim)
   410  		})
   411  	})
   412  }
   413  
   414  func TestJetStreamJWTClusteredTiers(t *testing.T) {
   415  	sysKp, syspub := createKey(t)
   416  	sysJwt := encodeClaim(t, jwt.NewAccountClaims(syspub), syspub)
   417  	newUser(t, sysKp)
   418  
   419  	accKp, aExpPub := createKey(t)
   420  	accClaim := jwt.NewAccountClaims(aExpPub)
   421  	accClaim.Name = "acc"
   422  	accClaim.Limits.JetStreamTieredLimits["R1"] = jwt.JetStreamLimits{
   423  		DiskStorage: 1100, Consumer: 2, Streams: 2}
   424  	accClaim.Limits.JetStreamTieredLimits["R3"] = jwt.JetStreamLimits{
   425  		DiskStorage: 1100, Consumer: 1, Streams: 1}
   426  	accJwt := encodeClaim(t, accClaim, aExpPub)
   427  	accCreds := newUser(t, accKp)
   428  	tmlp := `
   429  		listen: 127.0.0.1:-1
   430  		server_name: %s
   431  		jetstream: {max_mem_store: 256MB, max_file_store: 2GB, store_dir: '%s'}
   432  		leaf {
   433  			listen: 127.0.0.1:-1
   434  		}
   435  		cluster {
   436  			name: %s
   437  			listen: 127.0.0.1:%d
   438  			routes = [%s]
   439  		}
   440  	` + fmt.Sprintf(`
   441  		operator: %s
   442  		system_account: %s
   443  		resolver = MEMORY
   444  		resolver_preload = {
   445  			%s : %s
   446  			%s : %s
   447  		}
   448  	`, ojwt, syspub, syspub, sysJwt, aExpPub, accJwt)
   449  
   450  	c := createJetStreamClusterWithTemplate(t, tmlp, "cluster", 3)
   451  	defer c.shutdown()
   452  
   453  	nc := natsConnect(t, c.randomServer().ClientURL(), nats.UserCredentials(accCreds))
   454  	defer nc.Close()
   455  
   456  	js, err := nc.JetStream()
   457  	require_NoError(t, err)
   458  
   459  	// Test absent tiers
   460  	_, err = js.AddStream(&nats.StreamConfig{Name: "testR2", Replicas: 2, Subjects: []string{"testR2"}})
   461  	require_Error(t, err)
   462  	require_Equal(t, err.Error(), "nats: no JetStream default or applicable tiered limit present")
   463  	_, err = js.AddStream(&nats.StreamConfig{Name: "testR5", Replicas: 5, Subjects: []string{"testR5"}})
   464  	require_Error(t, err)
   465  	require_Equal(t, err.Error(), "nats: no JetStream default or applicable tiered limit present")
   466  
   467  	// Test tiers up to stream limits
   468  	_, err = js.AddStream(&nats.StreamConfig{Name: "testR1-1", Replicas: 1, Subjects: []string{"testR1-1"}})
   469  	require_NoError(t, err)
   470  	_, err = js.AddStream(&nats.StreamConfig{Name: "testR3-1", Replicas: 3, Subjects: []string{"testR3-1"}})
   471  	require_NoError(t, err)
   472  	_, err = js.AddStream(&nats.StreamConfig{Name: "testR1-2", Replicas: 1, Subjects: []string{"testR1-2"}})
   473  	require_NoError(t, err)
   474  
   475  	// Test exceeding tiered stream limit
   476  	_, err = js.AddStream(&nats.StreamConfig{Name: "testR1-3", Replicas: 1, Subjects: []string{"testR1-3"}})
   477  	require_Error(t, err)
   478  	require_Equal(t, err.Error(), "nats: maximum number of streams reached")
   479  	_, err = js.AddStream(&nats.StreamConfig{Name: "testR3-3", Replicas: 3, Subjects: []string{"testR3-3"}})
   480  	require_Error(t, err)
   481  	require_Equal(t, err.Error(), "nats: maximum number of streams reached")
   482  
   483  	// Test tiers up to consumer limits
   484  	_, err = js.AddConsumer("testR1-1", &nats.ConsumerConfig{Durable: "dur1", AckPolicy: nats.AckExplicitPolicy})
   485  	require_NoError(t, err)
   486  	_, err = js.AddConsumer("testR3-1", &nats.ConsumerConfig{Durable: "dur2", AckPolicy: nats.AckExplicitPolicy})
   487  	require_NoError(t, err)
   488  	_, err = js.AddConsumer("testR1-1", &nats.ConsumerConfig{Durable: "dur3", AckPolicy: nats.AckExplicitPolicy})
   489  	require_NoError(t, err)
   490  
   491  	// test exceeding tiered consumer limits
   492  	_, err = js.AddConsumer("testR1-1", &nats.ConsumerConfig{Durable: "dur4", AckPolicy: nats.AckExplicitPolicy})
   493  	require_Error(t, err)
   494  	require_Equal(t, err.Error(), "nats: maximum consumers limit reached")
   495  	_, err = js.AddConsumer("testR1-1", &nats.ConsumerConfig{Durable: "dur5", AckPolicy: nats.AckExplicitPolicy})
   496  	require_Error(t, err)
   497  	require_Equal(t, err.Error(), "nats: maximum consumers limit reached")
   498  
   499  	// test tiered storage limit
   500  	msg := [512]byte{}
   501  	_, err = js.Publish("testR1-1", msg[:])
   502  	require_NoError(t, err)
   503  	_, err = js.Publish("testR3-1", msg[:])
   504  	require_NoError(t, err)
   505  	_, err = js.Publish("testR3-1", msg[:])
   506  	require_NoError(t, err)
   507  	_, err = js.Publish("testR1-2", msg[:])
   508  	require_NoError(t, err)
   509  
   510  	time.Sleep(2000 * time.Millisecond) // wait for update timer to synchronize totals
   511  
   512  	// test exceeding tiered storage limit
   513  	_, err = js.Publish("testR1-1", []byte("1"))
   514  	require_Error(t, err)
   515  	require_Equal(t, err.Error(), "nats: resource limits exceeded for account")
   516  	_, err = js.Publish("testR3-1", []byte("fail this message!"))
   517  	require_Error(t, err)
   518  	require_Equal(t, err.Error(), "nats: resource limits exceeded for account")
   519  
   520  	// retrieve limits
   521  	var info JSApiAccountInfoResponse
   522  	m, err := nc.Request("$JS.API.INFO", nil, time.Second)
   523  	require_NoError(t, err)
   524  	err = json.Unmarshal(m.Data, &info)
   525  	require_NoError(t, err)
   526  
   527  	require_True(t, info.Memory == 0)
   528  	// R1 streams fail message with an add followed by remove, if the update was sent in between, the count is > limit
   529  	// Alternative to checking both values is, prior to the info request, wait for another update
   530  	require_True(t, info.Store == 4400 || info.Store == 4439)
   531  	require_True(t, info.Streams == 3)
   532  	require_True(t, info.Consumers == 3)
   533  	require_True(t, info.Limits == JetStreamAccountLimits{})
   534  	r1 := info.Tiers["R1"]
   535  	require_True(t, r1.Streams == 2)
   536  	require_True(t, r1.Consumers == 2)
   537  	// R1 streams fail message with an add followed by remove, if the update was sent in between, the count is > limit
   538  	// Alternative to checking both values is, prior to the info request, wait for another update
   539  	require_True(t, r1.Store == 1100 || r1.Store == 1139)
   540  	require_True(t, r1.Memory == 0)
   541  	require_True(t, r1.Limits == JetStreamAccountLimits{
   542  		MaxMemory:            0,
   543  		MaxStore:             1100,
   544  		MaxStreams:           2,
   545  		MaxConsumers:         2,
   546  		MaxAckPending:        -1,
   547  		MemoryMaxStreamBytes: -1,
   548  		StoreMaxStreamBytes:  -1,
   549  		MaxBytesRequired:     false,
   550  	})
   551  	r3 := info.Tiers["R3"]
   552  	require_True(t, r3.Streams == 1)
   553  	require_True(t, r3.Consumers == 1)
   554  	require_True(t, r3.Store == 3300)
   555  	require_True(t, r3.Memory == 0)
   556  	require_True(t, r3.Limits == JetStreamAccountLimits{
   557  		MaxMemory:            0,
   558  		MaxStore:             1100,
   559  		MaxStreams:           1,
   560  		MaxConsumers:         1,
   561  		MaxAckPending:        -1,
   562  		MemoryMaxStreamBytes: -1,
   563  		StoreMaxStreamBytes:  -1,
   564  		MaxBytesRequired:     false,
   565  	})
   566  }
   567  
   568  func TestJetStreamJWTClusteredTiersChange(t *testing.T) {
   569  	sysKp, syspub := createKey(t)
   570  	sysJwt := encodeClaim(t, jwt.NewAccountClaims(syspub), syspub)
   571  	sysCreds := newUser(t, sysKp)
   572  
   573  	accKp, aExpPub := createKey(t)
   574  	accClaim := jwt.NewAccountClaims(aExpPub)
   575  	accClaim.Name = "acc"
   576  	accClaim.Limits.JetStreamTieredLimits["R1"] = jwt.JetStreamLimits{
   577  		DiskStorage: 1000, MemoryStorage: 0, Consumer: 1, Streams: 1}
   578  	accClaim.Limits.JetStreamTieredLimits["R3"] = jwt.JetStreamLimits{
   579  		DiskStorage: 500, MemoryStorage: 0, Consumer: 1, Streams: 1}
   580  	accJwt1 := encodeClaim(t, accClaim, aExpPub)
   581  	accCreds := newUser(t, accKp)
   582  	start := time.Now()
   583  
   584  	tmlp := `
   585  		listen: 127.0.0.1:-1
   586  		server_name: %s
   587  		jetstream: {max_mem_store: 256MB, max_file_store: 2GB, store_dir: '%s'}
   588  		leaf {
   589  			listen: 127.0.0.1:-1
   590  		}
   591  		cluster {
   592  			name: %s
   593  			listen: 127.0.0.1:%d
   594  			routes = [%s]
   595  		}
   596  	`
   597  	c := createJetStreamClusterWithTemplateAndModHook(t, tmlp, "cluster", 3,
   598  		func(serverName, clustername, storeDir, conf string) string {
   599  			return conf + fmt.Sprintf(`
   600  				operator: %s
   601  				system_account: %s
   602  				resolver: {
   603  					type: full
   604  					dir: '%s/jwt'
   605  				}`, ojwt, syspub, storeDir)
   606  		})
   607  	defer c.shutdown()
   608  
   609  	updateJwt(t, c.randomServer().ClientURL(), sysCreds, sysJwt, 3)
   610  	updateJwt(t, c.randomServer().ClientURL(), sysCreds, accJwt1, 3)
   611  
   612  	nc := natsConnect(t, c.randomServer().ClientURL(), nats.UserCredentials(accCreds))
   613  	defer nc.Close()
   614  
   615  	js, err := nc.JetStream()
   616  	require_NoError(t, err)
   617  
   618  	// Test tiers up to stream limits
   619  	cfg := &nats.StreamConfig{Name: "testR1-1", Replicas: 1, Subjects: []string{"testR1-1"}, MaxBytes: 1000}
   620  	_, err = js.AddStream(cfg)
   621  	require_NoError(t, err)
   622  
   623  	cfg.Replicas = 3
   624  	_, err = js.UpdateStream(cfg)
   625  	require_Error(t, err, errors.New("nats: insufficient storage resources available"))
   626  
   627  	time.Sleep(time.Second - time.Since(start)) // make sure the time stamp changes
   628  	accClaim.Limits.JetStreamTieredLimits["R3"] = jwt.JetStreamLimits{
   629  		DiskStorage: 1000, MemoryStorage: 0, Consumer: 1, Streams: 1}
   630  	accJwt2 := encodeClaim(t, accClaim, aExpPub)
   631  
   632  	updateJwt(t, c.randomServer().ClientURL(), sysCreds, accJwt2, 3)
   633  
   634  	var rBefore, rAfter JSApiAccountInfoResponse
   635  	m, err := nc.Request("$JS.API.INFO", nil, time.Second)
   636  	require_NoError(t, err)
   637  	err = json.Unmarshal(m.Data, &rBefore)
   638  	require_NoError(t, err)
   639  	_, err = js.UpdateStream(cfg)
   640  	require_NoError(t, err)
   641  
   642  	m, err = nc.Request("$JS.API.INFO", nil, time.Second)
   643  	require_NoError(t, err)
   644  	err = json.Unmarshal(m.Data, &rAfter)
   645  	require_NoError(t, err)
   646  	require_True(t, rBefore.Tiers["R1"].Streams == 1)
   647  	require_True(t, rBefore.Tiers["R1"].Streams == rAfter.Tiers["R3"].Streams)
   648  	require_True(t, rBefore.Tiers["R3"].Streams == 0)
   649  	require_True(t, rAfter.Tiers["R1"].Streams == 0)
   650  }
   651  
   652  func TestJetStreamJWTClusteredDeleteTierWithStreamAndMove(t *testing.T) {
   653  	sysKp, syspub := createKey(t)
   654  	sysJwt := encodeClaim(t, jwt.NewAccountClaims(syspub), syspub)
   655  	sysCreds := newUser(t, sysKp)
   656  
   657  	accKp, aExpPub := createKey(t)
   658  	accClaim := jwt.NewAccountClaims(aExpPub)
   659  	accClaim.Name = "acc"
   660  	accClaim.Limits.JetStreamTieredLimits["R1"] = jwt.JetStreamLimits{
   661  		DiskStorage: 1000, MemoryStorage: 0, Consumer: 1, Streams: 1}
   662  	accClaim.Limits.JetStreamTieredLimits["R3"] = jwt.JetStreamLimits{
   663  		DiskStorage: 3000, MemoryStorage: 0, Consumer: 1, Streams: 1}
   664  	accJwt1 := encodeClaim(t, accClaim, aExpPub)
   665  	accCreds := newUser(t, accKp)
   666  	start := time.Now()
   667  
   668  	tmlp := `
   669  		listen: 127.0.0.1:-1
   670  		server_name: %s
   671  		jetstream: {max_mem_store: 256MB, max_file_store: 2GB, store_dir: '%s'}
   672  		leaf {
   673  			listen: 127.0.0.1:-1
   674  		}
   675  		cluster {
   676  			name: %s
   677  			listen: 127.0.0.1:%d
   678  			routes = [%s]
   679  		}
   680  	`
   681  	c := createJetStreamClusterWithTemplateAndModHook(t, tmlp, "cluster", 3,
   682  		func(serverName, clustername, storeDir, conf string) string {
   683  			return conf + fmt.Sprintf(`
   684  				operator: %s
   685  				system_account: %s
   686  				resolver: {
   687  					type: full
   688  					dir: '%s/jwt'
   689  				}`, ojwt, syspub, storeDir)
   690  		})
   691  	defer c.shutdown()
   692  
   693  	updateJwt(t, c.randomServer().ClientURL(), sysCreds, sysJwt, 3)
   694  	updateJwt(t, c.randomServer().ClientURL(), sysCreds, accJwt1, 3)
   695  
   696  	nc := natsConnect(t, c.randomServer().ClientURL(), nats.UserCredentials(accCreds))
   697  	defer nc.Close()
   698  
   699  	js, err := nc.JetStream()
   700  	require_NoError(t, err)
   701  
   702  	// Test tiers up to stream limits
   703  	cfg := &nats.StreamConfig{Name: "testR1-1", Replicas: 1, Subjects: []string{"testR1-1"}, MaxBytes: 1000}
   704  	_, err = js.AddStream(cfg)
   705  	require_NoError(t, err)
   706  
   707  	_, err = js.Publish("testR1-1", nil)
   708  	require_NoError(t, err)
   709  
   710  	time.Sleep(time.Second - time.Since(start)) // make sure the time stamp changes
   711  	delete(accClaim.Limits.JetStreamTieredLimits, "R1")
   712  	accJwt2 := encodeClaim(t, accClaim, aExpPub)
   713  	updateJwt(t, c.randomServer().ClientURL(), sysCreds, accJwt2, 3)
   714  
   715  	var respBefore JSApiAccountInfoResponse
   716  	m, err := nc.Request("$JS.API.INFO", nil, time.Second)
   717  	require_NoError(t, err)
   718  	err = json.Unmarshal(m.Data, &respBefore)
   719  	require_NoError(t, err)
   720  
   721  	require_True(t, respBefore.JetStreamAccountStats.Tiers["R3"].Streams == 0)
   722  	require_True(t, respBefore.JetStreamAccountStats.Tiers["R1"].Streams == 1)
   723  
   724  	_, err = js.Publish("testR1-1", nil)
   725  	require_Error(t, err)
   726  	require_Equal(t, err.Error(), "nats: no JetStream default or applicable tiered limit present")
   727  
   728  	cfg.Replicas = 3
   729  	_, err = js.UpdateStream(cfg)
   730  	require_NoError(t, err)
   731  
   732  	// I noticed this taking > 5 seconds
   733  	checkFor(t, 10*time.Second, 250*time.Millisecond, func() error {
   734  		_, err = js.Publish("testR1-1", nil)
   735  		return err
   736  	})
   737  
   738  	var respAfter JSApiAccountInfoResponse
   739  	m, err = nc.Request("$JS.API.INFO", nil, time.Second)
   740  	require_NoError(t, err)
   741  	err = json.Unmarshal(m.Data, &respAfter)
   742  	require_NoError(t, err)
   743  
   744  	require_True(t, respAfter.JetStreamAccountStats.Tiers["R3"].Streams == 1)
   745  	require_True(t, respAfter.JetStreamAccountStats.Tiers["R3"].Store > 0)
   746  
   747  	_, ok := respAfter.JetStreamAccountStats.Tiers["R1"]
   748  	require_True(t, !ok)
   749  }
   750  
   751  func TestJetStreamJWTSysAccUpdateMixedMode(t *testing.T) {
   752  	skp, spub := createKey(t)
   753  	sUsr := createUserCreds(t, nil, skp)
   754  	sysClaim := jwt.NewAccountClaims(spub)
   755  	sysClaim.Name = "SYS"
   756  	sysJwt := encodeClaim(t, sysClaim, spub)
   757  	encodeJwt1Time := time.Now()
   758  
   759  	akp, apub := createKey(t)
   760  	aUsr := createUserCreds(t, nil, akp)
   761  	claim := jwt.NewAccountClaims(apub)
   762  	claim.Limits.JetStreamLimits.DiskStorage = 1024 * 1024
   763  	claim.Limits.JetStreamLimits.Streams = 1
   764  	jwt1 := encodeClaim(t, claim, apub)
   765  
   766  	basePath := "/ngs/v1/accounts/jwt/"
   767  	reqCount := int32(0)
   768  	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   769  		if r.URL.Path == basePath {
   770  			w.Write([]byte("ok"))
   771  		} else if strings.HasSuffix(r.URL.Path, spub) {
   772  			w.Write([]byte(sysJwt))
   773  		} else if strings.HasSuffix(r.URL.Path, apub) {
   774  			w.Write([]byte(jwt1))
   775  		} else {
   776  			// only count requests that could be filled
   777  			return
   778  		}
   779  		atomic.AddInt32(&reqCount, 1)
   780  	}))
   781  	defer ts.Close()
   782  
   783  	tmpl := `
   784  		listen: 127.0.0.1:-1
   785  		server_name: %s
   786  		jetstream: {max_mem_store: 256MB, max_file_store: 2GB, store_dir: '%s'}
   787  		cluster {
   788  			name: %s
   789  			listen: 127.0.0.1:%d
   790  			routes = [%s]
   791  		}
   792      `
   793  
   794  	sc := createJetStreamSuperClusterWithTemplateAndModHook(t, tmpl, 3, 2,
   795  		func(serverName, clusterName, storeDir, conf string) string {
   796  			// create an ngs like setup, with connection and non connection server
   797  			if clusterName == "C1" {
   798  				conf = strings.ReplaceAll(conf, "jetstream", "#jetstream")
   799  			}
   800  			return fmt.Sprintf(`%s
   801  				operator: %s
   802  				system_account: %s
   803  				resolver: URL("%s%s")`, conf, ojwt, spub, ts.URL, basePath)
   804  		}, nil)
   805  	defer sc.shutdown()
   806  	disconnectChan := make(chan struct{}, 100)
   807  	defer close(disconnectChan)
   808  	disconnectCb := nats.DisconnectErrHandler(func(conn *nats.Conn, err error) {
   809  		disconnectChan <- struct{}{}
   810  	})
   811  
   812  	s := sc.clusterForName("C1").randomServer()
   813  
   814  	sysNc := natsConnect(t, s.ClientURL(), sUsr, disconnectCb, nats.NoCallbacksAfterClientClose())
   815  	defer sysNc.Close()
   816  	aNc := natsConnect(t, s.ClientURL(), aUsr, disconnectCb, nats.NoCallbacksAfterClientClose())
   817  	defer aNc.Close()
   818  
   819  	js, err := aNc.JetStream()
   820  	require_NoError(t, err)
   821  
   822  	si, err := js.AddStream(&nats.StreamConfig{Name: "bar", Subjects: []string{"bar"}, Replicas: 3})
   823  	require_NoError(t, err)
   824  	require_Equal(t, si.Cluster.Name, "C2")
   825  	_, err = js.AccountInfo()
   826  	require_NoError(t, err)
   827  
   828  	r, err := sysNc.Request(fmt.Sprintf(serverPingReqSubj, "ACCOUNTZ"),
   829  		[]byte(fmt.Sprintf(`{"account":"%s"}`, spub)), time.Second)
   830  	require_NoError(t, err)
   831  	respb := ServerAPIResponse{Data: &Accountz{}}
   832  	require_NoError(t, json.Unmarshal(r.Data, &respb))
   833  
   834  	hasJSExp := func(resp *ServerAPIResponse) bool {
   835  		found := false
   836  		for _, e := range resp.Data.(*Accountz).Account.Exports {
   837  			if e.Subject == jsAllAPI {
   838  				found = true
   839  				break
   840  			}
   841  		}
   842  		return found
   843  	}
   844  	require_True(t, hasJSExp(&respb))
   845  
   846  	// make sure jti increased
   847  	time.Sleep(time.Second - time.Since(encodeJwt1Time))
   848  	sysJwt2 := encodeClaim(t, sysClaim, spub)
   849  
   850  	oldRcount := atomic.LoadInt32(&reqCount)
   851  	_, err = sysNc.Request(fmt.Sprintf(accUpdateEventSubjNew, spub), []byte(sysJwt2), time.Second)
   852  	require_NoError(t, err)
   853  	// test to make sure connected client (aNc) was not kicked
   854  	time.Sleep(200 * time.Millisecond)
   855  	require_True(t, len(disconnectChan) == 0)
   856  
   857  	// ensure nothing new has happened, lookup for account not found is skipped during inc
   858  	require_True(t, atomic.LoadInt32(&reqCount) == oldRcount)
   859  	// no responders
   860  	_, err = aNc.Request("foo", nil, time.Second)
   861  	require_Error(t, err)
   862  	require_Equal(t, err.Error(), "nats: no responders available for request")
   863  
   864  	nc2, js2 := jsClientConnect(t, sc.clusterForName("C2").randomServer(), aUsr)
   865  	defer nc2.Close()
   866  	_, err = js2.AccountInfo()
   867  	require_NoError(t, err)
   868  
   869  	r, err = sysNc.Request(fmt.Sprintf(serverPingReqSubj, "ACCOUNTZ"),
   870  		[]byte(fmt.Sprintf(`{"account":"%s"}`, spub)), time.Second)
   871  	require_NoError(t, err)
   872  	respa := ServerAPIResponse{Data: &Accountz{}}
   873  	require_NoError(t, json.Unmarshal(r.Data, &respa))
   874  	require_True(t, hasJSExp(&respa))
   875  
   876  	_, err = js.AccountInfo()
   877  	require_NoError(t, err)
   878  }
   879  
   880  func TestJetStreamJWTExpiredAccountNotCountedTowardLimits(t *testing.T) {
   881  	op, _ := nkeys.CreateOperator()
   882  	opPk, _ := op.PublicKey()
   883  	sk, _ := nkeys.CreateOperator()
   884  	skPk, _ := sk.PublicKey()
   885  	opClaim := jwt.NewOperatorClaims(opPk)
   886  	opClaim.SigningKeys.Add(skPk)
   887  	opJwt, err := opClaim.Encode(op)
   888  	require_NoError(t, err)
   889  	createAccountAndUser := func(pubKey, jwt1, creds1 *string) {
   890  		t.Helper()
   891  		kp, _ := nkeys.CreateAccount()
   892  		*pubKey, _ = kp.PublicKey()
   893  		claim := jwt.NewAccountClaims(*pubKey)
   894  		claim.Limits.JetStreamLimits = jwt.JetStreamLimits{MemoryStorage: 7 * 1024 * 1024, DiskStorage: 7 * 1024 * 1024, Streams: 10}
   895  		var err error
   896  		*jwt1, err = claim.Encode(sk)
   897  		require_NoError(t, err)
   898  
   899  		ukp, _ := nkeys.CreateUser()
   900  		seed, _ := ukp.Seed()
   901  		upub, _ := ukp.PublicKey()
   902  		uclaim := newJWTTestUserClaims()
   903  		uclaim.Subject = upub
   904  
   905  		ujwt1, err := uclaim.Encode(kp)
   906  		require_NoError(t, err)
   907  		*creds1 = genCredsFile(t, ujwt1, seed)
   908  	}
   909  	generateRequest := func(accs []string, kp nkeys.KeyPair) []byte {
   910  		t.Helper()
   911  		opk, _ := kp.PublicKey()
   912  		c := jwt.NewGenericClaims(opk)
   913  		c.Data["accounts"] = accs
   914  		cJwt, err := c.Encode(kp)
   915  		if err != nil {
   916  			t.Fatalf("Expected no error %v", err)
   917  		}
   918  		return []byte(cJwt)
   919  	}
   920  
   921  	var syspub, sysjwt, sysCreds string
   922  	createAccountAndUser(&syspub, &sysjwt, &sysCreds)
   923  
   924  	dirSrv := t.TempDir()
   925  	conf := createConfFile(t, []byte(fmt.Sprintf(`
   926  		listen: 127.0.0.1:-1
   927  		operator: %s
   928  		jetstream: {max_mem_store: 10Mb, max_file_store: 10Mb, store_dir: "%s"}
   929  		system_account: %s
   930  		resolver: {
   931  			type: full
   932  			allow_delete: true
   933  			dir: '%s'
   934  			timeout: "500ms"
   935  		}
   936      `, opJwt, dirSrv, syspub, dirSrv)))
   937  
   938  	s, _ := RunServerWithConfig(conf)
   939  	defer s.Shutdown()
   940  
   941  	// update system account jwt
   942  	updateJwt(t, s.ClientURL(), sysCreds, sysjwt, 1)
   943  
   944  	var apub, ajwt1, aCreds1 string
   945  	createAccountAndUser(&apub, &ajwt1, &aCreds1)
   946  	// push jwt (for full resolver)
   947  	updateJwt(t, s.ClientURL(), sysCreds, ajwt1, 1)
   948  
   949  	ncA, jsA := jsClientConnect(t, s, nats.UserCredentials(aCreds1))
   950  	defer ncA.Close()
   951  
   952  	ai, err := jsA.AccountInfo()
   953  	require_NoError(t, err)
   954  	require_True(t, ai.Limits.MaxMemory == 7*1024*1024)
   955  	ncA.Close()
   956  
   957  	nc := natsConnect(t, s.ClientURL(), nats.UserCredentials(sysCreds))
   958  	defer nc.Close()
   959  	resp, err := nc.Request(accDeleteReqSubj, generateRequest([]string{apub}, sk), time.Second)
   960  	require_NoError(t, err)
   961  	require_True(t, strings.Contains(string(resp.Data), `"message":"deleted 1 accounts"`))
   962  
   963  	var apub2, ajwt2, aCreds2 string
   964  	createAccountAndUser(&apub2, &ajwt2, &aCreds2)
   965  	// push jwt (for full resolver)
   966  	updateJwt(t, s.ClientURL(), sysCreds, ajwt2, 1)
   967  
   968  	ncB, jsB := jsClientConnect(t, s, nats.UserCredentials(aCreds2))
   969  	defer ncB.Close()
   970  
   971  	ai, err = jsB.AccountInfo()
   972  	require_NoError(t, err)
   973  	require_True(t, ai.Limits.MaxMemory == 7*1024*1024)
   974  }
   975  
   976  func TestJetStreamJWTDeletedAccountDoesNotLeakSubscriptions(t *testing.T) {
   977  	op, _ := nkeys.CreateOperator()
   978  	opPk, _ := op.PublicKey()
   979  	sk, _ := nkeys.CreateOperator()
   980  	skPk, _ := sk.PublicKey()
   981  	opClaim := jwt.NewOperatorClaims(opPk)
   982  	opClaim.SigningKeys.Add(skPk)
   983  	opJwt, err := opClaim.Encode(op)
   984  	require_NoError(t, err)
   985  	createAccountAndUser := func(pubKey, jwt1, creds1 *string) {
   986  		t.Helper()
   987  		kp, _ := nkeys.CreateAccount()
   988  		*pubKey, _ = kp.PublicKey()
   989  		claim := jwt.NewAccountClaims(*pubKey)
   990  		claim.Limits.JetStreamLimits = jwt.JetStreamLimits{MemoryStorage: 7 * 1024 * 1024, DiskStorage: 7 * 1024 * 1024, Streams: 10}
   991  		var err error
   992  		*jwt1, err = claim.Encode(sk)
   993  		require_NoError(t, err)
   994  
   995  		ukp, _ := nkeys.CreateUser()
   996  		seed, _ := ukp.Seed()
   997  		upub, _ := ukp.PublicKey()
   998  		uclaim := newJWTTestUserClaims()
   999  		uclaim.Subject = upub
  1000  
  1001  		ujwt1, err := uclaim.Encode(kp)
  1002  		require_NoError(t, err)
  1003  		*creds1 = genCredsFile(t, ujwt1, seed)
  1004  	}
  1005  	generateRequest := func(accs []string, kp nkeys.KeyPair) []byte {
  1006  		t.Helper()
  1007  		opk, _ := kp.PublicKey()
  1008  		c := jwt.NewGenericClaims(opk)
  1009  		c.Data["accounts"] = accs
  1010  		cJwt, err := c.Encode(kp)
  1011  		if err != nil {
  1012  			t.Fatalf("Expected no error %v", err)
  1013  		}
  1014  		return []byte(cJwt)
  1015  	}
  1016  
  1017  	var syspub, sysjwt, sysCreds string
  1018  	createAccountAndUser(&syspub, &sysjwt, &sysCreds)
  1019  
  1020  	dirSrv := t.TempDir()
  1021  	conf := createConfFile(t, []byte(fmt.Sprintf(`
  1022  		listen: 127.0.0.1:-1
  1023  		operator: %s
  1024  		jetstream: {max_mem_store: 10Mb, max_file_store: 10Mb, store_dir: %v}
  1025  		system_account: %s
  1026  		resolver: {
  1027  			type: full
  1028  			allow_delete: true
  1029  			dir: '%s'
  1030  			timeout: "500ms"
  1031  		}
  1032  	`, opJwt, dirSrv, syspub, dirSrv)))
  1033  
  1034  	s, _ := RunServerWithConfig(conf)
  1035  	defer s.Shutdown()
  1036  
  1037  	checkNumSubs := func(expected uint32) uint32 {
  1038  		t.Helper()
  1039  		// Wait a bit before capturing number of subs...
  1040  		time.Sleep(250 * time.Millisecond)
  1041  
  1042  		var ns uint32
  1043  		checkFor(t, time.Second, 50*time.Millisecond, func() error {
  1044  			subsz, err := s.Subsz(nil)
  1045  			if err != nil {
  1046  				return err
  1047  			}
  1048  			ns = subsz.NumSubs
  1049  			if expected > 0 && ns > expected {
  1050  				return fmt.Errorf("Expected num subs to be back at %v, got %v",
  1051  					expected, ns)
  1052  			}
  1053  			return nil
  1054  		})
  1055  		return ns
  1056  	}
  1057  	beforeCreate := checkNumSubs(0)
  1058  
  1059  	// update system account jwt
  1060  	updateJwt(t, s.ClientURL(), sysCreds, sysjwt, 1)
  1061  
  1062  	createAndDelete := func() {
  1063  		t.Helper()
  1064  
  1065  		var apub, ajwt1, aCreds1 string
  1066  		createAccountAndUser(&apub, &ajwt1, &aCreds1)
  1067  		// push jwt (for full resolver)
  1068  		updateJwt(t, s.ClientURL(), sysCreds, ajwt1, 1)
  1069  
  1070  		ncA, jsA := jsClientConnect(t, s, nats.UserCredentials(aCreds1))
  1071  		defer ncA.Close()
  1072  
  1073  		ai, err := jsA.AccountInfo()
  1074  		require_NoError(t, err)
  1075  		require_True(t, ai.Limits.MaxMemory == 7*1024*1024)
  1076  		ncA.Close()
  1077  
  1078  		nc := natsConnect(t, s.ClientURL(), nats.UserCredentials(sysCreds))
  1079  		defer nc.Close()
  1080  
  1081  		resp, err := nc.Request(accDeleteReqSubj, generateRequest([]string{apub}, sk), time.Second)
  1082  		require_NoError(t, err)
  1083  		require_True(t, strings.Contains(string(resp.Data), `"message":"deleted 1 accounts"`))
  1084  	}
  1085  
  1086  	// Create and delete multiple accounts
  1087  	for i := 0; i < 10; i++ {
  1088  		createAndDelete()
  1089  	}
  1090  
  1091  	// There is a subscription on `_R_.>` that is created on the system account
  1092  	// and that will not go away, so discount it.
  1093  	checkNumSubs(beforeCreate + 1)
  1094  }
  1095  
  1096  func TestJetStreamJWTDeletedAccountIsReEnabled(t *testing.T) {
  1097  	op, _ := nkeys.CreateOperator()
  1098  	opPk, _ := op.PublicKey()
  1099  	sk, _ := nkeys.CreateOperator()
  1100  	skPk, _ := sk.PublicKey()
  1101  	opClaim := jwt.NewOperatorClaims(opPk)
  1102  	opClaim.SigningKeys.Add(skPk)
  1103  	opJwt, err := opClaim.Encode(op)
  1104  	require_NoError(t, err)
  1105  	createAccountAndUser := func(pubKey, jwt1, creds1 *string) {
  1106  		t.Helper()
  1107  		kp, _ := nkeys.CreateAccount()
  1108  		*pubKey, _ = kp.PublicKey()
  1109  		claim := jwt.NewAccountClaims(*pubKey)
  1110  		claim.Limits.JetStreamLimits = jwt.JetStreamLimits{MemoryStorage: 7 * 1024 * 1024, DiskStorage: 7 * 1024 * 1024, Streams: 10}
  1111  		var err error
  1112  		*jwt1, err = claim.Encode(sk)
  1113  		require_NoError(t, err)
  1114  
  1115  		ukp, _ := nkeys.CreateUser()
  1116  		seed, _ := ukp.Seed()
  1117  		upub, _ := ukp.PublicKey()
  1118  		uclaim := newJWTTestUserClaims()
  1119  		uclaim.Subject = upub
  1120  
  1121  		ujwt1, err := uclaim.Encode(kp)
  1122  		require_NoError(t, err)
  1123  		*creds1 = genCredsFile(t, ujwt1, seed)
  1124  	}
  1125  	generateRequest := func(accs []string, kp nkeys.KeyPair) []byte {
  1126  		t.Helper()
  1127  		opk, _ := kp.PublicKey()
  1128  		c := jwt.NewGenericClaims(opk)
  1129  		c.Data["accounts"] = accs
  1130  		cJwt, err := c.Encode(kp)
  1131  		if err != nil {
  1132  			t.Fatalf("Expected no error %v", err)
  1133  		}
  1134  		return []byte(cJwt)
  1135  	}
  1136  
  1137  	// admin user
  1138  	var syspub, sysjwt, sysCreds string
  1139  	createAccountAndUser(&syspub, &sysjwt, &sysCreds)
  1140  
  1141  	dirSrv := t.TempDir()
  1142  	conf := createConfFile(t, []byte(fmt.Sprintf(`
  1143  		listen: 127.0.0.1:-1
  1144  		operator: %s
  1145  		jetstream: {max_mem_store: 10Mb, max_file_store: 10Mb, store_dir: "%s"}
  1146  		system_account: %s
  1147  		resolver: {
  1148  			type: full
  1149  			allow_delete: true
  1150  			dir: '%s'
  1151  			timeout: "500ms"
  1152  		}
  1153  	`, opJwt, dirSrv, syspub, dirSrv)))
  1154  
  1155  	s, _ := RunServerWithConfig(conf)
  1156  	defer s.Shutdown()
  1157  
  1158  	// update system account jwt
  1159  	updateJwt(t, s.ClientURL(), sysCreds, sysjwt, 1)
  1160  
  1161  	// create account
  1162  	var apub, ajwt1, aCreds1 string
  1163  	kp, _ := nkeys.CreateAccount()
  1164  	apub, _ = kp.PublicKey()
  1165  	claim := jwt.NewAccountClaims(apub)
  1166  	claim.Limits.JetStreamLimits = jwt.JetStreamLimits{
  1167  		MemoryStorage: 7 * 1024 * 1024,
  1168  		DiskStorage:   7 * 1024 * 1024,
  1169  		Streams:       10,
  1170  	}
  1171  	ajwt1, err = claim.Encode(sk)
  1172  	require_NoError(t, err)
  1173  
  1174  	// user
  1175  	ukp, _ := nkeys.CreateUser()
  1176  	seed, _ := ukp.Seed()
  1177  	upub, _ := ukp.PublicKey()
  1178  	uclaim := newJWTTestUserClaims()
  1179  	uclaim.Subject = upub
  1180  
  1181  	ujwt1, err := uclaim.Encode(kp)
  1182  	require_NoError(t, err)
  1183  	aCreds1 = genCredsFile(t, ujwt1, seed)
  1184  
  1185  	// push user account
  1186  	updateJwt(t, s.ClientURL(), sysCreds, ajwt1, 1)
  1187  
  1188  	ncA, jsA := jsClientConnect(t, s, nats.UserCredentials(aCreds1))
  1189  	defer ncA.Close()
  1190  
  1191  	jsA.AddStream(&nats.StreamConfig{Name: "foo"})
  1192  	jsA.Publish("foo", []byte("Hello World"))
  1193  	jsA.Publish("foo", []byte("Hello Again"))
  1194  
  1195  	// JS should be working
  1196  	ai, err := jsA.AccountInfo()
  1197  	require_NoError(t, err)
  1198  	require_True(t, ai.Limits.MaxMemory == 7*1024*1024)
  1199  	require_True(t, ai.Limits.MaxStore == 7*1024*1024)
  1200  	require_True(t, ai.Tier.Streams == 1)
  1201  
  1202  	// connect with a different connection and delete the account.
  1203  	nc := natsConnect(t, s.ClientURL(), nats.UserCredentials(sysCreds))
  1204  	defer nc.Close()
  1205  
  1206  	// delete account
  1207  	resp, err := nc.Request(accDeleteReqSubj, generateRequest([]string{apub}, sk), time.Second)
  1208  	require_NoError(t, err)
  1209  	require_True(t, strings.Contains(string(resp.Data), `"message":"deleted 1 accounts"`))
  1210  
  1211  	// account was disabled and now disconnected, this should get a connection is closed error.
  1212  	_, err = jsA.AccountInfo()
  1213  	if err == nil || !errors.Is(err, nats.ErrConnectionClosed) {
  1214  		t.Errorf("Expected connection closed error, got: %v", err)
  1215  	}
  1216  	ncA.Close()
  1217  
  1218  	// re-enable, same claims would be detected
  1219  	updateJwt(t, s.ClientURL(), sysCreds, ajwt1, 1)
  1220  
  1221  	// expected to get authorization timeout at this time
  1222  	_, err = nats.Connect(s.ClientURL(), nats.UserCredentials(aCreds1))
  1223  	if !errors.Is(err, nats.ErrAuthorization) {
  1224  		t.Errorf("Expected authorization issue on connect, got: %v", err)
  1225  	}
  1226  
  1227  	// edit the account and push again with updated claims to same account
  1228  	claim = jwt.NewAccountClaims(apub)
  1229  	claim.Limits.JetStreamLimits = jwt.JetStreamLimits{
  1230  		MemoryStorage: -1,
  1231  		DiskStorage:   10 * 1024 * 1024,
  1232  		Streams:       10,
  1233  	}
  1234  	ajwt1, err = claim.Encode(sk)
  1235  	require_NoError(t, err)
  1236  	updateJwt(t, s.ClientURL(), sysCreds, ajwt1, 1)
  1237  
  1238  	// reconnect with the updated account
  1239  	ncA, jsA = jsClientConnect(t, s, nats.UserCredentials(aCreds1))
  1240  	defer ncA.Close()
  1241  	ai, err = jsA.AccountInfo()
  1242  	if err != nil {
  1243  		t.Fatal(err)
  1244  	}
  1245  	require_True(t, ai.Limits.MaxMemory == -1)
  1246  	require_True(t, ai.Limits.MaxStore == 10*1024*1024)
  1247  	require_True(t, ai.Tier.Streams == 1)
  1248  
  1249  	// should be possible to get stream info again
  1250  	si, err := jsA.StreamInfo("foo")
  1251  	if err != nil {
  1252  		t.Fatal(err)
  1253  	}
  1254  	if si.State.Msgs != 2 {
  1255  		t.Fatal("Unexpected number of messages from recovered stream")
  1256  	}
  1257  	msg, err := jsA.GetMsg("foo", 1)
  1258  	if err != nil {
  1259  		t.Fatal(err)
  1260  	}
  1261  	if string(msg.Data) != "Hello World" {
  1262  		t.Error("Unexpected message")
  1263  	}
  1264  	ncA.Close()
  1265  }
  1266  
  1267  // Make sure 100MB HA means 100MB of R3, not 33.3MB.
  1268  func TestJetStreamJWTHAStorageLimitsAndAccounting(t *testing.T) {
  1269  	sysKp, syspub := createKey(t)
  1270  	sysJwt := encodeClaim(t, jwt.NewAccountClaims(syspub), syspub)
  1271  	newUser(t, sysKp)
  1272  
  1273  	maxFileStorage := int64(100 * 1024 * 1024)
  1274  	maxMemStorage := int64(2 * 1024 * 1024)
  1275  
  1276  	accKp, aExpPub := createKey(t)
  1277  	accClaim := jwt.NewAccountClaims(aExpPub)
  1278  	accClaim.Name = "acc"
  1279  	accClaim.Limits.JetStreamTieredLimits["R3"] = jwt.JetStreamLimits{DiskStorage: maxFileStorage, MemoryStorage: maxMemStorage}
  1280  	accJwt := encodeClaim(t, accClaim, aExpPub)
  1281  	accCreds := newUser(t, accKp)
  1282  	tmlp := `
  1283  		listen: 127.0.0.1:-1
  1284  		server_name: %s
  1285  		jetstream: {max_mem_store: 256MB, max_file_store: 2GB, store_dir: '%s'}
  1286  		leaf { listen: 127.0.0.1:-1 }
  1287  		cluster {
  1288  			name: %s
  1289  			listen: 127.0.0.1:%d
  1290  			routes = [%s]
  1291  		}
  1292  	` + fmt.Sprintf(`
  1293  		operator: %s
  1294  		system_account: %s
  1295  		resolver = MEMORY
  1296  		resolver_preload = {
  1297  			%s : %s
  1298  			%s : %s
  1299  		}
  1300  	`, ojwt, syspub, syspub, sysJwt, aExpPub, accJwt)
  1301  
  1302  	c := createJetStreamClusterWithTemplate(t, tmlp, "cluster", 3)
  1303  	defer c.shutdown()
  1304  
  1305  	nc := natsConnect(t, c.randomServer().ClientURL(), nats.UserCredentials(accCreds))
  1306  	defer nc.Close()
  1307  
  1308  	js, err := nc.JetStream()
  1309  	require_NoError(t, err)
  1310  
  1311  	// Test max bytes first.
  1312  	_, err = js.AddStream(&nats.StreamConfig{Name: "TEST", Replicas: 3, MaxBytes: maxFileStorage, Subjects: []string{"foo"}})
  1313  	require_NoError(t, err)
  1314  
  1315  	require_NoError(t, js.DeleteStream("TEST"))
  1316  
  1317  	_, err = js.AddStream(&nats.StreamConfig{Name: "TEST", Replicas: 3, Subjects: []string{"foo"}})
  1318  	require_NoError(t, err)
  1319  
  1320  	// Now test actual usage.
  1321  	// We should be able to send just over 200 of these.
  1322  	msg := [500 * 1024]byte{}
  1323  	for i := 0; i < 250; i++ {
  1324  		if _, err := js.Publish("foo", msg[:]); err != nil {
  1325  			require_Error(t, err, NewJSAccountResourcesExceededError())
  1326  			require_True(t, i > 200)
  1327  			break
  1328  		}
  1329  	}
  1330  
  1331  	si, err := js.StreamInfo("TEST")
  1332  	require_NoError(t, err)
  1333  	// Make sure we are no more then 1 msg below our max in terms of size.
  1334  	delta := maxFileStorage - int64(si.State.Bytes)
  1335  	require_True(t, int(delta) < len(msg))
  1336  
  1337  	// Now memory as well.
  1338  	require_NoError(t, js.DeleteStream("TEST"))
  1339  
  1340  	// Test max bytes first.
  1341  	_, err = js.AddStream(&nats.StreamConfig{Name: "TEST", Replicas: 3, MaxBytes: maxMemStorage, Storage: nats.MemoryStorage, Subjects: []string{"foo"}})
  1342  	require_NoError(t, err)
  1343  
  1344  	require_NoError(t, js.DeleteStream("TEST"))
  1345  
  1346  	_, err = js.AddStream(&nats.StreamConfig{Name: "TEST", Replicas: 3, Storage: nats.MemoryStorage, Subjects: []string{"foo"}})
  1347  	require_NoError(t, err)
  1348  
  1349  	// This is much smaller, so should only be able to send 4.
  1350  	for i := 0; i < 5; i++ {
  1351  		if _, err := js.Publish("foo", msg[:]); err != nil {
  1352  			require_Error(t, err, NewJSAccountResourcesExceededError())
  1353  			require_Equal(t, i, 4)
  1354  			break
  1355  		}
  1356  	}
  1357  
  1358  	si, err = js.StreamInfo("TEST")
  1359  	require_NoError(t, err)
  1360  	// Make sure we are no more then 1 msg below our max in terms of size.
  1361  	delta = maxMemStorage - int64(si.State.Bytes)
  1362  	require_True(t, int(delta) < len(msg))
  1363  }
  1364  
  1365  func TestJetStreamJWTHAStorageLimitsOnScaleAndUpdate(t *testing.T) {
  1366  	sysKp, syspub := createKey(t)
  1367  	sysJwt := encodeClaim(t, jwt.NewAccountClaims(syspub), syspub)
  1368  	newUser(t, sysKp)
  1369  
  1370  	maxFileStorage := int64(5 * 1024 * 1024)
  1371  	maxMemStorage := int64(1 * 1024 * 1024)
  1372  
  1373  	accKp, aExpPub := createKey(t)
  1374  	accClaim := jwt.NewAccountClaims(aExpPub)
  1375  	accClaim.Name = "acc"
  1376  	accClaim.Limits.JetStreamTieredLimits["R3"] = jwt.JetStreamLimits{DiskStorage: maxFileStorage, MemoryStorage: maxMemStorage}
  1377  	accClaim.Limits.JetStreamTieredLimits["R1"] = jwt.JetStreamLimits{DiskStorage: maxFileStorage, MemoryStorage: maxMemStorage}
  1378  
  1379  	accJwt := encodeClaim(t, accClaim, aExpPub)
  1380  	accCreds := newUser(t, accKp)
  1381  	tmlp := `
  1382  		listen: 127.0.0.1:-1
  1383  		server_name: %s
  1384  		jetstream: {max_mem_store: 256MB, max_file_store: 2GB, store_dir: '%s'}
  1385  		leaf { listen: 127.0.0.1:-1 }
  1386  		cluster {
  1387  			name: %s
  1388  			listen: 127.0.0.1:%d
  1389  			routes = [%s]
  1390  		}
  1391  	` + fmt.Sprintf(`
  1392  		operator: %s
  1393  		system_account: %s
  1394  		resolver = MEMORY
  1395  		resolver_preload = {
  1396  			%s : %s
  1397  			%s : %s
  1398  		}
  1399  	`, ojwt, syspub, syspub, sysJwt, aExpPub, accJwt)
  1400  
  1401  	c := createJetStreamClusterWithTemplate(t, tmlp, "cluster", 3)
  1402  	defer c.shutdown()
  1403  
  1404  	nc := natsConnect(t, c.randomServer().ClientURL(), nats.UserCredentials(accCreds))
  1405  	defer nc.Close()
  1406  
  1407  	js, err := nc.JetStream()
  1408  	require_NoError(t, err)
  1409  
  1410  	// Test max bytes first.
  1411  	_, err = js.AddStream(&nats.StreamConfig{Name: "TEST", Replicas: 3, MaxBytes: maxFileStorage, Subjects: []string{"foo"}})
  1412  	require_NoError(t, err)
  1413  	// Now delete
  1414  	require_NoError(t, js.DeleteStream("TEST"))
  1415  	// Now do 5 1MB streams.
  1416  	for i := 1; i <= 5; i++ {
  1417  		sname := fmt.Sprintf("TEST%d", i)
  1418  		_, err = js.AddStream(&nats.StreamConfig{Name: sname, Replicas: 3, MaxBytes: 1 * 1024 * 1024})
  1419  		require_NoError(t, err)
  1420  	}
  1421  	// Should fail.
  1422  	_, err = js.AddStream(&nats.StreamConfig{Name: "TEST6", Replicas: 3, MaxBytes: 1 * 1024 * 1024})
  1423  	require_Error(t, err, errors.New("insufficient storage resources"))
  1424  
  1425  	// Update Test1 and Test2 to smaller reservations.
  1426  	_, err = js.UpdateStream(&nats.StreamConfig{Name: "TEST1", Replicas: 3, MaxBytes: 512 * 1024})
  1427  	require_NoError(t, err)
  1428  	_, err = js.UpdateStream(&nats.StreamConfig{Name: "TEST2", Replicas: 3, MaxBytes: 512 * 1024})
  1429  	require_NoError(t, err)
  1430  	// Now make sure TEST6 succeeds.
  1431  	_, err = js.AddStream(&nats.StreamConfig{Name: "TEST6", Replicas: 3, MaxBytes: 1 * 1024 * 1024})
  1432  	require_NoError(t, err)
  1433  	// Now delete the R3 version.
  1434  	require_NoError(t, js.DeleteStream("TEST6"))
  1435  	// Now do R1 version and then we will scale up.
  1436  	_, err = js.AddStream(&nats.StreamConfig{Name: "TEST6", Replicas: 1, MaxBytes: 1 * 1024 * 1024})
  1437  	require_NoError(t, err)
  1438  	// Now make sure scale up works.
  1439  	_, err = js.UpdateStream(&nats.StreamConfig{Name: "TEST6", Replicas: 3, MaxBytes: 1 * 1024 * 1024})
  1440  	require_NoError(t, err)
  1441  	// Add in a few more streams to check reserved reporting in account info.
  1442  	_, err = js.AddStream(&nats.StreamConfig{Name: "TEST7", Replicas: 1, MaxBytes: 2 * 1024 * 1024})
  1443  	require_NoError(t, err)
  1444  	_, err = js.AddStream(&nats.StreamConfig{Name: "TEST8", Replicas: 1, MaxBytes: 256 * 1024, Storage: nats.MemoryStorage})
  1445  	require_NoError(t, err)
  1446  	_, err = js.AddStream(&nats.StreamConfig{Name: "TEST9", Replicas: 3, MaxBytes: 22 * 1024, Storage: nats.MemoryStorage})
  1447  	require_NoError(t, err)
  1448  
  1449  	// Now make sure we report reserved correctly.
  1450  	// Do this direct to server since client does not support it yet.
  1451  	var info JSApiAccountInfoResponse
  1452  	resp, err := nc.Request("$JS.API.INFO", nil, time.Second)
  1453  	require_NoError(t, err)
  1454  	require_NoError(t, json.Unmarshal(resp.Data, &info))
  1455  	stats := info.JetStreamAccountStats
  1456  	r1, r3 := stats.Tiers["R1"], stats.Tiers["R3"]
  1457  
  1458  	require_Equal(t, r1.ReservedMemory, 256*1024)   // TEST8
  1459  	require_Equal(t, r1.ReservedStore, 2*1024*1024) // TEST7
  1460  	require_Equal(t, r3.ReservedMemory, 22*1024)    // TEST9
  1461  	require_Equal(t, r3.ReservedStore, 5*1024*1024) // TEST1-TEST6
  1462  }