Skip to content

Commit 0858cd3

Browse files
committed
Remote indices too
1 parent c8fc1f7 commit 0858cd3

File tree

7 files changed

+72
-39
lines changed

7 files changed

+72
-39
lines changed

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/permission/Role.java

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -426,17 +426,28 @@ static SimpleRole buildFromRoleDescriptor(
426426
final String[] clusterAliases = remoteIndicesPrivileges.remoteClusters();
427427
assert Arrays.equals(new String[] { "*" }, clusterAliases)
428428
: "reserved role should not define remote indices privileges for specific clusters";
429-
final RoleDescriptor.IndicesPrivileges indicesPrivileges = remoteIndicesPrivileges.indicesPrivileges();
430-
builder.addRemoteIndicesGroup(
431-
Set.of(clusterAliases),
432-
fieldPermissionsCache.getFieldPermissions(
433-
new FieldPermissionsDefinition(indicesPrivileges.getGrantedFields(), indicesPrivileges.getDeniedFields())
434-
),
435-
indicesPrivileges.getQuery() == null ? null : Collections.singleton(indicesPrivileges.getQuery()),
436-
IndexPrivilege.get(Set.of(indicesPrivileges.getPrivileges())),
437-
indicesPrivileges.allowRestrictedIndices(),
438-
indicesPrivileges.getIndices()
429+
final RoleDescriptor.IndicesPrivileges indexPrivilege = remoteIndicesPrivileges.indicesPrivileges();
430+
FieldPermissions fieldPermissions = fieldPermissionsCache.getFieldPermissions(
431+
new FieldPermissionsDefinition(indexPrivilege.getGrantedFields(), indexPrivilege.getDeniedFields())
432+
);
433+
Set<BytesReference> query = indexPrivilege.getQuery() == null ? null : Collections.singleton(indexPrivilege.getQuery());
434+
boolean allowRestrictedIndices = indexPrivilege.allowRestrictedIndices();
435+
Map<IndexComponentSelectorPrivilege, Set<String>> split = IndexComponentSelectorPrivilege.partitionBySelectorPrivilege(
436+
indexPrivilege.getPrivileges()
439437
);
438+
for (var entry : split.entrySet()) {
439+
IndexPrivilege privilege = IndexPrivilege.get(entry.getValue());
440+
assert privilege.getSelectorPrivilege() == entry.getKey()
441+
: "expected selector privilege to match the partitioned privilege";
442+
builder.addRemoteIndicesGroup(
443+
Set.of(clusterAliases),
444+
fieldPermissions,
445+
query,
446+
privilege,
447+
allowRestrictedIndices,
448+
indexPrivilege.getIndices()
449+
);
450+
}
440451
}
441452

442453
RemoteClusterPermissions remoteClusterPermissions = roleDescriptor.getRemoteClusterPermissions();

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/ConfigurableClusterPrivileges.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,6 @@ public ManageRolesPrivilege(List<ManageRolesIndexPermissionGroup> manageRolesInd
419419
FieldPermissions.DEFAULT,
420420
null,
421421
false,
422-
// TODO
423422
indexPatternPrivilege.indexPatterns()
424423
);
425424
}

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/IndexComponentSelectorPrivilege.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
import java.util.function.Predicate;
1717
import java.util.stream.Collectors;
1818

