Skip to content
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

Extend support of allowedFields to getMatchingFieldNames and getAllFields #106862

Merged
merged 3 commits into from
Mar 28, 2024

Conversation

javanna
Copy link
Member

@javanna javanna commented Mar 28, 2024

The SearchExecutionContext supports the notion of allowed fields, provided via a specific setter method. Fields are though only filtered for the getFieldType method. There needs to be consistency between getMatchingFieldNames and getFieldType. In fact there are places in the code where getMatchingFieldNames is called to resolve field name patterns, and later getFieldType is called on each of the resolved fields. If the former resolves to one field that we can't retrieve a field type for, that is unexpected and to be considered a bug.

In addition, this commit adds consistency for getAllFields: this is only called by field caps, hence a different codepath that does not seem to set allowed fields for now, but it's important for the context to provide consistency around fields access, especially for methods that are as broad as getAllFields, despite their currently very specific usage.

This surfaced as we are trying to move fetching of the _ignored field to use value fetchers, which use a search execution context and resolve the field type, whereas until now they are retrieved directly via StoredFieldsPhase and completely bypass such check.

This commit also adds a test that was missing around verifying that SearchExecutionContext applies the allowedFields predicate when provided.

…elds

The SearchExecutionContext supports the notion of allowed fields, provided via a specific setter method.
Fields are though only filtered for the getFieldType method. There needs to be consistency between getMatchingFieldNames and getFieldType.
In fact there are places in the code where getMatchingFieldNames is called to resolve field name patterns, and later getFieldType is called
on each of the resolved fields. If the former resolves to one field that we can't retrieve a field type for, that is unexpected and to be considered a bug.

In addition, this commit adds consistency for getAllFields: this is only called by field caps, hence a different codepath that does not seem to set allowed fields
for now, but it's important for the context to provide consistency around fields access, especially for methods that are as broad as getAllFields,
despite their currently very specific usage.

This surfaced as we are trying to move fetching of the `_ignored` field to use value fetchers, which use a search execution context and resolve the field type,
whereas until now they are retrieved directly via StoredFieldsPhase and completely bypass such check.

This commit also adds a test that was missing around verifying that SearchExecutionContext applies the allowedFields predicate when provided.
@javanna javanna added >bug :Search Foundations/Mapping Index mappings, including merging and defining field types :Security/Security Security issues without another label v8.14.0 labels Mar 28, 2024
@elasticsearchmachine elasticsearchmachine added Team:Search Meta label for search team Team:Security Meta label for security team labels Mar 28, 2024
@elasticsearchmachine
Copy link
Collaborator

Hi @javanna, I've created a changelog YAML for you.

@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/es-security (Team:Security)

@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/es-search (Team:Search)

@javanna javanna removed :Security/Security Security issues without another label Team:Security Meta label for security team labels Mar 28, 2024
}
}
}
return matches;
// If the field is not allowed, behave as if it is not mapped
return allowedFields == null ? matches : matches.stream().filter(allowedFields).collect(Collectors.toSet());
Copy link
Contributor

@salvatore-campagna salvatore-campagna Mar 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see here and below we always need to check for allowedFields to be null or not to decide if we need to filter one or more fields. I am wondering if we should require it to be not null and force the caller to use an identity predicate lambda (fieldName -> true) in case no field is filtered out.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not too sure what is best here. Skip the filtering entirely when the predicate is null, or always filter although the predicate always returns true? I went for the former, which leaves things as close as they are outside of api keys queries (when setAllowedFields is not called).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that, maybe, performance-wise not applying the filter at all might be better if there is nothing to filter out...which is the reason why I said it looks good to me...it is just that all those null checks are annoying for me.

@salvatore-campagna
Copy link
Contributor

salvatore-campagna commented Mar 28, 2024

LGTM...I just left a couple of comments.

Copy link
Contributor

@tteofili tteofili left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the changes look good, Luca ;)

}
}
}
return matches;
// If the field is not allowed, behave as if it is not mapped
return allowedFields == null ? matches : matches.stream().filter(allowedFields).collect(Collectors.toSet());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand correctly this is just the same we were doing before + an additional filter on allowed fields based n field names...maybe we can just extract the existing method into something like a private getMatchingFieldNamesInternal to which we apply the filter?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the gain compared to a single method?

@javanna javanna merged commit 917f54a into elastic:main Mar 28, 2024
14 checks passed
@javanna javanna deleted the fix/allowed_fields_support branch March 28, 2024 14:10
salvatore-campagna added a commit to salvatore-campagna/elasticsearch that referenced this pull request Apr 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
>bug :Search Foundations/Mapping Index mappings, including merging and defining field types Team:Search Meta label for search team v8.14.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants