Skip to content

Commit 513b079

Browse files
authored
Doug/add json option (#3)
* Added fixes for missing commit-sha option. Added option to export SBOM file. Added node, npm, and yarn to Dockerfile * Added fixes for missing commit-sha option. Added option to export SBOM file. Added node, npm, and yarn to Dockerfile (#1) * Doug/fix gitlab main flow (#2) * Added fixes for missing commit-sha option. Added option to export SBOM file. Added node, npm, and yarn to Dockerfile * Fixed how to check for the gitlab workflow * Added in fix for unknown issue types and updated .gitignore * Added handler for keyboard interrupt and unexpected errors. Unexpected errors will have exit code 3, keyboard interrupt will be 2, unhealthy report due to Security policy 1, and no issues exit code 0 * Added support for JSON output for the CLI with --enable-json
1 parent 702176c commit 513b079

File tree

6 files changed

+70
-27
lines changed

6 files changed

+70
-27
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ scripts/*.py
1616
markdown_overview_temp.md
1717
markdown_security_temp.md
1818
.DS_Store
19-
*.pyc
19+
*.pyc
20+
test.py

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "socketsecurity"
7-
version = "0.0.74"
7+
version = "0.0.76"
88
requires-python = ">= 3.9"
99
dependencies = [
1010
'requests',

socketsecurity/core/__init__.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626

2727
__author__ = 'socket.dev'
28-
__version__ = '0.0.74'
28+
__version__ = '0.0.76'
2929
__all__ = [
3030
"Core",
3131
"log",
@@ -489,7 +489,7 @@ def create_new_diff(path: str, params: FullScanParams, workspace: str) -> Diff:
489489
head_full_scan = Core.get_sbom_data(head_full_scan_id)
490490
head_end = time.time()
491491
total_head_time = head_end - head_start
492-
print(f"Total time to get head full-scan {total_head_time: .2f}")
492+
log.info(f"Total time to get head full-scan {total_head_time: .2f}")
493493
except APIResourceNotFound:
494494
head_full_scan = []
495495
if files is not None and len(files) > 0:
@@ -498,7 +498,7 @@ def create_new_diff(path: str, params: FullScanParams, workspace: str) -> Diff:
498498
new_full_scan.packages = Core.create_sbom_dict(new_full_scan.sbom_artifacts)
499499
new_scan_end = time.time()
500500
total_new_time = new_scan_end - new_scan_start
501-
print(f"Total time to get new full-scan {total_new_time: .2f}")
501+
log.info(f"Total time to get new full-scan {total_new_time: .2f}")
502502
diff_report = Core.compare_sboms(new_full_scan.sbom_artifacts, head_full_scan)
503503
diff_report.packages = new_full_scan.packages
504504
else:
@@ -644,7 +644,10 @@ def create_issue_alerts(package: Package, alerts: dict, packages: dict) -> dict:
644644
"""
645645
for item in package.alerts:
646646
alert = Alert(**item)
647-
props = getattr(all_issues, alert.type)
647+
try:
648+
props = getattr(all_issues, alert.type)
649+
except AttributeError:
650+
props = None
648651
if props is not None:
649652
description = props.description
650653
title = props.title

socketsecurity/core/classes.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ class Issue:
145145
suggestion: str
146146
introduced_by: list
147147
manifests: str
148+
url: str
149+
purl: str
148150

149151
def __init__(self, **kwargs):
150152
if kwargs:
@@ -157,6 +159,8 @@ def __init__(self, **kwargs):
157159
self.introduced_by = []
158160
if not hasattr(self, "manifests"):
159161
self.manifests = ""
162+
self.url = f"https://socket.dev/{self.pkg_type}/{self.pkg_name}/overview/{self.pkg_version}"
163+
self.purl = f"{self.pkg_type}/{self.pkg_name}@{self.pkg_version}"
160164

161165
def __str__(self):
162166
return json.dumps(self.__dict__)

socketsecurity/core/messages.py

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,28 @@
1+
import json
2+
13
from mdutils import MdUtils
24
from socketsecurity.core.classes import Diff, Purl, Issue
35
from prettytable import PrettyTable
46

57

68
class Messages:
79

10+
@staticmethod
11+
def create_security_comment_json(diff: Diff) -> dict:
12+
if len(diff.new_alerts) == 0:
13+
scan_failed = False
14+
else:
15+
scan_failed = True
16+
output = {
17+
"scan_failed": scan_failed,
18+
"new_alerts": []
19+
}
20+
for alert in diff.new_alerts:
21+
alert: Issue
22+
output["new_alerts"].append(json.loads(str(alert)))
23+
return output
24+
25+
826
@staticmethod
927
def security_comment_template(diff: Diff) -> str:
1028
"""
@@ -124,14 +142,13 @@ def create_security_alert_table(diff: Diff, md: MdUtils) -> (MdUtils, list, dict
124142
alert.description,
125143
alert.suggestion
126144
]
127-
package_url, purl = Messages.create_package_link(alert)
128-
ignore = f"`SocketSecurity ignore {purl}`"
145+
ignore = f"`SocketSecurity ignore {alert.purl}`"
129146
if ignore not in ignore_commands:
130147
ignore_commands.append(ignore)
131148
manifest_str, sources = Messages.create_sources(alert, "console")
132149
row = [
133150
alert.title,
134-
package_url,
151+
alert.url,
135152
", ".join(sources),
136153
manifest_str
137154
]
@@ -247,20 +264,6 @@ def create_purl_link(details: Purl) -> str:
247264
package_url = f"[{purl}](https://socket.dev/{details.ecosystem}/{details.name}/overview/{details.version})"
248265
return package_url
249266

250-
@staticmethod
251-
def create_package_link(details: Issue) -> (str, str):
252-
"""
253-
Creates the package link for the Security Comment Template
254-
:param details: Purl - Details about the package needed to create the URLs
255-
:return:
256-
"""
257-
purl = f"{details.pkg_name}@{details.pkg_version}"
258-
package_url = (
259-
f"[{purl}]"
260-
f"(https://socket.dev/{details.pkg_type}/{details.pkg_name}/overview/{details.pkg_version})"
261-
)
262-
return package_url, purl
263-
264267
@staticmethod
265268
def create_console_security_alert_table(diff: Diff) -> PrettyTable:
266269
"""
@@ -278,11 +281,10 @@ def create_console_security_alert_table(diff: Diff) -> PrettyTable:
278281
)
279282
for alert in diff.new_alerts:
280283
alert: Issue
281-
package_url, purl = Messages.create_package_link(alert)
282284
manifest_str, sources = Messages.create_sources(alert, "console")
283285
row = [
284286
alert.title,
285-
package_url,
287+
alert.url,
286288
", ".join(sources),
287289
manifest_str
288290
]

socketsecurity/socketcli.py

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,13 @@
105105
default=False
106106
)
107107

108+
parser.add_argument(
109+
'--enable-json',
110+
help='Enable json output of results instead of table formatted',
111+
action='store_true',
112+
default=False
113+
)
114+
108115

109116
def output_console_comments(diff_report) -> None:
110117
console_security_comment = Messages.create_console_security_alert_table(diff_report)
@@ -116,7 +123,26 @@ def output_console_comments(diff_report) -> None:
116123
log.info("No New Security issues detected by Socket Security")
117124

118125

126+
def output_console_json(diff_report) -> None:
127+
console_security_comment = Messages.create_security_comment_json(diff_report)
128+
print(json.dumps(console_security_comment))
129+
if len(diff_report.new_alerts) > 0:
130+
sys.exit(1)
131+
132+
119133
def cli():
134+
try:
135+
main_code()
136+
except KeyboardInterrupt:
137+
log.info("Keyboard Interrupt detected, exiting")
138+
sys.exit(2)
139+
except Exception as error:
140+
log.error("Unexpected error when running the cli")
141+
log.error(error)
142+
sys.exit(3)
143+
144+
145+
def main_code():
120146
arguments = parser.parse_args()
121147
debug = arguments.enable_debug
122148
if debug:
@@ -132,6 +158,7 @@ def cli():
132158
commit_sha = arguments.commit_sha
133159
sbom_file = arguments.sbom_file
134160
license_mode = arguments.generate_license
161+
enable_json = arguments.enable_json
135162
license_file = f"{repo}"
136163
if branch is not None:
137164
license_file += f"_{branch}"
@@ -196,12 +223,18 @@ def cli():
196223
new_security_comment,
197224
new_overview_comment
198225
)
199-
output_console_comments(diff)
226+
if enable_json:
227+
output_console_json(diff)
228+
else:
229+
output_console_comments(diff)
200230
else:
201231
log.info("API Mode")
202232
diff: Diff
203233
diff = core.create_new_diff(target_path, params, workspace=target_path)
204-
output_console_comments(diff)
234+
if enable_json:
235+
output_console_json(diff)
236+
else:
237+
output_console_comments(diff)
205238
if diff is not None and license_mode:
206239
all_packages = {}
207240
for package_id in diff.packages:

0 commit comments

Comments
 (0)