Skip to content

Commit 4ea349d

Browse files
authored
More robust and consistent allowAll indicesAccessControl (#79415)
This PR ensures that AllowAllIndicesAccessControl is able to behave well for all superclass's methods. Previously it throws NPE when it is asked about Fls/Dls usage because it has a null index permissions map as a placeholder. In this PR, we also get rid of the null and also mandate non-null in the constructor of IndicesAccessControl. In additional, whether a role has DLS/FLS and whether an AllowAllIndicesAccessControl should be used for short circuit is determined more consistently. In both places, whether a group has total access to all indices is used as part of the criteria. Previously it is possible that the role reports it has DLS/FLS while the cindicesAccessControl does not have it. This could happen when one of the group has DLS/FLS but another group has total access to all indices. In this case, the code now correctly reports no DLS/FLS in both places. Resolves: #79361
1 parent 3151198 commit 4ea349d

File tree

4 files changed

+54
-11
lines changed

4 files changed

+54
-11
lines changed

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/accesscontrol/IndicesAccessControl.java

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public class IndicesAccessControl {
4040

4141
public IndicesAccessControl(boolean granted, Map<String, IndexAccessControl> indexPermissions) {
4242
this.granted = granted;
43-
this.indexPermissions = indexPermissions;
43+
this.indexPermissions = Objects.requireNonNull(indexPermissions);
4444
}
4545

4646
/**
@@ -292,7 +292,7 @@ private static class AllowAllIndicesAccessControl extends IndicesAccessControl {
292292
private final IndexAccessControl allowAllIndexAccessControl = new IndexAccessControl(true, null, null);
293293

294294
private AllowAllIndicesAccessControl() {
295-
super(true, null);
295+
super(true, Map.of());
296296
}
297297

298298
@Override
@@ -301,13 +301,8 @@ public IndexAccessControl getIndexPermissions(String index) {
301301
}
302302

303303
@Override
304-
public boolean isGranted() {
305-
return true;
306-
}
307-
308-
@Override
309-
public Collection<?> getDeniedIndices() {
310-
return Set.of();
304+
public String toString() {
305+
return "AllowAllIndicesAccessControl{}";
311306
}
312307
}
313308

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ private IndicesPermission(Automaton restrictedNamesAutomaton, Group[] groups) {
8686
this.restrictedNamesAutomaton = restrictedNamesAutomaton;
8787
this.characterRunAutomaton = new CharacterRunAutomaton(restrictedNamesAutomaton);
8888
this.groups = groups;
89-
this.hasFieldOrDocumentLevelSecurity = Arrays.stream(groups)
90-
.anyMatch(g -> g.hasQuery() || g.fieldPermissions.hasFieldLevelSecurity());
89+
this.hasFieldOrDocumentLevelSecurity = Arrays.stream(groups).noneMatch(Group::isTotal)
90+
&& Arrays.stream(groups).anyMatch(g -> g.hasQuery() || g.fieldPermissions.hasFieldLevelSecurity());
9191
}
9292

9393
/**

x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/accesscontrol/IndicesAccessControlTests.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@
1616
import org.elasticsearch.xpack.core.security.authz.permission.FieldPermissionsDefinition;
1717

1818
import java.util.Collections;
19+
import java.util.Map;
1920
import java.util.Set;
2021

22+
import static org.hamcrest.Matchers.emptyIterable;
2123
import static org.hamcrest.Matchers.equalTo;
2224
import static org.hamcrest.Matchers.is;
2325
import static org.hamcrest.Matchers.notNullValue;
@@ -122,4 +124,19 @@ public void testSLimitedIndicesAccessControl() {
122124
assertThat(result.getIndexPermissions("_index").getDocumentPermissions().getQueries(), is(nullValue()));
123125
assertThat(result.getIndexPermissions("_index").getDocumentPermissions().getLimitedByQueries(), equalTo(queries));
124126
}
127+
128+
public void testAllowAllIndicesAccessControl() {
129+
final IndicesAccessControl allowAll = IndicesAccessControl.allowAll();
130+
final IndexAccessControl indexAccessControl = allowAll.getIndexPermissions(randomAlphaOfLengthBetween(3, 8));
131+
assertThat(indexAccessControl.isGranted(), is(true));
132+
assertThat(indexAccessControl.getDocumentPermissions(), is(DocumentPermissions.allowAll()));
133+
assertThat(indexAccessControl.getFieldPermissions(), is(FieldPermissions.DEFAULT));
134+
assertThat(allowAll.getDeniedIndices(), emptyIterable());
135+
assertThat(allowAll.getFieldAndDocumentLevelSecurityUsage(), is(IndicesAccessControl.DlsFlsUsage.NONE));
136+
assertThat(allowAll.getIndicesWithFieldOrDocumentLevelSecurity(), emptyIterable());
137+
138+
final IndicesAccessControl indicesAccessControl = new IndicesAccessControl(randomBoolean(), Map.of());
139+
assertThat(allowAll.limitIndicesAccessControl(indicesAccessControl), is(indicesAccessControl));
140+
assertThat(indicesAccessControl.limitIndicesAccessControl(allowAll), is(indicesAccessControl));
141+
}
125142
}

x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/accesscontrol/IndicesPermissionTests.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,37 @@ public void testAuthorizationForMappingUpdates() {
503503
}
504504
}
505505

506+
public void testIndicesPermissionHasFieldOrDocumentLevelSecurity() {
507+
// Make sure we have at least one of fieldPermissions and documentPermission
508+
final FieldPermissions fieldPermissions = randomBoolean() ?
509+
new FieldPermissions(new FieldPermissionsDefinition(Strings.EMPTY_ARRAY, Strings.EMPTY_ARRAY)) :
510+
FieldPermissions.DEFAULT;
511+
final Set<BytesReference> queries;
512+
if (fieldPermissions == FieldPermissions.DEFAULT) {
513+
queries = Set.of(new BytesArray("a query"));
514+
} else {
515+
queries = randomBoolean() ? Set.of(new BytesArray("a query")) : null;
516+
}
517+
518+
final IndicesPermission indicesPermission1 = new IndicesPermission.Builder(RESTRICTED_INDICES_AUTOMATON)
519+
.addGroup(IndexPrivilege.ALL, fieldPermissions, queries, randomBoolean(), "*")
520+
.build();
521+
assertThat(indicesPermission1.hasFieldOrDocumentLevelSecurity(), is(true));
522+
523+
// IsTotal means no DLS/FLS
524+
final IndicesPermission indicesPermission2 = new IndicesPermission.Builder(RESTRICTED_INDICES_AUTOMATON)
525+
.addGroup(IndexPrivilege.ALL, FieldPermissions.DEFAULT, null, true, "*")
526+
.build();
527+
assertThat(indicesPermission2.hasFieldOrDocumentLevelSecurity(), is(false));
528+
529+
// IsTotal means NO DLS/FLS even when there is another group that has DLS/FLS
530+
final IndicesPermission indicesPermission3 = new IndicesPermission.Builder(RESTRICTED_INDICES_AUTOMATON)
531+
.addGroup(IndexPrivilege.ALL, FieldPermissions.DEFAULT, null, true, "*")
532+
.addGroup(IndexPrivilege.NONE, fieldPermissions, queries, randomBoolean(), "*")
533+
.build();
534+
assertThat(indicesPermission3.hasFieldOrDocumentLevelSecurity(), is(false));
535+
}
536+
506537
private static IndexMetadata createIndexMetadata(String name) {
507538
Settings.Builder settingsBuilder = Settings.builder()
508539
.put(IndexMetadata.SETTING_VERSION_CREATED, Version.CURRENT)

0 commit comments

Comments
 (0)