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 }