github.com/nats-io/nsc@v0.0.0-20221206222106-35db9400b257/cmd/editaccount_test.go (about)

     1  /*
     2   * Copyright 2018-2022 The NATS Authors
     3   * Licensed under the Apache License, Version 2.0 (the "License");
     4   * you may not use this file except in compliance with the License.
     5   * You may obtain a copy of the License at
     6   *
     7   * http://www.apache.org/licenses/LICENSE-2.0
     8   *
     9   * Unless required by applicable law or agreed to in writing, software
    10   * distributed under the License is distributed on an "AS IS" BASIS,
    11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12   * See the License for the specific language governing permissions and
    13   * limitations under the License.
    14   */
    15  
    16  package cmd
    17  
    18  import (
    19  	"testing"
    20  	"time"
    21  
    22  	"github.com/nats-io/nkeys"
    23  
    24  	"github.com/stretchr/testify/require"
    25  )
    26  
    27  func Test_EditAccount(t *testing.T) {
    28  	ts := NewTestStore(t, "edit account")
    29  	defer ts.Done(t)
    30  
    31  	ts.AddAccount(t, "A")
    32  	ts.AddAccount(t, "B")
    33  
    34  	tests := CmdTests{
    35  		{createEditAccount(), []string{"edit", "account"}, nil, []string{"specify an edit option"}, true},
    36  		{createEditAccount(), []string{"edit", "account", "--info-url", "http://foo/bar"}, nil, []string{"changed info url to"}, false},
    37  		{createEditAccount(), []string{"edit", "account", "--description", "my account is about this"}, nil, []string{"changed description to"}, false},
    38  		{createEditAccount(), []string{"edit", "account", "--tag", "A", "--name", "A"}, nil, []string{"edited account \"A\""}, false},
    39  	}
    40  
    41  	tests.Run(t, "root", "edit")
    42  }
    43  
    44  func Test_EditAccountRequired(t *testing.T) {
    45  	ts := NewTestStore(t, "edit account")
    46  	defer ts.Done(t)
    47  
    48  	ts.AddAccount(t, "A")
    49  	ts.AddAccount(t, "B")
    50  	require.NoError(t, GetConfig().SetAccount(""))
    51  	_, _, err := ExecuteCmd(createEditAccount(), "--tag", "A")
    52  	require.Error(t, err)
    53  	require.Contains(t, "an account is required", err.Error())
    54  }
    55  
    56  func Test_EditAccount_Tag(t *testing.T) {
    57  	ts := NewTestStore(t, "edit account")
    58  	defer ts.Done(t)
    59  
    60  	ts.AddAccount(t, "A")
    61  	_, _, err := ExecuteCmd(createEditAccount(), "--tag", "A,B,C")
    62  	require.NoError(t, err)
    63  
    64  	ac, err := ts.Store.ReadAccountClaim("A")
    65  	require.NoError(t, err)
    66  
    67  	require.Len(t, ac.Tags, 3)
    68  	require.ElementsMatch(t, ac.Tags, []string{"a", "b", "c"})
    69  }
    70  
    71  func Test_EditAccount_RmTag(t *testing.T) {
    72  	ts := NewTestStore(t, "edit account")
    73  	defer ts.Done(t)
    74  
    75  	ts.AddAccount(t, "A")
    76  	_, _, err := ExecuteCmd(createEditAccount(), "--tag", "A,B,C")
    77  	require.NoError(t, err)
    78  
    79  	_, _, err = ExecuteCmd(createEditAccount(), "--rm-tag", "A,B")
    80  	require.NoError(t, err)
    81  
    82  	ac, err := ts.Store.ReadAccountClaim("A")
    83  	require.NoError(t, err)
    84  
    85  	require.Len(t, ac.Tags, 1)
    86  	require.ElementsMatch(t, ac.Tags, []string{"c"})
    87  }
    88  
    89  func Test_EditAccount_Times(t *testing.T) {
    90  	ts := NewTestStore(t, "edit account")
    91  	defer ts.Done(t)
    92  
    93  	ts.AddAccount(t, "A")
    94  
    95  	_, _, err := ExecuteCmd(createEditAccount(), "--start", "2018-01-01", "--expiry", "2050-01-01")
    96  	require.NoError(t, err)
    97  
    98  	start, err := ParseExpiry("2018-01-01")
    99  	require.NoError(t, err)
   100  
   101  	expiry, err := ParseExpiry("2050-01-01")
   102  	require.NoError(t, err)
   103  
   104  	ac, err := ts.Store.ReadAccountClaim("A")
   105  	require.NoError(t, err)
   106  	require.Equal(t, start, ac.NotBefore)
   107  	require.Equal(t, expiry, ac.Expires)
   108  }
   109  
   110  func Test_EditAccountLimits(t *testing.T) {
   111  	ts := NewTestStore(t, "edit account")
   112  	defer ts.Done(t)
   113  
   114  	ts.AddAccount(t, "A")
   115  	_, _, err := ExecuteCmd(createEditAccount(), "--conns", "5", "--data", "10mib", "--exports", "15",
   116  		"--imports", "20", "--payload", "1Kib", "--subscriptions", "30", "--leaf-conns", "31",
   117  		"--js-streams", "5", "--js-consumer", "6", "--js-disk-storage", "7", "--js-mem-storage", "8",
   118  		"--js-max-disk-stream", "9mib", "--js-max-mem-stream", "10", "--js-max-ack-pending", "11", "--js-max-bytes-required")
   119  	require.NoError(t, err)
   120  
   121  	ac, err := ts.Store.ReadAccountClaim("A")
   122  	require.NoError(t, err)
   123  	require.Equal(t, int64(5), ac.Limits.Conn)
   124  	require.Equal(t, int64(31), ac.Limits.LeafNodeConn)
   125  	require.Equal(t, int64(1024*1024*10), ac.Limits.Data)
   126  	require.Equal(t, int64(15), ac.Limits.Exports)
   127  	require.Equal(t, int64(20), ac.Limits.Imports)
   128  	require.Equal(t, int64(1024), ac.Limits.Payload)
   129  	require.Equal(t, int64(30), ac.Limits.Subs)
   130  	require.Equal(t, int64(5), ac.Limits.Streams)
   131  	require.Equal(t, int64(6), ac.Limits.Consumer)
   132  	require.Equal(t, int64(7), ac.Limits.DiskStorage)
   133  	require.Equal(t, int64(8), ac.Limits.MemoryStorage)
   134  	require.Equal(t, int64(1024*1024*9), ac.Limits.DiskMaxStreamBytes)
   135  	require.Equal(t, int64(10), ac.Limits.MemoryMaxStreamBytes)
   136  	require.Equal(t, int64(11), ac.Limits.MaxAckPending)
   137  	require.True(t, ac.Limits.MaxBytesRequired)
   138  }
   139  
   140  func Test_EditJsOptionsOnTierDelete(t *testing.T) {
   141  	ts := NewTestStore(t, "edit account")
   142  	defer ts.Done(t)
   143  
   144  	ts.AddAccount(t, "A")
   145  	_, _, err := ExecuteCmd(createEditAccount(),
   146  		"--js-streams", "5", "--js-consumer", "6", "--js-disk-storage", "7")
   147  	require.NoError(t, err)
   148  
   149  	ac, err := ts.Store.ReadAccountClaim("A")
   150  	require.NoError(t, err)
   151  	require.Equal(t, int64(5), ac.Limits.Streams)
   152  	require.Equal(t, int64(6), ac.Limits.Consumer)
   153  	require.Equal(t, int64(7), ac.Limits.DiskStorage)
   154  
   155  	_, _, err = ExecuteCmd(createEditAccount(),
   156  		"--js-streams", "1", "--rm-js-tier", "0")
   157  	require.Error(t, err)
   158  	require.Equal(t, "rm-js-tier is exclusive of all other js options", err.Error())
   159  
   160  	_, _, err = ExecuteCmd(createEditAccount(),
   161  		"--rm-js-tier", "0")
   162  	require.NoError(t, err)
   163  	ac, err = ts.Store.ReadAccountClaim("A")
   164  	require.NoError(t, err)
   165  	require.Equal(t, int64(0), ac.Limits.Streams)
   166  	require.Equal(t, int64(0), ac.Limits.Consumer)
   167  	require.Equal(t, int64(0), ac.Limits.DiskStorage)
   168  }
   169  
   170  func Test_GlobalPreventsTiered(t *testing.T) {
   171  	ts := NewTestStore(t, "edit account")
   172  	defer ts.Done(t)
   173  
   174  	ts.AddAccount(t, "A")
   175  	_, _, err := ExecuteCmd(createEditAccount(),
   176  		"--js-streams", "5", "--js-disk-storage", "10")
   177  	require.NoError(t, err)
   178  
   179  	ac, err := ts.Store.ReadAccountClaim("A")
   180  	require.NoError(t, err)
   181  	require.Equal(t, int64(5), ac.Limits.Streams)
   182  
   183  	_, _, err = ExecuteCmd(createEditAccount(),
   184  		"--js-tier", "1", "--js-disk-storage", "10")
   185  	require.Error(t, err)
   186  	require.Equal(t, "cannot set a jetstream tier limit when a configuration has a global limit", err.Error())
   187  }
   188  
   189  func Test_TieredPreventsGlobal(t *testing.T) {
   190  	ts := NewTestStore(t, "edit account")
   191  	defer ts.Done(t)
   192  
   193  	ts.AddAccount(t, "A")
   194  	_, _, err := ExecuteCmd(createEditAccount(),
   195  		"--js-tier", "2", "--js-streams", "5", "--js-disk-storage", "10")
   196  	require.NoError(t, err)
   197  
   198  	ac, err := ts.Store.ReadAccountClaim("A")
   199  	require.NoError(t, err)
   200  	require.Equal(t, int64(5), ac.Limits.JetStreamTieredLimits["R2"].Streams)
   201  
   202  	_, _, err = ExecuteCmd(createEditAccount(),
   203  		"--js-disk-storage", "10")
   204  	require.Error(t, err)
   205  	require.Equal(t, "cannot set a jetstream global limit when a configuration has tiered limits 'R2'", err.Error())
   206  }
   207  
   208  func Test_TieredDoesntPreventOtherClaims(t *testing.T) {
   209  	ts := NewTestStore(t, "edit account")
   210  	defer ts.Done(t)
   211  
   212  	ts.AddAccount(t, "A")
   213  	_, _, err := ExecuteCmd(createEditAccount(),
   214  		"--js-tier", "2", "--js-streams", "5", "--js-disk-storage", "10")
   215  	require.NoError(t, err)
   216  
   217  	ac, err := ts.Store.ReadAccountClaim("A")
   218  	require.NoError(t, err)
   219  	require.Equal(t, int64(5), ac.Limits.JetStreamTieredLimits["R2"].Streams)
   220  
   221  	_, _, err = ExecuteCmd(createEditAccount(),
   222  		"--sk", "generate")
   223  	require.NoError(t, err)
   224  }
   225  
   226  func Test_EditAccountSigningKeys(t *testing.T) {
   227  	ts := NewTestStore(t, "edit account")
   228  	defer ts.Done(t)
   229  
   230  	ts.AddAccount(t, "A")
   231  	_, pk, _ := CreateAccountKey(t)
   232  	_, pk2, _ := CreateAccountKey(t)
   233  
   234  	_, _, err := ExecuteCmd(createEditAccount(), "--sk", pk, "--sk", pk2)
   235  	require.NoError(t, err)
   236  
   237  	ac, err := ts.Store.ReadAccountClaim("A")
   238  	require.NoError(t, err)
   239  	require.Contains(t, ac.SigningKeys, pk)
   240  	require.Contains(t, ac.SigningKeys, pk2)
   241  
   242  	_, _, err = ExecuteCmd(createEditAccount(), "--rm-sk", pk)
   243  	require.NoError(t, err)
   244  
   245  	ac, err = ts.Store.ReadAccountClaim("A")
   246  	require.NoError(t, err)
   247  	require.NotContains(t, ac.SigningKeys, pk)
   248  }
   249  
   250  func Test_EditAccount_Pubs(t *testing.T) {
   251  	ts := NewTestStore(t, "edit user")
   252  	defer ts.Done(t)
   253  
   254  	ts.AddAccount(t, "A")
   255  
   256  	_, _, err := ExecuteCmd(createEditAccount(), "--allow-pub", "a,b", "--allow-pubsub", "c", "--deny-pub", "foo", "--deny-pubsub", "bar")
   257  	require.NoError(t, err)
   258  
   259  	cc, err := ts.Store.ReadAccountClaim("A")
   260  	require.NoError(t, err)
   261  	require.NotNil(t, cc)
   262  	require.ElementsMatch(t, cc.DefaultPermissions.Pub.Allow, []string{"a", "b", "c"})
   263  	require.ElementsMatch(t, cc.DefaultPermissions.Sub.Allow, []string{"c"})
   264  	require.ElementsMatch(t, cc.DefaultPermissions.Pub.Deny, []string{"foo", "bar"})
   265  	require.ElementsMatch(t, cc.DefaultPermissions.Sub.Deny, []string{"bar"})
   266  
   267  	_, _, err = ExecuteCmd(createEditAccount(), "--rm", "c,bar")
   268  	require.NoError(t, err)
   269  	cc, err = ts.Store.ReadAccountClaim("A")
   270  	require.NoError(t, err)
   271  	require.NotNil(t, cc)
   272  
   273  	require.ElementsMatch(t, cc.DefaultPermissions.Pub.Allow, []string{"a", "b"})
   274  	require.Len(t, cc.DefaultPermissions.Sub.Allow, 0)
   275  	require.ElementsMatch(t, cc.DefaultPermissions.Pub.Deny, []string{"foo"})
   276  	require.Len(t, cc.DefaultPermissions.Sub.Deny, 0)
   277  }
   278  
   279  func Test_EditAccountResponsePermissions(t *testing.T) {
   280  	ts := NewTestStore(t, "O")
   281  	defer ts.Done(t)
   282  	ts.AddAccount(t, "A")
   283  
   284  	_, _, err := ExecuteCmd(createEditAccount(), "--max-responses", "1000", "--response-ttl", "4ms")
   285  	require.NoError(t, err)
   286  
   287  	uc, err := ts.Store.ReadAccountClaim("A")
   288  	require.NoError(t, err)
   289  	require.NotNil(t, uc.DefaultPermissions.Resp)
   290  	require.Equal(t, 1000, uc.DefaultPermissions.Resp.MaxMsgs)
   291  	d, _ := time.ParseDuration("4ms")
   292  	require.Equal(t, d, uc.DefaultPermissions.Resp.Expires)
   293  
   294  	_, _, err = ExecuteCmd(createEditAccount(), "--rm-response-perms")
   295  	require.NoError(t, err)
   296  
   297  	uc, err = ts.Store.ReadAccountClaim("A")
   298  	require.NoError(t, err)
   299  	require.Nil(t, uc.DefaultPermissions.Resp)
   300  }
   301  
   302  func Test_EditAccountSk(t *testing.T) {
   303  	ts := NewTestStore(t, "O")
   304  	defer ts.Done(t)
   305  
   306  	sk, err := nkeys.CreateOperator()
   307  	require.NoError(t, err)
   308  	_, err = ts.KeyStore.Store(sk)
   309  	require.NoError(t, err)
   310  	pSk, err := sk.PublicKey()
   311  	require.NoError(t, err)
   312  
   313  	_, _, err = ExecuteCmd(createEditOperatorCmd(), "--sk", pSk)
   314  	require.NoError(t, err)
   315  
   316  	ts.AddAccountWithSigner(t, "A", sk)
   317  	ac, err := ts.Store.ReadAccountClaim("A")
   318  	require.NoError(t, err)
   319  	require.Equal(t, ac.Issuer, pSk)
   320  
   321  	_, _, err = ExecuteCmd(createEditAccount(), "--tag", "foo")
   322  	require.NoError(t, err)
   323  	ac, err = ts.Store.ReadAccountClaim("A")
   324  	require.NoError(t, err)
   325  	require.Equal(t, ac.Issuer, pSk)
   326  }
   327  
   328  func Test_EditOperatorDisallowBearerToken(t *testing.T) {
   329  	ts := NewTestStore(t, "O")
   330  	defer ts.Done(t)
   331  	ts.AddAccount(t, "A")
   332  	ts.AddUser(t, "A", "U")
   333  
   334  	_, _, err := ExecuteCmd(createEditUserCmd(), "--name", "U", "--bearer")
   335  	require.NoError(t, err)
   336  
   337  	_, _, err = ExecuteCmd(createEditAccount(), "--name", "A", "--disallow-bearer")
   338  	require.Error(t, err)
   339  	require.Equal(t, err.Error(), `user "U" in account "A" uses bearer token (needs to be deleted/changed first)`)
   340  
   341  	// delete offending user
   342  	_, _, err = ExecuteCmd(createDeleteUserCmd(), "--account", "A", "--name", "U")
   343  	require.NoError(t, err)
   344  	// set option
   345  	_, _, err = ExecuteCmd(createEditAccount(), "--name", "A", "--disallow-bearer")
   346  	require.NoError(t, err)
   347  	// test user creation
   348  	_, _, err = ExecuteCmd(CreateAddUserCmd(), "--account", "A", "--name", "U", "--bearer")
   349  	require.Error(t, err)
   350  	require.Equal(t, err.Error(), `account "A" forbids the use of bearer token`)
   351  	_, _, err = ExecuteCmd(CreateAddUserCmd(), "--account", "A", "--name", "U")
   352  	require.NoError(t, err)
   353  	_, _, err = ExecuteCmd(createEditUserCmd(), "--account", "A", "--name", "U", "--bearer")
   354  	require.Error(t, err)
   355  	require.Equal(t, err.Error(), "account disallows bearer token")
   356  }