Skip to content

Commit 2a6ca83

Browse files
add data stream alias tests
1 parent 411a5ab commit 2a6ca83

File tree

1 file changed

+211
-46
lines changed

1 file changed

+211
-46
lines changed

x-pack/plugin/security/qa/security-trial/src/javaRestTest/java/org/elasticsearch/xpack/security/failurestore/FailureStoreSecurityRestIT.java

Lines changed: 211 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,10 @@ public class FailureStoreSecurityRestIT extends ESRestTestCase {
6969
@ClassRule
7070
public static ElasticsearchCluster cluster = ElasticsearchCluster.local()
7171
.apply(SecurityOnTrialLicenseRestTestCase.commonTrialSecurityClusterConfig)
72+
.nodes(5)
7273
.feature(FeatureFlag.FAILURE_STORE_ENABLED)
74+
.setting("logger.rest.suppressed", "TRACE")
75+
.setting("logger.org.elasticsearch.transport.TransportService.tracer", "trace")
7376
.build();
7477

7578
@Override
@@ -1931,19 +1934,11 @@ public void testModifyingFailureStoreBackingIndices() throws Exception {
19311934
String failureIndexName = backingIndices.v2();
19321935

19331936
createUser(MANAGE_ACCESS, PASSWORD, MANAGE_ACCESS);
1934-
upsertRole(Strings.format("""
1937+
createOrUpdateRoleAndApiKey(MANAGE_ACCESS, MANAGE_ACCESS, """
19351938
{
19361939
"cluster": ["all"],
19371940
"indices": [{"names": ["test*"], "privileges": ["manage"]}]
1938-
}"""), MANAGE_ACCESS);
1939-
createAndStoreApiKey(MANAGE_ACCESS, randomBoolean() ? null : """
1940-
{
1941-
"role": {
1942-
"cluster": ["all"],
1943-
"indices": [{"names": ["test*"], "privileges": ["manage"]}]
1944-
}
1945-
}
1946-
""");
1941+
}""");
19471942
assertOK(addFailureStoreBackingIndex(MANAGE_ACCESS, "test1", failureIndexName));
19481943
assertDataStreamHasDataAndFailureIndices("test1", dataIndexName, failureIndexName);
19491944

@@ -1955,58 +1950,34 @@ public void testModifyingFailureStoreBackingIndices() throws Exception {
19551950
expectThrows(() -> addFailureStoreBackingIndex(MANAGE_ACCESS, "test1", failureIndexName), 403);
19561951

19571952
// let's change that
1958-
upsertRole(Strings.format("""
1953+
createOrUpdateRoleAndApiKey(MANAGE_ACCESS, MANAGE_ACCESS, """
19591954
{
19601955
"cluster": ["all"],
19611956
"indices": [{"names": ["test*", ".fs*"], "privileges": ["manage"]}]
1962-
}"""), MANAGE_ACCESS);
1963-
createOrUpdateApiKey(MANAGE_ACCESS, randomBoolean() ? null : """
1964-
{
1965-
"role": {
1966-
"cluster": ["all"],
1967-
"indices": [{"names": ["test*", ".fs*"], "privileges": ["manage"]}]
1968-
}
1969-
}
1970-
""");
1957+
}""");
19711958

19721959
// adding should succeed now
19731960
assertOK(addFailureStoreBackingIndex(MANAGE_ACCESS, "test1", failureIndexName));
19741961
assertDataStreamHasDataAndFailureIndices("test1", dataIndexName, failureIndexName);
19751962

19761963
createUser(MANAGE_FAILURE_STORE_ACCESS, PASSWORD, MANAGE_FAILURE_STORE_ACCESS);
1977-
upsertRole(Strings.format("""
1964+
createOrUpdateRoleAndApiKey(MANAGE_FAILURE_STORE_ACCESS, MANAGE_FAILURE_STORE_ACCESS, """
19781965
{
19791966
"cluster": ["all"],
19801967
"indices": [{"names": ["test*"], "privileges": ["manage_failure_store"]}]
1981-
}"""), MANAGE_FAILURE_STORE_ACCESS);
1982-
createAndStoreApiKey(MANAGE_FAILURE_STORE_ACCESS, randomBoolean() ? null : """
1983-
{
1984-
"role": {
1985-
"cluster": ["all"],
1986-
"indices": [{"names": ["test*"], "privileges": ["manage_failure_store"]}]
1987-
}
1988-
}
1989-
""");
1968+
}""");
19901969

19911970
// manage_failure_store can only remove the failure backing index, but not add it
19921971
assertOK(removeFailureStoreBackingIndex(MANAGE_FAILURE_STORE_ACCESS, "test1", failureIndexName));
19931972
assertDataStreamHasNoFailureIndices("test1", dataIndexName);
19941973
expectThrows(() -> addFailureStoreBackingIndex(MANAGE_FAILURE_STORE_ACCESS, "test1", failureIndexName), 403);
19951974

19961975
// not even with access to .fs*
1997-
upsertRole(Strings.format("""
1976+
createOrUpdateRoleAndApiKey(MANAGE_FAILURE_STORE_ACCESS, MANAGE_FAILURE_STORE_ACCESS, """
19981977
{
19991978
"cluster": ["all"],
20001979
"indices": [{"names": ["test*", ".fs*"], "privileges": ["manage_failure_store"]}]
2001-
}"""), MANAGE_FAILURE_STORE_ACCESS);
2002-
createOrUpdateApiKey(MANAGE_FAILURE_STORE_ACCESS, randomBoolean() ? null : """
2003-
{
2004-
"role": {
2005-
"cluster": ["all"],
2006-
"indices": [{"names": ["test*", ".fs*"], "privileges": ["manage_failure_store"]}]
2007-
}
2008-
}
2009-
""");
1980+
}""");
20101981
expectThrows(() -> addFailureStoreBackingIndex(MANAGE_FAILURE_STORE_ACCESS, "test1", failureIndexName), 403);
20111982
}
20121983

@@ -2055,9 +2026,199 @@ public void testDataStreamApi() {
20552026
// test data stream stats
20562027
}
20572028

2058-
public void testAliasBasedAccess() {
2059-
// test alias based access with failure store
2060-
// test filtered alias based access with failure store
2029+
public void testAliasBasedAccess() throws Exception {
2030+
List<String> docIds = setupDataStream();
2031+
assertThat(docIds.size(), equalTo(2));
2032+
assertThat(docIds, hasItem("1"));
2033+
String dataDocId = "1";
2034+
String failuresDocId = docIds.stream().filter(id -> false == id.equals(dataDocId)).findFirst().get();
2035+
2036+
List<String> otherDocIds = setupOtherDataStream();
2037+
assertThat(otherDocIds.size(), equalTo(2));
2038+
assertThat(otherDocIds, hasItem("3"));
2039+
String otherDataDocId = "3";
2040+
String otherFailuresDocId = otherDocIds.stream().filter(id -> false == id.equals(otherDataDocId)).findFirst().get();
2041+
2042+
final Tuple<String, String> backingIndices = getSingleDataAndFailureIndices("test1");
2043+
final String dataIndexName = backingIndices.v1();
2044+
final String failureIndexName = backingIndices.v2();
2045+
2046+
final String aliasName = "my-alias";
2047+
final String username = "user";
2048+
final String roleName = "role";
2049+
2050+
createUser(username, PASSWORD, roleName);
2051+
// manage is required to add the alias to the data stream
2052+
createOrUpdateRoleAndApiKey(username, roleName, Strings.format("""
2053+
{
2054+
"cluster": ["all"],
2055+
"indices": [
2056+
{
2057+
"names": ["test1", "%s", "other1"],
2058+
"privileges": ["manage"]
2059+
}
2060+
]
2061+
}
2062+
""", aliasName));
2063+
2064+
addAlias(username, "test1", aliasName, "");
2065+
addAlias(username, "other1", aliasName, "");
2066+
assertThat(fetchAliases(username, "test1"), containsInAnyOrder(aliasName));
2067+
expectSearchThrows(username, new Search(randomFrom(aliasName + "::data", aliasName)), 403);
2068+
expectSearchThrows(username, new Search(randomFrom(aliasName + "::failures")), 403);
2069+
2070+
createOrUpdateRoleAndApiKey(username, roleName, Strings.format("""
2071+
{
2072+
"cluster": ["all"],
2073+
"indices": [
2074+
{
2075+
"names": ["%s"],
2076+
"privileges": ["read_failure_store"]
2077+
}
2078+
]
2079+
}
2080+
""", aliasName));
2081+
expectSearch(username, new Search(aliasName + "::failures"), failuresDocId, otherFailuresDocId);
2082+
expectSearchThrows(
2083+
username,
2084+
new Search(randomFrom(aliasName + "::data", "my-alias::failures", dataIndexName, failureIndexName)),
2085+
403
2086+
);
2087+
2088+
createOrUpdateRoleAndApiKey(username, roleName, Strings.format("""
2089+
{
2090+
"cluster": ["all"],
2091+
"indices": [
2092+
{
2093+
"names": ["%s"],
2094+
"privileges": ["read"]
2095+
}
2096+
]
2097+
}
2098+
""", aliasName));
2099+
expectSearch(username, new Search(randomFrom(aliasName + "::data")), dataDocId, otherDataDocId);
2100+
expectSearchThrows(username, new Search(aliasName + "::failures"), 403);
2101+
2102+
expectThrows(() -> removeAlias(username, "test1", aliasName), 403);
2103+
createOrUpdateRoleAndApiKey(username, roleName, Strings.format("""
2104+
{
2105+
"cluster": ["all"],
2106+
"indices": [
2107+
{
2108+
"names": ["test1", "%s", "other1"],
2109+
"privileges": ["manage"]
2110+
}
2111+
]
2112+
}
2113+
""", aliasName));
2114+
removeAlias(username, "test1", aliasName);
2115+
removeAlias(username, "other1", aliasName);
2116+
2117+
final String filteredAliasName = "my-filtered-alias";
2118+
createOrUpdateRoleAndApiKey(username, roleName, Strings.format("""
2119+
{
2120+
"cluster": ["all"],
2121+
"indices": [
2122+
{
2123+
"names": ["test1", "%s", "other1"],
2124+
"privileges": ["manage"]
2125+
}
2126+
]
2127+
}
2128+
""", filteredAliasName));
2129+
addAlias(username, "test1", filteredAliasName, """
2130+
{
2131+
"term": {
2132+
"document.source.name": "jack"
2133+
}
2134+
}
2135+
""");
2136+
addAlias(username, "other1", filteredAliasName, """
2137+
{
2138+
"term": {
2139+
"document.source.name": "jack"
2140+
}
2141+
}
2142+
""");
2143+
assertThat(fetchAliases(username, "test1"), containsInAnyOrder(filteredAliasName));
2144+
assertThat(fetchAliases(username, "other1"), containsInAnyOrder(filteredAliasName));
2145+
2146+
createOrUpdateRoleAndApiKey(username, roleName, Strings.format("""
2147+
{
2148+
"cluster": ["all"],
2149+
"indices": [
2150+
{
2151+
"names": ["%s"],
2152+
"privileges": ["read", "read_failure_store"]
2153+
}
2154+
]
2155+
}
2156+
""", filteredAliasName));
2157+
2158+
expectSearch(username, new Search(randomFrom(filteredAliasName + "::data", filteredAliasName)));
2159+
// the alias filter is not applied to the failure store
2160+
expectSearch(username, new Search(filteredAliasName + "::failures"), failuresDocId, otherDataDocId);
2161+
}
2162+
2163+
private void createOrUpdateRoleAndApiKey(String username, String roleName, String roleDescriptor) throws IOException {
2164+
upsertRole(roleDescriptor, roleName);
2165+
createOrUpdateApiKey(username, randomBoolean() ? null : Strings.format("""
2166+
{
2167+
"%s": %s
2168+
}
2169+
""", roleName, roleDescriptor));
2170+
}
2171+
2172+
private void addAlias(String user, String dataStream, String alias, String filter) throws IOException {
2173+
aliasAction(user, "add", dataStream, alias, filter);
2174+
}
2175+
2176+
private void removeAlias(String user, String dataStream, String alias) throws IOException {
2177+
aliasAction(user, "remove", dataStream, alias, "");
2178+
}
2179+
2180+
private void aliasAction(String user, String action, String dataStream, String alias, String filter) throws IOException {
2181+
Request request = new Request("POST", "/_aliases");
2182+
if (filter == null || filter.isEmpty()) {
2183+
request.setJsonEntity(Strings.format("""
2184+
{
2185+
"actions": [
2186+
{
2187+
"%s": {
2188+
"index": "%s",
2189+
"alias": "%s"
2190+
}
2191+
}
2192+
]
2193+
}
2194+
""", action, dataStream, alias));
2195+
} else {
2196+
request.setJsonEntity(Strings.format("""
2197+
{
2198+
"actions": [
2199+
{
2200+
"%s": {
2201+
"index": "%s",
2202+
"alias": "%s",
2203+
"filter": %s
2204+
}
2205+
}
2206+
]
2207+
}
2208+
""", action, dataStream, alias, filter));
2209+
}
2210+
Response response = performRequestMaybeUsingApiKey(user, request);
2211+
var path = assertOKAndCreateObjectPath(response);
2212+
assertThat(path.evaluate("acknowledged"), is(true));
2213+
assertThat(path.evaluate("errors"), is(false));
2214+
2215+
}
2216+
2217+
private Set<String> fetchAliases(String user, String dataStream) throws IOException {
2218+
Response response = performRequestMaybeUsingApiKey(user, new Request("GET", dataStream + "/_alias"));
2219+
ObjectPath path = assertOKAndCreateObjectPath(response);
2220+
Map<String, Object> aliases = path.evaluate(dataStream + ".aliases");
2221+
return aliases.keySet();
20612222
}
20622223

20632224
public void testPatternExclusions() throws Exception {
@@ -2917,9 +3078,13 @@ private static void expectSearch(Response response, String... docIds) throws IOE
29173078
final SearchResponse searchResponse = SearchResponseUtils.parseSearchResponse(responseAsParser(response));
29183079
try {
29193080
SearchHit[] hits = searchResponse.getHits().getHits();
2920-
assertThat(hits.length, equalTo(docIds.length));
2921-
List<String> actualDocIds = Arrays.stream(hits).map(SearchHit::getId).toList();
2922-
assertThat(actualDocIds, containsInAnyOrder(docIds));
3081+
if (docIds != null) {
3082+
assertThat(Arrays.toString(hits), hits.length, equalTo(docIds.length));
3083+
List<String> actualDocIds = Arrays.stream(hits).map(SearchHit::getId).toList();
3084+
assertThat(actualDocIds, containsInAnyOrder(docIds));
3085+
} else {
3086+
assertThat(hits.length, equalTo(0));
3087+
}
29233088
} finally {
29243089
searchResponse.decRef();
29253090
}

0 commit comments

Comments
 (0)