Skip to content

Commit 8558071

Browse files
Fixing Results Output (#37)
* Fixing results output * matching should happen on matched no results --------- Co-authored-by: Harrison Bornstein <harrison.bornstein@getcruise.com>
1 parent bdc9431 commit 8558071

5 files changed

Lines changed: 53 additions & 33 deletions

File tree

setup.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def read(fname):
3434

3535
setup(
3636
name="sublime-cli",
37-
version="0.0.31",
37+
version="0.0.32",
3838
description="Abstraction to interact with the Sublime API.",
3939
url="https://sublimesecurity.com/",
4040
author="Sublime Security",
@@ -56,6 +56,7 @@ def read(fname):
5656
],
5757
entry_points={"console_scripts": ["sublime = sublime.cli:main"]},
5858
zip_safe=False,
59-
keywords=["security", "phishing", "analysts", "soc", "threat intelligence", "security-automation", "email security"],
59+
keywords=["security", "phishing", "analysts", "soc",
60+
"threat intelligence", "security-automation", "email security"],
6061
download_url="https://github.com/sublime-security/sublime-cli",
6162
)

src/sublime/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55
__maintainer__ = "Sublime Security"
66
__email__ = "hi@sublimesecurity.com"
77
__status__ = "BETA"
8-
__version__ = "0.0.30"
8+
__version__ = "0.0.32"

src/sublime/cli/formatter.py

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from jinja2 import Environment, PackageLoader
1616

1717
JINJA2_ENV = Environment(loader=PackageLoader("sublime.cli"),
18-
extensions=['jinja2.ext.loopcontrols'])
18+
extensions=['jinja2.ext.loopcontrols'])
1919

2020
colorama.init()
2121
ANSI_MARKUP = ansimarkup.AnsiMarkup(
@@ -60,14 +60,22 @@ def json_formatter(result, verbose=False, indent=4, offset=0):
6060
return string
6161

6262

63+
def filter_none_recursive(item):
64+
"""Recursive Filter Out Values"""
65+
if isinstance(item, list):
66+
return [filter_none_recursive(sub_item) for sub_item in item if sub_item is not None and (not isinstance(sub_item, list) or any(sub_sub_item is not None for sub_sub_item in sub_item))]
67+
return item
68+
69+
6370
@colored_output
6471
def analyze_formatter(results, verbose):
6572
"""Convert Analyze output into human-readable text."""
6673
mql_offset = 3
6774
json_offset = 2
68-
template_file = "analyze_multi.txt.j2" if len(results) > 1 else "analyze.txt.j2"
75+
template_file = "analyze_multi.txt.j2" if len(
76+
results) > 1 else "analyze.txt.j2"
6977
template = JINJA2_ENV.get_template(template_file)
70-
78+
7179
# calculate total stats
7280
sample_result = next(iter(results.values()))
7381
summary_stats = {
@@ -77,7 +85,7 @@ def analyze_formatter(results, verbose):
7785
}
7886
rules = [rule for rule in sample_result['rule_results']]
7987
queries = [query for query in sample_result['query_results']]
80-
88+
8189
# separate matched/unmatched messages and distinguish flagged/unflagged rules
8290
flagged_messages = []
8391
unflagged_messages = []
@@ -87,9 +95,17 @@ def analyze_formatter(results, verbose):
8795
falsey_queries = []
8896
failed_queries = []
8997
for query in result['query_results']:
90-
if query['result']:
98+
result_value = query.get('result')
99+
if isinstance(result_value, list):
100+
# Filter out None values from the result array
101+
filtered_result = filter_none_recursive(result_value)
102+
if filtered_result and any(item is not None for item in filtered_result):
103+
query['result'] = filtered_result
104+
normal_queries.append(query)
105+
elif result_value:
106+
# If the result is not a list and exists (is truthy)
91107
normal_queries.append(query)
92-
elif query['success']:
108+
elif query.get('success'):
93109
falsey_queries.append(query)
94110
else:
95111
failed_queries.append(query)
@@ -101,10 +117,12 @@ def analyze_formatter(results, verbose):
101117
unflagged_rules = []
102118
failed_rules = []
103119
for rule in result['rule_results']:
104-
if rule['result']:
120+
if rule.get('matched'):
105121
flagged_rules.append(rule)
106-
all_flagged_rules.add(rule['name']+rule['source']) # no unique identifier
107-
elif rule['success']:
122+
# no unique identifier
123+
all_flagged_rules.add(
124+
rule.get("rule").get('name')+rule.get("rule").get('source'))
125+
elif rule.get('success'):
108126
unflagged_rules.append(rule)
109127
else:
110128
failed_rules.append(rule)
@@ -116,30 +134,29 @@ def analyze_formatter(results, verbose):
116134
flagged_messages.append(result)
117135
else:
118136
unflagged_messages.append(result)
119-
137+
120138
# calculate flagged stats
121139
summary_stats['flagged_rules'] = len(all_flagged_rules)
122140
summary_stats['flagged_messages'] = len(flagged_messages)
123141

124142
# format mql and json outputs
125-
for msg in flagged_messages + unflagged_messages:
143+
for msg in flagged_messages + unflagged_messages:
126144
for result in msg['rule_results'] + msg['query_results']:
127145
if 'result' in result and (isinstance(result['result'], dict) or isinstance(result['result'], list)):
128146
result['result'] = json_formatter(
129-
result['result'],
130-
offset=json_offset,
131-
indent=2)
132-
147+
result['result'],
148+
offset=json_offset,
149+
indent=2)
133150

