github.com/nats-io/nsc/v2@v2.8.7-0.20240307184528-efd7023c6896/cmd/edituser_test.go (about)

     1  /*
     2   * Copyright 2018-2021 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  	cli "github.com/nats-io/cliprompts/v2"
    25  	"github.com/nats-io/jwt/v2"
    26  	"github.com/stretchr/testify/require"
    27  )
    28  
    29  func Test_EditUser(t *testing.T) {
    30  	ts := NewTestStore(t, "edit user")
    31  	defer ts.Done(t)
    32  
    33  	ts.AddUser(t, "A", "a")
    34  	ts.AddUser(t, "B", "b")
    35  	ts.AddUser(t, "B", "bb")
    36  
    37  	tests := CmdTests{
    38  		{createEditUserCmd(), []string{"edit", "user"}, nil, []string{"specify an edit option"}, true},
    39  		{createEditUserCmd(), []string{"edit", "user", "--tag", "A", "--account", "A"}, nil, []string{"edited user \"a\""}, false},
    40  		{createEditUserCmd(), []string{"edit", "user", "--conn-type", "MQTT", "--rm-conn-type", "LEAFNODE", "--account", "A"}, nil, []string{"added connection type MQTT", "added connection type MQTT"}, false},
    41  		{createEditUserCmd(), []string{"edit", "user", "--conn-type", "LEAFNODE_WS", "--account", "A"}, nil, []string{"added connection type LEAFNODE_WS"}, false},
    42  		{createEditUserCmd(), []string{"edit", "user", "--conn-type", "MQTT_WS", "--account", "A"}, nil, []string{"added connection type MQTT_WS"}, false},
    43  		{createEditUserCmd(), []string{"edit", "user", "--tag", "B", "--account", "B"}, nil, []string{"user name is required"}, true},
    44  		{createEditUserCmd(), []string{"edit", "user", "--tag", "B", "--account", "B", "--name", "bb"}, nil, []string{"edited user \"bb\""}, false},
    45  	}
    46  
    47  	tests.Run(t, "root", "edit")
    48  }
    49  
    50  func Test_EditUserInteractive(t *testing.T) {
    51  	ts := NewTestStore(t, "O")
    52  	defer ts.Done(t)
    53  	ts.AddUser(t, "A", "U")
    54  
    55  	inputs := []interface{}{"-1", "2018-01-01", "2050-01-01", false}
    56  	cli.LogFn = t.Log
    57  	_, _, err := ExecuteInteractiveCmd(createEditUserCmd(), inputs)
    58  	require.NoError(t, err)
    59  
    60  	uc, err := ts.Store.ReadUserClaim("A", "U")
    61  	require.NoError(t, err)
    62  
    63  	start, err := ParseExpiry("2018-01-01")
    64  	require.NoError(t, err)
    65  	require.Equal(t, start, uc.NotBefore)
    66  
    67  	expire, err := ParseExpiry("2050-01-01")
    68  	require.NoError(t, err)
    69  	require.Equal(t, expire, uc.Expires)
    70  	require.Nil(t, uc.Resp)
    71  }
    72  
    73  func Test_EditUserEditResponsePermissions(t *testing.T) {
    74  	t.Skip("response permissions not interactive")
    75  	ts := NewTestStore(t, "O")
    76  	defer ts.Done(t)
    77  	ts.AddUser(t, "A", "U")
    78  
    79  	inputs := []interface{}{true, 100, "1000ms", -1, 0, 0, false}
    80  	_, _, err := ExecuteInteractiveCmd(createEditUserCmd(), inputs)
    81  	require.NoError(t, err)
    82  
    83  	uc, err := ts.Store.ReadUserClaim("A", "U")
    84  	require.NoError(t, err)
    85  
    86  	require.NotNil(t, uc.Resp)
    87  	require.Equal(t, 100, uc.Resp.MaxMsgs)
    88  	require.Equal(t, time.Millisecond*1000, uc.Resp.Expires)
    89  }
    90  
    91  func Test_EditUserAccountRequired(t *testing.T) {
    92  	ts := NewTestStore(t, "edit user")
    93  	defer ts.Done(t)
    94  
    95  	ts.AddUser(t, "A", "a")
    96  	ts.AddUser(t, "B", "b")
    97  	require.NoError(t, GetConfig().SetAccount(""))
    98  	_, _, err := ExecuteCmd(createEditUserCmd(), "--tag", "A")
    99  	require.Error(t, err)
   100  	require.Contains(t, err.Error(), "account is required")
   101  }
   102  
   103  func Test_EditUser_Tag(t *testing.T) {
   104  	ts := NewTestStore(t, "edit user")
   105  	defer ts.Done(t)
   106  
   107  	ts.AddUser(t, "A", "a")
   108  	_, _, err := ExecuteCmd(createEditUserCmd(), "--tag", "A,B,C")
   109  	require.NoError(t, err)
   110  
   111  	cc, err := ts.Store.ReadUserClaim("A", "a")
   112  	require.NoError(t, err)
   113  	require.NotNil(t, cc)
   114  
   115  	require.Len(t, cc.Tags, 3)
   116  	require.ElementsMatch(t, cc.Tags, []string{"a", "b", "c"})
   117  
   118  	_, _, err = ExecuteCmd(createEditUserCmd(), "--rm-tag", "A,B")
   119  	require.NoError(t, err)
   120  
   121  	cc, err = ts.Store.ReadUserClaim("A", "a")
   122  	require.NoError(t, err)
   123  	require.NotNil(t, cc)
   124  
   125  	require.Len(t, cc.Tags, 1)
   126  	require.ElementsMatch(t, cc.Tags, []string{"c"})
   127  
   128  }
   129  
   130  func Test_EditUser_Pubs(t *testing.T) {
   131  	ts := NewTestStore(t, "edit user")
   132  	defer ts.Done(t)
   133  
   134  	ts.AddUser(t, "A", "a")
   135  
   136  	_, _, err := ExecuteCmd(createEditUserCmd(), "--allow-pub", "a,b", "--allow-pubsub", "c", "--deny-pub", "foo", "--deny-pubsub", "bar")
   137  	require.NoError(t, err)
   138  
   139  	cc, err := ts.Store.ReadUserClaim("A", "a")
   140  	require.NoError(t, err)
   141  	require.NotNil(t, cc)
   142  	require.ElementsMatch(t, cc.Pub.Allow, []string{"a", "b", "c"})
   143  	require.ElementsMatch(t, cc.Sub.Allow, []string{"c"})
   144  	require.ElementsMatch(t, cc.Pub.Deny, []string{"foo", "bar"})
   145  	require.ElementsMatch(t, cc.Sub.Deny, []string{"bar"})
   146  
   147  	_, _, err = ExecuteCmd(createEditUserCmd(), "--rm", "c,bar")
   148  	require.NoError(t, err)
   149  	cc, err = ts.Store.ReadUserClaim("A", "a")
   150  	require.NoError(t, err)
   151  	require.NotNil(t, cc)
   152  
   153  	require.ElementsMatch(t, cc.Pub.Allow, []string{"a", "b"})
   154  	require.Len(t, cc.Sub.Allow, 0)
   155  	require.ElementsMatch(t, cc.Pub.Deny, []string{"foo"})
   156  	require.Len(t, cc.Sub.Deny, 0)
   157  }
   158  
   159  func Test_EditUser_Src(t *testing.T) {
   160  	ts := NewTestStore(t, "edit user")
   161  	defer ts.Done(t)
   162  
   163  	ts.AddUser(t, "A", "a")
   164  
   165  	_, _, err := ExecuteCmd(createEditUserCmd(), "--source-network", "192.0.2.0/24,192.0.1.0/8")
   166  	require.NoError(t, err)
   167  
   168  	cc, err := ts.Store.ReadUserClaim("A", "a")
   169  	require.NoError(t, err)
   170  	require.NotNil(t, cc)
   171  	require.ElementsMatch(t, cc.Src, []string{"192.0.2.0/24", "192.0.1.0/8"})
   172  
   173  	_, _, err = ExecuteCmd(createEditUserCmd(), "--rm-source-network", "192.0.2.0/24")
   174  	require.NoError(t, err)
   175  
   176  	cc, err = ts.Store.ReadUserClaim("A", "a")
   177  	require.NoError(t, err)
   178  	require.NotNil(t, cc)
   179  	require.ElementsMatch(t, cc.Src, []string{"192.0.1.0/8"})
   180  }
   181  
   182  func Test_EditUser_Times(t *testing.T) {
   183  	ts := NewTestStore(t, "edit user")
   184  	defer ts.Done(t)
   185  
   186  	ts.AddUser(t, "A", "a")
   187  
   188  	_, _, err := ExecuteCmd(createEditUserCmd(), "--time", "16:04:05-17:04:09", "--time", "18:04:05-19:04:09", "--locale", "America/New_York")
   189  	require.NoError(t, err)
   190  
   191  	cc, err := ts.Store.ReadUserClaim("A", "a")
   192  	require.NoError(t, err)
   193  	require.NotNil(t, cc)
   194  
   195  	require.ElementsMatch(t, cc.Times, []jwt.TimeRange{
   196  		{Start: "16:04:05", End: "17:04:09"},
   197  		{Start: "18:04:05", End: "19:04:09"}})
   198  	require.Equal(t, "America/New_York", cc.Locale)
   199  
   200  	_, _, err = ExecuteCmd(createEditUserCmd(), "--rm-time", "16:04:05", "--locale", "")
   201  	require.NoError(t, err)
   202  
   203  	cc, err = ts.Store.ReadUserClaim("A", "a")
   204  	require.NoError(t, err)
   205  	require.NotNil(t, cc)
   206  	require.ElementsMatch(t, cc.Times, []jwt.TimeRange{
   207  		{Start: "18:04:05", End: "19:04:09"}})
   208  	require.Equal(t, "UTC", cc.Locale)
   209  }
   210  
   211  func Test_EditUserSK(t *testing.T) {
   212  	ts := NewTestStore(t, "O")
   213  	t.Log(ts.Dir)
   214  
   215  	s, p, _ := CreateAccountKey(t)
   216  	ts.AddAccount(t, "A")
   217  	_, _, err := ExecuteCmd(HoistRootFlags(createEditAccount()), "--name", "A", "--sk", p)
   218  	require.NoError(t, err)
   219  
   220  	ac, err := ts.Store.ReadAccountClaim("A")
   221  	require.NoError(t, err)
   222  	require.Contains(t, ac.SigningKeys, p)
   223  
   224  	ts.AddUser(t, "A", "U")
   225  	uc, err := ts.Store.ReadUserClaim("A", "U")
   226  	require.NoError(t, err)
   227  	require.Equal(t, uc.Issuer, ac.Subject)
   228  	require.Empty(t, uc.IssuerAccount)
   229  
   230  	_, _, err = ExecuteCmd(HoistRootFlags(createEditUserCmd()), "-n", "U", "--allow-pub", "foo", "-K", string(s))
   231  	require.NoError(t, err)
   232  	uc, err = ts.Store.ReadUserClaim("A", "U")
   233  	require.NoError(t, err)
   234  	require.Equal(t, uc.Issuer, p)
   235  	require.Equal(t, uc.IssuerAccount, ac.Subject)
   236  }
   237  
   238  func Test_EditUserAddedWithSK(t *testing.T) {
   239  	ts := NewTestStore(t, "O")
   240  	t.Log(ts.Dir)
   241  
   242  	s, p, sk := CreateAccountKey(t)
   243  	ts.AddAccount(t, "A")
   244  	_, _, err := ExecuteCmd(HoistRootFlags(createEditAccount()), "--name", "A", "--sk", p)
   245  	require.NoError(t, err)
   246  
   247  	ac, err := ts.Store.ReadAccountClaim("A")
   248  	require.NoError(t, err)
   249  	require.Contains(t, ac.SigningKeys, p)
   250  
   251  	ts.AddUserWithSigner(t, "A", "U", sk)
   252  	uc, err := ts.Store.ReadUserClaim("A", "U")
   253  	require.NoError(t, err)
   254  	require.Equal(t, uc.Issuer, p)
   255  	require.Equal(t, uc.IssuerAccount, ac.Subject)
   256  
   257  	_, _, err = ExecuteCmd(HoistRootFlags(createEditUserCmd()), "-n", "U", "--allow-pub", "foo", "-K", string(s))
   258  	require.NoError(t, err)
   259  	uc, err = ts.Store.ReadUserClaim("A", "U")
   260  	require.NoError(t, err)
   261  	require.Equal(t, uc.Issuer, p)
   262  	require.Equal(t, uc.IssuerAccount, ac.Subject)
   263  }
   264  
   265  func Test_EditUser_Payload(t *testing.T) {
   266  	ts := NewTestStore(t, "edit user")
   267  	defer ts.Done(t)
   268  
   269  	ts.AddUser(t, "A", "U")
   270  
   271  	_, _, err := ExecuteCmd(createEditUserCmd(), "--payload", "1000")
   272  	require.NoError(t, err)
   273  
   274  	cc, err := ts.Store.ReadUserClaim("A", "U")
   275  	require.NoError(t, err)
   276  	require.NotNil(t, cc)
   277  	require.Equal(t, int64(1000), cc.Limits.Payload)
   278  
   279  	_, _, err = ExecuteCmd(createEditUserCmd(), "--payload", "-1")
   280  	require.NoError(t, err)
   281  
   282  	cc, err = ts.Store.ReadUserClaim("A", "U")
   283  	require.NoError(t, err)
   284  	require.NotNil(t, cc)
   285  	require.Equal(t, int64(jwt.NoLimit), cc.Limits.Payload)
   286  }
   287  
   288  func Test_EditUserResponsePermissions(t *testing.T) {
   289  	ts := NewTestStore(t, "O")
   290  	defer ts.Done(t)
   291  	ts.AddAccount(t, "A")
   292  
   293  	_, _, err := ExecuteCmd(CreateAddUserCmd(), "U", "--max-responses", "100", "--response-ttl", "2ms")
   294  	require.NoError(t, err)
   295  
   296  	uc, err := ts.Store.ReadUserClaim("A", "U")
   297  	require.NoError(t, err)
   298  	require.NotNil(t, uc.Resp)
   299  
   300  	_, _, err = ExecuteCmd(createEditUserCmd(), "--max-responses", "1000", "--response-ttl", "4ms")
   301  	require.NoError(t, err)
   302  
   303  	uc, err = ts.Store.ReadUserClaim("A", "U")
   304  	require.NoError(t, err)
   305  	require.NotNil(t, uc.Resp)
   306  	require.Equal(t, 1000, uc.Resp.MaxMsgs)
   307  	d, _ := time.ParseDuration("4ms")
   308  	require.Equal(t, d, uc.Resp.Expires)
   309  
   310  	_, _, err = ExecuteCmd(createEditUserCmd(), "--rm-response-perms")
   311  	require.NoError(t, err)
   312  
   313  	uc, err = ts.Store.ReadUserClaim("A", "U")
   314  	require.NoError(t, err)
   315  	require.Nil(t, uc.Resp)
   316  }
   317  
   318  func Test_EditUserResponsePermissions2(t *testing.T) {
   319  	ts := NewTestStore(t, "O")
   320  	defer ts.Done(t)
   321  	ts.AddAccount(t, "A")
   322  
   323  	_, _, err := ExecuteCmd(CreateAddUserCmd(), "U", "--allow-pub-response", "--response-ttl", "2ms")
   324  	require.NoError(t, err)
   325  	uc, err := ts.Store.ReadUserClaim("A", "U")
   326  	require.NoError(t, err)
   327  	require.NotNil(t, uc.Resp)
   328  	require.Equal(t, 1, uc.Resp.MaxMsgs)
   329  
   330  	_, _, err = ExecuteCmd(createEditUserCmd(), "U", "--allow-pub-response=100", "--response-ttl", "2ms")
   331  	require.NoError(t, err)
   332  
   333  	uc, err = ts.Store.ReadUserClaim("A", "U")
   334  	require.NoError(t, err)
   335  	require.NotNil(t, uc.Resp)
   336  	require.Equal(t, 100, uc.Resp.MaxMsgs)
   337  
   338  	_, _, err = ExecuteCmd(createEditUserCmd(), "--rm-response-perms")
   339  	require.NoError(t, err)
   340  
   341  	uc, err = ts.Store.ReadUserClaim("A", "U")
   342  	require.NoError(t, err)
   343  	require.Nil(t, uc.Resp)
   344  }
   345  
   346  func Test_EditUserBearerToken(t *testing.T) {
   347  	ts := NewTestStore(t, "O")
   348  	defer ts.Done(t)
   349  	ts.AddAccount(t, "A")
   350  
   351  	_, _, err := ExecuteCmd(CreateAddUserCmd(), "U")
   352  	require.NoError(t, err)
   353  
   354  	u, err := ts.Store.ReadUserClaim("A", "U")
   355  	require.NoError(t, err)
   356  	require.False(t, u.BearerToken)
   357  
   358  	_, stderr, err := ExecuteCmd(createEditUserCmd(), "--name", "U", "--bearer")
   359  	require.NoError(t, err)
   360  	require.Contains(t, stderr, "changed bearer to true")
   361  
   362  	u, err = ts.Store.ReadUserClaim("A", "U")
   363  	require.NoError(t, err)
   364  	require.True(t, u.BearerToken)
   365  
   366  	_, stderr, err = ExecuteCmd(createEditUserCmd(), "--name", "U", "--bearer=false")
   367  	require.NoError(t, err)
   368  	require.Contains(t, stderr, "ignoring change to bearer - value is already false")
   369  
   370  	u, err = ts.Store.ReadUserClaim("A", "U")
   371  	require.NoError(t, err)
   372  	require.False(t, u.BearerToken)
   373  }
   374  
   375  func Test_EditUserWithSigningKeyOnly(t *testing.T) {
   376  	ts := NewTestStore(t, "O")
   377  	defer ts.Done(t)
   378  
   379  	// create a signing key
   380  	kp, err := nkeys.CreateAccount()
   381  	require.NoError(t, err)
   382  	_, err = ts.KeyStore.Store(kp)
   383  	require.NoError(t, err)
   384  	pk, err := kp.PublicKey()
   385  	require.NoError(t, err)
   386  	require.True(t, ts.KeyStore.HasPrivateKey(pk))
   387  
   388  	ts.AddAccount(t, "A")
   389  	_, _, err = ExecuteCmd(createEditAccount(), "--sk", pk)
   390  	require.NoError(t, err)
   391  
   392  	ac, err := ts.Store.ReadAccountClaim("A")
   393  	require.NoError(t, err)
   394  	require.NotNil(t, ac)
   395  	require.NoError(t, ts.KeyStore.Remove(ac.Subject))
   396  	require.False(t, ts.KeyStore.HasPrivateKey(ac.Subject))
   397  
   398  	_, _, err = ExecuteCmd(HoistRootFlags(CreateAddUserCmd()), "--name", "AAA")
   399  	require.NoError(t, err)
   400  	_, _, err = ExecuteCmd(HoistRootFlags(createEditUserCmd()), "--name", "AAA", "--payload", "5")
   401  	require.NoError(t, err)
   402  
   403  	claim, err := ts.Store.ReadUserClaim("A", "AAA")
   404  	require.NoError(t, err)
   405  	require.Equal(t, claim.Limits.Payload, int64(5))
   406  	require.NotEmpty(t, claim.IssuerAccount)
   407  	require.NotEqual(t, claim.Issuer, claim.IssuerAccount)
   408  	require.Equal(t, claim.Issuer, pk)
   409  }
   410  
   411  func Test_EditUserWithSigningKeyInteractive(t *testing.T) {
   412  	ts := NewTestStore(t, "O")
   413  	defer ts.Done(t)
   414  
   415  	// create a signing key
   416  	kp, err := nkeys.CreateAccount()
   417  	require.NoError(t, err)
   418  	_, err = ts.KeyStore.Store(kp)
   419  	require.NoError(t, err)
   420  	pk, err := kp.PublicKey()
   421  	require.NoError(t, err)
   422  	require.True(t, ts.KeyStore.HasPrivateKey(pk))
   423  
   424  	ts.AddAccount(t, "A")
   425  	_, _, err = ExecuteCmd(createEditAccount(), "--sk", pk)
   426  	require.NoError(t, err)
   427  
   428  	ac, err := ts.Store.ReadAccountClaim("A")
   429  	require.NoError(t, err)
   430  	require.NotNil(t, ac)
   431  	require.True(t, ts.KeyStore.HasPrivateKey(ac.Subject))
   432  
   433  	_, _, err = ExecuteCmd(HoistRootFlags(CreateAddUserCmd()), "--name", "AAA")
   434  	require.NoError(t, err)
   435  
   436  	inputs := []interface{}{1, "5", "0", "0", false}
   437  	cmd := createEditUserCmd()
   438  	HoistRootFlags(cmd)
   439  	_, _, err = ExecuteInteractiveCmd(cmd, inputs, "--name", "AAA")
   440  	require.NoError(t, err)
   441  
   442  	claim, err := ts.Store.ReadUserClaim("A", "AAA")
   443  	require.NoError(t, err)
   444  	require.Equal(t, claim.Limits.Payload, int64(5))
   445  	require.NotEmpty(t, claim.IssuerAccount)
   446  	require.NotEqual(t, claim.Issuer, claim.IssuerAccount)
   447  	require.Equal(t, claim.Issuer, pk)
   448  }
   449  
   450  func Test_EditUserSk(t *testing.T) {
   451  	ts := NewTestStore(t, "O")
   452  	defer ts.Done(t)
   453  	ts.AddAccount(t, "A")
   454  
   455  	sk, err := nkeys.CreateAccount()
   456  	require.NoError(t, err)
   457  	_, err = ts.KeyStore.Store(sk)
   458  	require.NoError(t, err)
   459  	pSk, err := sk.PublicKey()
   460  	require.NoError(t, err)
   461  
   462  	_, _, err = ExecuteCmd(createEditAccount(), "--sk", pSk)
   463  	require.NoError(t, err)
   464  
   465  	ts.AddUserWithSigner(t, "A", "u", sk)
   466  	uc, err := ts.Store.ReadUserClaim("A", "u")
   467  	require.NoError(t, err)
   468  	require.Equal(t, uc.Issuer, pSk)
   469  
   470  	_, _, err = ExecuteCmd(createEditUserCmd(), "--tag", "foo")
   471  	require.NoError(t, err)
   472  	uc, err = ts.Store.ReadUserClaim("A", "u")
   473  	require.NoError(t, err)
   474  	require.Equal(t, uc.Issuer, pSk)
   475  }
   476  
   477  func Test_EditUserSubs(t *testing.T) {
   478  	ts := NewTestStore(t, "O")
   479  	defer ts.Done(t)
   480  	ts.AddAccount(t, "A")
   481  	ts.AddUser(t, "A", "U")
   482  	uc, err := ts.Store.ReadUserClaim("A", "U")
   483  	require.NoError(t, err)
   484  	require.Equal(t, int64(-1), uc.Subs)
   485  
   486  	_, _, err = ExecuteCmd(createEditUserCmd(), "--subs", "100")
   487  	require.NoError(t, err)
   488  	uc, err = ts.Store.ReadUserClaim("A", "U")
   489  	require.NoError(t, err)
   490  	require.Equal(t, int64(100), uc.Subs)
   491  	require.NoError(t, err)
   492  }
   493  
   494  func Test_EditUserData(t *testing.T) {
   495  	ts := NewTestStore(t, "O")
   496  	defer ts.Done(t)
   497  	ts.AddAccount(t, "A")
   498  	ts.AddUser(t, "A", "U")
   499  	uc, err := ts.Store.ReadUserClaim("A", "U")
   500  	require.NoError(t, err)
   501  	require.Equal(t, int64(-1), uc.Limits.Data)
   502  
   503  	_, _, err = ExecuteCmd(HoistRootFlags(createEditUserCmd()), "--data", "1Kib")
   504  	require.NoError(t, err)
   505  	uc, err = ts.Store.ReadUserClaim("A", "U")
   506  	require.NoError(t, err)
   507  	require.Equal(t, int64(1024), uc.Limits.Data)
   508  	require.NoError(t, err)
   509  }