Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions tenable/io/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,20 @@ def _normalize(self, filterset: list[dict[str, Any]]) -> dict[str, Any]:
# is a list of dictionary items, and in other cases the "list"
# is a list of string values.
if isinstance(item['control']['list'][0], dict):
key = 'value' if 'value' in item['control']['list'][0] else 'id'
datablock['choices'] = [
str(i[key]) for i in item['control']['list']
]
# The list items don't always carry the same key. Most use
# 'value' or 'id', but some (e.g. the target_group filter)
# only provide a 'name'. Pick the first key that exists
# rather than assuming 'id', which raised KeyError before.
first = item['control']['list'][0]
key = next(
(k for k in ('value', 'id', 'name') if k in first), None
)
if key is not None:
datablock['choices'] = [
str(i[key])
for i in item['control']['list']
if key in i
]
elif isinstance(item['control']['list'], list):
datablock['choices'] = [str(i) for i in item['control']['list']]
if 'regex' in item['control']:
Expand Down
21 changes: 21 additions & 0 deletions tests/io/test_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,24 @@ def test_filters_credentials_false_filters(api):
check(data[1], 'readable_name', str, allow_none=True)
check(data[1], 'operators', list, allow_none=True)
check(data[1], 'control', dict, allow_none=True)


def test_normalize_name_only_choices(api):
"""
test that _normalize handles list items that only carry a 'name' key
(e.g. the target_group filter) instead of raising KeyError: 'id'
"""
filterset = [
{
'name': 'target_group',
'operators': ['eq', 'neq'],
'control': {
'type': 'dropdown_multi',
'list': [{'name': 'mygroup'}],
},
}
]
result = getattr(api.filters, '_normalize')(filterset)
assert result['target_group']['choices'] == ['mygroup']
assert result['target_group']['operators'] == ['eq', 'neq']
assert result['target_group']['pattern'] is None
Loading