19+
import static org.elasticsearch.common.util.set.Sets.newHashSet;
20+
1921
public record IndexComponentSelectorPrivilege(String name, Predicate<IndexComponentSelector> predicate) {
2022
public static final IndexComponentSelectorPrivilege ALL = new IndexComponentSelectorPrivilege("all", Predicates.always());
2123
public static final IndexComponentSelectorPrivilege DATA = new IndexComponentSelectorPrivilege(
@@ -40,7 +42,7 @@ public static Set<IndexComponentSelectorPrivilege> get(Set<String> indexPrivileg
4042
}
4143

4244
public static Map<IndexComponentSelectorPrivilege, Set<String>> partitionBySelectorPrivilege(String... indexPrivileges) {
43-
return partitionBySelectorPrivilege(Set.of(indexPrivileges));
45+
return partitionBySelectorPrivilege(newHashSet(indexPrivileges));
4446
}
4547

4648
public static Map<IndexComponentSelectorPrivilege, Set<String>> partitionBySelectorPrivilege(Set<String> indexPrivileges) {

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStore.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,12 @@ public class ReservedRolesStore implements BiConsumer<Set<String>, ActionListene
101101
new RoleDescriptor.RemoteIndicesPrivileges(
102102
RoleDescriptor.IndicesPrivileges.builder()
103103
.indices("*")
104-
.privileges("monitor", "read", "view_index_metadata", "read_cross_cluster")
104+
.privileges(
105+
// TODO are there edge-cases where this is a bad idea?
106+
DataStream.isFailureStoreFeatureFlagEnabled()
107+
? new String[] { "monitor", "read", "view_index_metadata", "read_cross_cluster", "read_failure_store" }
108+
: new String[] { "monitor", "read", "view_index_metadata", "read_cross_cluster" }
109+
)
105110
.allowRestrictedIndices(true)
106111
.build(),
107112
"*"

x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/IndexPrivilegeTests.java

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,32 +58,26 @@ public void testOrderingOfPrivilegeNames() throws Exception {
5858
}
5959

6060
public void testFindPrivilegesThatGrant() {
61-
assertThat(findPrivilegesThatGrant(TransportSearchAction.TYPE.name()), equalTo(List.of("read", "read_failure_store", "all")));
61+
assertThat(findPrivilegesThatGrant(TransportSearchAction.TYPE.name()), equalTo(List.of("read", "all")));
6262
assertThat(findPrivilegesThatGrant(TransportIndexAction.NAME), equalTo(List.of("create_doc", "create", "index", "write", "all")));
6363
assertThat(findPrivilegesThatGrant(TransportUpdateAction.NAME), equalTo(List.of("index", "write", "all")));
6464
assertThat(findPrivilegesThatGrant(TransportDeleteAction.NAME), equalTo(List.of("delete", "write", "all")));
6565
assertThat(
6666
findPrivilegesThatGrant(IndicesStatsAction.NAME),
67-
equalTo(List.of("monitor", "manage", "manage_failure_store_internal", "cross_cluster_replication", "all"))
68-
);
69-
assertThat(
70-
findPrivilegesThatGrant(RefreshAction.NAME),
71-
equalTo(List.of("maintenance", "manage", "manage_failure_store_internal", "all"))
67+
equalTo(List.of("monitor", "manage", "cross_cluster_replication", "all"))
7268
);
69+
assertThat(findPrivilegesThatGrant(RefreshAction.NAME), equalTo(List.of("maintenance", "manage", "all")));
7370
}
7471

7572
public void testPrivilegesForRollupFieldCapsAction() {
7673
final Collection<String> privileges = findPrivilegesThatGrant(GetRollupIndexCapsAction.NAME);
77-
assertThat(
78-
Set.copyOf(privileges),
79-
equalTo(Set.of("manage", "all", "read_failure_store", "view_index_metadata", "read", "manage_failure_store_internal"))
80-
);
74+
assertThat(Set.copyOf(privileges), equalTo(Set.of("manage", "all", "view_index_metadata", "read")));
8175
}
8276

8377
public void testPrivilegesForGetCheckPointAction() {
8478
assertThat(
8579
findPrivilegesThatGrant(GetCheckpointAction.NAME),
86-
containsInAnyOrder("monitor", "view_index_metadata", "manage", "manage_failure_store_internal", "all")
80+
containsInAnyOrder("monitor", "view_index_metadata", "manage", "all")
8781
);
8882
}
8983

x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStore.java

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -556,11 +556,11 @@ public static void buildRoleFromDescriptors(
556556
}
557557
for (Map.Entry<Set<String>, MergeableIndicesPrivilege> entry : restrictedIndicesPrivilegesMap.entrySet()) {
558558
MergeableIndicesPrivilege indicesPrivilege = entry.getValue();
559+
FieldPermissions fieldPermissions = fieldPermissionsCache.getFieldPermissions(indicesPrivilege.fieldPermissionsDefinition);
560+
String[] indices = indicesPrivilege.indices.toArray(Strings.EMPTY_ARRAY);
559561
Map<IndexComponentSelectorPrivilege, Set<String>> split = IndexComponentSelectorPrivilege.partitionBySelectorPrivilege(
560562
indicesPrivilege.privileges
561563
);
562-
FieldPermissions fieldPermissions = fieldPermissionsCache.getFieldPermissions(indicesPrivilege.fieldPermissionsDefinition);
563-
String[] indices = indicesPrivilege.indices.toArray(Strings.EMPTY_ARRAY);
564564
for (Map.Entry<IndexComponentSelectorPrivilege, Set<String>> privilegesBySelector : split.entrySet()) {
565565
IndexPrivilege indexPrivilege = IndexPrivilege.get(privilegesBySelector.getValue());
566566
assert indexPrivilege.getSelectorPrivilege() == privilegesBySelector.getKey();
@@ -569,18 +569,28 @@ public static void buildRoleFromDescriptors(
569569
}
570570

571571
remoteIndicesPrivilegesByCluster.forEach((clusterAliasKey, remoteIndicesPrivilegesForCluster) -> {
572-
remoteIndicesPrivilegesForCluster.forEach(
573-
(privilege) -> builder.addRemoteIndicesGroup(
574-
clusterAliasKey,
575-
fieldPermissionsCache.getFieldPermissions(
576-
new FieldPermissionsDefinition(privilege.getGrantedFields(), privilege.getDeniedFields())
577-
),
578-
privilege.getQuery() == null ? null : newHashSet(privilege.getQuery()),
579-
IndexPrivilege.get(newHashSet(Objects.requireNonNull(privilege.getPrivileges()))),
580-
privilege.allowRestrictedIndices(),
581-
newHashSet(Objects.requireNonNull(privilege.getIndices())).toArray(new String[0])
582-
)
583-
);
572+
remoteIndicesPrivilegesForCluster.forEach((privilege) -> {
573+
FieldPermissions fieldPermissions = fieldPermissionsCache.getFieldPermissions(
574+
new FieldPermissionsDefinition(privilege.getGrantedFields(), privilege.getDeniedFields())
575+
);
576+
Set<BytesReference> query = privilege.getQuery() == null ? null : newHashSet(privilege.getQuery());
577+
String[] indices = newHashSet(Objects.requireNonNull(privilege.getIndices())).toArray(new String[0]);
578+
Map<IndexComponentSelectorPrivilege, Set<String>> split = IndexComponentSelectorPrivilege.partitionBySelectorPrivilege(
579+
Objects.requireNonNull(privilege.getPrivileges())
580+
);
581+
for (Map.Entry<IndexComponentSelectorPrivilege, Set<String>> privilegesBySelector : split.entrySet()) {
582+
IndexPrivilege indexPrivilege = IndexPrivilege.get(privilegesBySelector.getValue());
583+
assert indexPrivilege.getSelectorPrivilege() == privilegesBySelector.getKey();
584+
builder.addRemoteIndicesGroup(
585+
clusterAliasKey,
586+
fieldPermissions,
587+
query,
588+
indexPrivilege,
589+
privilege.allowRestrictedIndices(),
590+
indices
591+
);
592+
}
593+
});
584594
});
585595

586596
if (remoteClusterPermissions.hasAnyPrivileges()) {

x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/rest/action/privilege/RestGetBuiltinPrivilegesAction.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,12 @@
2424
import org.elasticsearch.xpack.core.security.action.privilege.GetBuiltinPrivilegesRequest;
2525
import org.elasticsearch.xpack.core.security.action.privilege.GetBuiltinPrivilegesResponse;
2626
import org.elasticsearch.xpack.core.security.action.privilege.GetBuiltinPrivilegesResponseTranslator;
27+
import org.elasticsearch.xpack.core.security.authz.privilege.IndexPrivilege;
2728
import org.elasticsearch.xpack.security.authz.store.NativeRolesStore;
2829
import org.elasticsearch.xpack.security.rest.action.SecurityBaseRestHandler;
2930

3031
import java.io.IOException;
32+
import java.util.Arrays;
3133
import java.util.List;
3234

3335
import static org.elasticsearch.rest.RestRequest.Method.GET;
@@ -71,14 +73,24 @@ public RestResponse buildResponse(GetBuiltinPrivilegesResponse response, XConten
7173
final var translatedResponse = responseTranslator.translate(response);
7274
builder.startObject();
7375
builder.array("cluster", translatedResponse.getClusterPrivileges());
74-
builder.array("index", translatedResponse.getIndexPrivileges());
76+
// TODO remove the filter once we can update docs tests again
77+
builder.array("index", filterOutFailureStorePrivileges(translatedResponse));
7578
String[] remoteClusterPrivileges = translatedResponse.getRemoteClusterPrivileges();
7679
if (remoteClusterPrivileges.length > 0) { // remote clusters are not supported in stateless mode, so hide entirely
7780
builder.array("remote_cluster", remoteClusterPrivileges);
7881
}
7982
builder.endObject();
8083
return new RestResponse(RestStatus.OK, builder);
8184
}
85+
86+
private static String[] filterOutFailureStorePrivileges(GetBuiltinPrivilegesResponse translatedResponse) {
87+
return Arrays.stream(translatedResponse.getIndexPrivileges())
88+
.filter(
89+
p -> false == (p.equals(IndexPrivilege.READ_FAILURE_STORE.getSingleName())
90+
|| p.equals(IndexPrivilege.MANAGE_FAILURE_STORE_INTERNAL.getSingleName()))
91+
)
92+
.toArray(String[]::new);
93+
}
8294
}
8395
);
8496
}

0 commit comments

Comments
 (0)