-
Notifications
You must be signed in to change notification settings - Fork 25.6k
Failure Store Access Authorization #123986
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 122 commits
0ff0bf5
78170dc
4c0d584
37d5427
0789eea
9976ca1
bcd42c0
6ceb401
793215f
a531e5f
2ccd969
444112b
79d15eb
125e808
671cf70
1988a21
ffcf427
c8fc1f7
0858cd3
8fcb15c
bf3d46b
4d301c9
b03a593
d0e61c1
da43e54
8582f80
9732f8d
0c848e4
83f2148
fc01664
79433cb
6ae9f84
66ccd33
7e1e2c0
37dd755
aae20bd
d434496
253f6ab
5922f1f
8f2eddc
e7fcf93
17855ab
4a44748
481da2a
8036ecf
d470e5a
12d00b8
16668b0
879b2b6
6b9640b
f6b6cfb
cafd8d2
c2baa5b
baf63ed
22b861f
2bc314e
18258c1
cd4897b
6422450
79a7fd5
747597e
b05f82b
a603121
172141f
20f4c5c
aae2ace
183cebc
35a9935
efd11b5
95d6369
fa783df
126d615
2a654ba
8b1fedb
47c30cc
55c88db
58e938b
4456c2d
a750b38
df8c04d
674277a
dfe957a
ba33b7c
5a81747
1e33a1f
2bd7437
94b71b7
abcb1a3
e555f74
9aafa69
ab87f55
1b96a23
776d49a
39995f8
f76392a
6b0b6c9
d728fd6
2a22090
375fe69
365b2b8
db2be5d
28f207f
084ac8c
d8ed014
be718df
400a1f7
fb599ca
79d50be
0c4ec24
c8205fb
599658d
aa74147
a3e6429
e77fb81
e8d9542
0f01492
4d7d0f5
a1e9c5b
6a938f1
f7e1690
49f9c4c
ca566e8
8efd2d2
4f56acc
24db961
240007e
a5b5ac4
2f218db
8222abc
bdf134a
092371e
ff82c48
903941e
5d0d5d8
da81d50
cd6e74a
e5d3447
fc5c405
dae2ce8
af90738
82959d7
3d66d16
8020982
1667883
063954b
758fadb
4590f04
d78cc3e
3b6e030
0b09483
2ccbcdf
a2ea6f2
d3f50dc
4ca9978
b23f04c
fa467f4
2931c85
21f1218
9cb1db6
75dbd7b
1ee4988
917b2c7
2bb84a0
1698536
80619ec
f7c5c8e
bfe9448
d05ddcf
6465b7a
5b71fb7
6dd03c6
75224d8
a5b59bb
91879e7
ff94545
998ad64
3c04acf
21c920a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,7 +27,6 @@ | |
| import java.util.List; | ||
| import java.util.Set; | ||
| import java.util.concurrent.TimeUnit; | ||
| import java.util.function.Supplier; | ||
|
|
||
| import static org.elasticsearch.index.mapper.MapperService.SINGLE_MAPPING_NAME; | ||
| import static org.elasticsearch.indices.SystemIndices.EXTERNAL_SYSTEM_INDEX_ACCESS_CONTROL_HEADER_KEY; | ||
|
|
@@ -48,7 +47,7 @@ public class IndexAbstractionResolverTests extends ESTestCase { | |
| private String dateTimeIndexTomorrow; | ||
|
|
||
| // Only used when resolving wildcard expressions | ||
| private final Supplier<Set<String>> defaultMask = () -> Set.of("index1", "index2", "data-stream1"); | ||
| private final Set<String> defaultMask = Set.of("index1", "index2", "data-stream1"); | ||
|
|
||
| @Override | ||
| public void setUp() throws Exception { | ||
|
|
@@ -215,13 +214,11 @@ public void testResolveIndexAbstractions() { | |
|
|
||
| public void testIsIndexVisible() { | ||
| assertThat(isIndexVisible("index1", null), is(true)); | ||
| assertThat(isIndexVisible("index1", "*"), is(true)); | ||
| assertThat(isIndexVisible("index1", "data"), is(true)); | ||
| assertThat(isIndexVisible("index1", "failures"), is(false)); // * | ||
| // * Indices don't have failure components so the failure component is not visible | ||
|
|
||
| assertThat(isIndexVisible("data-stream1", null), is(true)); | ||
| assertThat(isIndexVisible("data-stream1", "*"), is(true)); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems to be leftover from the #121900 PR, right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yup, I'll note this down to look into in a follow up. |
||
| assertThat(isIndexVisible("data-stream1", "data"), is(true)); | ||
| assertThat(isIndexVisible("data-stream1", "failures"), is(true)); | ||
| } | ||
|
|
@@ -290,14 +287,14 @@ public void testIsNetNewSystemIndexVisible() { | |
| indexAbstractionResolver = new IndexAbstractionResolver(indexNameExpressionResolver); | ||
|
|
||
| // this covers the GET * case -- with system access, you can see everything | ||
| assertThat(isIndexVisible("other", "*"), is(true)); | ||
| assertThat(isIndexVisible(".foo", "*"), is(true)); | ||
| assertThat(isIndexVisible(".bar", "*"), is(true)); | ||
| assertThat(isIndexVisible("other", null), is(true)); | ||
| assertThat(isIndexVisible(".foo", null), is(true)); | ||
| assertThat(isIndexVisible(".bar", null), is(true)); | ||
|
|
||
| // but if you don't ask for hidden and aliases, you won't see hidden indices or aliases, naturally | ||
| assertThat(isIndexVisible("other", "*", noHiddenNoAliases), is(true)); | ||
| assertThat(isIndexVisible(".foo", "*", noHiddenNoAliases), is(false)); | ||
| assertThat(isIndexVisible(".bar", "*", noHiddenNoAliases), is(false)); | ||
| assertThat(isIndexVisible("other", null, noHiddenNoAliases), is(true)); | ||
| assertThat(isIndexVisible(".foo", null, noHiddenNoAliases), is(false)); | ||
| assertThat(isIndexVisible(".bar", null, noHiddenNoAliases), is(false)); | ||
| } | ||
|
|
||
| { | ||
|
|
@@ -311,14 +308,14 @@ public void testIsNetNewSystemIndexVisible() { | |
| indexAbstractionResolver = new IndexAbstractionResolver(indexNameExpressionResolver); | ||
|
|
||
| // this covers the GET * case -- without system access, you can't see everything | ||
| assertThat(isIndexVisible("other", "*"), is(true)); | ||
| assertThat(isIndexVisible(".foo", "*"), is(false)); | ||
| assertThat(isIndexVisible(".bar", "*"), is(false)); | ||
| assertThat(isIndexVisible("other", null), is(true)); | ||
| assertThat(isIndexVisible(".foo", null), is(false)); | ||
| assertThat(isIndexVisible(".bar", null), is(false)); | ||
|
|
||
| // no difference here in the datastream case, you can't see these then, either | ||
| assertThat(isIndexVisible("other", "*", noHiddenNoAliases), is(true)); | ||
| assertThat(isIndexVisible(".foo", "*", noHiddenNoAliases), is(false)); | ||
| assertThat(isIndexVisible(".bar", "*", noHiddenNoAliases), is(false)); | ||
| assertThat(isIndexVisible("other", null, noHiddenNoAliases), is(true)); | ||
| assertThat(isIndexVisible(".foo", null, noHiddenNoAliases), is(false)); | ||
| assertThat(isIndexVisible(".bar", null, noHiddenNoAliases), is(false)); | ||
| } | ||
|
|
||
| { | ||
|
|
@@ -333,14 +330,14 @@ public void testIsNetNewSystemIndexVisible() { | |
| indexAbstractionResolver = new IndexAbstractionResolver(indexNameExpressionResolver); | ||
|
|
||
| // this covers the GET * case -- with product (only) access, you can't see everything | ||
| assertThat(isIndexVisible("other", "*"), is(true)); | ||
| assertThat(isIndexVisible(".foo", "*"), is(false)); | ||
| assertThat(isIndexVisible(".bar", "*"), is(false)); | ||
| assertThat(isIndexVisible("other", null), is(true)); | ||
| assertThat(isIndexVisible(".foo", null), is(false)); | ||
| assertThat(isIndexVisible(".bar", null), is(false)); | ||
|
|
||
| // no difference here in the datastream case, you can't see these then, either | ||
| assertThat(isIndexVisible("other", "*", noHiddenNoAliases), is(true)); | ||
| assertThat(isIndexVisible(".foo", "*", noHiddenNoAliases), is(false)); | ||
| assertThat(isIndexVisible(".bar", "*", noHiddenNoAliases), is(false)); | ||
| assertThat(isIndexVisible("other", null, noHiddenNoAliases), is(true)); | ||
| assertThat(isIndexVisible(".foo", null, noHiddenNoAliases), is(false)); | ||
| assertThat(isIndexVisible(".bar", null, noHiddenNoAliases), is(false)); | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -366,8 +363,15 @@ private List<String> resolveAbstractionsSelectorAllowed(List<String> expressions | |
| return resolveAbstractions(expressions, IndicesOptions.strictExpandOpen(), defaultMask); | ||
| } | ||
|
|
||
| private List<String> resolveAbstractions(List<String> expressions, IndicesOptions indicesOptions, Supplier<Set<String>> mask) { | ||
| return indexAbstractionResolver.resolveIndexAbstractions(expressions, indicesOptions, projectMetadata, mask, (idx) -> true, true); | ||
| private List<String> resolveAbstractions(List<String> expressions, IndicesOptions indicesOptions, Set<String> mask) { | ||
| return indexAbstractionResolver.resolveIndexAbstractions( | ||
| expressions, | ||
| indicesOptions, | ||
| projectMetadata, | ||
| (ignored) -> mask, | ||
| (ignored, nothing) -> true, | ||
| true | ||
| ); | ||
| } | ||
|
|
||
| private boolean isIndexVisible(String index, String selector) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -39,7 +39,6 @@ | |
| import java.util.Map; | ||
| import java.util.Objects; | ||
| import java.util.Set; | ||
| import java.util.function.Supplier; | ||
| import java.util.stream.Collectors; | ||
|
|
||
| import static org.elasticsearch.action.ValidateActions.addValidationError; | ||
|
|
@@ -281,22 +280,23 @@ default AuthorizationInfo getAuthenticatedUserAuthorizationInfo() { | |
| } | ||
|
|
||
| /** | ||
| * Used to retrieve index-like resources that the user has access to, for a specific access action type, | ||
| * Used to retrieve index-like resources that the user has access to, for a specific access action type and selector, | ||
| * at a specific point in time (for a fixed cluster state view). | ||
| * It can also be used to check if a specific resource name is authorized (access to the resource name | ||
| * can be authorized even if it doesn't exist). | ||
| */ | ||
| interface AuthorizedIndices { | ||
| /** | ||
| * Returns all the index-like resource names that are available and accessible for an action type by a user, | ||
| * Returns all the index-like resource names that are available and accessible for an action type and selector by a user, | ||
| * at a fixed point in time (for a single cluster state view). | ||
| * The result is cached and subsequent calls to this method are idempotent. | ||
| */ | ||
| Supplier<Set<String>> all(); | ||
| Set<String> all(@Nullable String selector); | ||
|
||
|
|
||
| /** | ||
| * Checks if an index-like resource name is authorized, for an action by a user. The resource might or might not exist. | ||
| */ | ||
| boolean check(String name); | ||
| boolean check(String name, @Nullable String selector); | ||
n1v0lg marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| /** | ||
|
|
@@ -366,6 +366,15 @@ public ActionRequestValidationException validate(ActionRequestValidationExceptio | |
| && application.length == 0) { | ||
| validationException = addValidationError("must specify at least one privilege", validationException); | ||
| } | ||
| if (index != null) { | ||
n1v0lg marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| for (RoleDescriptor.IndicesPrivileges indexPrivilege : index) { | ||
| if (indexPrivilege.getPrivileges() != null | ||
| && Arrays.stream(indexPrivilege.getPrivileges()) | ||
| .anyMatch(p -> "read_failure_store".equals(p) || "manage_failure_store".equals(p))) { | ||
| validationException = addValidationError("checking failure store privileges is not supported", validationException); | ||
| } | ||
| } | ||
| } | ||
| return validationException; | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,6 +6,7 @@ | |
| */ | ||
| package org.elasticsearch.xpack.core.security.authz.accesscontrol; | ||
|
|
||
| import org.elasticsearch.action.support.IndexComponentSelector; | ||
| import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; | ||
| import org.elasticsearch.common.io.stream.StreamOutput; | ||
| import org.elasticsearch.common.util.CachedSupplier; | ||
|
|
@@ -62,7 +63,12 @@ protected IndicesAccessControl(IndicesAccessControl copy) { | |
| @Nullable | ||
| public IndexAccessControl getIndexPermissions(String index) { | ||
| Tuple<String, String> indexAndSelector = IndexNameExpressionResolver.splitSelectorExpression(index); | ||
| return this.getAllIndexPermissions().get(indexAndSelector.v1()); | ||
| return this.getAllIndexPermissions() | ||
|
||
| .get( | ||
| IndexComponentSelector.FAILURES.equals(IndexComponentSelector.getByKey(indexAndSelector.v2())) | ||
| ? index | ||
| : indexAndSelector.v1() | ||
| ); | ||
| } | ||
|
|
||
| public boolean hasIndexPermissions(String index) { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.