Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issue with Get mappings on a Closed index #4685

Merged
merged 7 commits into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
import org.opensearch.test.framework.cluster.TestRestClient;
import org.opensearch.test.framework.log.LogsRule;

import static org.apache.http.HttpStatus.SC_OK;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.containsString;
Expand Down Expand Up @@ -230,6 +231,12 @@ public class FlsAndFieldMaskingTests {
"cluster_composite_ops_ro"
).indexPermissions("read").fls(String.format("~%s", FIELD_TITLE)).on(FIRST_INDEX_NAME);

static final TestSecurityConfig.Role ROLE_NO_FIELD_TITLE_WILDCARD_INDEX_FLS = new TestSecurityConfig.Role("example_exclusive_fls")
.clusterPermissions("cluster_composite_ops_ro")
.indexPermissions("read", "indices:admin/mappings/get")
.fls(String.format("~%s", FIELD_TITLE))
.on("*");

static final TestSecurityConfig.Role ROLE_ONLY_FIELD_TITLE_MASKED = new TestSecurityConfig.Role("example_mask").clusterPermissions(
"cluster_composite_ops_ro"
).indexPermissions("read").maskedFields(FIELD_TITLE.concat("::/(?<=.{1})./::").concat(MASK_VALUE)).on(FIRST_INDEX_NAME);
Expand All @@ -248,6 +255,12 @@ public class FlsAndFieldMaskingTests {
ROLE_NO_FIELD_TITLE_FLS
);

/**
* Example user with fls filter in which the user can see every field but the {@link Song#FIELD_TITLE} field.
*/
static final TestSecurityConfig.User USER_NO_FIELD_TITLE_WILDCARD_INDEX_FLS = new TestSecurityConfig.User("exclusive_wildcard_fls_user")
.roles(ROLE_NO_FIELD_TITLE_WILDCARD_INDEX_FLS);

/**
* Example user in which {@link Song#FIELD_TITLE} field is masked.
*/
Expand Down Expand Up @@ -305,6 +318,7 @@ public class FlsAndFieldMaskingTests {
ALL_INDICES_STARS_LESS_THAN_ZERO_READER,
TWINS_FIRST_ARTIST_READER,
USER_ONLY_FIELD_TITLE_FLS,
USER_NO_FIELD_TITLE_WILDCARD_INDEX_FLS,
USER_NO_FIELD_TITLE_FLS,
USER_ONLY_FIELD_TITLE_MASKED,
USER_BOTH_ONLY_AND_NO_FIELD_TITLE_FLS,
Expand Down Expand Up @@ -1778,4 +1792,26 @@ public void testFlsOnAClosedAndReopenedIndex() throws IOException {
}
}

