github.com/authzed/spicedb@v1.32.1-0.20240520085336-ebda56537386/internal/services/v1/hash_test.go (about) 1 package v1 2 3 import ( 4 "testing" 5 6 "google.golang.org/protobuf/types/known/structpb" 7 8 v1 "github.com/authzed/authzed-go/proto/authzed/api/v1" 9 "github.com/stretchr/testify/require" 10 ) 11 12 func TestReadRelationshipsHashStability(t *testing.T) { 13 tcs := []struct { 14 name string 15 request *v1.ReadRelationshipsRequest 16 expectedHash string 17 }{ 18 { 19 "basic read", 20 &v1.ReadRelationshipsRequest{ 21 RelationshipFilter: &v1.RelationshipFilter{ 22 ResourceType: "someresourcetype", 23 }, 24 }, 25 "0a0e721527f9e3b2", 26 }, 27 { 28 "full read", 29 &v1.ReadRelationshipsRequest{ 30 RelationshipFilter: &v1.RelationshipFilter{ 31 ResourceType: "someresourcetype", 32 OptionalResourceId: "foo", 33 OptionalRelation: "somerelation", 34 OptionalSubjectFilter: &v1.SubjectFilter{ 35 SubjectType: "somesubjectype", 36 OptionalSubjectId: "somesubject", 37 OptionalRelation: &v1.SubjectFilter_RelationFilter{ 38 Relation: "subrelation", 39 }, 40 }, 41 }, 42 OptionalLimit: 1000, 43 }, 44 "0375e86e0c72f281", 45 }, 46 { 47 "different resource type", 48 &v1.ReadRelationshipsRequest{ 49 RelationshipFilter: &v1.RelationshipFilter{ 50 ResourceType: "someresourcetype2", 51 OptionalResourceId: "foo", 52 OptionalRelation: "somerelation", 53 OptionalSubjectFilter: &v1.SubjectFilter{ 54 SubjectType: "somesubjectype", 55 OptionalSubjectId: "somesubject", 56 OptionalRelation: &v1.SubjectFilter_RelationFilter{ 57 Relation: "subrelation", 58 }, 59 }, 60 }, 61 OptionalLimit: 1000, 62 }, 63 "a7d3548f8303f0ba", 64 }, 65 { 66 "different resource id", 67 &v1.ReadRelationshipsRequest{ 68 RelationshipFilter: &v1.RelationshipFilter{ 69 ResourceType: "someresourcetype", 70 OptionalResourceId: "foo2", 71 OptionalRelation: "somerelation", 72 OptionalSubjectFilter: &v1.SubjectFilter{ 73 SubjectType: "somesubjectype", 74 OptionalSubjectId: "somesubject", 75 OptionalRelation: &v1.SubjectFilter_RelationFilter{ 76 Relation: "subrelation", 77 }, 78 }, 79 }, 80 OptionalLimit: 1000, 81 }, 82 "77c9a81be9232973", 83 }, 84 { 85 "different resource relation", 86 &v1.ReadRelationshipsRequest{ 87 RelationshipFilter: &v1.RelationshipFilter{ 88 ResourceType: "someresourcetype", 89 OptionalResourceId: "foo", 90 OptionalRelation: "somerelation2", 91 OptionalSubjectFilter: &v1.SubjectFilter{ 92 SubjectType: "somesubjectype", 93 OptionalSubjectId: "somesubject", 94 OptionalRelation: &v1.SubjectFilter_RelationFilter{ 95 Relation: "subrelation", 96 }, 97 }, 98 }, 99 OptionalLimit: 1000, 100 }, 101 "765b640f81f98ff5", 102 }, 103 { 104 "no subject filter", 105 &v1.ReadRelationshipsRequest{ 106 RelationshipFilter: &v1.RelationshipFilter{ 107 ResourceType: "someresourcetype", 108 OptionalResourceId: "foo", 109 OptionalRelation: "somerelation", 110 }, 111 OptionalLimit: 1000, 112 }, 113 "42abbaaaf9d6cb12", 114 }, 115 { 116 "different subject type", 117 &v1.ReadRelationshipsRequest{ 118 RelationshipFilter: &v1.RelationshipFilter{ 119 ResourceType: "someresourcetype", 120 OptionalResourceId: "foo", 121 OptionalRelation: "somerelation", 122 OptionalSubjectFilter: &v1.SubjectFilter{ 123 SubjectType: "somesubjectype2", 124 OptionalSubjectId: "somesubject", 125 OptionalRelation: &v1.SubjectFilter_RelationFilter{ 126 Relation: "subrelation", 127 }, 128 }, 129 }, 130 OptionalLimit: 1000, 131 }, 132 "55b37fccd04ae2df", 133 }, 134 { 135 "different subject id", 136 &v1.ReadRelationshipsRequest{ 137 RelationshipFilter: &v1.RelationshipFilter{ 138 ResourceType: "someresourcetype", 139 OptionalResourceId: "foo", 140 OptionalRelation: "somerelation", 141 OptionalSubjectFilter: &v1.SubjectFilter{ 142 SubjectType: "somesubjectype", 143 OptionalSubjectId: "somesubject2", 144 OptionalRelation: &v1.SubjectFilter_RelationFilter{ 145 Relation: "subrelation", 146 }, 147 }, 148 }, 149 OptionalLimit: 1000, 150 }, 151 "0ba2e49c26fb8ae1", 152 }, 153 { 154 "different subject relation", 155 &v1.ReadRelationshipsRequest{ 156 RelationshipFilter: &v1.RelationshipFilter{ 157 ResourceType: "someresourcetype", 158 OptionalResourceId: "foo", 159 OptionalRelation: "somerelation", 160 OptionalSubjectFilter: &v1.SubjectFilter{ 161 SubjectType: "somesubjectype", 162 OptionalSubjectId: "somesubject", 163 OptionalRelation: &v1.SubjectFilter_RelationFilter{ 164 Relation: "subrelation2", 165 }, 166 }, 167 }, 168 OptionalLimit: 1000, 169 }, 170 "73e715ccd9ea2225", 171 }, 172 { 173 "different limit", 174 &v1.ReadRelationshipsRequest{ 175 RelationshipFilter: &v1.RelationshipFilter{ 176 ResourceType: "someresourcetype", 177 OptionalResourceId: "foo", 178 OptionalRelation: "somerelation", 179 OptionalSubjectFilter: &v1.SubjectFilter{ 180 SubjectType: "somesubjectype", 181 OptionalSubjectId: "somesubject", 182 OptionalRelation: &v1.SubjectFilter_RelationFilter{ 183 Relation: "subrelation", 184 }, 185 }, 186 }, 187 OptionalLimit: 999, 188 }, 189 "7e7fdc450bf08327", 190 }, 191 } 192 193 for _, tc := range tcs { 194 tc := tc 195 t.Run(tc.name, func(t *testing.T) { 196 verr := tc.request.Validate() 197 require.NoError(t, verr) 198 199 hash, err := computeReadRelationshipsRequestHash(tc.request) 200 require.NoError(t, err) 201 require.Equal(t, tc.expectedHash, hash) 202 }) 203 } 204 } 205 206 func TestLRHashStability(t *testing.T) { 207 tcs := []struct { 208 name string 209 request *v1.LookupResourcesRequest 210 expectedHash string 211 }{ 212 { 213 "basic LR", 214 &v1.LookupResourcesRequest{ 215 ResourceObjectType: "resource", 216 Permission: "view", 217 Subject: &v1.SubjectReference{ 218 Object: &v1.ObjectReference{ 219 ObjectType: "user", 220 ObjectId: "tom", 221 }, 222 }, 223 Consistency: &v1.Consistency{ 224 Requirement: &v1.Consistency_MinimizeLatency{ 225 MinimizeLatency: true, 226 }, 227 }, 228 OptionalLimit: 1000, 229 }, 230 "f5c7ca6296253717", 231 }, 232 { 233 "different LR subject", 234 &v1.LookupResourcesRequest{ 235 ResourceObjectType: "resource", 236 Permission: "view", 237 Subject: &v1.SubjectReference{ 238 Object: &v1.ObjectReference{ 239 ObjectType: "user", 240 ObjectId: "sarah", 241 }, 242 }, 243 Consistency: &v1.Consistency{ 244 Requirement: &v1.Consistency_MinimizeLatency{ 245 MinimizeLatency: true, 246 }, 247 }, 248 OptionalLimit: 1000, 249 }, 250 "aa8b67b886ecf3fd", 251 }, 252 { 253 "different LR resource", 254 &v1.LookupResourcesRequest{ 255 ResourceObjectType: "resource2", 256 Permission: "view", 257 Subject: &v1.SubjectReference{ 258 Object: &v1.ObjectReference{ 259 ObjectType: "user", 260 ObjectId: "tom", 261 }, 262 }, 263 Consistency: &v1.Consistency{ 264 Requirement: &v1.Consistency_MinimizeLatency{ 265 MinimizeLatency: true, 266 }, 267 }, 268 OptionalLimit: 1000, 269 }, 270 "fb16e4dd9395864a", 271 }, 272 { 273 "different LR resource permission", 274 &v1.LookupResourcesRequest{ 275 ResourceObjectType: "resource", 276 Permission: "viewer", 277 Subject: &v1.SubjectReference{ 278 Object: &v1.ObjectReference{ 279 ObjectType: "user", 280 ObjectId: "tom", 281 }, 282 }, 283 Consistency: &v1.Consistency{ 284 Requirement: &v1.Consistency_MinimizeLatency{ 285 MinimizeLatency: true, 286 }, 287 }, 288 OptionalLimit: 1000, 289 }, 290 "593e60bf77f8bdb4", 291 }, 292 { 293 "different limit LR", 294 &v1.LookupResourcesRequest{ 295 ResourceObjectType: "resource", 296 Permission: "view", 297 Subject: &v1.SubjectReference{ 298 Object: &v1.ObjectReference{ 299 ObjectType: "user", 300 ObjectId: "sarah", 301 }, 302 }, 303 Consistency: &v1.Consistency{ 304 Requirement: &v1.Consistency_MinimizeLatency{ 305 MinimizeLatency: true, 306 }, 307 }, 308 OptionalLimit: 999, 309 }, 310 "0097cf2ee303ec31", 311 }, 312 { 313 "LR with different consistency", 314 &v1.LookupResourcesRequest{ 315 ResourceObjectType: "resource", 316 Permission: "view", 317 Subject: &v1.SubjectReference{ 318 Object: &v1.ObjectReference{ 319 ObjectType: "user", 320 ObjectId: "tom", 321 }, 322 }, 323 Consistency: &v1.Consistency{ 324 Requirement: &v1.Consistency_FullyConsistent{ 325 FullyConsistent: true, 326 }, 327 }, 328 OptionalLimit: 1000, 329 }, 330 "d8b707db35cb7043", 331 }, 332 { 333 "basic LR with caveat context", 334 &v1.LookupResourcesRequest{ 335 ResourceObjectType: "resource", 336 Permission: "view", 337 Subject: &v1.SubjectReference{ 338 Object: &v1.ObjectReference{ 339 ObjectType: "user", 340 ObjectId: "tom", 341 }, 342 }, 343 Consistency: &v1.Consistency{ 344 Requirement: &v1.Consistency_MinimizeLatency{ 345 MinimizeLatency: true, 346 }, 347 }, 348 OptionalLimit: 1000, 349 Context: func() *structpb.Struct { 350 s, _ := structpb.NewStruct(map[string]any{ 351 "somecondition": 42, 352 "anothercondition": "hello world", 353 }) 354 return s 355 }(), 356 }, 357 "d40193c84ec59e6f", 358 }, 359 { 360 "basic LR with different caveat context", 361 &v1.LookupResourcesRequest{ 362 ResourceObjectType: "resource", 363 Permission: "view", 364 Subject: &v1.SubjectReference{ 365 Object: &v1.ObjectReference{ 366 ObjectType: "user", 367 ObjectId: "tom", 368 }, 369 }, 370 Consistency: &v1.Consistency{ 371 Requirement: &v1.Consistency_MinimizeLatency{ 372 MinimizeLatency: true, 373 }, 374 }, 375 OptionalLimit: 1000, 376 Context: func() *structpb.Struct { 377 s, _ := structpb.NewStruct(map[string]any{ 378 "somecondition": 43, 379 "anothercondition": "hello world", 380 }) 381 return s 382 }(), 383 }, 384 "a5af756163998c88", 385 }, 386 } 387 388 for _, tc := range tcs { 389 tc := tc 390 t.Run(tc.name, func(t *testing.T) { 391 verr := tc.request.Validate() 392 require.NoError(t, verr) 393 394 hash, err := computeLRRequestHash(tc.request) 395 require.NoError(t, err) 396 require.Equal(t, tc.expectedHash, hash) 397 }) 398 } 399 } 400 401 func TestCheckBulkPermissionsItemWithoutResourceIDHashStability(t *testing.T) { 402 tcs := []struct { 403 name string 404 request *v1.CheckBulkPermissionsRequestItem 405 expectedHash string 406 }{ 407 { 408 "basic bulk check item", 409 &v1.CheckBulkPermissionsRequestItem{ 410 Resource: &v1.ObjectReference{ 411 ObjectType: "resource", 412 ObjectId: "someid", 413 }, 414 Permission: "view", 415 Subject: &v1.SubjectReference{ 416 Object: &v1.ObjectReference{ 417 ObjectType: "user", 418 ObjectId: "tom", 419 }, 420 }, 421 }, 422 "f518629690bd9dc0", 423 }, 424 { 425 "different resource ID, should still be the same hash", 426 &v1.CheckBulkPermissionsRequestItem{ 427 Resource: &v1.ObjectReference{ 428 ObjectType: "resource", 429 ObjectId: "someid2", 430 }, 431 Permission: "view", 432 Subject: &v1.SubjectReference{ 433 Object: &v1.ObjectReference{ 434 ObjectType: "user", 435 ObjectId: "tom", 436 }, 437 }, 438 }, 439 "f518629690bd9dc0", 440 }, 441 { 442 "basic bulk check item - transcribed letter", 443 &v1.CheckBulkPermissionsRequestItem{ 444 Resource: &v1.ObjectReference{ 445 ObjectType: "resourc", 446 ObjectId: "esomeid", 447 }, 448 Permission: "view", 449 Subject: &v1.SubjectReference{ 450 Object: &v1.ObjectReference{ 451 ObjectType: "user", 452 ObjectId: "tom", 453 }, 454 }, 455 }, 456 "60f1e177297e915e", 457 }, 458 { 459 "different resource type", 460 &v1.CheckBulkPermissionsRequestItem{ 461 Resource: &v1.ObjectReference{ 462 ObjectType: "resource2", 463 ObjectId: "someid", 464 }, 465 Permission: "view", 466 Subject: &v1.SubjectReference{ 467 Object: &v1.ObjectReference{ 468 ObjectType: "user", 469 ObjectId: "tom", 470 }, 471 }, 472 }, 473 "5117abaee3adf638", 474 }, 475 { 476 "different permission", 477 &v1.CheckBulkPermissionsRequestItem{ 478 Resource: &v1.ObjectReference{ 479 ObjectType: "resource", 480 ObjectId: "someid", 481 }, 482 Permission: "view2", 483 Subject: &v1.SubjectReference{ 484 Object: &v1.ObjectReference{ 485 ObjectType: "user", 486 ObjectId: "tom", 487 }, 488 }, 489 }, 490 "716f7be27e600292", 491 }, 492 { 493 "different subject type", 494 &v1.CheckBulkPermissionsRequestItem{ 495 Resource: &v1.ObjectReference{ 496 ObjectType: "resource", 497 ObjectId: "someid", 498 }, 499 Permission: "view", 500 Subject: &v1.SubjectReference{ 501 Object: &v1.ObjectReference{ 502 ObjectType: "user2", 503 ObjectId: "tom", 504 }, 505 }, 506 }, 507 "7cb5945314ccbdce", 508 }, 509 { 510 "different subject id", 511 &v1.CheckBulkPermissionsRequestItem{ 512 Resource: &v1.ObjectReference{ 513 ObjectType: "resource", 514 ObjectId: "someid", 515 }, 516 Permission: "view", 517 Subject: &v1.SubjectReference{ 518 Object: &v1.ObjectReference{ 519 ObjectType: "user", 520 ObjectId: "tom2", 521 }, 522 }, 523 }, 524 "b24ecacf87fd0bb8", 525 }, 526 { 527 "different subject relation", 528 &v1.CheckBulkPermissionsRequestItem{ 529 Resource: &v1.ObjectReference{ 530 ObjectType: "resource", 531 ObjectId: "someid", 532 }, 533 Permission: "view", 534 Subject: &v1.SubjectReference{ 535 Object: &v1.ObjectReference{ 536 ObjectType: "user", 537 ObjectId: "tom", 538 }, 539 OptionalRelation: "foo", 540 }, 541 }, 542 "ee8c34ab206c80d7", 543 }, 544 { 545 "with context", 546 &v1.CheckBulkPermissionsRequestItem{ 547 Resource: &v1.ObjectReference{ 548 ObjectType: "resource", 549 ObjectId: "someid", 550 }, 551 Permission: "view", 552 Subject: &v1.SubjectReference{ 553 Object: &v1.ObjectReference{ 554 ObjectType: "user", 555 ObjectId: "tom", 556 }, 557 OptionalRelation: "foo", 558 }, 559 Context: func() *structpb.Struct { 560 s, _ := structpb.NewStruct(map[string]any{ 561 "somecondition": 42, 562 "anothercondition": "hello world", 563 }) 564 return s 565 }(), 566 }, 567 "7a5b1fec3cbed446", 568 }, 569 { 570 "with different context", 571 &v1.CheckBulkPermissionsRequestItem{ 572 Resource: &v1.ObjectReference{ 573 ObjectType: "resource", 574 ObjectId: "someid", 575 }, 576 Permission: "view", 577 Subject: &v1.SubjectReference{ 578 Object: &v1.ObjectReference{ 579 ObjectType: "user", 580 ObjectId: "tom", 581 }, 582 OptionalRelation: "foo", 583 }, 584 Context: func() *structpb.Struct { 585 s, _ := structpb.NewStruct(map[string]any{ 586 "somecondition": 42, 587 "anothercondition": "hi there", 588 }) 589 return s 590 }(), 591 }, 592 "f17da513a6207c30", 593 }, 594 } 595 596 for _, tc := range tcs { 597 tc := tc 598 t.Run(tc.name, func(t *testing.T) { 599 verr := tc.request.Validate() 600 require.NoError(t, verr) 601 602 hash, err := computeCheckBulkPermissionsItemHashWithoutResourceID(tc.request) 603 require.NoError(t, err) 604 require.Equal(t, tc.expectedHash, hash) 605 }) 606 } 607 } 608 609 func TestCheckBulkPermissionsItemWIDHashStability(t *testing.T) { 610 tcs := []struct { 611 name string 612 request *v1.CheckBulkPermissionsRequestItem 613 expectedHash string 614 }{ 615 { 616 "basic bulk check item", 617 &v1.CheckBulkPermissionsRequestItem{ 618 Resource: &v1.ObjectReference{ 619 ObjectType: "resource", 620 ObjectId: "someid", 621 }, 622 Permission: "view", 623 Subject: &v1.SubjectReference{ 624 Object: &v1.ObjectReference{ 625 ObjectType: "user", 626 ObjectId: "tom", 627 }, 628 }, 629 }, 630 "5edbb3bbb8079754", 631 }, 632 { 633 "different resource ID, should be a different hash", 634 &v1.CheckBulkPermissionsRequestItem{ 635 Resource: &v1.ObjectReference{ 636 ObjectType: "resource", 637 ObjectId: "someid2", 638 }, 639 Permission: "view", 640 Subject: &v1.SubjectReference{ 641 Object: &v1.ObjectReference{ 642 ObjectType: "user", 643 ObjectId: "tom", 644 }, 645 }, 646 }, 647 "e6711064500e65ba", 648 }, 649 { 650 "basic bulk check item - transcribed letter", 651 &v1.CheckBulkPermissionsRequestItem{ 652 Resource: &v1.ObjectReference{ 653 ObjectType: "resourc", 654 ObjectId: "esomeid", 655 }, 656 Permission: "view", 657 Subject: &v1.SubjectReference{ 658 Object: &v1.ObjectReference{ 659 ObjectType: "user", 660 ObjectId: "tom", 661 }, 662 }, 663 }, 664 "8cda00b7188572b7", 665 }, 666 { 667 "different resource type", 668 &v1.CheckBulkPermissionsRequestItem{ 669 Resource: &v1.ObjectReference{ 670 ObjectType: "resource2", 671 ObjectId: "someid", 672 }, 673 Permission: "view", 674 Subject: &v1.SubjectReference{ 675 Object: &v1.ObjectReference{ 676 ObjectType: "user", 677 ObjectId: "tom", 678 }, 679 }, 680 }, 681 "51df43a69e51d3b0", 682 }, 683 { 684 "different permission", 685 &v1.CheckBulkPermissionsRequestItem{ 686 Resource: &v1.ObjectReference{ 687 ObjectType: "resource", 688 ObjectId: "someid", 689 }, 690 Permission: "view2", 691 Subject: &v1.SubjectReference{ 692 Object: &v1.ObjectReference{ 693 ObjectType: "user", 694 ObjectId: "tom", 695 }, 696 }, 697 }, 698 "62aaa50b2821130d", 699 }, 700 { 701 "different subject type", 702 &v1.CheckBulkPermissionsRequestItem{ 703 Resource: &v1.ObjectReference{ 704 ObjectType: "resource", 705 ObjectId: "someid", 706 }, 707 Permission: "view", 708 Subject: &v1.SubjectReference{ 709 Object: &v1.ObjectReference{ 710 ObjectType: "user2", 711 ObjectId: "tom", 712 }, 713 }, 714 }, 715 "82a445d3ffc0823a", 716 }, 717 { 718 "different subject id", 719 &v1.CheckBulkPermissionsRequestItem{ 720 Resource: &v1.ObjectReference{ 721 ObjectType: "resource", 722 ObjectId: "someid", 723 }, 724 Permission: "view", 725 Subject: &v1.SubjectReference{ 726 Object: &v1.ObjectReference{ 727 ObjectType: "user", 728 ObjectId: "tom2", 729 }, 730 }, 731 }, 732 "d3d624a310fa7781", 733 }, 734 { 735 "different subject relation", 736 &v1.CheckBulkPermissionsRequestItem{ 737 Resource: &v1.ObjectReference{ 738 ObjectType: "resource", 739 ObjectId: "someid", 740 }, 741 Permission: "view", 742 Subject: &v1.SubjectReference{ 743 Object: &v1.ObjectReference{ 744 ObjectType: "user", 745 ObjectId: "tom", 746 }, 747 OptionalRelation: "foo", 748 }, 749 }, 750 "a9d96f0572caef89", 751 }, 752 { 753 "with context", 754 &v1.CheckBulkPermissionsRequestItem{ 755 Resource: &v1.ObjectReference{ 756 ObjectType: "resource", 757 ObjectId: "someid", 758 }, 759 Permission: "view", 760 Subject: &v1.SubjectReference{ 761 Object: &v1.ObjectReference{ 762 ObjectType: "user", 763 ObjectId: "tom", 764 }, 765 OptionalRelation: "foo", 766 }, 767 Context: func() *structpb.Struct { 768 s, _ := structpb.NewStruct(map[string]any{ 769 "somecondition": 42, 770 "anothercondition": "hello world", 771 }) 772 return s 773 }(), 774 }, 775 "94dea3fccff039ed", 776 }, 777 { 778 "with different context", 779 &v1.CheckBulkPermissionsRequestItem{ 780 Resource: &v1.ObjectReference{ 781 ObjectType: "resource", 782 ObjectId: "someid", 783 }, 784 Permission: "view", 785 Subject: &v1.SubjectReference{ 786 Object: &v1.ObjectReference{ 787 ObjectType: "user", 788 ObjectId: "tom", 789 }, 790 OptionalRelation: "foo", 791 }, 792 Context: func() *structpb.Struct { 793 s, _ := structpb.NewStruct(map[string]any{ 794 "somecondition": 42, 795 "anothercondition": "hi there", 796 }) 797 return s 798 }(), 799 }, 800 "7ffdedbe12d578ee", 801 }, 802 } 803 804 for _, tc := range tcs { 805 tc := tc 806 t.Run(tc.name, func(t *testing.T) { 807 verr := tc.request.Validate() 808 require.NoError(t, verr) 809 810 hash, err := computeCheckBulkPermissionsItemHash(tc.request) 811 require.NoError(t, err) 812 require.Equal(t, tc.expectedHash, hash) 813 }) 814 } 815 } 816 817 func TestLSHashStability(t *testing.T) { 818 tcs := []struct { 819 name string 820 request *v1.LookupSubjectsRequest 821 expectedHash string 822 }{ 823 { 824 "basic LS", 825 &v1.LookupSubjectsRequest{ 826 SubjectObjectType: "subject", 827 Permission: "view", 828 Resource: &v1.ObjectReference{ 829 ObjectType: "resource", 830 ObjectId: "somedoc", 831 }, 832 Consistency: &v1.Consistency{ 833 Requirement: &v1.Consistency_MinimizeLatency{ 834 MinimizeLatency: true, 835 }, 836 }, 837 OptionalConcreteLimit: 1000, 838 }, 839 "15f87f570009e190", 840 }, 841 { 842 "different subject", 843 &v1.LookupSubjectsRequest{ 844 SubjectObjectType: "subject2", 845 Permission: "view", 846 Resource: &v1.ObjectReference{ 847 ObjectType: "resource", 848 ObjectId: "somedoc", 849 }, 850 Consistency: &v1.Consistency{ 851 Requirement: &v1.Consistency_MinimizeLatency{ 852 MinimizeLatency: true, 853 }, 854 }, 855 OptionalConcreteLimit: 1000, 856 }, 857 "a41898256f42203a", 858 }, 859 { 860 "different permission", 861 &v1.LookupSubjectsRequest{ 862 SubjectObjectType: "subject", 863 Permission: "view2", 864 Resource: &v1.ObjectReference{ 865 ObjectType: "resource", 866 ObjectId: "somedoc", 867 }, 868 Consistency: &v1.Consistency{ 869 Requirement: &v1.Consistency_MinimizeLatency{ 870 MinimizeLatency: true, 871 }, 872 }, 873 OptionalConcreteLimit: 1000, 874 }, 875 "5dbe04c00a1cd2b0", 876 }, 877 { 878 "different resource type", 879 &v1.LookupSubjectsRequest{ 880 SubjectObjectType: "subject", 881 Permission: "view", 882 Resource: &v1.ObjectReference{ 883 ObjectType: "resource2", 884 ObjectId: "somedoc", 885 }, 886 Consistency: &v1.Consistency{ 887 Requirement: &v1.Consistency_MinimizeLatency{ 888 MinimizeLatency: true, 889 }, 890 }, 891 OptionalConcreteLimit: 1000, 892 }, 893 "0ede1ecdd53c204f", 894 }, 895 { 896 "different resource id", 897 &v1.LookupSubjectsRequest{ 898 SubjectObjectType: "subject", 899 Permission: "view", 900 Resource: &v1.ObjectReference{ 901 ObjectType: "resource", 902 ObjectId: "somedoc2", 903 }, 904 Consistency: &v1.Consistency{ 905 Requirement: &v1.Consistency_MinimizeLatency{ 906 MinimizeLatency: true, 907 }, 908 }, 909 OptionalConcreteLimit: 1000, 910 }, 911 "5f957ee550300986", 912 }, 913 { 914 "no limit", 915 &v1.LookupSubjectsRequest{ 916 SubjectObjectType: "subject", 917 Permission: "view", 918 Resource: &v1.ObjectReference{ 919 ObjectType: "resource", 920 ObjectId: "somedoc", 921 }, 922 Consistency: &v1.Consistency{ 923 Requirement: &v1.Consistency_MinimizeLatency{ 924 MinimizeLatency: true, 925 }, 926 }, 927 }, 928 "dc3f5673a6a3d173", 929 }, 930 { 931 "different limit", 932 &v1.LookupSubjectsRequest{ 933 SubjectObjectType: "subject", 934 Permission: "view", 935 Resource: &v1.ObjectReference{ 936 ObjectType: "resource", 937 ObjectId: "somedoc", 938 }, 939 Consistency: &v1.Consistency{ 940 Requirement: &v1.Consistency_MinimizeLatency{ 941 MinimizeLatency: true, 942 }, 943 }, 944 OptionalConcreteLimit: 999, 945 }, 946 "3b350c4c36efb985", 947 }, 948 { 949 "default wildcard option", 950 &v1.LookupSubjectsRequest{ 951 SubjectObjectType: "subject", 952 Permission: "view", 953 Resource: &v1.ObjectReference{ 954 ObjectType: "resource", 955 ObjectId: "somedoc", 956 }, 957 Consistency: &v1.Consistency{ 958 Requirement: &v1.Consistency_MinimizeLatency{ 959 MinimizeLatency: true, 960 }, 961 }, 962 OptionalConcreteLimit: 1000, 963 WildcardOption: v1.LookupSubjectsRequest_WILDCARD_OPTION_UNSPECIFIED, 964 }, 965 "15f87f570009e190", 966 }, 967 { 968 "different wildcard option", 969 &v1.LookupSubjectsRequest{ 970 SubjectObjectType: "subject", 971 Permission: "view", 972 Resource: &v1.ObjectReference{ 973 ObjectType: "resource", 974 ObjectId: "somedoc", 975 }, 976 Consistency: &v1.Consistency{ 977 Requirement: &v1.Consistency_MinimizeLatency{ 978 MinimizeLatency: true, 979 }, 980 }, 981 OptionalConcreteLimit: 1000, 982 WildcardOption: v1.LookupSubjectsRequest_WILDCARD_OPTION_EXCLUDE_WILDCARDS, 983 }, 984 "df28dbb33cdcc8dd", 985 }, 986 } 987 988 for _, tc := range tcs { 989 tc := tc 990 t.Run(tc.name, func(t *testing.T) { 991 verr := tc.request.Validate() 992 require.NoError(t, verr) 993 994 hash, err := computeLSRequestHash(tc.request) 995 require.NoError(t, err) 996 require.Equal(t, tc.expectedHash, hash) 997 }) 998 } 999 }