@@ -57,6 +57,10 @@ type mySubjectMappingClient struct {
57
57
sm.SubjectMappingServiceClient
58
58
}
59
59
60
+ type paginatedMockSubjectMappingClient struct {
61
+ sm.SubjectMappingServiceClient
62
+ }
63
+
60
64
func (* mySubjectMappingClient ) ListSubjectMappings (_ context.Context , _ * sm.ListSubjectMappingsRequest , _ ... grpc.CallOption ) (* sm.ListSubjectMappingsResponse , error ) {
61
65
return & listSubjectMappings , nil
62
66
}
@@ -69,6 +73,52 @@ func (*myERSClient) ResolveEntities(_ context.Context, _ *entityresolution.Resol
69
73
return & resolveEntitiesResp , nil
70
74
}
71
75
76
+ var (
77
+ smPaginationOffset = 3
78
+ smListCallCount = 0
79
+ )
80
+
81
+ func (* paginatedMockSubjectMappingClient ) ListSubjectMappings (_ context.Context , _ * sm.ListSubjectMappingsRequest , _ ... grpc.CallOption ) (* sm.ListSubjectMappingsResponse , error ) {
82
+ smListCallCount ++
83
+ // simulate paginated list and policy LIST behavior
84
+ if smPaginationOffset > 0 {
85
+ rsp := & sm.ListSubjectMappingsResponse {
86
+ SubjectMappings : nil ,
87
+ Pagination : & policy.PageResponse {
88
+ NextOffset : int32 (smPaginationOffset ),
89
+ },
90
+ }
91
+ smPaginationOffset = 0
92
+ return rsp , nil
93
+ }
94
+ return & listSubjectMappings , nil
95
+ }
96
+
97
+ type paginatedMockAttributesClient struct {
98
+ attr.AttributesServiceClient
99
+ }
100
+
101
+ var (
102
+ attrPaginationOffset = 3
103
+ attrListCallCount = 0
104
+ )
105
+
106
+ func (* paginatedMockAttributesClient ) ListAttributes (_ context.Context , _ * attr.ListAttributesRequest , _ ... grpc.CallOption ) (* attr.ListAttributesResponse , error ) {
107
+ attrListCallCount ++
108
+ // simulate paginated list and policy LIST behavior
109
+ if attrPaginationOffset > 0 {
110
+ rsp := & attr.ListAttributesResponse {
111
+ Attributes : nil ,
112
+ Pagination : & policy.PageResponse {
113
+ NextOffset : int32 (attrPaginationOffset ),
114
+ },
115
+ }
116
+ attrPaginationOffset = 0
117
+ return rsp , nil
118
+ }
119
+ return & listAttributeResp , nil
120
+ }
121
+
72
122
func TestGetComprehensiveHierarchy (t * testing.T ) {
73
123
as := & AuthorizationService {
74
124
logger : logger .CreateTestLogger (),
@@ -763,6 +813,91 @@ func Test_GetEntitlementsFqnCasing(t *testing.T) {
763
813
assert .Equal (t , []string {"https://www.example.org/attr/foo/value/value1" }, resp .Msg .GetEntitlements ()[0 ].GetAttributeValueFqns ())
764
814
}
765
815
816
+ func Test_GetEntitlements_HandlesPagination (t * testing.T ) {
817
+ logger := logger .CreateTestLogger ()
818
+
819
+ listAttributeResp = attr.ListAttributesResponse {}
820
+ attrDef := policy.Attribute {
821
+ Name : mockAttrName ,
822
+ Namespace : & policy.Namespace {
823
+ Name : mockNamespace ,
824
+ },
825
+ Rule : policy .AttributeRuleTypeEnum_ATTRIBUTE_RULE_TYPE_ENUM_ALL_OF ,
826
+ Values : []* policy.Value {
827
+ {
828
+ Value : mockAttrValue1 ,
829
+ },
830
+ {
831
+ Value : mockAttrValue2 ,
832
+ },
833
+ },
834
+ }
835
+ listAttributeResp .Attributes = []* policy.Attribute {& attrDef }
836
+ userRepresentation := map [string ]interface {}{
837
+ "A" : "B" ,
838
+ "C" : "D" ,
839
+ }
840
+ userStruct , _ := structpb .NewStruct (userRepresentation )
841
+ resolveEntitiesResp = entityresolution.ResolveEntitiesResponse {
842
+ EntityRepresentations : []* entityresolution.EntityRepresentation {
843
+ {
844
+ OriginalId : "e1" ,
845
+ AdditionalProps : []* structpb.Struct {
846
+ userStruct ,
847
+ },
848
+ },
849
+ },
850
+ }
851
+
852
+ ctxb := context .Background ()
853
+
854
+ rego := rego .New (
855
+ rego .Query ("data.example.p" ),
856
+ rego .Module ("example.rego" ,
857
+ `package example
858
+ p = {"e1":["https://www.example.org/attr/foo/value/value1"]} { true }` ,
859
+ ))
860
+
861
+ // Run evaluation.
862
+ prepared , err := rego .PrepareForEval (ctxb )
863
+ require .NoError (t , err )
864
+
865
+ as := AuthorizationService {
866
+ logger : logger , sdk : & otdf.SDK {
867
+ SubjectMapping : & paginatedMockSubjectMappingClient {},
868
+ Attributes : & paginatedMockAttributesClient {},
869
+ EntityResoution : & myERSClient {},
870
+ },
871
+ eval : prepared ,
872
+ }
873
+
874
+ req := connect.Request [authorization.GetEntitlementsRequest ]{
875
+ Msg : & authorization.GetEntitlementsRequest {
876
+ Entities : []* authorization.Entity {{Id : "e1" , EntityType : & authorization.Entity_ClientId {ClientId : "testclient" }, Category : authorization .Entity_CATEGORY_ENVIRONMENT }},
877
+ // Using mixed case here
878
+ Scope : & authorization.ResourceAttribute {AttributeValueFqns : []string {"https://www.example.org/attr/foo/value/VaLuE1" }},
879
+ },
880
+ }
881
+
882
+ for fqn := range makeScopeMap (req .Msg .GetScope ()) {
883
+ assert .Equal (t , fqn , strings .ToLower (fqn ))
884
+ }
885
+
886
+ resp , err := as .GetEntitlements (ctxb , & req )
887
+
888
+ require .NoError (t , err )
889
+ assert .NotNil (t , resp )
890
+ assert .Len (t , resp .Msg .GetEntitlements (), 1 )
891
+ assert .Equal (t , "e1" , resp .Msg .GetEntitlements ()[0 ].GetEntityId ())
892
+ assert .Equal (t , []string {"https://www.example.org/attr/foo/value/value1" }, resp .Msg .GetEntitlements ()[0 ].GetAttributeValueFqns ())
893
+
894
+ // paginated successfully
895
+ assert .Equal (t , 2 , smListCallCount )
896
+ assert .Zero (t , smPaginationOffset )
897
+ assert .Equal (t , 2 , attrListCallCount )
898
+ assert .Zero (t , attrPaginationOffset )
899
+ }
900
+
766
901
func Test_GetEntitlementsWithComprehensiveHierarchy (t * testing.T ) {
767
902
logger := logger .CreateTestLogger ()
768
903
attrDef := policy.Attribute {
0 commit comments