github.com/dbernstein1/tyk@v2.9.0-beta9-dl-apic+incompatible/gateway/policy_test.go (about) 1 package gateway 2 3 import ( 4 "encoding/json" 5 "net/http" 6 "net/http/httptest" 7 "reflect" 8 "sort" 9 "strings" 10 "testing" 11 12 "github.com/lonelycode/go-uuid/uuid" 13 14 "github.com/TykTechnologies/tyk/test" 15 16 "github.com/TykTechnologies/tyk/apidef" 17 "github.com/TykTechnologies/tyk/config" 18 "github.com/TykTechnologies/tyk/user" 19 ) 20 21 func TestLoadPoliciesFromDashboardReLogin(t *testing.T) { 22 // Test Dashboard 23 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 24 w.WriteHeader(403) 25 })) 26 defer ts.Close() 27 28 globalConf := config.Global() 29 oldUseDBAppConfigs := globalConf.UseDBAppConfigs 30 globalConf.UseDBAppConfigs = false 31 config.SetGlobal(globalConf) 32 33 defer func() { 34 globalConf.UseDBAppConfigs = oldUseDBAppConfigs 35 config.SetGlobal(globalConf) 36 }() 37 38 allowExplicitPolicyID := config.Global().Policies.AllowExplicitPolicyID 39 40 policyMap := LoadPoliciesFromDashboard(ts.URL, "", allowExplicitPolicyID) 41 42 if policyMap != nil { 43 t.Error("Should be nil because got back 403 from Dashboard") 44 } 45 } 46 47 type dummySessionManager struct { 48 DefaultSessionManager 49 } 50 51 func (*dummySessionManager) UpdateSession(key string, sess *user.SessionState, ttl int64, hashed bool) error { 52 return nil 53 } 54 55 type testApplyPoliciesData struct { 56 name string 57 policies []string 58 errMatch string // substring 59 sessMatch func(*testing.T, *user.SessionState) // ignored if nil 60 } 61 62 func testPrepareApplyPolicies() (*BaseMiddleware, []testApplyPoliciesData) { 63 policiesMu.RLock() 64 policiesByID = map[string]user.Policy{ 65 "nonpart1": {}, 66 "nonpart2": {}, 67 "difforg": {OrgID: "different"}, 68 "tags1": { 69 Partitions: user.PolicyPartitions{Quota: true}, 70 Tags: []string{"tagA"}, 71 }, 72 "tags2": { 73 Partitions: user.PolicyPartitions{RateLimit: true}, 74 Tags: []string{"tagX", "tagY"}, 75 }, 76 "inactive1": { 77 Partitions: user.PolicyPartitions{RateLimit: true}, 78 IsInactive: true, 79 }, 80 "inactive2": { 81 Partitions: user.PolicyPartitions{Quota: true}, 82 IsInactive: true, 83 }, 84 "quota1": { 85 Partitions: user.PolicyPartitions{Quota: true}, 86 QuotaMax: 2, 87 }, 88 "quota2": {Partitions: user.PolicyPartitions{Quota: true}}, 89 "rate1": { 90 Partitions: user.PolicyPartitions{RateLimit: true}, 91 Rate: 3, 92 }, 93 "rate2": {Partitions: user.PolicyPartitions{RateLimit: true}}, 94 "acl1": { 95 Partitions: user.PolicyPartitions{Acl: true}, 96 AccessRights: map[string]user.AccessDefinition{"a": {}}, 97 }, 98 "acl2": { 99 Partitions: user.PolicyPartitions{Acl: true}, 100 AccessRights: map[string]user.AccessDefinition{"b": {}}, 101 }, 102 "acl3": { 103 AccessRights: map[string]user.AccessDefinition{"c": {}}, 104 }, 105 "per_api_and_partitions": { 106 ID: "per_api_and_partitions", 107 Partitions: user.PolicyPartitions{ 108 PerAPI: true, 109 Quota: true, 110 RateLimit: true, 111 Acl: true, 112 }, 113 AccessRights: map[string]user.AccessDefinition{"d": { 114 Limit: &user.APILimit{ 115 QuotaMax: 1000, 116 QuotaRenewalRate: 3600, 117 Rate: 20, 118 Per: 1, 119 }, 120 }}, 121 }, 122 "per_api_and_some_partitions": { 123 ID: "per_api_and_some_partitions", 124 Partitions: user.PolicyPartitions{ 125 PerAPI: true, 126 Quota: false, 127 RateLimit: true, 128 Acl: false, 129 }, 130 AccessRights: map[string]user.AccessDefinition{"d": { 131 Limit: &user.APILimit{ 132 QuotaMax: 1000, 133 QuotaRenewalRate: 3600, 134 Rate: 20, 135 Per: 1, 136 }, 137 }}, 138 }, 139 "per_api_and_no_other_partitions": { 140 ID: "per_api_and_no_other_partitions", 141 Partitions: user.PolicyPartitions{ 142 PerAPI: true, 143 Quota: false, 144 RateLimit: false, 145 Acl: false, 146 }, 147 AccessRights: map[string]user.AccessDefinition{ 148 "d": { 149 Limit: &user.APILimit{ 150 QuotaMax: 1000, 151 QuotaRenewalRate: 3600, 152 Rate: 20, 153 Per: 1, 154 }, 155 }, 156 "c": { 157 Limit: &user.APILimit{ 158 QuotaMax: -1, 159 Rate: 2000, 160 Per: 60, 161 }, 162 }, 163 }, 164 }, 165 "per_api_with_the_same_api": { 166 ID: "per_api_with_the_same_api", 167 Partitions: user.PolicyPartitions{ 168 PerAPI: true, 169 Quota: false, 170 RateLimit: false, 171 Acl: false, 172 }, 173 AccessRights: map[string]user.AccessDefinition{ 174 "d": { 175 Limit: &user.APILimit{ 176 QuotaMax: 5000, 177 QuotaRenewalRate: 3600, 178 Rate: 200, 179 Per: 10, 180 }, 181 }, 182 }, 183 }, 184 "per_api_with_limit_set_from_policy": { 185 ID: "per_api_with_limit_set_from_policy", 186 QuotaMax: -1, 187 Rate: 300, 188 Per: 1, 189 Partitions: user.PolicyPartitions{ 190 PerAPI: true, 191 Quota: false, 192 RateLimit: false, 193 Acl: false, 194 }, 195 AccessRights: map[string]user.AccessDefinition{ 196 "d": { 197 Limit: &user.APILimit{ 198 QuotaMax: 5000, 199 QuotaRenewalRate: 3600, 200 Rate: 200, 201 Per: 10, 202 }, 203 }, 204 "e": {}, 205 }, 206 }, 207 } 208 policiesMu.RUnlock() 209 bmid := &BaseMiddleware{Spec: &APISpec{ 210 APIDefinition: &apidef.APIDefinition{}, 211 SessionManager: &dummySessionManager{}, 212 }} 213 tests := []testApplyPoliciesData{ 214 { 215 "Empty", nil, 216 "", nil, 217 }, 218 { 219 "Single", []string{"nonpart1"}, 220 "", nil, 221 }, 222 { 223 "Missing", []string{"nonexistent"}, 224 "not found", nil, 225 }, 226 { 227 "DiffOrg", []string{"difforg"}, 228 "different org", nil, 229 }, 230 { 231 "MultiNonPart", []string{"nonpart1", "nonpart2"}, 232 "any are non-part", nil, 233 }, 234 { 235 "NonpartAndPart", []string{"nonpart1", "quota1"}, 236 "any are non-part", nil, 237 }, 238 { 239 "TagMerge", []string{"tags1", "tags2"}, 240 "", func(t *testing.T, s *user.SessionState) { 241 want := []string{"tagA", "tagX", "tagY"} 242 sort.Strings(s.Tags) 243 if !reflect.DeepEqual(want, s.Tags) { 244 t.Fatalf("want Tags %v, got %v", want, s.Tags) 245 } 246 }, 247 }, 248 { 249 "InactiveMergeOne", []string{"tags1", "inactive1"}, 250 "", func(t *testing.T, s *user.SessionState) { 251 if !s.IsInactive { 252 t.Fatalf("want IsInactive to be true") 253 } 254 }, 255 }, 256 { 257 "InactiveMergeAll", []string{"inactive1", "inactive2"}, 258 "", func(t *testing.T, s *user.SessionState) { 259 if !s.IsInactive { 260 t.Fatalf("want IsInactive to be true") 261 } 262 }, 263 }, 264 { 265 "QuotaPart", []string{"quota1"}, 266 "", func(t *testing.T, s *user.SessionState) { 267 if s.QuotaMax != 2 { 268 t.Fatalf("want QuotaMax to be 2") 269 } 270 }, 271 }, 272 { 273 "QuotaParts", []string{"quota1", "quota2"}, 274 "multiple quota policies", nil, 275 }, 276 { 277 "RatePart", []string{"rate1"}, 278 "", func(t *testing.T, s *user.SessionState) { 279 if s.Rate != 3 { 280 t.Fatalf("want Rate to be 3") 281 } 282 }, 283 }, 284 { 285 "RateParts", []string{"rate1", "rate2"}, 286 "multiple rate limit policies", nil, 287 }, 288 { 289 "AclPart", []string{"acl1"}, 290 "", func(t *testing.T, s *user.SessionState) { 291 want := map[string]user.AccessDefinition{"a": {}} 292 if !reflect.DeepEqual(want, s.AccessRights) { 293 t.Fatalf("want %v got %v", want, s.AccessRights) 294 } 295 }, 296 }, 297 { 298 "AclPart", []string{"acl1", "acl2"}, 299 "", func(t *testing.T, s *user.SessionState) { 300 want := map[string]user.AccessDefinition{"a": {}, "b": {}} 301 if !reflect.DeepEqual(want, s.AccessRights) { 302 t.Fatalf("want %v got %v", want, s.AccessRights) 303 } 304 }, 305 }, 306 { 307 "RightsUpdate", []string{"acl3"}, 308 "", func(t *testing.T, s *user.SessionState) { 309 newPolicy := user.Policy{ 310 AccessRights: map[string]user.AccessDefinition{"a": {}, "b": {}, "c": {}}, 311 } 312 policiesMu.Lock() 313 policiesByID["acl3"] = newPolicy 314 policiesMu.Unlock() 315 err := bmid.ApplyPolicies(s) 316 if err != nil { 317 t.Fatalf("couldn't apply policy: %s", err.Error()) 318 } 319 want := newPolicy.AccessRights 320 if !reflect.DeepEqual(want, s.AccessRights) { 321 t.Fatalf("want %v got %v", want, s.AccessRights) 322 } 323 }, 324 }, 325 { 326 name: "Per API is set with other partitions to true", 327 policies: []string{"per_api_and_partitions"}, 328 errMatch: "cannot apply policy per_api_and_partitions which has per_api and any of partitions set", 329 }, 330 { 331 name: "Per API is set to true with some partitions set to true", 332 policies: []string{"per_api_and_some_partitions"}, 333 errMatch: "cannot apply policy per_api_and_some_partitions which has per_api and any of partitions set", 334 }, 335 { 336 name: "Per API is set to true with no other partitions set to true", 337 policies: []string{"per_api_and_no_other_partitions"}, 338 sessMatch: func(t *testing.T, s *user.SessionState) { 339 want := map[string]user.AccessDefinition{ 340 "d": { 341 Limit: &user.APILimit{ 342 QuotaMax: 1000, 343 QuotaRenewalRate: 3600, 344 Rate: 20, 345 Per: 1, 346 }, 347 }, 348 "c": { 349 Limit: &user.APILimit{ 350 QuotaMax: -1, 351 Rate: 2000, 352 Per: 60, 353 }, 354 }, 355 } 356 if !reflect.DeepEqual(want, s.AccessRights) { 357 t.Fatalf("want %v got %v", want, s.AccessRights) 358 } 359 }, 360 }, 361 { 362 name: "several policies with Per API set to true but specifying limit for the same API", 363 policies: []string{"per_api_and_no_other_partitions", "per_api_with_the_same_api"}, 364 errMatch: "cannot apply multiple policies for API: d", 365 }, 366 { 367 name: "several policies, mixed the one which has Per API set to true and partitioned ones", 368 policies: []string{"per_api_and_no_other_partitions", "quota1"}, 369 errMatch: "cannot apply multiple policies when some are partitioned and some have per_api set", 370 }, 371 { 372 name: "several policies, mixed the one which has Per API set to true and partitioned ones (different order)", 373 policies: []string{"rate1", "per_api_and_no_other_partitions"}, 374 errMatch: "cannot apply multiple policies when some have per_api set and some are partitioned", 375 }, 376 { 377 name: "Per API is set to true and some API gets limit set from policy's fields", 378 policies: []string{"per_api_with_limit_set_from_policy"}, 379 sessMatch: func(t *testing.T, s *user.SessionState) { 380 want := map[string]user.AccessDefinition{ 381 "d": { 382 Limit: &user.APILimit{ 383 QuotaMax: 5000, 384 QuotaRenewalRate: 3600, 385 Rate: 200, 386 Per: 10, 387 }, 388 }, 389 "e": { 390 Limit: &user.APILimit{ 391 QuotaMax: -1, 392 Rate: 300, 393 Per: 1, 394 SetByPolicy: true, 395 }, 396 }, 397 } 398 if !reflect.DeepEqual(want, s.AccessRights) { 399 t.Fatalf("want %v got %v", want, s.AccessRights) 400 } 401 }, 402 }, 403 } 404 405 return bmid, tests 406 } 407 408 func TestApplyPolicies(t *testing.T) { 409 bmid, tests := testPrepareApplyPolicies() 410 411 for _, tc := range tests { 412 t.Run(tc.name, func(t *testing.T) { 413 sess := &user.SessionState{} 414 sess.SetPolicies(tc.policies...) 415 errStr := "" 416 if err := bmid.ApplyPolicies(sess); err != nil { 417 errStr = err.Error() 418 } 419 if tc.errMatch == "" && errStr != "" { 420 t.Fatalf("didn't want err but got %s", errStr) 421 } else if !strings.Contains(errStr, tc.errMatch) { 422 t.Fatalf("error %q doesn't match %q", 423 errStr, tc.errMatch) 424 } 425 if tc.sessMatch != nil { 426 tc.sessMatch(t, sess) 427 } 428 }) 429 } 430 } 431 432 func BenchmarkApplyPolicies(b *testing.B) { 433 b.ReportAllocs() 434 435 bmid, tests := testPrepareApplyPolicies() 436 437 for i := 0; i < b.N; i++ { 438 for _, tc := range tests { 439 sess := &user.SessionState{} 440 sess.SetPolicies(tc.policies...) 441 bmid.ApplyPolicies(sess) 442 } 443 } 444 } 445 446 func TestApplyPoliciesQuotaAPILimit(t *testing.T) { 447 policiesMu.RLock() 448 policy := user.Policy{ 449 ID: "two_of_three_with_api_limit", 450 Per: 1, 451 Rate: 1000, 452 QuotaMax: 50, 453 QuotaRenewalRate: 3600, 454 OrgID: "default", 455 Partitions: user.PolicyPartitions{ 456 PerAPI: true, 457 Quota: false, 458 RateLimit: false, 459 Acl: false, 460 }, 461 AccessRights: map[string]user.AccessDefinition{ 462 "api1": { 463 Versions: []string{"v1"}, 464 Limit: &user.APILimit{ 465 QuotaMax: 100, 466 QuotaRenewalRate: 3600, 467 Rate: 1000, 468 Per: 1, 469 }, 470 }, 471 "api2": { 472 Versions: []string{"v1"}, 473 Limit: &user.APILimit{ 474 QuotaMax: 200, 475 QuotaRenewalRate: 3600, 476 Rate: 1000, 477 Per: 1, 478 }, 479 }, 480 "api3": { 481 Versions: []string{"v1"}, 482 }, 483 }, 484 } 485 policiesByID = map[string]user.Policy{ 486 "two_of_three_with_api_limit": policy, 487 } 488 policiesMu.RUnlock() 489 490 ts := StartTest() 491 defer ts.Close() 492 493 // load APIs 494 BuildAndLoadAPI( 495 func(spec *APISpec) { 496 spec.Name = "api 1" 497 spec.APIID = "api1" 498 spec.UseKeylessAccess = false 499 spec.Proxy.ListenPath = "/api1" 500 spec.OrgID = "default" 501 }, 502 func(spec *APISpec) { 503 spec.Name = "api 2" 504 spec.APIID = "api2" 505 spec.UseKeylessAccess = false 506 spec.Proxy.ListenPath = "/api2" 507 spec.OrgID = "default" 508 }, 509 func(spec *APISpec) { 510 spec.Name = "api 3" 511 spec.APIID = "api3" 512 spec.UseKeylessAccess = false 513 spec.Proxy.ListenPath = "/api3" 514 spec.OrgID = "default" 515 }, 516 ) 517 518 // create test session 519 session := &user.SessionState{ 520 ApplyPolicies: []string{"two_of_three_with_api_limit"}, 521 OrgID: "default", 522 AccessRights: map[string]user.AccessDefinition{ 523 "api1": { 524 APIID: "api1", 525 Versions: []string{"v1"}, 526 }, 527 "api2": { 528 APIID: "api2", 529 Versions: []string{"v1"}, 530 }, 531 "api3": { 532 APIID: "api3", 533 Versions: []string{"v1"}, 534 }, 535 }, 536 } 537 538 // create key 539 key := uuid.New() 540 ts.Run(t, []test.TestCase{ 541 {Method: http.MethodPost, Path: "/tyk/keys/" + key, Data: session, AdminAuth: true, Code: 200}, 542 }...) 543 544 // run requests to different APIs 545 authHeader := map[string]string{"Authorization": key} 546 ts.Run(t, []test.TestCase{ 547 // 2 requests to api1, API limit quota remaining should be 98 548 {Method: http.MethodGet, Path: "/api1", Headers: authHeader, Code: http.StatusOK, 549 HeadersMatch: map[string]string{XRateLimitRemaining: "99"}}, 550 {Method: http.MethodGet, Path: "/api1", Headers: authHeader, Code: http.StatusOK, 551 HeadersMatch: map[string]string{XRateLimitRemaining: "98"}}, 552 // 3 requests to api2, API limit quota remaining should be 197 553 {Method: http.MethodGet, Path: "/api2", Headers: authHeader, Code: http.StatusOK, 554 HeadersMatch: map[string]string{XRateLimitRemaining: "199"}}, 555 {Method: http.MethodGet, Path: "/api2", Headers: authHeader, Code: http.StatusOK, 556 HeadersMatch: map[string]string{XRateLimitRemaining: "198"}}, 557 {Method: http.MethodGet, Path: "/api2", Headers: authHeader, Code: http.StatusOK, 558 HeadersMatch: map[string]string{XRateLimitRemaining: "197"}}, 559 // 5 requests to api3, API limit quota remaining should be 45 560 {Method: http.MethodGet, Path: "/api3", Headers: authHeader, Code: http.StatusOK, 561 HeadersMatch: map[string]string{XRateLimitRemaining: "49"}}, 562 {Method: http.MethodGet, Path: "/api3", Headers: authHeader, Code: http.StatusOK, 563 HeadersMatch: map[string]string{XRateLimitRemaining: "48"}}, 564 {Method: http.MethodGet, Path: "/api3", Headers: authHeader, Code: http.StatusOK, 565 HeadersMatch: map[string]string{XRateLimitRemaining: "47"}}, 566 {Method: http.MethodGet, Path: "/api3", Headers: authHeader, Code: http.StatusOK, 567 HeadersMatch: map[string]string{XRateLimitRemaining: "46"}}, 568 {Method: http.MethodGet, Path: "/api3", Headers: authHeader, Code: http.StatusOK, 569 HeadersMatch: map[string]string{XRateLimitRemaining: "45"}}, 570 }...) 571 572 // check key session 573 ts.Run(t, []test.TestCase{ 574 { 575 Method: http.MethodGet, 576 Path: "/tyk/keys/" + key, 577 AdminAuth: true, 578 Code: http.StatusOK, 579 BodyMatchFunc: func(data []byte) bool { 580 sessionData := user.SessionState{} 581 if err := json.Unmarshal(data, &sessionData); err != nil { 582 t.Log(err.Error()) 583 return false 584 } 585 api1Limit := sessionData.AccessRights["api1"].Limit 586 if api1Limit == nil { 587 t.Log("api1 limit is not set") 588 return false 589 } 590 api1LimitExpected := user.APILimit{ 591 Rate: 1000, 592 Per: 1, 593 QuotaMax: 100, 594 QuotaRenewalRate: 3600, 595 QuotaRenews: api1Limit.QuotaRenews, 596 QuotaRemaining: 98, 597 } 598 if !reflect.DeepEqual(*api1Limit, api1LimitExpected) { 599 t.Log("api1 limit received:", *api1Limit, "expected:", api1LimitExpected) 600 return false 601 } 602 api2Limit := sessionData.AccessRights["api2"].Limit 603 if api2Limit == nil { 604 t.Log("api2 limit is not set") 605 return false 606 } 607 api2LimitExpected := user.APILimit{ 608 Rate: 1000, 609 Per: 1, 610 QuotaMax: 200, 611 QuotaRenewalRate: 3600, 612 QuotaRenews: api2Limit.QuotaRenews, 613 QuotaRemaining: 197, 614 } 615 if !reflect.DeepEqual(*api2Limit, api2LimitExpected) { 616 t.Log("api2 limit received:", *api2Limit, "expected:", api2LimitExpected) 617 return false 618 } 619 api3Limit := sessionData.AccessRights["api3"].Limit 620 if api3Limit == nil { 621 t.Log("api3 limit is not set") 622 return false 623 } 624 api3LimitExpected := user.APILimit{ 625 Rate: 1000, 626 Per: 1, 627 QuotaMax: 50, 628 QuotaRenewalRate: 3600, 629 QuotaRenews: api3Limit.QuotaRenews, 630 QuotaRemaining: 45, 631 SetByPolicy: true, 632 } 633 if !reflect.DeepEqual(*api3Limit, api3LimitExpected) { 634 t.Log("api3 limit received:", *api3Limit, "expected:", api3LimitExpected) 635 return false 636 } 637 return true 638 }, 639 }, 640 }...) 641 642 // Reset quota 643 ts.Run(t, []test.TestCase{ 644 { 645 Method: http.MethodPut, 646 Path: "/tyk/keys/" + key, 647 AdminAuth: true, 648 Code: http.StatusOK, 649 Data: session, 650 }, 651 { 652 Method: http.MethodGet, 653 Path: "/tyk/keys/" + key, 654 AdminAuth: true, 655 Code: http.StatusOK, 656 BodyMatchFunc: func(data []byte) bool { 657 sessionData := user.SessionState{} 658 if err := json.Unmarshal(data, &sessionData); err != nil { 659 t.Log(err.Error()) 660 return false 661 } 662 api1Limit := sessionData.AccessRights["api1"].Limit 663 if api1Limit == nil { 664 t.Error("api1 limit is not set") 665 return false 666 } 667 668 if api1Limit.QuotaRemaining != 100 { 669 t.Error("Should reset quota:", api1Limit.QuotaRemaining) 670 return false 671 } 672 673 return true 674 }, 675 }, 676 }...) 677 } 678 679 func TestPerAPIPolicyUpdate(t *testing.T) { 680 policiesMu.RLock() 681 policy := user.Policy{ 682 ID: "per_api_policy_with_two_apis", 683 OrgID: "default", 684 Partitions: user.PolicyPartitions{ 685 PerAPI: true, 686 Quota: false, 687 RateLimit: false, 688 Acl: false, 689 }, 690 AccessRights: map[string]user.AccessDefinition{ 691 "api1": { 692 Versions: []string{"v1"}, 693 }, 694 "api2": { 695 Versions: []string{"v1"}, 696 }, 697 }, 698 } 699 policiesByID = map[string]user.Policy{ 700 "per_api_policy_with_two_apis": policy, 701 } 702 policiesMu.RUnlock() 703 704 ts := StartTest() 705 defer ts.Close() 706 707 // load APIs 708 BuildAndLoadAPI( 709 func(spec *APISpec) { 710 spec.Name = "api 1" 711 spec.APIID = "api1" 712 spec.UseKeylessAccess = false 713 spec.Proxy.ListenPath = "/api1" 714 spec.OrgID = "default" 715 }, 716 func(spec *APISpec) { 717 spec.Name = "api 2" 718 spec.APIID = "api2" 719 spec.UseKeylessAccess = false 720 spec.Proxy.ListenPath = "/api2" 721 spec.OrgID = "default" 722 }, 723 ) 724 725 // create test session 726 session := &user.SessionState{ 727 ApplyPolicies: []string{"per_api_policy_with_two_apis"}, 728 OrgID: "default", 729 AccessRights: map[string]user.AccessDefinition{ 730 "api1": { 731 APIID: "api1", 732 Versions: []string{"v1"}, 733 }, 734 "api2": { 735 APIID: "api2", 736 Versions: []string{"v1"}, 737 }, 738 }, 739 } 740 741 // create key 742 key := uuid.New() 743 ts.Run(t, []test.TestCase{ 744 {Method: http.MethodPost, Path: "/tyk/keys/" + key, Data: session, AdminAuth: true, Code: 200}, 745 }...) 746 747 // check key session 748 ts.Run(t, []test.TestCase{ 749 { 750 Method: http.MethodGet, 751 Path: "/tyk/keys/" + key, 752 AdminAuth: true, 753 Code: http.StatusOK, 754 BodyMatchFunc: func(data []byte) bool { 755 sessionData := user.SessionState{} 756 if err := json.Unmarshal(data, &sessionData); err != nil { 757 t.Log(err.Error()) 758 return false 759 } 760 761 if len(sessionData.AccessRights) != 2 { 762 t.Fatalf("expected 2 entries in AccessRights found %d", len(sessionData.AccessRights)) 763 } 764 765 _, ok1 := sessionData.AccessRights["api1"] 766 _, ok2 := sessionData.AccessRights["api2"] 767 768 if !ok1 || !ok2 { 769 t.Fatalf("expected api1 and api2 in AccessRights found %v", sessionData.AccessRights) 770 } 771 772 return true 773 }, 774 }, 775 }...) 776 777 //Update policy 778 policiesMu.RLock() 779 policy = user.Policy{ 780 ID: "per_api_policy_with_two_apis", 781 OrgID: "default", 782 Partitions: user.PolicyPartitions{ 783 PerAPI: true, 784 Quota: false, 785 RateLimit: false, 786 Acl: false, 787 }, 788 AccessRights: map[string]user.AccessDefinition{ 789 "api1": { 790 Versions: []string{"v1"}, 791 }, 792 }, 793 } 794 policiesByID = map[string]user.Policy{ 795 "per_api_policy_with_two_apis": policy, 796 } 797 policiesMu.RUnlock() 798 799 ts.Run(t, []test.TestCase{ 800 { 801 Method: http.MethodGet, 802 Path: "/tyk/keys/" + key, 803 AdminAuth: true, 804 Code: http.StatusOK, 805 BodyMatchFunc: func(data []byte) bool { 806 sessionData := user.SessionState{} 807 if err := json.Unmarshal(data, &sessionData); err != nil { 808 t.Log(err.Error()) 809 return false 810 } 811 812 if len(sessionData.AccessRights) != 1 { 813 t.Fatalf("expected only 1 entry in AccessRights found %d", len(sessionData.AccessRights)) 814 } 815 816 _, ok1 := sessionData.AccessRights["api1"] 817 818 if !ok1 { 819 t.Fatalf("expected api1 in AccessRights found %v", sessionData.AccessRights) 820 } 821 822 return true 823 }, 824 }, 825 }...) 826 }