1919import java .util .Map ;
2020import java .util .Random ;
2121import java .util .Set ;
22+ import java .util .function .Supplier ;
2223import java .util .stream .Collectors ;
2324
2425import com .google .common .collect .ImmutableList ;
3132import org .junit .runners .Suite ;
3233
3334import org .opensearch .action .support .IndicesOptions ;
35+ import org .opensearch .cluster .ClusterName ;
36+ import org .opensearch .cluster .ClusterState ;
3437import org .opensearch .cluster .metadata .IndexAbstraction ;
3538import org .opensearch .cluster .metadata .IndexMetadata ;
3639import org .opensearch .cluster .metadata .IndexNameExpressionResolver ;
40+ import org .opensearch .cluster .metadata .Metadata ;
3741import org .opensearch .common .settings .Settings ;
3842import org .opensearch .common .util .concurrent .ThreadContext ;
3943import org .opensearch .core .common .unit .ByteSizeUnit ;
@@ -960,6 +964,43 @@ public void aliasesOnDataStreamBackingIndices() throws Exception {
960964 );
961965 assertThat (resultForIndexNotCoveredByAlias , isForbidden ());
962966 }
967+
968+ /**
969+ * Tests the behavior of hasIndexPrivilege when the resolved indices are empty.
970+ * @throws Exception If failed.
971+ */
972+ @ Test
973+ public void hasIndexPrivilegeEmptyResolvedIndices () throws Exception {
974+ SecurityDynamicConfiguration <RoleV7 > roles = SecurityDynamicConfiguration .fromYaml (
975+ "test_role:\n "
976+ + " index_permissions:\n "
977+ + " - index_patterns: ['*']\n "
978+ + " allowed_actions: ['indices:monitor/recovery']" ,
979+ CType .ROLES
980+ );
981+
982+ PrivilegesEvaluationContext context = ctxWithState (
983+ () -> ClusterState .builder (ClusterName .CLUSTER_NAME_SETTING .getDefault (Settings .EMPTY ))
984+ .metadata (Metadata .builder ().build ())
985+ .build (),
986+ "test_role"
987+ );
988+
989+ ActionPrivileges subject = new ActionPrivileges (
990+ roles ,
991+ FlattenedActionGroups .EMPTY ,
992+ Collections ::emptyMap ,
993+ Settings .EMPTY
994+ );
995+
996+ PrivilegesEvaluatorResponse result = subject .hasIndexPrivilege (
997+ context ,
998+ ImmutableSet .of ("indices:monitor/recovery" ),
999+ IndexResolverReplacer .Resolved ._LOCAL_ALL
1000+ );
1001+
1002+ assertThat (result , isAllowed ());
1003+ }
9631004 }
9641005
9651006 /**
@@ -1071,6 +1112,10 @@ static SecurityDynamicConfiguration<RoleV7> createRoles(int numberOfRoles, int n
10711112 }
10721113
10731114 static PrivilegesEvaluationContext ctx (String ... roles ) {
1115+ return ctxWithState (null , roles );
1116+ }
1117+
1118+ static PrivilegesEvaluationContext ctxWithState (Supplier <ClusterState > clusterStateSupplier , String ... roles ) {
10741119 User user = new User ("test_user" );
10751120 user .addAttributes (ImmutableMap .of ("attrs.dept_no" , "a11" ));
10761121 return new PrivilegesEvaluationContext (
@@ -1081,7 +1126,7 @@ static PrivilegesEvaluationContext ctx(String... roles) {
10811126 null ,
10821127 null ,
10831128 new IndexNameExpressionResolver (new ThreadContext (Settings .EMPTY )),
1084- null
1129+ clusterStateSupplier
10851130 );
10861131 }
10871132
0 commit comments