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