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