github.com/nats-io/jwt/v2@v2.5.6/v1compat/imports_test.go (about) 1 /* 2 * Copyright 2018 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 "fmt" 20 "net/http" 21 "net/http/httptest" 22 "sort" 23 "testing" 24 "time" 25 ) 26 27 func TestImportValidation(t *testing.T) { 28 ak := createAccountNKey(t) 29 ak2 := createAccountNKey(t) 30 akp := publicKey(ak, t) 31 akp2 := publicKey(ak2, t) 32 i := &Import{Subject: "test", Account: akp2, To: "bar", Type: Stream} 33 34 vr := CreateValidationResults() 35 i.Validate("", vr) 36 37 if !vr.IsEmpty() { 38 t.Errorf("imports should not generate an issue") 39 } 40 41 vr = CreateValidationResults() 42 i.Validate("", vr) 43 44 if !vr.IsEmpty() { 45 t.Errorf("imports should not generate an issue") 46 } 47 48 activation := NewActivationClaims(akp) 49 activation.Expires = time.Now().Add(time.Hour).UTC().Unix() 50 51 activation.ImportSubject = "test" 52 activation.ImportType = Stream 53 actJWT := encode(activation, ak2, t) 54 55 i.Token = actJWT 56 vr = CreateValidationResults() 57 i.Validate(akp, vr) 58 59 if !vr.IsEmpty() { 60 t.Errorf("imports with token should be valid") 61 } 62 } 63 64 func TestInvalidImportType(t *testing.T) { 65 ak := createAccountNKey(t) 66 akp := publicKey(ak, t) 67 i := &Import{Subject: "foo", Account: akp, To: "bar", Type: Unknown} 68 69 vr := CreateValidationResults() 70 i.Validate("", vr) 71 72 if vr.IsEmpty() { 73 t.Errorf("imports without token or url should warn the caller") 74 } 75 76 if !vr.IsBlocking(true) { 77 t.Errorf("invalid type is blocking") 78 } 79 } 80 81 func TestInvalidImportToken(t *testing.T) { 82 ak := createAccountNKey(t) 83 akp := publicKey(ak, t) 84 i := &Import{Subject: "foo", Account: akp, Token: "bad token", To: "bar", Type: Stream} 85 86 vr := CreateValidationResults() 87 i.Validate("", vr) 88 89 if !vr.IsBlocking(true) { 90 t.Errorf("bad token should be blocking") 91 } 92 } 93 94 func TestInvalidImportURL(t *testing.T) { 95 ak := createAccountNKey(t) 96 akp := publicKey(ak, t) 97 i := &Import{Subject: "foo", Account: akp, Token: "foo://bad-token-url", To: "bar", Type: Stream} 98 99 vr := CreateValidationResults() 100 i.Validate("", vr) 101 102 if vr.IsEmpty() { 103 t.Errorf("imports with a bad token or url should warn the caller") 104 } 105 106 if !vr.IsBlocking(true) { 107 t.Errorf("invalid type should be blocking") 108 } 109 } 110 111 func TestInvalidImportTokenValuesValidation(t *testing.T) { 112 ak := createAccountNKey(t) 113 ak2 := createAccountNKey(t) 114 akp := publicKey(ak, t) 115 akp2 := publicKey(ak2, t) 116 i := &Import{Subject: "bar", Account: akp2, To: "test", Type: Service} 117 118 vr := CreateValidationResults() 119 i.Validate("", vr) 120 121 if vr.IsBlocking(true) { 122 t.Errorf("imports without token or url should not be blocking") 123 } 124 125 i.Type = Service 126 vr = CreateValidationResults() 127 i.Validate("", vr) 128 129 if vr.IsBlocking(true) { 130 t.Errorf("imports without token or url should not be blocking") 131 } 132 133 activation := NewActivationClaims(akp) 134 activation.Max = 1024 * 1024 135 activation.Expires = time.Now().Add(time.Duration(time.Hour)).UTC().Unix() 136 137 activation.ImportSubject = "test" 138 activation.ImportType = Service 139 actJWT := encode(activation, ak2, t) 140 141 i.Token = actJWT 142 vr = CreateValidationResults() 143 i.Validate(akp, vr) 144 145 if !vr.IsEmpty() { 146 t.Errorf("imports with token should be valid") 147 } 148 149 actJWT = encode(activation, ak, t) // wrong issuer 150 i.Token = actJWT 151 vr = CreateValidationResults() 152 i.Validate(akp, vr) 153 154 if vr.IsEmpty() { 155 t.Errorf("imports with wrong issuer") 156 } 157 158 activation.Subject = akp2 // wrong subject 159 actJWT = encode(activation, ak2, t) // right issuer 160 i.Token = actJWT 161 vr = CreateValidationResults() 162 i.Validate(akp, vr) 163 164 if vr.IsEmpty() { 165 t.Errorf("imports with wrong issuer") 166 } 167 } 168 169 func TestMissingAccountInImport(t *testing.T) { 170 i := &Import{Subject: "foo", To: "bar", Type: Stream} 171 172 vr := CreateValidationResults() 173 i.Validate("", vr) 174 175 if len(vr.Issues) != 1 { 176 t.Errorf("expected only one issue") 177 } 178 179 if !vr.IsBlocking(true) { 180 t.Errorf("Missing Account is blocking") 181 } 182 } 183 184 func TestServiceImportWithWildcard(t *testing.T) { 185 ak := createAccountNKey(t) 186 akp := publicKey(ak, t) 187 i := &Import{Subject: "foo.*", Account: akp, To: "bar", Type: Service} 188 189 vr := CreateValidationResults() 190 i.Validate("", vr) 191 192 if !vr.IsBlocking(true) { 193 t.Errorf("expected service import with a wildcard subject to be a blocking error") 194 } 195 } 196 197 func TestStreamImportWithWildcardPrefix(t *testing.T) { 198 i := &Import{Subject: "foo", To: "bar.>", Type: Stream} 199 200 vr := CreateValidationResults() 201 i.Validate("", vr) 202 203 if len(vr.Issues) != 2 { 204 t.Errorf("should have registered 2 issues with this import, got %d", len(vr.Issues)) 205 } 206 207 if !vr.IsBlocking(true) { 208 t.Fatalf("expected stream import prefix with a wildcard to produce a blocking error") 209 } 210 } 211 212 func TestImportsValidation(t *testing.T) { 213 ak := createAccountNKey(t) 214 akp := publicKey(ak, t) 215 i := &Import{Subject: "foo", Account: akp, To: "bar", Type: Stream} 216 i2 := &Import{Subject: "foo.*", Account: akp, To: "bar", Type: Service} 217 218 imports := &Imports{} 219 imports.Add(i, i2) 220 221 vr := CreateValidationResults() 222 imports.Validate("", vr) 223 224 if len(vr.Issues) != 1 { 225 t.Errorf("warn about wildcard service") 226 } 227 228 if !vr.IsBlocking(true) { 229 t.Errorf("expected service import with a wildcard subject to be a blocking error") 230 } 231 } 232 233 func TestTokenURLImportValidation(t *testing.T) { 234 ak := createAccountNKey(t) 235 ak2 := createAccountNKey(t) 236 akp := publicKey(ak, t) 237 akp2 := publicKey(ak2, t) 238 i := &Import{Subject: "test", Account: akp2, To: "bar", Type: Stream} 239 240 activation := NewActivationClaims(akp) 241 activation.Max = 1024 * 1024 242 activation.Expires = time.Now().Add(time.Duration(time.Hour)).UTC().Unix() 243 activation.ImportSubject = "test" 244 activation.ImportType = Stream 245 246 actJWT := encode(activation, ak2, t) 247 248 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 249 w.Write([]byte(actJWT)) 250 })) 251 defer ts.Close() 252 253 i.Token = ts.URL 254 vr := CreateValidationResults() 255 i.Validate(akp, vr) 256 257 if !vr.IsEmpty() { 258 fmt.Printf("vr is %+v\n", vr) 259 t.Errorf("imports with token url should be valid") 260 } 261 262 i.Token = "http://Bad URL" 263 vr = CreateValidationResults() 264 i.Validate(akp, vr) 265 266 if vr.IsEmpty() { 267 t.Errorf("imports with bad token url should be valid") 268 } 269 270 ts = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 271 w.Write([]byte("bad jwt")) 272 })) 273 defer ts.Close() 274 275 i.Token = ts.URL 276 vr = CreateValidationResults() 277 i.Validate(akp, vr) 278 279 if vr.IsEmpty() { 280 t.Errorf("imports with token url pointing to bad JWT") 281 } 282 283 ts = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 284 w.WriteHeader(http.StatusBadRequest) 285 })) 286 defer ts.Close() 287 288 i.Token = ts.URL 289 vr = CreateValidationResults() 290 i.Validate(akp, vr) 291 292 if vr.IsEmpty() { 293 t.Errorf("imports with token url pointing to bad url") 294 } 295 } 296 297 func TestImportSubjectValidation(t *testing.T) { 298 ak := createAccountNKey(t) 299 akp := publicKey(ak, t) 300 activation := NewActivationClaims(akp) 301 activation.Max = 1024 * 1024 302 activation.Expires = time.Now().Add(time.Duration(time.Hour)).UTC().Unix() 303 activation.ImportSubject = "one.*" 304 activation.ImportType = Stream 305 306 ak2 := createAccountNKey(t) 307 akp2 := publicKey(ak2, t) 308 i := &Import{Subject: "one.two", Account: akp2, To: "bar", Type: Stream} 309 310 actJWT := encode(activation, ak2, t) 311 i.Token = actJWT 312 vr := CreateValidationResults() 313 i.Validate(akp, vr) 314 315 if !vr.IsEmpty() { 316 t.Log(vr.Issues[0].Description) 317 t.Errorf("imports with valid contains subject should be valid") 318 } 319 320 activation.ImportSubject = "two" 321 activation.ImportType = Stream 322 actJWT = encode(activation, ak2, t) 323 i.Token = actJWT 324 vr = CreateValidationResults() 325 i.Validate(akp, vr) 326 327 if vr.IsEmpty() { 328 t.Errorf("imports with non-contains subject should be not valid") 329 } 330 331 activation.ImportSubject = ">" 332 activation.ImportType = Stream 333 actJWT = encode(activation, ak2, t) 334 i.Token = actJWT 335 vr = CreateValidationResults() 336 i.Validate(akp, vr) 337 338 if !vr.IsEmpty() { 339 t.Errorf("imports with valid contains subject should be valid") 340 } 341 } 342 343 func TestImportServiceDoubleToSubjectsValidation(t *testing.T) { 344 akp := createAccountNKey(t) 345 akp2 := createAccountNKey(t) 346 apk := publicKey(akp, t) 347 apk2 := publicKey(akp2, t) 348 349 account := NewAccountClaims(apk) 350 351 i := &Import{Subject: "one.two", Account: apk2, To: "foo.bar", Type: Service} 352 account.Imports.Add(i) 353 354 vr := CreateValidationResults() 355 account.Validate(vr) 356 357 if vr.IsBlocking(true) { 358 t.Fatalf("Expected no blocking validation errors") 359 } 360 361 i2 := &Import{Subject: "two.three", Account: apk2, To: "foo.bar", Type: Service} 362 account.Imports.Add(i2) 363 364 vr = CreateValidationResults() 365 account.Validate(vr) 366 367 if !vr.IsBlocking(true) { 368 t.Fatalf("Expected multiple import 'to' subjects to produce an error") 369 } 370 } 371 372 func TestImport_Sorting(t *testing.T) { 373 var imports Imports 374 pk := publicKey(createAccountNKey(t), t) 375 imports.Add(&Import{Subject: "x", Type: Service, Account: pk}) 376 imports.Add(&Import{Subject: "z", Type: Service, Account: pk}) 377 imports.Add(&Import{Subject: "y", Type: Service, Account: pk}) 378 if imports[0].Subject != "x" { 379 t.Fatal("added import not in expected order") 380 } 381 sort.Sort(imports) 382 if imports[0].Subject != "x" && imports[1].Subject != "y" && imports[2].Subject != "z" { 383 t.Fatal("imports not sorted") 384 } 385 }