Skip to content

Commit 222bd48

Browse files
tests
1 parent eae2648 commit 222bd48

File tree

2 files changed

+165
-11
lines changed

2 files changed

+165
-11
lines changed

x-pack/plugin/esql/qa/security/src/javaRestTest/java/org/elasticsearch/xpack/esql/EsqlSecurityIT.java

Lines changed: 121 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@
4242
import static org.elasticsearch.test.MapMatcher.matchesMap;
4343
import static org.hamcrest.Matchers.containsString;
4444
import static org.hamcrest.Matchers.equalTo;
45+
import static org.hamcrest.Matchers.is;
4546
import static org.hamcrest.Matchers.not;
47+
import static org.hamcrest.Matchers.nullValue;
4648

4749
public class EsqlSecurityIT extends ESRestTestCase {
4850
@ClassRule
@@ -59,10 +61,14 @@ public class EsqlSecurityIT extends ESRestTestCase {
5961
.user("user5", "x-pack-test-password", "user5", false)
6062
.user("fls_user", "x-pack-test-password", "fls_user", false)
6163
.user("fls_user2", "x-pack-test-password", "fls_user2", false)
64+
.user("fls_user2_alias", "x-pack-test-password", "fls_user2_alias", false)
6265
.user("fls_user3", "x-pack-test-password", "fls_user3", false)
66+
.user("fls_user3_alias", "x-pack-test-password", "fls_user3_alias", false)
6367
.user("fls_user4_1", "x-pack-test-password", "fls_user4_1", false)
68+
.user("fls_user4_1_alias", "x-pack-test-password", "fls_user4_1_alias", false)
6469
.user("dls_user", "x-pack-test-password", "dls_user", false)
6570
.user("metadata1_read2", "x-pack-test-password", "metadata1_read2", false)
71+
.user("metadata1_alias_read2", "x-pack-test-password", "metadata1_alias_read2", false)
6672
.user("alias_user1", "x-pack-test-password", "alias_user1", false)
6773
.user("alias_user2", "x-pack-test-password", "alias_user2", false)
6874
.user("logs_foo_all", "x-pack-test-password", "logs_foo_all", false)
@@ -159,6 +165,12 @@ public void indexDocuments() throws IOException {
159165
}
160166
}
161167
},
168+
{
169+
"add": {
170+
"alias": "lookup-second-alias",
171+
"index": "lookup-user2"
172+
}
173+
},
162174
{
163175
"add": {
164176
"alias": "second-alias",
@@ -196,6 +208,17 @@ private void createMultiRoleUsers() throws IOException {
196208
}
197209
""");
198210
assertOK(client().performRequest(request));
211+
212+
request = new Request("POST", "_security/user/fls_user4_alias");
213+
request.setJsonEntity("""
214+
{
215+
"password" : "x-pack-test-password",
216+
"roles" : [ "fls_user4_1_alias", "fls_user4_2_alias" ],
217+
"full_name" : "Test Role",
218+
"email" : "[email protected]"
219+
}
220+
""");
221+
assertOK(client().performRequest(request));
199222
}
200223

201224
protected MapMatcher responseMatcher(Map<String, Object> result) {
@@ -586,22 +609,51 @@ public void testLookupJoinIndexAllowed() throws Exception {
586609
);
587610
assertThat(respMap.get("values"), equalTo(List.of(List.of(40.0, "sales"))));
588611

589-
// Aliases are not allowed in LOOKUP JOIN
590-
var resp2 = expectThrows(
612+
// user is not allowed to use the alias (but is allowed to use the index)
613+
expectThrows(
591614
ResponseException.class,
592-
() -> runESQLCommand("alias_user1", "ROW x = 31.0 | EVAL value = x | LOOKUP JOIN lookup-first-alias ON value | KEEP x, org")
615+
() -> runESQLCommand(
616+
"metadata1_read2",
617+
"ROW x = 40.0 | EVAL value = x | LOOKUP JOIN lookup-second-alias ON value | KEEP x, org"
618+
)
593619
);
594620

595-
assertThat(resp2.getMessage(), containsString("Aliases and index patterns are not allowed for LOOKUP JOIN [lookup-first-alias]"));
596-
assertThat(resp2.getResponse().getStatusLine().getStatusCode(), equalTo(HttpStatus.SC_BAD_REQUEST));
597-
598-
// Aliases are not allowed in LOOKUP JOIN, regardless of alias filters
599-
resp2 = expectThrows(
621+
// user is not allowed to use the index (but is allowed to use the alias)
622+
expectThrows(
600623
ResponseException.class,
601-
() -> runESQLCommand("alias_user1", "ROW x = 123.0 | EVAL value = x | LOOKUP JOIN lookup-first-alias ON value | KEEP x, org")
624+
() -> runESQLCommand("metadata1_alias_read2", "ROW x = 40.0 | EVAL value = x | LOOKUP JOIN lookup-user2 ON value | KEEP x, org")
625+
);
626+
627+
// user has permission on the alias, and can read the key
628+
resp = runESQLCommand(
629+
"metadata1_alias_read2",
630+
"ROW x = 40.0 | EVAL value = x | LOOKUP JOIN lookup-second-alias ON value | KEEP x, org"
631+
);
632+
assertOK(resp);
633+
respMap = entityAsMap(resp);
634+
assertThat(
635+
respMap.get("columns"),
636+
equalTo(List.of(Map.of("name", "x", "type", "double"), Map.of("name", "org", "type", "keyword")))
637+
);
638+
assertThat(respMap.get("values"), equalTo(List.of(List.of(40.0, "sales"))));
639+
640+
// user has permission on the alias, but can't read the key (doc level security)
641+
resp = runESQLCommand(
642+
"metadata1_alias_read2",
643+
"ROW x = 32.0 | EVAL value = x | LOOKUP JOIN lookup-second-alias ON value | KEEP x, org"
644+
);
645+
assertOK(resp);
646+
respMap = entityAsMap(resp);
647+
assertThat(
648+
respMap.get("columns"),
649+
equalTo(List.of(Map.of("name", "x", "type", "double"), Map.of("name", "org", "type", "keyword")))
602650
);
603-
assertThat(resp2.getMessage(), containsString("Aliases and index patterns are not allowed for LOOKUP JOIN [lookup-first-alias]"));
604-
assertThat(resp2.getResponse().getStatusLine().getStatusCode(), equalTo(HttpStatus.SC_BAD_REQUEST));
651+
List<?> values = (List<?>) respMap.get("values");
652+
assertThat(values.size(), is(1));
653+
List<?> row = (List<?>) values.get(0);
654+
assertThat(row.size(), is(2));
655+
assertThat(row.get(0), is(32.0));
656+
assertThat(row.get(1), is(nullValue()));
605657
}
606658

607659
@SuppressWarnings("unchecked")
@@ -712,6 +764,64 @@ public void testLookupJoinFieldLevelSecurity() throws Exception {
712764
assertThat(error.getResponse().getStatusLine().getStatusCode(), equalTo(HttpStatus.SC_BAD_REQUEST));
713765
}
714766

767+
public void testLookupJoinFieldLevelSecurityOnAlias() throws Exception {
768+
assumeTrue(
769+
"Requires LOOKUP JOIN capability",
770+
EsqlSpecTestCase.hasCapabilities(adminClient(), List.of(EsqlCapabilities.Cap.JOIN_LOOKUP_V12.capabilityName()))
771+
);
772+
773+
Response resp = runESQLCommand("fls_user2_alias", "ROW x = 40.0 | EVAL value = x | LOOKUP JOIN lookup-second-alias ON value");
774+
assertOK(resp);
775+
Map<String, Object> respMap = entityAsMap(resp);
776+
assertThat(
777+
respMap.get("columns"),
778+
equalTo(
779+
List.of(
780+
Map.of("name", "x", "type", "double"),
781+
Map.of("name", "value", "type", "double"),
782+
Map.of("name", "org", "type", "keyword")
783+
)
784+
)
785+
);
786+
787+
resp = runESQLCommand("fls_user3_alias", "ROW x = 40.0 | EVAL value = x | LOOKUP JOIN lookup-second-alias ON value");
788+
assertOK(resp);
789+
respMap = entityAsMap(resp);
790+
assertThat(
791+
respMap.get("columns"),
792+
equalTo(
793+
List.of(
794+
Map.of("name", "x", "type", "double"),
795+
Map.of("name", "value", "type", "double"),
796+
Map.of("name", "org", "type", "keyword"),
797+
Map.of("name", "other", "type", "keyword")
798+
)
799+
)
800+
801+
);
802+
803+
resp = runESQLCommand("fls_user4_alias", "ROW x = 40.0 | EVAL value = x | LOOKUP JOIN lookup-second-alias ON value");
804+
assertOK(resp);
805+
respMap = entityAsMap(resp);
806+
assertThat(
807+
respMap.get("columns"),
808+
equalTo(
809+
List.of(
810+
Map.of("name", "x", "type", "double"),
811+
Map.of("name", "value", "type", "double"),
812+
Map.of("name", "org", "type", "keyword")
813+
)
814+
)
815+
);
816+
817+
ResponseException error = expectThrows(
818+
ResponseException.class,
819+
() -> runESQLCommand("fls_user4_1_alias", "ROW x = 40.0 | EVAL value = x | LOOKUP JOIN lookup-second-alias ON value")
820+
);
821+
assertThat(error.getMessage(), containsString("Unknown column [value] in right side of join"));
822+
assertThat(error.getResponse().getStatusLine().getStatusCode(), equalTo(HttpStatus.SC_BAD_REQUEST));
823+
}
824+
715825
public void testLookupJoinIndexForbidden() throws Exception {
716826
assumeTrue(
717827
"Requires LOOKUP JOIN capability",

x-pack/plugin/esql/qa/security/src/javaRestTest/resources/roles.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,17 @@ metadata1_read2:
4040
- names: [ 'index-user2', 'lookup-user2' ]
4141
privileges: [ 'read' ]
4242

43+
metadata1_alias_read2:
44+
cluster: []
45+
indices:
46+
- names: [ 'index-user1', 'lookup-first-alias' ]
47+
privileges: [ 'view_index_metadata' ]
48+
- names: [ 'index-user2' ]
49+
privileges: [ 'read' ]
50+
- names: [ 'lookup-second-alias' ]
51+
privileges: [ 'read' ]
52+
query: '{"match": {"org": "sales"}}'
53+
4354
alias_user1:
4455
cluster: []
4556
indices:
@@ -101,6 +112,14 @@ fls_user2:
101112
field_security:
102113
grant: [ "org", "value" ]
103114

115+
fls_user2_alias:
116+
cluster: []
117+
indices:
118+
- names: [ 'lookup-second-alias' ]
119+
privileges: [ 'read' ]
120+
field_security:
121+
grant: [ "org", "value" ]
122+
104123
fls_user3:
105124
cluster: []
106125
indices:
@@ -109,6 +128,15 @@ fls_user3:
109128
field_security:
110129
grant: [ "org", "value", "other" ]
111130

131+
fls_user3_alias:
132+
cluster: []
133+
indices:
134+
- names: [ 'lookup-second-alias' ]
135+
privileges: [ 'read' ]
136+
field_security:
137+
grant: [ "org", "value", "other" ]
138+
139+
112140
fls_user4_1:
113141
cluster: []
114142
indices:
@@ -117,6 +145,14 @@ fls_user4_1:
117145
field_security:
118146
grant: [ "org" ]
119147

148+
fls_user4_1_alias:
149+
cluster: []
150+
indices:
151+
- names: [ 'lookup-second-alias' ]
152+
privileges: [ 'read' ]
153+
field_security:
154+
grant: [ "org" ]
155+
120156
fls_user4_2:
121157
cluster: []
122158
indices:
@@ -125,6 +161,14 @@ fls_user4_2:
125161
field_security:
126162
grant: [ "value" ]
127163

164+
fls_user4_2_alias:
165+
cluster: []
166+
indices:
167+
- names: [ 'lookup-second-alias' ]
168+
privileges: [ 'read' ]
169+
field_security:
170+
grant: [ "value" ]
171+
128172
dls_user:
129173
cluster: []
130174
indices:

0 commit comments

Comments
 (0)