Skip to content

Commit

Permalink
Replace search bar on Agent > Inventory data (#5443)
Browse files Browse the repository at this point in the history
* feat: add a search bar component

Features:
- Supports multiple query languages
- Decouple the business logic of query languages of the search bar
  component
- Ability of query language to interact with the search bar

Query language implementations
- AQL: custom implementation of the Wazuh Query Language. Include
  suggestions.
- UIQL: simple implementation (as another example)

* feat(search-bar): change the AQL implemenation to use the regular expression used in the Wazuh manager API

- Change the implementation of AQL query language to use the regular
  expression decomposition defined in the Wazuh manager API
- Adapt the tests for the tokenizer and getting the suggestions
- Enchance documentation of search bar
- Add documentation of AQL query language
- Add more fields and values for the use example in Agents section
- Add description to the query language select input

* fix(search-bar): fixes a problem hidding the suggestion popover when using the Search suggestion in AQL

- Fixes a problem hidding the suggestion popover when using the Search
  suggestion in AQL
- Fixes a problem of input text with undefined value
- Minor fixes
  - Remove `syntax` property of SearchBar component
  - Add disableFocusTrap property to the custom EuiSuggestInput component to be
    forwarded to the EuiInputPopover
  - Replace the inputRef by a reference instead of a state and pass as
    a parameter in the query language run function
  - Move the rebuiding of input text when using some suggestion that changes
    the input to be done when a related suggestion was clicked instead
    of any suggestion (exclude Search).

* feat(search-bar): add the ability to update the input of example
implemenation

- Add the ability to update the input of the search bar in the example
  implementation
- Enhance the component documentation

* feat(search-bar): add initial suggestions to AQL

- (AQL) Add the fields and an open operator group when there is no input text

* feat(search-bar): add target and rel attributes to the documentation
link of query language displayed in the popover

* feat(search-bar): enhancements in AQL and search bar documentation

- AQL enhancements:
  - documentation:
    - Enhance some descriptions
    - Enhance input processing
    - Remove intermetiate interface of EuiSuggestItem
  - Remove the intermediate interface of EuiSuggestItem. Now it is
    managed in the internal of query language instead of be built by the
    suggestion handler
  - Display suggestions when the input text is empty
  - Add the unifiedQuery field to the query language output
  - Adapt tests

- Search Bar component:
  - Enhance documentation

* feat(search-bar): Add HAQL

- Remove UIQL
- Add HAQL query language that is a high-level implementation of AQL
  - Add the query language interface
  - Add tests for tokenizer, get suggestions and
    transformSpecificQLToUnifiedQL method
  - Add documentation about the language
    - Syntax
    - Options
    - Workflow

* feat(search-bar): add test to HAQL and AQL query languages

- Add tests to HAQL and AQL query languages
- Fix suggestions for HAQL when typing as first element a value entity.
  Now there are no suggestions because the field and operator_compare
  are missing.
- Enhance documentation of HAQL and AQL
- Removed unnecesary returns of suggestion handler in the example
  implementation of search bar on Agents section

* feat(search-bar): Rename HAQL query language to WQL

- Rename query language HAQL to WQL
- Update tests
- Remove AQL usage from the implementation in the agents section

* feat(search-bar): Add more use cases to the tests of WQL query language

- Add more use cases to the test of WQL query language
- Replace some literals by constants in the WQL query language
  implementation

* feat(search-bar): enhance the documenation of query languages

* feat(search-bar): Add a popover title to replicate similar UI to the platform search bar

* feat(search-bar): wrap the user input with group operators when there is an implicit query

* feat(search-bar): add implicit query mode to WQL

- WQL
  - add implicit query mode to WQL
  - enhance query language documentation
  - renamed transformUnifiedQuery to transformUQLToQL
  - now wraps the user input if this is defined and there a implicit
    query string
  - fix a problem with the value suggestions if there is a previous
    conjunction
    - add tests cases
  - update tests
- AQL
  - enhance query language documentation
  - renamed transformUnifiedQuery to transformUQLToQL
  - add warning about the query language implementation is not updated
    to the last changes in the search bar component
  - update tests

- Search Bar
  - renamed transformUnifiedQuery to transformUQLToQL

* feat(search-bar): set the width of the syntax options popover

* feat(search-bar): unify suggestion descriptions in WQL

- Set a width for the syntax options popover
- Unify the description in the suggestions of WQL example implementation
- Update tests
- Fix minor bugs in the WQL example implementation in Agents

* feat(search-bar): add enhancements to WQL

- WQL
  - Enhance documentation
  - Add partial and "expanded" input validation
  - Add tests

* feat(search-bar): rename previousField and previousOperatorCompare in WQL

* fix(tests): update snapshot

* fix(search-bar): fix documentation link for WQL

* fix(search-bar): remove example usage of SearchBar component in Agents

* fix(search-bar): fix an error using the value suggestions in WQL

Fix an error when the last token in the input was a value and used
a value suggestion whose label contains whitespaces, the value was
not wrapped with quotes.

* feat(search-bar): add search function suggestion when the input is empty

* fix(search-bar): ensure the query language output changed to trigger the onChange handler

* feat(search-bar): allow the API query output can be redone when the search term fields changed

- Search bar:
  - Add a dependency to run the query language output
  - Adapt search bar documentation to the changes
- WQL
  - Create a new parameter called `options`
  - Moved the `implicitFilter` and `searchTerm` settings to `options`
  - Update tests
  - Update documentation

* feat(search-bar): enhance the validation of value token in WQL

* feat(search-bar): enhance search bar and WQL

Search bar:
  - Add the possibility to render buttons to the right of the input
  - Minor changes
WQL:
  - Add options.filterButtons to render filter buttons and component
    rendering
  - Extract the quoted value for the quoted token values
  - Add the `validate` parameter to validate the tokens (only available for
    `value` token)
  - Enhance language description
  - Add test related to value token validation
  - Update language documentation with this changes

* feat(search-bar): replace search bar in TableWzAPI

Replace search bar in TableWzAPI
Replace each usage of TableWzAPI
Adapt external filters

* feat(search-bar): replace search bar on Agent/Inventory data section

Replace search bar on Agents/Invetory data section
Add table columns definitions on files
Remove SyscollectorTable component

* feat(vulnerabilities): change filter by severity tooltip

* fix(test): update test and snapthost

* fix(test): update snapshot

* feat(table-wz-api): add field selection to the TableWzAPI component

Add field selection to the TableWzAPI
Possibility to save the selected fields on storage (localStorage,
sessionStorage)
Create useStateStorage that allows save the state in localStorage or
sessionStorage

* feat(search-bar): enhace search bar and WQL

Search bar:
- rename method from `transformUQLtoQL` to `transformInput`
- add a options paramenter to `transformInput` to manage when there is
  an implicit filter, that this methods can remove the filter from the
  query
- update documentation
WQL:
- rename method from `transformUQLtoQL` to `transformInput`
- add a options paramenter to `transformInput` to manage when there is
  an implicit filter, that this methods can remove the filter from the
  query
- add tests

* feat(table-wz-api): Adapt TableWzAPI usage to the recent changes when
using the search bar

Enhance Management/Decoders table

* fix(test): fixed test and update snapshot

* fix(table-wz-api): minor fixes on TableWzAPI usage

* fix: fixed prop type

* fix(search-bar): adapt search bar parameters on TableWzAPI of Agents/Inventory

* fix(table-wz-api): adapt the search bar parameters

* fix: fix search term field on TableWzAPI for composed column

* fix(table-wz-api): enhance TableWithSearchBar types and fix error HTML attributes

* fix: enhance search bar and WQL types

* fix: test snapshot

* fix: test snapshot

* fix: remove duplicated search bar

* feat: add the distinct values for the search bar suggestions in some
sections

- Add the distinct values for the search bar suggestions in some
  sections:
  - Modules > Security Configuration Assessment policy checks table
  - Modules > Vulnerabilities > Inventory table
  - Modules > MITRE ATT&CK > Inventory table
  - Management > Rules table
  - Management > Decoders table
  - Management > CDB Lists table

- Add Path column to Rules files table
- Add Path column to Decoders files table

* fix: remove exact validation for the token value due to performance problems

* fix: add suggestions for search bar in the Agents inventory data tables

* fix: fix token value validation

* fix: fix Management > Rules search bar filters

Add id field
Fix groups filter in Rule info flyout
Remove onFiltersChange handler

* fix: update the link to the documentation of WQL

* fix(search-bar): use value of value token as the value used to get the value suggestions in the search bar instead of raw token that could include " character

* fix(search-bar): fix a problem extracting value for value tokens wrapped by double quotation marks that contains the new line character and remove separation of invalid characters in the value token

- Fix tests

* fix(search-bar): update test snapshot

* fix(table-wz-api): avoid the double toast message when there is an error fetching data and replace the error.name to RequestError

* fix(search-bar): add validation for value token in WQL

* fix(search-bar): value token in message related to this is invalid

* fix(search-bar): fix error related to details.program_name suggestion in the Decoders section

* feat(search-bar): add constant to define the count of distinct values to get in the suggestions

* feat(search-bar): use constant to define the count of distinct values to get in the suggestions

* fix(search-bar): fix value suggestions in the Decoders section

* fix: add comment to constant

* workaround(search-bar): add a filter to the value suggestions in WQL

When getting the distinct values for some fields, the value could not
match the regular expression that validates them, and this causes that
the search can not be run. So, we filters the distinct values to ensure
or reduce the suggestions can be used to search. This causes some
possible values are not displayed in the suggestions. To undone this,
then the API should allow these values.

* changelog: add entry

* changelog: add entry

* changelog: add entry

* fix(search-bar): fix prop type error related to EuiSuggestItem

* fix(wql): add whitespace before closing grouping operator ) when using the suggestions

