github.com/nats-io/jwt/v2@v2.5.6/user_claims_test.go (about) 1 /* 2 * Copyright 2018-2020 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 jwt 17 18 import ( 19 "testing" 20 "time" 21 22 "github.com/nats-io/nkeys" 23 ) 24 25 func TestNewUserClaims(t *testing.T) { 26 akp := createAccountNKey(t) 27 ukp := createUserNKey(t) 28 29 uc := NewUserClaims(publicKey(ukp, t)) 30 if !uc.Limits.IsUnlimited() { 31 t.Fatal("unlimited after creation") 32 } 33 34 uc.Expires = time.Now().Add(time.Hour).Unix() 35 uJwt := encode(uc, akp, t) 36 37 uc2, err := DecodeUserClaims(uJwt) 38 if err != nil { 39 t.Fatal("failed to decode uc", err) 40 } 41 42 AssertEquals(uc.String(), uc2.String(), t) 43 44 AssertEquals(uc.Claims() != nil, true, t) 45 AssertEquals(uc.Payload() != nil, true, t) 46 } 47 48 func TestUserClaimIssuer(t *testing.T) { 49 akp := createAccountNKey(t) 50 ukp := createUserNKey(t) 51 52 uc := NewUserClaims(publicKey(ukp, t)) 53 uc.Expires = time.Now().Add(time.Hour).Unix() 54 uJwt := encode(uc, akp, t) 55 56 temp, err := DecodeGeneric(uJwt) 57 if err != nil { 58 t.Fatal("failed to decode", err) 59 } 60 61 type kpInputs struct { 62 name string 63 kp nkeys.KeyPair 64 ok bool 65 } 66 67 inputs := []kpInputs{ 68 {"account", createAccountNKey(t), true}, 69 {"user", createUserNKey(t), false}, 70 {"operator", createOperatorNKey(t), false}, 71 {"server", createServerNKey(t), false}, 72 {"cluster", createClusterNKey(t), false}, 73 } 74 75 for _, i := range inputs { 76 bad := encode(temp, i.kp, t) 77 _, err = DecodeUserClaims(bad) 78 if i.ok && err != nil { 79 t.Fatalf("unexpected error for %q: %v", i.name, err) 80 } 81 if !i.ok && err == nil { 82 t.Logf("should have failed to decode user signed by %q", i.name) 83 t.Fail() 84 } 85 } 86 } 87 88 func TestUserSubjects(t *testing.T) { 89 type kpInputs struct { 90 name string 91 kp nkeys.KeyPair 92 ok bool 93 } 94 95 inputs := []kpInputs{ 96 {"account", createAccountNKey(t), false}, 97 {"cluster", createClusterNKey(t), false}, 98 {"operator", createOperatorNKey(t), false}, 99 {"server", createServerNKey(t), false}, 100 {"user", createUserNKey(t), true}, 101 } 102 103 for _, i := range inputs { 104 c := NewUserClaims(publicKey(i.kp, t)) 105 _, err := c.Encode(createAccountNKey(t)) 106 if i.ok && err != nil { 107 t.Fatalf("unexpected error for %q: %v", i.name, err) 108 } 109 if !i.ok && err == nil { 110 t.Logf("should have failed to encode user with with %q subject", i.name) 111 t.Fail() 112 } 113 } 114 } 115 116 func TestNewNilUserClaim(t *testing.T) { 117 v := NewUserClaims("") 118 if v != nil { 119 t.Fatal("expected nil user claim") 120 } 121 } 122 123 func TestUserType(t *testing.T) { 124 c := NewUserClaims(publicKey(createUserNKey(t), t)) 125 s := encode(c, createAccountNKey(t), t) 126 u, err := DecodeUserClaims(s) 127 if err != nil { 128 t.Fatalf("failed to decode user claim: %v", err) 129 } 130 131 if UserClaim != u.Type { 132 t.Fatalf("user type is unexpected %q", u.Type) 133 } 134 } 135 136 func TestSubjects(t *testing.T) { 137 s := StringList{} 138 if len(s) != 0 { 139 t.Fatalf("expected len 0") 140 } 141 if s.Contains("a") { 142 t.Fatalf("didn't expect 'a'") 143 } 144 s.Add("a") 145 if !s.Contains("a") { 146 t.Fatalf("expected 'a'") 147 } 148 s.Remove("a") 149 if s.Contains("a") { 150 t.Fatalf("didn't expect 'a' after removing") 151 } 152 } 153 154 func TestUserValidation(t *testing.T) { 155 ukp := createUserNKey(t) 156 157 uc := NewUserClaims(publicKey(ukp, t)) 158 uc.Permissions.Pub.Allow.Add("a") 159 uc.Permissions.Pub.Deny.Add("b") 160 uc.Permissions.Sub.Allow.Add("a") 161 uc.Permissions.Sub.Deny.Add("b") 162 uc.Permissions.Resp = &ResponsePermission{ 163 MaxMsgs: 10, 164 Expires: 50 * time.Minute, 165 } 166 uc.Limits.Payload = 10 167 uc.Limits.Src.Set("192.0.2.0/24") 168 uc.Limits.Times = []TimeRange{ 169 { 170 Start: "01:15:00", 171 End: "03:15:00", 172 }, 173 { 174 Start: "06:15:00", 175 End: "09:15:00", 176 }, 177 } 178 uc.Limits.Locale = "Europe/Berlin" 179 180 vr := CreateValidationResults() 181 uc.Validate(vr) 182 183 if !vr.IsEmpty() { 184 t.Error("valid user permissions should be valid") 185 } 186 187 uc.Limits.Src.Set("hello world") 188 vr = CreateValidationResults() 189 uc.Validate(vr) 190 191 if vr.IsEmpty() || len(vr.Issues) != 1 || !vr.IsBlocking(true) { 192 t.Error("bad limit should be invalid") 193 } 194 195 uc.Limits.Payload = 10 196 uc.Limits.Src.Set("hello world") 197 vr = CreateValidationResults() 198 uc.Validate(vr) 199 200 if vr.IsEmpty() || len(vr.Issues) != 1 || !vr.IsBlocking(true) { 201 t.Error("bad limit should be invalid") 202 } 203 204 tr := TimeRange{ 205 Start: "hello", 206 End: "03:15:00", 207 } 208 uc.Limits.Src.Set("192.0.2.0/24") 209 uc.Limits.Times = append(uc.Limits.Times, tr) 210 vr = CreateValidationResults() 211 uc.Validate(vr) 212 213 if vr.IsEmpty() || len(vr.Issues) != 1 || !vr.IsBlocking(true) { 214 t.Error("bad limit should be invalid") 215 } 216 217 uc.Limits.Times = []TimeRange{{ 218 Start: "02:15:00", 219 End: "03:15:00", 220 }} 221 uc.Limits.Locale = "foo" 222 vr = CreateValidationResults() 223 uc.Validate(vr) 224 225 if vr.IsEmpty() || len(vr.Issues) != 1 || !vr.IsBlocking(true) { 226 t.Error("bad location should be invalid") 227 } 228 } 229 230 func TestUserAccountID(t *testing.T) { 231 akp := createAccountNKey(t) 232 apk := publicKey(akp, t) 233 a2kp := createAccountNKey(t) 234 ac := NewAccountClaims(apk) 235 ac.SigningKeys.Add(publicKey(a2kp, t)) 236 237 token, err := ac.Encode(akp) 238 if err != nil { 239 t.Fatal(err) 240 } 241 ac, err = DecodeAccountClaims(token) 242 if err != nil { 243 t.Fatal(err) 244 } 245 246 uc := NewUserClaims(publicKey(createUserNKey(t), t)) 247 uc.IssuerAccount = apk 248 userToken, err := uc.Encode(a2kp) 249 if err != nil { 250 t.Fatal(err) 251 } 252 253 uc, err = DecodeUserClaims(userToken) 254 if err != nil { 255 t.Fatal(err) 256 } 257 258 if uc.IssuerAccount != apk { 259 t.Fatalf("expected AccountID to be set to %s - got %s", apk, uc.IssuerAccount) 260 } 261 262 signed := ac.DidSign(uc) 263 if !signed { 264 t.Fatal("expected user signed by account") 265 } 266 } 267 268 func TestUserAccountIDValidation(t *testing.T) { 269 uc := NewUserClaims(publicKey(createUserNKey(t), t)) 270 uc.IssuerAccount = publicKey(createAccountNKey(t), t) 271 var vr ValidationResults 272 uc.Validate(&vr) 273 if len(vr.Issues) != 0 { 274 t.Fatal("expected no issues") 275 } 276 277 uc.IssuerAccount = publicKey(createUserNKey(t), t) 278 uc.Validate(&vr) 279 if len(vr.Issues) != 1 { 280 t.Fatal("expected validation issues") 281 } 282 } 283 284 func TestSourceNetworkValidation(t *testing.T) { 285 ukp := createUserNKey(t) 286 uc := NewUserClaims(publicKey(ukp, t)) 287 288 uc.Limits.Src = CIDRList{"192.0.2.0/24"} 289 vr := CreateValidationResults() 290 uc.Validate(vr) 291 292 if !vr.IsEmpty() { 293 t.Error("limits should be valid") 294 } 295 296 uc.Limits.Src = CIDRList{"192.0.2.0/24"} 297 vr = CreateValidationResults() 298 uc.Validate(vr) 299 300 if !vr.IsEmpty() { 301 t.Error("limits should be valid") 302 } 303 304 uc.Limits.Src = CIDRList{"192.0.2.0/24", "2001:db8:a0b:12f0::1/32"} 305 vr = CreateValidationResults() 306 uc.Validate(vr) 307 308 if !vr.IsEmpty() { 309 t.Error("limits should be valid") 310 } 311 312 uc.Limits.Src.Set("192.0.2.0/24, \t2001:db8:a0b:12f0::1/32 , 192.168.1.1/1") 313 vr = CreateValidationResults() 314 uc.Validate(vr) 315 316 if !vr.IsEmpty() { 317 t.Error("limits should be valid") 318 } 319 320 uc.Limits.Src.Set("192.0.2.0/24,2001:db8:a0b:12f0::1/32,192.168.1.1/1") 321 vr = CreateValidationResults() 322 uc.Validate(vr) 323 324 if !vr.IsEmpty() { 325 t.Error("limits should be valid") 326 } 327 328 uc.Limits.Src = CIDRList{"foo"} 329 vr = CreateValidationResults() 330 uc.Validate(vr) 331 332 if vr.IsEmpty() || len(vr.Issues) != 1 { 333 t.Error("limits should be invalid") 334 } 335 336 uc.Limits.Src = CIDRList{"192.0.2.0/24", "foo"} 337 vr = CreateValidationResults() 338 uc.Validate(vr) 339 340 if vr.IsEmpty() || len(vr.Issues) != 1 { 341 t.Error("limits should be invalid") 342 } 343 344 uc.Limits.Src = CIDRList{"bloo", "foo"} 345 vr = CreateValidationResults() 346 uc.Validate(vr) 347 348 if vr.IsEmpty() || len(vr.Issues) != 2 { 349 t.Error("limits should be invalid") 350 } 351 } 352 353 func TestUserAllowedConnectionTypes(t *testing.T) { 354 akp := createAccountNKey(t) 355 ukp := createUserNKey(t) 356 357 uc := NewUserClaims(publicKey(ukp, t)) 358 uc.AllowedConnectionTypes.Add(ConnectionTypeStandard) 359 uc.AllowedConnectionTypes.Add(ConnectionTypeWebsocket) 360 uc.AllowedConnectionTypes.Add(ConnectionTypeLeafnode) 361 uc.AllowedConnectionTypes.Add(ConnectionTypeLeafnodeWS) 362 uc.AllowedConnectionTypes.Add(ConnectionTypeMqtt) 363 uc.AllowedConnectionTypes.Add(ConnectionTypeMqttWS) 364 uJwt := encode(uc, akp, t) 365 366 uc2, err := DecodeUserClaims(uJwt) 367 if err != nil { 368 t.Fatal("failed to decode uc", err) 369 } 370 AssertTrue(uc2.AllowedConnectionTypes.Contains(ConnectionTypeStandard), t) 371 AssertTrue(uc2.AllowedConnectionTypes.Contains(ConnectionTypeWebsocket), t) 372 AssertTrue(uc2.AllowedConnectionTypes.Contains(ConnectionTypeLeafnode), t) 373 AssertTrue(uc2.AllowedConnectionTypes.Contains(ConnectionTypeLeafnodeWS), t) 374 AssertTrue(uc2.AllowedConnectionTypes.Contains(ConnectionTypeMqtt), t) 375 AssertTrue(uc2.AllowedConnectionTypes.Contains(ConnectionTypeMqttWS), t) 376 } 377 378 func TestUserClaimRevocation(t *testing.T) { 379 akp := createAccountNKey(t) 380 apk := publicKey(akp, t) 381 account := NewAccountClaims(apk) 382 383 u := publicKey(createUserNKey(t), t) 384 aminAgo := time.Now().Add(-time.Minute) 385 if account.Revocations.IsRevoked(u, aminAgo) { 386 t.Fatal("shouldn't be revoked") 387 } 388 account.RevokeAt(u, aminAgo) 389 if !account.Revocations.IsRevoked(u, aminAgo) { 390 t.Fatal("should be revoked") 391 } 392 393 u2 := publicKey(createUserNKey(t), t) 394 if account.Revocations.IsRevoked(u2, aminAgo) { 395 t.Fatal("should not be revoked") 396 } 397 account.RevokeAt("*", aminAgo) 398 if !account.Revocations.IsRevoked(u2, time.Now().Add(-time.Hour)) { 399 t.Fatal("should be revoked") 400 } 401 402 vr := ValidationResults{} 403 account.Validate(&vr) 404 if !vr.IsEmpty() { 405 t.Fatal("account validation shouldn't have failed") 406 } 407 } 408 409 func TestUserClaims_GetTags(t *testing.T) { 410 akp := createAccountNKey(t) 411 ukp := createUserNKey(t) 412 upk := publicKey(ukp, t) 413 414 uc := NewUserClaims(upk) 415 uc.User.Tags.Add("foo", "bar") 416 tags := uc.GetTags() 417 if len(tags) != 2 { 418 t.Fatal("expected 2 tags") 419 } 420 if tags[0] != "foo" { 421 t.Fatal("expected tag foo") 422 } 423 if tags[1] != "bar" { 424 t.Fatal("expected tag bar") 425 } 426 427 token, err := uc.Encode(akp) 428 if err != nil { 429 t.Fatal("error encoding") 430 } 431 uc, err = DecodeUserClaims(token) 432 if err != nil { 433 t.Fatal("error decoding") 434 } 435 tags = uc.GetTags() 436 if len(tags) != 2 { 437 t.Fatal("expected 2 tags") 438 } 439 if tags[0] != "foo" { 440 t.Fatal("expected tag foo") 441 } 442 if tags[1] != "bar" { 443 t.Fatal("expected tag bar") 444 } 445 }