5858@ ThreadLeakScope (ThreadLeakScope .Scope .NONE )
5959public class DataStreamAuthorizationReadOnlyIntTests {
6060
61+ // -------------------------------------------------------------------------------------------------------
62+ // Test data streams and indices used by this test suite. Indices are usually initially created; the only
63+ // exception is ds_ax, which is referred to in tests, but which does not exist on purpose.
64+ // -------------------------------------------------------------------------------------------------------
65+
6166 static TestDataStream ds_a1 = TestDataStream .name ("ds_a1" ).documentCount (100 ).rolloverAfter (10 ).seed (1 ).build ();
6267 static TestDataStream ds_a2 = TestDataStream .name ("ds_a2" ).documentCount (110 ).rolloverAfter (10 ).seed (2 ).build ();
6368 static TestDataStream ds_a3 = TestDataStream .name ("ds_a3" ).documentCount (120 ).rolloverAfter (10 ).seed (3 ).build ();
@@ -78,6 +83,18 @@ public class DataStreamAuthorizationReadOnlyIntTests {
7883 openSearchSecurityConfigIndex ()
7984 );
8085
86+ static final List <TestIndexOrAliasOrDatastream > ALL_DATA_STREAMS = List .of (ds_a1 , ds_a2 , ds_a3 , ds_b1 , ds_b2 , ds_b3 );
87+
88+ // -------------------------------------------------------------------------------------------------------
89+ // Test users with which the tests will be executed; the users need to be added to the list USERS below
90+ // The users have two redundant versions or privilege configuration, which needs to be kept in sync:
91+ // - The standard role configuration defined with .roles()
92+ // - IndexMatchers which act as test oracles, defined with the indexMatcher() methods
93+ // -------------------------------------------------------------------------------------------------------
94+
95+ /**
96+ * A simple user that can read from ds_a*
97+ */
8198 static TestSecurityConfig .User LIMITED_USER_A = new TestSecurityConfig .User ("limited_user_A" )//
8299 .description ("ds_a*" )//
83100 .roles (
@@ -94,6 +111,9 @@ public class DataStreamAuthorizationReadOnlyIntTests {
94111 )//
95112 .indexMatcher ("read" , limitedTo (ds_a1 , ds_a2 , ds_a3 , ds_ax ));
96113
114+ /**
115+ * A simple user that can read from ds_b*
116+ */
97117 static TestSecurityConfig .User LIMITED_USER_B = new TestSecurityConfig .User ("limited_user_B" )//
98118 .description ("ds_b*" )//
99119 .roles (
@@ -110,6 +130,9 @@ public class DataStreamAuthorizationReadOnlyIntTests {
110130 )//
111131 .indexMatcher ("read" , limitedTo (ds_b1 , ds_b2 , ds_b3 ));
112132
133+ /**
134+ * A simple user that can read from ds_b1
135+ */
113136 static TestSecurityConfig .User LIMITED_USER_B1 = new TestSecurityConfig .User ("limited_user_B1" )//
114137 .description ("ds_b1" )//
115138 .roles (
@@ -126,7 +149,11 @@ public class DataStreamAuthorizationReadOnlyIntTests {
126149 )//
127150 .indexMatcher ("read" , limitedTo (ds_b1 ));
128151
129- static TestSecurityConfig .User LIMITED_USER_NONE = new TestSecurityConfig .User ("limited_user_none" )//
152+ /**
153+ * This user has no privileges for indices that are used in this test. But they have privileges for other indices.
154+ * This allows them to use actions like _search and receive empty result sets.
155+ */
156+ static TestSecurityConfig .User LIMITED_USER_OTHER_PRIVILEGES = new TestSecurityConfig .User ("limited_user_other_index_privileges" )//
130157 .description ("no privileges for existing indices" )//
131158 .roles (
132159 new TestSecurityConfig .Role ("r1" )//
@@ -142,6 +169,10 @@ public class DataStreamAuthorizationReadOnlyIntTests {
142169 )//
143170 .indexMatcher ("read" , limitedToNone ());
144171
172+ /**
173+ * A user with "*" privileges on "*"; as it is a regular user, they are still subject to system index
174+ * restrictions and similar things.
175+ */
145176 static TestSecurityConfig .User UNLIMITED_USER = new TestSecurityConfig .User ("unlimited_user" )//
146177 .description ("unlimited" )//
147178 .roles (
@@ -165,7 +196,7 @@ public class DataStreamAuthorizationReadOnlyIntTests {
165196 LIMITED_USER_A ,
166197 LIMITED_USER_B ,
167198 LIMITED_USER_B1 ,
168- LIMITED_USER_NONE ,
199+ LIMITED_USER_OTHER_PRIVILEGES ,
169200 UNLIMITED_USER ,
170201 SUPER_UNLIMITED_USER
171202 );
@@ -230,7 +261,7 @@ public void search_noPattern_allowNoIndicesFalse() throws Exception {
230261
231262 assertThat (
232263 httpResponse ,
233- containsExactly (ds_a1 , ds_a2 , ds_a3 , ds_b1 , ds_b2 , ds_b3 , index_c1 ).at ("hits.hits[*]._index" )
264+ containsExactly (ALL_INDICES ).at ("hits.hits[*]._index" )
234265 .reducedBy (user .indexMatcher ("read" ))
235266 .whenEmpty (clusterConfig .allowsEmptyResultSets ? isNotFound () : isForbidden ())
236267 );
@@ -243,7 +274,7 @@ public void search_all() throws Exception {
243274 TestRestClient .HttpResponse httpResponse = restClient .get ("_all/_search?size=1000" );
244275 assertThat (
245276 httpResponse ,
246- containsExactly (ds_a1 , ds_a2 , ds_a3 , ds_b1 , ds_b2 , ds_b3 , index_c1 ).at ("hits.hits[*]._index" )
277+ containsExactly (ALL_INDICES ).at ("hits.hits[*]._index" )
247278 .reducedBy (user .indexMatcher ("read" ))
248279 .whenEmpty (clusterConfig .allowsEmptyResultSets ? isOk () : isForbidden ())
249280 );
@@ -276,7 +307,7 @@ public void search_wildcard() throws Exception {
276307 TestRestClient .HttpResponse httpResponse = restClient .get ("*/_search?size=1000" );
277308 assertThat (
278309 httpResponse ,
279- containsExactly (ds_a1 , ds_a2 , ds_a3 , ds_b1 , ds_b2 , ds_b3 , index_c1 ).at ("hits.hits[*]._index" )
310+ containsExactly (ALL_INDICES ).at ("hits.hits[*]._index" )
280311 .reducedBy (user .indexMatcher ("read" ))
281312 .whenEmpty (clusterConfig .allowsEmptyResultSets ? isOk () : isForbidden ())
282313 );
@@ -483,7 +514,7 @@ public void search_termsAggregation_index() throws Exception {
483514 if (user == SUPER_UNLIMITED_USER || user == UNLIMITED_USER ) {
484515 assertThat (
485516 httpResponse ,
486- containsExactly (ds_a1 , ds_a2 , ds_a3 , ds_b1 , ds_b2 , ds_b3 , index_c1 ).at ("aggregations.indices.buckets[*].key" )
517+ containsExactly (ALL_INDICES ).at ("aggregations.indices.buckets[*].key" )
487518 .reducedBy (user .indexMatcher ("read" ))
488519 .whenEmpty (isOk ())
489520 );
@@ -520,7 +551,7 @@ public void index_stats_all() throws Exception {
520551 TestRestClient .HttpResponse httpResponse = restClient .get ("_stats" );
521552 assertThat (
522553 httpResponse ,
523- containsExactly (ds_a1 , ds_a2 , ds_a3 , ds_b1 , ds_b2 , ds_b3 , index_c1 ).at ("indices.keys()" )
554+ containsExactly (ALL_INDICES ).at ("indices.keys()" )
524555 .reducedBy (user .indexMatcher ("read" ))
525556 .whenEmpty (clusterConfig .allowsEmptyResultSets ? isOk () : isForbidden ())
526557 );
@@ -547,7 +578,7 @@ public void getDataStream_all() throws Exception {
547578 // The legacy mode does not support dnfof for indices:admin/data_stream/get
548579 assertThat (
549580 httpResponse ,
550- containsExactly (ds_a1 , ds_a2 , ds_a3 , ds_b1 , ds_b2 , ds_b3 ).at ("$.data_streams[*].name" )
581+ containsExactly (ALL_DATA_STREAMS ).at ("$.data_streams[*].name" )
551582 .butForbiddenIfIncomplete (user .indexMatcher ("read" ))
552583 );
553584 }
@@ -560,7 +591,7 @@ public void getDataStream_wildcard() throws Exception {
560591 // The legacy mode does not support dnfof for indices:admin/data_stream/get
561592 assertThat (
562593 httpResponse ,
563- containsExactly (ds_a1 , ds_a2 , ds_a3 , ds_b1 , ds_b2 , ds_b3 ).at ("$.data_streams[*].name" )
594+ containsExactly (ALL_DATA_STREAMS ).at ("$.data_streams[*].name" )
564595 .butForbiddenIfIncomplete (user .indexMatcher ("read" ))
565596 );
566597 }
@@ -608,7 +639,7 @@ public void getDataStreamStats_all() throws Exception {
608639 // The legacy mode does not support dnfof for indices:monitor/data_stream/stats
609640 assertThat (
610641 httpResponse ,
611- containsExactly (ds_a1 , ds_a2 , ds_a3 , ds_b1 , ds_b2 , ds_b3 ).at ("$.data_streams[*].data_stream" )
642+ containsExactly (ALL_DATA_STREAMS ).at ("$.data_streams[*].data_stream" )
612643 .butForbiddenIfIncomplete (user .indexMatcher ("read" ))
613644 );
614645 }
@@ -621,7 +652,7 @@ public void getDataStreamStats_wildcard() throws Exception {
621652 // The legacy mode does not support dnfof for indices:monitor/data_stream/stats
622653 assertThat (
623654 httpResponse ,
624- containsExactly (ds_a1 , ds_a2 , ds_a3 , ds_b1 , ds_b2 , ds_b3 ).at ("$.data_streams[*].data_stream" )
655+ containsExactly (ALL_DATA_STREAMS ).at ("$.data_streams[*].data_stream" )
625656 .butForbiddenIfIncomplete (user .indexMatcher ("read" ))
626657 );
627658 }
@@ -656,7 +687,7 @@ public void resolve_wildcard() throws Exception {
656687 TestRestClient .HttpResponse httpResponse = restClient .get ("_resolve/index/*" );
657688 assertThat (
658689 httpResponse ,
659- containsExactly (ds_a1 , ds_a2 , ds_a3 , ds_b1 , ds_b2 , ds_b3 , index_c1 ).at ("$.*[*].name" )
690+ containsExactly (ALL_INDICES ).at ("$.*[*].name" )
660691 .reducedBy (user .indexMatcher ("read" ))
661692 .whenEmpty (clusterConfig .allowsEmptyResultSets ? isOk () : isForbidden ())
662693 );
@@ -682,7 +713,7 @@ public void field_caps_all() throws Exception {
682713 TestRestClient .HttpResponse httpResponse = restClient .get ("_field_caps?fields=*" );
683714 assertThat (
684715 httpResponse ,
685- containsExactly (ds_a1 , ds_a2 , ds_a3 , ds_b1 , ds_b2 , ds_b3 , index_c1 ).at ("indices" )
716+ containsExactly (ALL_INDICES ).at ("indices" )
686717 .reducedBy (user .indexMatcher ("read" ))
687718 .whenEmpty (clusterConfig .allowsEmptyResultSets ? isOk () : isForbidden ())
688719 );
0 commit comments