1717import org .elasticsearch .common .Strings ;
1818import org .elasticsearch .common .settings .SecureString ;
1919import org .elasticsearch .common .settings .Settings ;
20+ import org .elasticsearch .common .util .Maps ;
2021import org .elasticsearch .common .util .concurrent .ThreadContext ;
2122import org .elasticsearch .common .xcontent .XContentHelper ;
2223import org .elasticsearch .common .xcontent .support .XContentMapValues ;
@@ -1388,8 +1389,7 @@ public void testDlsFls() throws Exception {
13881389 Map .of (dataIndexName , Set .of ("@timestamp" , "age" ))
13891390 );
13901391
1391- // FLS sort of applies to failure store
1392- // TODO this will change with FLS handling
1392+ // FLS applies to failure store
13931393 assertSearchResponseContainsExpectedIndicesAndFields (
13941394 performRequest (user , new Search ("test1::failures" ).toSearchRequest ()),
13951395 Map .of (failureIndexName , Set .of ("@timestamp" ))
@@ -1409,24 +1409,56 @@ public void testDlsFls() throws Exception {
14091409 {
14101410 "names": ["test*"],
14111411 "privileges": ["read_failure_store"],
1412+ "field_security": {
1413+ "grant": ["error.type", "error.message"]
1414+ }
1415+ }
1416+ ]
1417+ }""" , "test1" ), role );
1418+
1419+ // FLS applies to regular data stream
1420+ assertSearchResponseContainsExpectedIndicesAndFields (
1421+ performRequest (user , new Search (randomFrom ("test1" , "test1::data" )).toSearchRequest ()),
1422+ Map .of (dataIndexName , Set .of ("@timestamp" , "age" ))
1423+ );
1424+
1425+ // FLS applies to failure store
1426+ assertSearchResponseContainsExpectedIndicesAndFields (
1427+ performRequest (user , new Search ("test1::failures" ).toSearchRequest ()),
1428+ Map .of (failureIndexName , Set .of ("error.type" , "error.message" ))
1429+ );
1430+
1431+ upsertRole (Strings .format ("""
1432+ {
1433+ "cluster": ["all"],
1434+ "indices": [
1435+ {
1436+ "names": ["%s"],
1437+ "privileges": ["read"],
14121438 "field_security": {
14131439 "grant": ["@timestamp", "age"]
14141440 }
1441+ },
1442+ {
1443+ "names": ["test*"],
1444+ "privileges": ["read_failure_store"],
1445+ "field_security": {
1446+ "grant": ["error.type", "error.message"]
1447+ }
14151448 }
14161449 ]
1417- }""" , randomFrom ( "test*" , "test1" ) ), role );
1450+ }""" , "test*" ), role );
14181451
14191452 // FLS applies to regular data stream
14201453 assertSearchResponseContainsExpectedIndicesAndFields (
14211454 performRequest (user , new Search (randomFrom ("test1" , "test1::data" )).toSearchRequest ()),
14221455 Map .of (dataIndexName , Set .of ("@timestamp" , "age" ))
14231456 );
14241457
1425- // FLS sort of applies to failure store
1426- // TODO this will change with FLS handling
1458+ // FLS applies to failure store
14271459 assertSearchResponseContainsExpectedIndicesAndFields (
14281460 performRequest (user , new Search ("test1::failures" ).toSearchRequest ()),
1429- Map .of (failureIndexName , Set .of ("@timestamp" ))
1461+ Map .of (failureIndexName , Set .of ("@timestamp" , "error.type" , "error.message" ))
14301462 );
14311463
14321464 upsertRole ("""
@@ -1452,10 +1484,56 @@ public void testDlsFls() throws Exception {
14521484 performRequest (user , new Search (randomFrom ("test1" , "test1::data" )).toSearchRequest ()),
14531485 Map .of (dataIndexName , Set .of ("@timestamp" , "age" , "name" , "email" ))
14541486 );
1455-
14561487 assertSearchResponseContainsExpectedIndicesAndFields (
14571488 performRequest (user , new Search ("test1::failures" ).toSearchRequest ()),
1458- Map .of (failureIndexName , Set .of ("@timestamp" , "document" , "error" ))
1489+ Map .of (
1490+ failureIndexName ,
1491+ Set .of (
1492+ "@timestamp" ,
1493+ "document.id" ,
1494+ "document.index" ,
1495+ "document.source.@timestamp" ,
1496+ "document.source.age" ,
1497+ "document.source.email" ,
1498+ "document.source.name" ,
1499+ "error.message" ,
1500+ "error.stack_trace" ,
1501+ "error.type"
1502+ )
1503+ )
1504+ );
1505+
1506+ // check that direct read access to backing indices is working
1507+ upsertRole (Strings .format ("""
1508+ {
1509+ "cluster": ["all"],
1510+ "indices": [
1511+ {
1512+ "names": ["%s"],
1513+ "privileges": ["read"],
1514+ "field_security": {
1515+ "grant": ["@timestamp", "age"]
1516+ }
1517+ },
1518+ {
1519+ "names": ["%s"],
1520+ "privileges": ["read"],
1521+ "field_security": {
1522+ "grant": ["@timestamp", "document.source.name"]
1523+ }
1524+ }
1525+ ]
1526+ }""" , dataIndexName , failureIndexName ), role );
1527+
1528+ // FLS applies to backing data index
1529+ assertSearchResponseContainsExpectedIndicesAndFields (
1530+ performRequest (user , new Search (randomFrom (dataIndexName , ".ds-*" )).toSearchRequest ()),
1531+ Map .of (dataIndexName , Set .of ("@timestamp" , "age" ))
1532+ );
1533+ // and backing failure index
1534+ assertSearchResponseContainsExpectedIndicesAndFields (
1535+ performRequest (user , new Search (randomFrom (failureIndexName , ".fs-*" )).toSearchRequest ()),
1536+ Map .of (failureIndexName , Set .of ("@timestamp" , "document.source.name" ))
14591537 );
14601538
14611539 // DLS
@@ -1507,6 +1585,21 @@ public void testDlsFls() throws Exception {
15071585 }""" , role );
15081586 // DLS does not apply because there is a section without DLS
15091587 expectSearch (user , new Search (randomFrom ("test1" , "test1::data" )), dataIndexDocId );
1588+
1589+ // DLS is applicable to backing failure store when granted read directly
1590+ upsertRole (Strings .format ("""
1591+ {
1592+ "cluster": ["all"],
1593+ "indices": [
1594+ {
1595+ "names": ["%s"],
1596+ "privileges": ["read"],
1597+ "query":{"term":{"document.source.name":{"value":"jack"}}}
1598+ }
1599+ ]
1600+ }""" , failureIndexName ), role );
1601+ expectSearch (user , new Search (randomFrom (".fs-*" , failureIndexName )));
1602+
15101603 }
15111604
15121605 private static void expectThrows (ThrowingRunnable runnable , int statusCode ) {
@@ -1797,7 +1890,7 @@ protected void assertSearchResponseContainsExpectedIndicesAndFields(
17971890 assertThat (searchResult .keySet (), equalTo (expectedIndicesAndFields .keySet ()));
17981891 for (String index : expectedIndicesAndFields .keySet ()) {
17991892 Set <String > expectedFields = expectedIndicesAndFields .get (index );
1800- assertThat (searchResult .get (index ).keySet (), equalTo (expectedFields ));
1893+ assertThat (Maps . flatten ( searchResult .get (index ), false , true ).keySet (), equalTo (expectedFields ));
18011894 }
18021895 } finally {
18031896 response .decRef ();
0 commit comments