[Fleet] Update /uninstall_tokens API to use exact matching for policy_id query (#225113)

## Summary

Closes #215725 

- Updated the regex to not wrap the policy_id in wildcards so that only
exact matches based on the query would be returned.

Before: 


https://github.com/user-attachments/assets/ad2bd58a-4dad-48a6-85e1-980630753a93




After: 


https://github.com/user-attachments/assets/2e7ebc97-e5ac-401e-8b23-ea54f758e35f


### Checklist

Check the PR satisfies following conditions. 

Reviewers should verify this PR satisfies this list as well.

- [ ] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md)
- [ ]
[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials
- [ ] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
- [ ] If a plugin configuration key changed, check if it needs to be
allowlisted in the cloud and added to the [docker
list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)
- [ ] This was checked for breaking HTTP API changes, and any breaking
changes have been approved by the breaking-change committee. The
`release_note:breaking` label should be applied in these situations.
- [ ] [Flaky Test
Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was
used on any tests changed
- [ ] The PR description includes the appropriate Release Notes section,
and the correct `release_note:*` label is applied per the
[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)

### Identify risks

N/A

---------

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
Mason Herron 2025-06-25 07:52:11 -06:00 committed by GitHub
parent 5f2a519926
commit 1184cc2832
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 12 additions and 4 deletions

View file

@ -239,6 +239,11 @@ export class UninstallTokenService implements UninstallTokenServiceInterface {
: undefined;
}
private prepareExactPolicyIdQuery(policyId: string | undefined): string | undefined {
if (!policyId) return undefined;
// Escape special characters but don't add wildcards for exact matching
return policyId.replace(new RegExp(/[@#&*+()\[\]{}|.?~"<]/, 'g'), '\\$&');
}
private prepareRegexpQuery(str: string | undefined): string | undefined {
return this.prepareSearchString(str, /[@#&*+()[\]{}|.?~"<]/, '.*');
}
@ -279,7 +284,10 @@ export class UninstallTokenService implements UninstallTokenServiceInterface {
`getting token metadata with policyIdSearchTerm [${policyIdSearchTerm}] and poliyNameSearchTerm [${policyNameSearchTerm}] and excluded policy ids [${excludedPolicyIds}]`
);
const policyIdFilter = this.prepareRegexpQuery(policyIdSearchTerm);
// If theres a search term and not just a policy id, then we use partial, otherwise, use exact matching
const policyIdFilter = policyNameSearchTerm
? this.prepareRegexpQuery(policyIdSearchTerm)
: this.prepareExactPolicyIdQuery(policyIdSearchTerm);
let policyIdsFoundByName: string[] | undefined;
const policyNameSearchString = this.prepareQueryStringQuery(policyNameSearchTerm);

View file

@ -264,7 +264,7 @@ export default function (providerContext: FtrProviderContext) {
expect(body.items[0].policy_id).to.equal(selectedPolicyId);
});
it('should return token metadata for partial policyID if found', async () => {
it('should not return token metadata for partial policyID', async () => {
const selectedPolicyId = generatedPolicyArray[2].id;
const response = await supertest
@ -275,10 +275,10 @@ export default function (providerContext: FtrProviderContext) {
.expect(200);
const body: GetUninstallTokensMetadataResponse = response.body;
expect(body.total).to.equal(1);
expect(body.total).to.equal(0);
expect(body.page).to.equal(1);
expect(body.perPage).to.equal(20);
expect(body.items[0].policy_id).to.equal(selectedPolicyId);
expect(body.items).to.eql([]);
});
it('should not return token metadata by policy name', async () => {