@SuppressWarnings("unchecked")
@Test
public void testGetMappingsOnAClosedIndexWithFlsRestrictions() throws IOException {
String indexName = "fls_excludes_mappings";
List<String> docIds = createIndexWithDocs(indexName, SONGS[0], SONGS[1]);

try (TestRestClient client = cluster.getRestClient(ADMIN_USER)) {
TestRestClient.HttpResponse mappingsResponse = client.get(indexName + "/_mapping");
mappingsResponse.assertStatusCode(SC_OK);
assertThat(mappingsResponse.getBody(), containsString("title"));

TestRestClient.HttpResponse closeResponse = client.post(indexName + "/_close");
closeResponse.assertStatusCode(SC_OK);
}

try (TestRestClient client = cluster.getRestClient(USER_NO_FIELD_TITLE_WILDCARD_INDEX_FLS)) {
TestRestClient.HttpResponse mappingsResponse = client.get(indexName + "/_mapping");
mappingsResponse.assertStatusCode(SC_OK);
assertThat(mappingsResponse.getBody(), not(containsString("title")));
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -829,12 +829,12 @@ private Set<String> getResolvedIndexPattern(User user, IndexNameExpressionResolv
.toArray(String[]::new);

if (aliasesForPermittedPattern.length > 0) {
resolved = resolver.concreteIndexNames(cs.state(), IndicesOptions.lenientExpandOpen(), aliasesForPermittedPattern);
resolved = resolver.concreteIndexNames(cs.state(), IndicesOptions.lenientExpand(), aliasesForPermittedPattern);
cwperks marked this conversation as resolved.
Show resolved Hide resolved
}
}

if (resolved == null && !unresolved.isEmpty()) {
resolved = resolver.concreteIndexNames(cs.state(), IndicesOptions.lenientExpandOpen(), unresolved);
resolved = resolver.concreteIndexNames(cs.state(), IndicesOptions.lenientExpand(), unresolved);
}
if (resolved == null || resolved.length == 0) {
return ImmutableSet.of(unresolved);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -792,7 +792,7 @@ public Set<String> getResolvedIndexPattern(
if (aliasesAndDataStreamsForPermittedPattern.length > 0) {
final String[] resolvedAliasesAndDataStreamIndices = resolver.concreteIndexNames(
cs.state(),
IndicesOptions.lenientExpandOpen(),
IndicesOptions.lenientExpand(),
includeDataStreams,
aliasesAndDataStreamsForPermittedPattern
);
Expand All @@ -803,7 +803,7 @@ public Set<String> getResolvedIndexPattern(
if (!(unresolved == null || unresolved.isBlank())) {
final String[] resolvedIndicesFromPattern = resolver.concreteIndexNames(
cs.state(),
IndicesOptions.lenientExpandOpen(),
IndicesOptions.lenientExpand(),
includeDataStreams,
unresolved
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,25 +109,23 @@ public void testAttemptResolveIndexNamesOverload() {
public void testExactNameWithNoMatches() {
doReturn("index-17").when(ip).getUnresolvedIndexPattern(user);
when(clusterService.state()).thenReturn(mock(ClusterState.class));
when(resolver.concreteIndexNames(any(), eq(IndicesOptions.lenientExpandOpen()), eq(true), eq("index-17"))).thenReturn(
new String[] {}
);
when(resolver.concreteIndexNames(any(), eq(IndicesOptions.lenientExpand()), eq(true), eq("index-17"))).thenReturn(new String[] {});

final Set<String> results = ip.concreteIndexNames(user, resolver, clusterService);

assertThat(results, contains("index-17"));

verify(clusterService).state();
verify(ip).getUnresolvedIndexPattern(user);
verify(resolver).concreteIndexNames(any(), eq(IndicesOptions.lenientExpandOpen()), eq(true), eq("index-17"));
verify(resolver).concreteIndexNames(any(), eq(IndicesOptions.lenientExpand()), eq(true), eq("index-17"));
}

/** Verify concreteIndexNames on exact name matches */
@Test
public void testExactName() {
doReturn("index-17").when(ip).getUnresolvedIndexPattern(user);
when(clusterService.state()).thenReturn(mock(ClusterState.class));
when(resolver.concreteIndexNames(any(), eq(IndicesOptions.lenientExpandOpen()), eq(true), eq("index-17"))).thenReturn(
when(resolver.concreteIndexNames(any(), eq(IndicesOptions.lenientExpand()), eq(true), eq("index-17"))).thenReturn(
new String[] { "resolved-index-17" }
);

Expand All @@ -137,15 +135,15 @@ public void testExactName() {

verify(clusterService).state();
verify(ip).getUnresolvedIndexPattern(user);
verify(resolver).concreteIndexNames(any(), eq(IndicesOptions.lenientExpandOpen()), eq(true), eq("index-17"));
verify(resolver).concreteIndexNames(any(), eq(IndicesOptions.lenientExpand()), eq(true), eq("index-17"));
}

/** Verify concreteIndexNames on multiple matches */
@Test
public void testMultipleConcreteIndices() {
doReturn("index-1*").when(ip).getUnresolvedIndexPattern(user);
doReturn(createClusterState()).when(clusterService).state();
when(resolver.concreteIndexNames(any(), eq(IndicesOptions.lenientExpandOpen()), eq(true), eq("index-1*"))).thenReturn(
when(resolver.concreteIndexNames(any(), eq(IndicesOptions.lenientExpand()), eq(true), eq("index-1*"))).thenReturn(
new String[] { "resolved-index-17", "resolved-index-18" }
);

Expand All @@ -155,7 +153,7 @@ public void testMultipleConcreteIndices() {

verify(clusterService, times(2)).state();
verify(ip).getUnresolvedIndexPattern(user);
verify(resolver).concreteIndexNames(any(), eq(IndicesOptions.lenientExpandOpen()), eq(true), eq("index-1*"));
verify(resolver).concreteIndexNames(any(), eq(IndicesOptions.lenientExpand()), eq(true), eq("index-1*"));
}

/** Verify concreteIndexNames when there is an alias */
Expand All @@ -169,10 +167,10 @@ public void testMultipleConcreteIndicesWithOneAlias() {
new IndexShorthand("19", Type.ALIAS) // Type matches/wrong name
)
).when(clusterService).state();
when(resolver.concreteIndexNames(any(), eq(IndicesOptions.lenientExpandOpen()), eq(true), eq("index-100"))).thenReturn(
when(resolver.concreteIndexNames(any(), eq(IndicesOptions.lenientExpand()), eq(true), eq("index-100"))).thenReturn(
new String[] { "resolved-index-100" }
);
when(resolver.concreteIndexNames(any(), eq(IndicesOptions.lenientExpandOpen()), eq(true), eq("index-1*"))).thenReturn(
when(resolver.concreteIndexNames(any(), eq(IndicesOptions.lenientExpand()), eq(true), eq("index-1*"))).thenReturn(
new String[] { "resolved-index-17", "resolved-index-18" }
);

Expand All @@ -182,8 +180,8 @@ public void testMultipleConcreteIndicesWithOneAlias() {

verify(clusterService, times(3)).state();
verify(ip).getUnresolvedIndexPattern(user);
verify(resolver).concreteIndexNames(any(), eq(IndicesOptions.lenientExpandOpen()), eq(true), eq("index-100"));
verify(resolver).concreteIndexNames(any(), eq(IndicesOptions.lenientExpandOpen()), eq(true), eq("index-1*"));
verify(resolver).concreteIndexNames(any(), eq(IndicesOptions.lenientExpand()), eq(true), eq("index-100"));
verify(resolver).concreteIndexNames(any(), eq(IndicesOptions.lenientExpand()), eq(true), eq("index-1*"));
}

/** Verify attemptResolveIndexNames with multiple aliases */
Expand All @@ -197,9 +195,10 @@ public void testMultipleConcreteAliasedAndUnresolved() {
new IndexShorthand("19", Type.ALIAS) // Type matches/wrong name
)
).when(clusterService).state();
when(resolver.concreteIndexNames(any(), eq(IndicesOptions.lenientExpandOpen()), eq(true), eq("index-100"), eq("index-101")))
.thenReturn(new String[] { "resolved-index-100", "resolved-index-101" });
when(resolver.concreteIndexNames(any(), eq(IndicesOptions.lenientExpandOpen()), eq(true), eq("index-1*"))).thenReturn(
when(resolver.concreteIndexNames(any(), eq(IndicesOptions.lenientExpand()), eq(true), eq("index-100"), eq("index-101"))).thenReturn(
new String[] { "resolved-index-100", "resolved-index-101" }
);
when(resolver.concreteIndexNames(any(), eq(IndicesOptions.lenientExpand()), eq(true), eq("index-1*"))).thenReturn(
new String[] { "resolved-index-17", "resolved-index-18" }
);

Expand All @@ -209,8 +208,8 @@ public void testMultipleConcreteAliasedAndUnresolved() {

verify(clusterService, times(3)).state();
verify(ip).getUnresolvedIndexPattern(user);
verify(resolver).concreteIndexNames(any(), eq(IndicesOptions.lenientExpandOpen()), eq(true), eq("index-100"), eq("index-101"));
verify(resolver).concreteIndexNames(any(), eq(IndicesOptions.lenientExpandOpen()), eq(true), eq("index-1*"));
verify(resolver).concreteIndexNames(any(), eq(IndicesOptions.lenientExpand()), eq(true), eq("index-100"), eq("index-101"));
verify(resolver).concreteIndexNames(any(), eq(IndicesOptions.lenientExpand()), eq(true), eq("index-1*"));
}

private ClusterState createClusterState(final IndexShorthand... indices) {
Expand Down
Loading