134151
# TO DO: sort each list of messages by extension and file name (or directory?)
135152

136153
return template.render(
137-
stats=summary_stats,
138-
flagged_messages=flagged_messages,
139-
unflagged_messages=unflagged_messages,
140-
rules=rules,
141-
queries=queries,
142-
verbose=verbose)
154+
stats=summary_stats,
155+
flagged_messages=flagged_messages,
156+
unflagged_messages=unflagged_messages,
157+
rules=rules,
158+
queries=queries,
159+
verbose=verbose)
143160

144161

145162
def mdm_formatter(results, verbose):
@@ -153,13 +170,15 @@ def mdm_formatter(results, verbose):
153170
# template = JINJA2_ENV.get_template("message_data_model.txt.j2")
154171
# return template.render(results=results, verbose=verbose)
155172

173+
156174
@colored_output
157175
def me_formatter(result, verbose):
158176
"""Convert 'me' output into human-readable text."""
159177
template = JINJA2_ENV.get_template("me_result.txt.j2")
160178

161179
return template.render(result=result, verbose=verbose)
162180

181+
163182
@colored_output
164183
def feedback_formatter(result, verbose):
165184
"""Convert 'feedback' output into human-readable text."""

src/sublime/cli/templates/analyze.txt.j2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
{%- set max_elements = 20 %}
3434
{%- set elements_slice = msg.unflagged_rule_results[:max_elements if verbose < 1 else None] %}
3535
{%- for rule in elements_slice %}
36-
- <not-detected><bold>{{ rule.name }}</bold></not-detected>
36+
- <not-detected><bold>{{ rule.rule.name }}</bold></not-detected>
3737
{%- if verbose %}
3838
<key>Source:</key> {{ rule.source }}
3939
{# new line #}

src/sublime/cli/templates/macros.txt.j2

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<header>FLAGGED RULES</header>
44
{# new line #}
55
{%- for rule in msg.flagged_rule_results %}
6-
- <detected><bold>{{ rule.name }}</bold></detected>
6+
- <detected><bold>{{ rule.rule.name}}</bold></detected>
77
{%- if verbose %}
88
<key>Source:</key> {{ rule.source }}
99
{# new line #}
@@ -16,7 +16,7 @@
1616
<header>FAILED RULES</header>
1717
{# new line #}
1818
{%- for rule in msg.failed_rule_results %}
19-
- <fail><bold>{{ rule.name }}</bold></fail>
19+
- <fail><bold>{{ rule.rule.name }}</bold></fail>
2020
<key>Error:</key> {{ rule.error }}
2121
{%- if verbose %}
2222
<key>Source:</key> {{ rule.source }}
@@ -34,8 +34,8 @@
3434

3535
{%- if msg.normal_query_results | length > 0 %}
3636
{%- for query in (msg.normal_query_results) %}
37-
{%- if query.name %}
38-
- <query><bold>{{ query.name }}</bold></query>
37+
{%- if query.query.name %}
38+
- <query><bold>{{ query.query.name }}</bold></query>
3939
{%- else %}
4040
- <query><bold>Query {{ loop.index }}</bold></query>
4141
{%- endif %}
@@ -49,8 +49,8 @@
4949

5050
{%- if (verbose and (msg.falsey_query_results | length > 0)) or msg.falsey_query_results|length == 1 %}
5151
{%- for query in (msg.falsey_query_results) %}
52-
{%- if query.name %}
53-
- <query><bold>{{ query.name }}</bold></query>
52+
{%- if query.query.name %}
53+
- <query><bold>{{ query.query.name }}</bold></query>
5454
{%- else %}
5555
- <query><bold>Query {{ loop.index }}</bold></query>
5656
{%- endif %}
@@ -68,8 +68,8 @@
6868
<header>FAILED QUERIES</header>
6969
{# new line #}
7070
{%- for query in msg.failed_query_results %}
71-
{%- if query.name %}
72-
- <fail><bold>{{ query.name }}</bold></fail>
71+
{%- if query.query.name %}
72+
- <fail><bold>{{ query.query.name }}</bold></fail>
7373
{%- else %}
7474
- <fail><bold>Query {{ loop.index }}</bold></fail>
7575
{%- endif %}

0 commit comments

Comments
 (0)