* feat(search-bar): add a debounce time to update the search bar state

* fix(search-bar): fix prop type error related to EuiSuggestItem

* fix(search-bar-wql): problem related to execute the search before the input is analyzed due to this process is debounced

* fix(search-bar-wql): remove unnued parameter in function

* fix(search-bar): fix tests

* fix(search-bar): suggestions in Modules > Vulenerabilities > Inventory
  • Loading branch information
Desvelao authored Aug 11, 2023
1 parent f987351 commit 0656efb
Show file tree
Hide file tree
Showing 10 changed files with 456 additions and 334 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ All notable changes to the Wazuh app project will be documented in this file.
- Added new global error treatment (client-side) [#4163](https://github.com/wazuh/wazuh-kibana-app/pull/4163)
- Added new CLI to generate API data from specification file [#5519](https://github.com/wazuh/wazuh-kibana-app/pull/5519)
- Added specific RBAC permissions to Security section [#5551](https://github.com/wazuh/wazuh-kibana-app/pull/5551)
- Added Refresh and Export formatted button to panels in Agents > Inventory data [#5443](https://github.com/wazuh/wazuh-kibana-app/pull/5443)

### Changed

Expand All @@ -20,7 +21,7 @@ All notable changes to the Wazuh app project will be documented in this file.
- Changed the query to search for an agent in `management/configuration`. [#5485](https://github.com/wazuh/wazuh-kibana-app/pull/5485)
- Changed the search bar in management/log to the one used in the rest of the app. [#5476](https://github.com/wazuh/wazuh-kibana-app/pull/5476)
- Changed the design of the wizard to add agents. [#5457](https://github.com/wazuh/wazuh-kibana-app/pull/5457)
- Changed the search bar in Management (Rules, Decoders, CDB List) and Modules (Vulnerabilities > Inventory, Security Configuration Assessment > Inventory > {Policy ID} > Checks, MITRE ATT&CK > Intelligence > {Resource}) [#5363](https://github.com/wazuh/wazuh-kibana-app/pull/5363) [#5442](https://github.com/wazuh/wazuh-kibana-app/pull/5442)
- Changed the search bar in Management (Rules, Decoders, CDB List) and Modules (Vulnerabilities > Inventory, Security Configuration Assessment > Inventory > {Policy ID} > Checks, MITRE ATT&CK > Intelligence > {Resource}), Agent Inventory data [#5363](https://github.com/wazuh/wazuh-kibana-app/pull/5363) [#5442](https://github.com/wazuh/wazuh-kibana-app/pull/5442) [#5443](https://github.com/wazuh/wazuh-kibana-app/pull/5443)

### Fixed

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
export { processColumns } from './process-columns'
export { portsColumns } from './ports-columns'
export { packagesColumns } from './packages-columns'
export { netaddrColumns } from './netaddr-columns';
export { netifaceColumns } from './netiface-columns';
export { processColumns } from './process-columns';
export { portsColumns } from './ports-columns';
export { packagesColumns } from './packages-columns';
export { windowsUpdatesColumns } from './windows-updates-columns';

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { KeyEquivalence } from "../../../../../common/csv-key-equivalence";

export const netaddrColumns = [
{ field: 'iface', searchable: true, sortable: true },
{ field: 'address', searchable: true, sortable: true },
{ field: 'netmask', searchable: true, sortable: true },
{ field: 'proto', searchable: true, sortable: true },
{ field: 'broadcast', searchable: true, sortable: true },
].map(({field, ...rest}) => ({...rest, field, name: rest.name || KeyEquivalence[field] || field}));
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { KeyEquivalence } from "../../../../../common/csv-key-equivalence";

export const netifaceColumns = [
{ field: 'name', searchable: true, sortable: true, },
{ field: 'mac', searchable: true, sortable: true },
{ field: 'state', searchable: true, name: 'State', sortable: true },
{ field: 'mtu', searchable: true, name: 'MTU', sortable: true },
{ field: 'type', searchable: true, name: 'Type', sortable: true },
].map(({field, ...rest}) => ({...rest, field, name: rest.name || KeyEquivalence[field] || field}));
Original file line number Diff line number Diff line change
@@ -1,31 +1,33 @@
import { KeyEquivalence } from "../../../../../common/csv-key-equivalence";

const windowsColumns = [
{ id: 'name' },
{ id: 'architecture', width: '10%' },
{ id: 'version' },
{ id: 'vendor', width: '30%' },
];
{ field: 'name', searchable: true, sortable: true },
{ field: 'architecture', searchable: true, sortable: true, width: '10%' },
{ field: 'version', searchable: true, sortable: true },
{ field: 'vendor', searchable: true, sortable: true, width: '30%' },
].map(({field, ...rest}) => ({...rest, field, name: rest.name || KeyEquivalence[field] || field}));
const linuxColumns = [
{ id: 'name' },
{ id: 'architecture', width: '10%' },
{ id: 'version' },
{ id: 'vendor', width: '30%' },
{ id: 'description', width: '30%' },
];
{ field: 'name', searchable: true, sortable: true },
{ field: 'architecture', searchable: true, sortable: true, width: '10%' },
{ field: 'version', searchable: true, sortable: true },
{ field: 'vendor', searchable: true, sortable: true, width: '30%' },
{ field: 'description', searchable: true, sortable: true, width: '30%' },
].map(({field, ...rest}) => ({...rest, field, name: rest.name || KeyEquivalence[field] || field}));
const MacColumns = [
{ id: 'name' },
{ id: 'version' },
{ id: 'format' },
{ id: 'location', width: '30%' },
{ id: 'description', width: '20%' },
];
{ field: 'name', searchable: true, sortable: true },
{ field: 'version', searchable: true, sortable: true },
{ field: 'format', searchable: true, sortable: true },
{ field: 'location', searchable: true, sortable: true, width: '30%' },
{ field: 'description', searchable: true, sortable: true, width: '20%' },
].map(({field, ...rest}) => ({...rest, field, name: rest.name || KeyEquivalence[field] || field}));
const FreebsdColumns = [
{ id: 'name' },
{ id: 'version' },
{ id: 'format' },
{ id: 'architecture', width: '20%' },
{ id: 'vendor', width: '20%' },
{ id: 'description', width: '30%' },
];
{ field: 'name', searchable: true, sortable: true },
{ field: 'version', searchable: true, sortable: true },
{ field: 'format', searchable: true, sortable: true },
{ field: 'architecture', searchable: true, sortable: true, width: '20%' },
{ field: 'vendor', searchable: true, sortable: true, width: '20%' },
{ field: 'description', searchable: true, sortable: true, width: '30%' },
].map(({field, ...rest}) => ({...rest, field, name: rest.name || KeyEquivalence[field] || field}));

export const packagesColumns = {
windows: windowsColumns,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import { KeyEquivalence } from "../../../../../common/csv-key-equivalence";

const windowsColumns = [
{ id: 'process' },
{ id: 'local.ip', sortable: false },
{ id: 'local.port', sortable: false },
{ id: 'state' },
{ id: 'protocol' },
];
{ field: 'process', searchable: true, sortable: true },
{ field: 'local.ip', searchable: true, sortable: false },
{ field: 'local.port', searchable: true, sortable: false },
{ field: 'state', searchable: true, sortable: true },
{ field: 'protocol', searchable: true, sortable: true },
].map(({field, ...rest}) => ({...rest, field, name: rest.name || KeyEquivalence[field] || field}));
const defaultColumns = [
{ id: 'local.ip', sortable: false },
{ id: 'local.port', sortable: false },
{ id: 'state' },
{ id: 'protocol' },
];
{ field: 'local.ip', searchable: true, sortable: false },
{ field: 'local.port', searchable: true, sortable: false },
{ field: 'state', searchable: true, sortable: true },
{ field: 'protocol', searchable: true, sortable: true },
].map(({field, ...rest}) => ({...rest, field, name: rest.name || KeyEquivalence[field] || field}));

export const portsColumns = {
windows: windowsColumns,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,35 +1,37 @@
import { KeyEquivalence } from "../../../../../common/csv-key-equivalence";

const windowsColumns = [
{ id: 'name', width: '10%' },
{ id: 'pid' },
{ id: 'ppid' },
{ id: 'vm_size' },
{ id: 'priority' },
{ id: 'nlwp' },
{ id: 'cmd', width: '30%' },
];
{ field: 'name', searchable: true, sortable: true, width: '10%' },
{ field: 'pid', searchable: true, sortable: true },
{ field: 'ppid', searchable: true, sortable: true },
{ field: 'vm_size', searchable: true, sortable: true },
{ field: 'priority', searchable: true, sortable: true },
{ field: 'nlwp', searchable: true, sortable: true },
{ field: 'cmd', searchable: true, sortable: true, width: '30%' },
].map(({field, ...rest}) => ({...rest, field, name: rest.name || KeyEquivalence[field] || field}));
const linuxColumns = [
{ id: 'name', width: '10%' },
{ id: 'euser' },
{ id: 'egroup' },
{ id: 'pid' },
{ id: 'ppid' },
{ id: 'cmd', width: '15%' },
{ id: 'argvs', width: '15%' },
{ id: 'vm_size' },
{ id: 'size' },
{ id: 'session' },
{ id: 'nice' },
{ id: 'state', width: '15%' },
];
{ field: 'name', searchable: true, sortable: true, width: '10%' },
{ field: 'euser', searchable: true, sortable: true },
{ field: 'egroup', searchable: true, sortable: true },
{ field: 'pid', searchable: true, sortable: true },
{ field: 'ppid', searchable: true, sortable: true },
{ field: 'cmd', searchable: true, sortable: true, width: '15%' },
{ field: 'argvs', searchable: true, sortable: true, width: '15%' },
{ field: 'vm_size', searchable: true, sortable: true },
{ field: 'size', searchable: true, sortable: true },
{ field: 'session', searchable: true, sortable: true },
{ field: 'nice', searchable: true, sortable: true },
{ field: 'state', searchable: true, sortable: true, width: '15%' },
].map(({field, ...rest}) => ({...rest, field, name: rest.name || KeyEquivalence[field] || field}));
const macColumns = [
{ id: 'name', width: '10%' },
{ id: 'euser' },
{ id: 'pid' },
{ id: 'ppid' },
{ id: 'vm_size' },
{ id: 'nice' },
{ id: 'state', width: '15%' },
];
{ field: 'name', searchable: true, sortable: true, width: '10%' },
{ field: 'euser', searchable: true, sortable: true },
{ field: 'pid', searchable: true, sortable: true },
{ field: 'ppid', searchable: true, sortable: true },
{ field: 'vm_size', searchable: true, sortable: true },
{ field: 'nice', searchable: true, sortable: true },
{ field: 'state', searchable: true, sortable: true, width: '15%' },
].map(({field, ...rest}) => ({...rest, field, name: rest.name || KeyEquivalence[field] || field}));

export const processColumns = {
windows: windowsColumns,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { KeyEquivalence } from "../../../../../common/csv-key-equivalence";

export const windowsUpdatesColumns = [
{ field: 'hotfix', searchable: true, sortable: true}
].map(({field, ...rest}) => ({...rest, field, name: rest.name || KeyEquivalence[field] || field}));

This file was deleted.

Loading

0 comments on commit 0656efb

Please sign in to comment.