Skip to content

Commit 2a9182f

Browse files
initial command
1 parent 868e5d8 commit 2a9182f

1 file changed

Lines changed: 179 additions & 0 deletions

File tree

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
import json
2+
import logging
3+
import os
4+
from importlib import import_module
5+
from importlib.util import find_spec
6+
from inspect import isclass
7+
from pathlib import Path
8+
9+
from django.core.management.base import BaseCommand
10+
from django.urls import reverse
11+
from django.utils import timezone
12+
from rest_framework.authtoken.models import Token
13+
from rest_framework.test import APIClient
14+
15+
import dojo.tools.factory
16+
from dojo.models import Engagement, Product, Product_Type
17+
from unittests.test_dashboard import User
18+
19+
logger = logging.getLogger(__name__)
20+
21+
22+
class Command(BaseCommand):
23+
24+
help = (
25+
"Command to import all scans available in unittests folder"
26+
)
27+
28+
def get_test_admin(self, *args, **kwargs):
29+
return User.objects.get(username="admin")
30+
31+
def import_scan(self, payload, expected_http_status_code):
32+
testuser = self.get_test_admin()
33+
token = Token.objects.get(user=testuser)
34+
self.client = APIClient()
35+
self.client.credentials(HTTP_AUTHORIZATION="Token " + token.key)
36+
37+
logger.debug("import_scan payload %s", payload)
38+
response = self.client.post(reverse("importscan-list"), payload)
39+
if expected_http_status_code != response.status_code:
40+
msg = f"Expected HTTP status code {expected_http_status_code}, got {response.status_code}: {response.content[:1000]}"
41+
raise AssertionError(
42+
msg,
43+
)
44+
return json.loads(response.content)
45+
46+
def import_scan_with_params(self, filename, scan_type="ZAP Scan", engagement=1, minimum_severity="Low", *, active=True, verified=False,
47+
push_to_jira=None, endpoint_to_add=None, tags=None, close_old_findings=False, group_by=None, engagement_name=None,
48+
product_name=None, product_type_name=None, auto_create_context=None, expected_http_status_code=201, test_title=None,
49+
scan_date=None, service=None, force_active=True, force_verified=True):
50+
51+
with (Path("unittests/scans") / filename).open(encoding="utf-8") as testfile:
52+
payload = {
53+
"minimum_severity": minimum_severity,
54+
"scan_type": scan_type,
55+
"file": testfile,
56+
"version": "1.0.1",
57+
"close_old_findings": close_old_findings,
58+
}
59+
60+
if active is not None:
61+
payload["active"] = active
62+
63+
if verified is not None:
64+
payload["verified"] = verified
65+
66+
if engagement:
67+
payload["engagement"] = engagement
68+
69+
if engagement_name:
70+
payload["engagement_name"] = engagement_name
71+
72+
if product_name:
73+
payload["product_name"] = product_name
74+
75+
if product_type_name:
76+
payload["product_type_name"] = product_type_name
77+
78+
if auto_create_context:
79+
payload["auto_create_context"] = auto_create_context
80+
81+
if push_to_jira is not None:
82+
payload["push_to_jira"] = push_to_jira
83+
84+
if endpoint_to_add is not None:
85+
payload["endpoint_to_add"] = endpoint_to_add
86+
87+
if tags is not None:
88+
payload["tags"] = tags
89+
90+
if group_by is not None:
91+
payload["group_by"] = group_by
92+
93+
if test_title is not None:
94+
payload["test_title"] = test_title
95+
96+
if scan_date is not None:
97+
payload["scan_date"] = scan_date
98+
99+
if service is not None:
100+
payload["service"] = service
101+
102+
return self.import_scan(payload, expected_http_status_code)
103+
104+
def handle(self, *args, **options):
105+
prod_type = Product_Type.objects.first()
106+
prod, _ = Product.objects.get_or_create(prod_type=prod_type, name="prod name")
107+
eng, _ = Engagement.objects.get_or_create(product=prod, name="valentijn engagement", target_start=timezone.now(), target_end=timezone.now())
108+
109+
error_count = 0
110+
error_messages = {}
111+
# iterate through the modules in the current package
112+
package_dir = str(Path(dojo.tools.factory.__file__).resolve().parent)
113+
for module_name in os.listdir(package_dir): # noqa: PTH208
114+
# check if it's dir
115+
if (Path(package_dir) / module_name).is_dir():
116+
try:
117+
# check if it's a Python module
118+
if find_spec(f"dojo.tools.{module_name}.parser"):
119+
# import the module and iterate through its attributes
120+
module = import_module(f"dojo.tools.{module_name}.parser")
121+
for attribute_name in dir(module):
122+
attribute = getattr(module, attribute_name)
123+
if isclass(attribute) and attribute_name.lower() == module_name.replace("_", "") + "parser":
124+
logger.info(f"Loading {module_name} parser")
125+
scan_dir = Path("unittests") / "scans" / module_name
126+
for scan_file in scan_dir.glob("*.json"):
127+
if scan_file.name != "report_invalid.json": # meterian
128+
if scan_file.name != "single_finding_no_libraryId.json": # checkmarx_osa
129+
if scan_file.name not in ["issue_7897.json", "empty_with_error.json", "many_vuln_npm7.json"]: # npm_audit # noqa: PLR6201
130+
if scan_file.name != "threat_composer_no_threats_with_error.json": # threat_composer
131+
if scan_file.name != "very_many_vulns.json": # jfrog_xray
132+
try:
133+
logger.debug(f"Importing scan {scan_file.name} using {module_name} parser")
134+
parser = attribute()
135+
# with scan_file.open(encoding="utf-8") as f:
136+
# findings = parser.get_findings(f, Test())
137+
result = self.import_scan_with_params(
138+
filename=module_name + "/" + scan_file.name,
139+
scan_type=parser.get_scan_types()[0],
140+
engagement=eng.id,
141+
)
142+
# logger.debug(f"Result of import: {result}")
143+
# raise Exception(f"Scan {scan_file.name} is not expected to be imported, but it was.")
144+
logger.info(f"Imported findings from {module_name + scan_file.name}")
145+
except Exception as e:
146+
logger.error(f"Error importing scan {module_name + scan_file.name}: {e}")
147+
error_count += 1
148+
error_messages[module_name + "/" + scan_file.name] = result.get("message", str(e))
149+
150+
except:
151+
logger.exception(f"failed to load {module_name}")
152+
raise
153+
154+
logger.error(f"Error count: {error_count}")
155+
for scan, message in error_messages.items():
156+
logger.error(f"Error importing scan {scan}: {message}")
157+
158+
159+
# errors:
160+
161+
# [25/Jun/2025 18:06:15] ERROR [dojo.management.commands.import_all_unittest_scans:154] Error count: 18
162+
# [25/Jun/2025 18:06:15] ERROR [dojo.management.commands.import_all_unittest_scans:156] Error importing scan generic/generic_empty.json: Expected HTTP status code 201, got 400: b'{"message":"[\\"Required fields are missing: [\'description\', \'severity\', \'title\']\\"]","pro":["Pro comes with support. Try today for free or email us at hello@defectdojo.com"]}'
163+
# [25/Jun/2025 18:06:15] ERROR [dojo.management.commands.import_all_unittest_scans:156] Error importing scan generic/test_with_image_no_ext.json: Expected HTTP status code 201, got 400: b'{"message":"[\'Unsupported extension. Supported extensions are as follows: .txt, .pdf, .json, .xml, .csv, .yml, .png, .jpeg, .sarif, .xlsx, .doc, .html, .js, .nessus, .zip, .fpr\']","pro":["Pro comes with support. Try today for free or email us at hello@defectdojo.com"]}'
164+
# [25/Jun/2025 18:06:15] ERROR [dojo.management.commands.import_all_unittest_scans:156] Error importing scan generic/generic_invalid.json: Expected HTTP status code 201, got 400: b'{"message":"[\\"Not allowed fields are present: [\'invalid_field\', \'last_status_update\']\\"]","pro":["Pro comes with support. Try today for free or email us at hello@defectdojo.com"]}'
165+
# [25/Jun/2025 18:06:15] ERROR [dojo.management.commands.import_all_unittest_scans:156] Error importing scan whitehat_sentinel/empty_file.json: Expected HTTP status code 201, got 400: b'{"message":"[\'collection key not present or there were not findings present.\']","pro":["Pro comes with support. Try today for free or email us at hello@defectdojo.com"]}'
166+
# [25/Jun/2025 18:06:15] ERROR [dojo.management.commands.import_all_unittest_scans:156] Error importing scan gitlab_api_fuzzing/gitlab_api_fuzzing_invalid.json: Expected HTTP status code 201, got 500: b'{"message":"Internal server error, check logs for details","pro":["Pro comes with support. Try today for free or email us at hello@defectdojo.com"]}'
167+
# [25/Jun/2025 18:06:15] ERROR [dojo.management.commands.import_all_unittest_scans:156] Error importing scan burp_graphql/null_title.json: Expected HTTP status code 201, got 400: b'{"message":"[\'Issue does not have a name\']","pro":["Pro comes with support. Try today for free or email us at hello@defectdojo.com"]}'
168+
# [25/Jun/2025 18:06:15] ERROR [dojo.management.commands.import_all_unittest_scans:156] Error importing scan stackhawk/oddly_familiar_json_that_isnt_us.json: Expected HTTP status code 201, got 400: b'{"message":"[\' Unexpected JSON format provided. Need help? Check out the StackHawk Docs at https://docs.stackhawk.com/workflow-integrations/defect-dojo.html\']","pro":["Pro comes with support. Try today for free or email us at hello@defectdojo.com"]}'
169+
# [25/Jun/2025 18:06:15] ERROR [dojo.management.commands.import_all_unittest_scans:156] Error importing scan stackhawk/invalid.json: Expected HTTP status code 201, got 400: b'{"message":"[\' Unexpected JSON format provided. Need help? Check out the StackHawk Docs at https://docs.stackhawk.com/workflow-integrations/defect-dojo.html\']","pro":["Pro comes with support. Try today for free or email us at hello@defectdojo.com"]}'
170+
# [25/Jun/2025 18:06:15] ERROR [dojo.management.commands.import_all_unittest_scans:156] Error importing scan kubehunter/empty.json: Expected HTTP status code 201, got 400: b'{"message":"[\'Expecting value: line 1 column 1 (char 0)\']","pro":["Pro comes with support. Try today for free or email us at hello@defectdojo.com"]}'
171+
# [25/Jun/2025 18:06:15] ERROR [dojo.management.commands.import_all_unittest_scans:156] Error importing scan threagile/bad_formatted_risks_file.json: Expected HTTP status code 201, got 500: b'{"message":"Internal server error, check logs for details","pro":["Pro comes with support. Try today for free or email us at hello@defectdojo.com"]}'
172+
# [25/Jun/2025 18:06:15] ERROR [dojo.management.commands.import_all_unittest_scans:156] Error importing scan hydra/oddly_familiar_json_that_isnt_us.json: Expected HTTP status code 201, got 400: b'{"message":"[\\"Unexpected JSON format provided. That doesn\'t look like a Hydra scan!\\"]","pro":["Pro comes with support. Try today for free or email us at hello@defectdojo.com"]}'
173+
# [25/Jun/2025 18:06:15] ERROR [dojo.management.commands.import_all_unittest_scans:156] Error importing scan hydra/invalid.json: Expected HTTP status code 201, got 400: b'{"message":"[\\"Unexpected JSON format provided. That doesn\'t look like a Hydra scan!\\"]","pro":["Pro comes with support. Try today for free or email us at hello@defectdojo.com"]}'
174+
# [25/Jun/2025 18:06:15] ERROR [dojo.management.commands.import_all_unittest_scans:156] Error importing scan anchore_enterprise/invalid_checks_format.json: Expected HTTP status code 201, got 400: b'{"message":"[\\"Invalid format: \'result\' key not found\\"]","pro":["Pro comes with support. Try today for free or email us at hello@defectdojo.com"]}'
175+
# [25/Jun/2025 18:06:15] ERROR [dojo.management.commands.import_all_unittest_scans:156] Error importing scan risk_recon/bad_key.json: Expected HTTP status code 201, got 500: b'{"message":"Internal server error, check logs for details","pro":["Pro comes with support. Try today for free or email us at hello@defectdojo.com"]}'
176+
# [25/Jun/2025 18:06:15] ERROR [dojo.management.commands.import_all_unittest_scans:156] Error importing scan risk_recon/bad_url.json: Expected HTTP status code 201, got 500: b'{"message":"Internal server error, check logs for details","pro":["Pro comes with support. Try today for free or email us at hello@defectdojo.com"]}'
177+
# [25/Jun/2025 18:06:15] ERROR [dojo.management.commands.import_all_unittest_scans:156] Error importing scan osv_scanner/some_findings.json: Expected HTTP status code 201, got 500: b'{"message":"Internal server error, check logs for details","pro":["Pro comes with support. Try today for free or email us at hello@defectdojo.com"]}'
178+
# [25/Jun/2025 18:06:15] ERROR [dojo.management.commands.import_all_unittest_scans:156] Error importing scan coverity_api/wrong.json: Expected HTTP status code 201, got 400: b'{"message":"[\\"(\'Report file is not a well-formed Coverity REST view report\', \'wrong.json\')\\"]","pro":["Pro comes with support. Try today for free or email us at hello@defectdojo.com"]}'
179+
# [25/Jun/2025 18:06:15] ERROR [dojo.management.commands.import_all_unittest_scans:156] Error importing scan govulncheck/empty.json: Expected HTTP status code 201, got 400: b'{"message":"[\'Invalid JSON format\']","pro":["Pro comes with support. Try today for free or email us at hello@defectdojo.com"]}'

0 commit comments

Comments
 (0)