regscale-cli 6.27.0.1__py3-none-any.whl → 6.27.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of regscale-cli might be problematic. Click here for more details.
- regscale/_version.py +1 -1
- regscale/core/app/utils/app_utils.py +41 -7
- regscale/integrations/commercial/aws/scanner.py +3 -2
- regscale/integrations/commercial/microsoft_defender/defender_api.py +1 -1
- regscale/integrations/commercial/sicura/api.py +65 -29
- regscale/integrations/commercial/sicura/scanner.py +36 -7
- regscale/integrations/commercial/tenablev2/commands.py +4 -4
- regscale/integrations/commercial/tenablev2/scanner.py +1 -2
- regscale/integrations/commercial/wizv2/scanner.py +40 -16
- regscale/integrations/public/cci_importer.py +400 -9
- regscale/models/integration_models/aqua.py +2 -2
- regscale/models/integration_models/cisa_kev_data.json +164 -3
- regscale/models/integration_models/flat_file_importer/__init__.py +4 -6
- regscale/models/integration_models/synqly_models/capabilities.json +1 -1
- regscale/models/integration_models/synqly_models/connectors/vulnerabilities.py +11 -10
- regscale/models/integration_models/synqly_models/ocsf_mapper.py +48 -8
- regscale/models/integration_models/synqly_models/synqly_model.py +34 -12
- {regscale_cli-6.27.0.1.dist-info → regscale_cli-6.27.2.0.dist-info}/METADATA +1 -1
- {regscale_cli-6.27.0.1.dist-info → regscale_cli-6.27.2.0.dist-info}/RECORD +26 -26
- tests/regscale/integrations/commercial/test_sicura.py +0 -1
- tests/regscale/integrations/commercial/wizv2/test_wizv2.py +86 -0
- tests/regscale/integrations/public/test_cci.py +596 -1
- {regscale_cli-6.27.0.1.dist-info → regscale_cli-6.27.2.0.dist-info}/LICENSE +0 -0
- {regscale_cli-6.27.0.1.dist-info → regscale_cli-6.27.2.0.dist-info}/WHEEL +0 -0
- {regscale_cli-6.27.0.1.dist-info → regscale_cli-6.27.2.0.dist-info}/entry_points.txt +0 -0
- {regscale_cli-6.27.0.1.dist-info → regscale_cli-6.27.2.0.dist-info}/top_level.txt +0 -0
|
@@ -122,16 +122,6 @@ class Vulnerabilities(SynqlyModel):
|
|
|
122
122
|
if asset_filter:
|
|
123
123
|
self.logger.debug(f"Asset filter: {asset_filter}")
|
|
124
124
|
|
|
125
|
-
self.logger.info(f"Fetching vulnerability data from {self.integration_name}...")
|
|
126
|
-
findings = (
|
|
127
|
-
self.fetch_integration_data(
|
|
128
|
-
func=self.tenant.engine_client.vulnerabilities.query_findings,
|
|
129
|
-
filter=vuln_filter, # Only severity/date filters for findings
|
|
130
|
-
**kwargs,
|
|
131
|
-
)
|
|
132
|
-
if self.can_fetch_vulns
|
|
133
|
-
else []
|
|
134
|
-
)
|
|
135
125
|
self.logger.info(f"Fetching asset data from {self.integration_name}...")
|
|
136
126
|
assets = (
|
|
137
127
|
self.fetch_integration_data(
|
|
@@ -143,6 +133,17 @@ class Vulnerabilities(SynqlyModel):
|
|
|
143
133
|
else []
|
|
144
134
|
)
|
|
145
135
|
|
|
136
|
+
self.logger.info(f"Fetching vulnerability data from {self.integration_name}...")
|
|
137
|
+
findings = (
|
|
138
|
+
self.fetch_integration_data(
|
|
139
|
+
func=self.tenant.engine_client.vulnerabilities.query_findings,
|
|
140
|
+
filter=vuln_filter, # Only severity/date filters for findings
|
|
141
|
+
**kwargs,
|
|
142
|
+
)
|
|
143
|
+
if self.can_fetch_vulns
|
|
144
|
+
else []
|
|
145
|
+
)
|
|
146
|
+
|
|
146
147
|
self.scanner_integration = VulnerabilitiesIntegration(plan_id=regscale_ssp_id)
|
|
147
148
|
self.logger.info(f"Mapping {self.provider} asset(s) data to RegScale asset(s)...")
|
|
148
149
|
if assets:
|
|
@@ -5,7 +5,11 @@ from typing import Any, Union, TYPE_CHECKING, Optional
|
|
|
5
5
|
|
|
6
6
|
if TYPE_CHECKING:
|
|
7
7
|
from regscale.models.integration_models.synqly_models.connectors import Edr, Ticketing, Vulnerabilities
|
|
8
|
-
from synqly.engine.resources.ocsf.resources.v_1_3_0.resources.securityfinding import
|
|
8
|
+
from synqly.engine.resources.ocsf.resources.v_1_3_0.resources.securityfinding import (
|
|
9
|
+
Finding,
|
|
10
|
+
ResourceDetails,
|
|
11
|
+
Vulnerability,
|
|
12
|
+
)
|
|
9
13
|
|
|
10
14
|
from synqly import engine
|
|
11
15
|
from synqly.engine import CreateTicketRequest
|
|
@@ -152,7 +156,39 @@ class Mapper:
|
|
|
152
156
|
)
|
|
153
157
|
|
|
154
158
|
@staticmethod
|
|
155
|
-
def
|
|
159
|
+
def _determine_date(
|
|
160
|
+
attribute: str, finding: Optional["Finding"] = None, vuln: Optional["Vulnerability"] = None
|
|
161
|
+
) -> datetime:
|
|
162
|
+
"""
|
|
163
|
+
Determine the date based on the provided vulnerability or finding
|
|
164
|
+
|
|
165
|
+
:param str attribute: The attribute to determine the date for
|
|
166
|
+
:param Optional[SecurityFinding] finding: The finding to determine the date for
|
|
167
|
+
:param Optional[Vulnerability] vuln: The vulnerability to determine the date for
|
|
168
|
+
:return: The date
|
|
169
|
+
:rtype: datetime
|
|
170
|
+
"""
|
|
171
|
+
from regscale.core.utils.date import normalize_timestamp
|
|
172
|
+
|
|
173
|
+
vuln_date = getattr(vuln, attribute) if vuln else None
|
|
174
|
+
fallback_vuln_date = getattr(vuln, attribute.replace("_dt", ""), None) if vuln else None
|
|
175
|
+
finding_date = getattr(finding, attribute) if finding else None
|
|
176
|
+
fallback_finding_date = getattr(finding, attribute.replace("_dt", ""), None) if finding else None
|
|
177
|
+
if vuln_date:
|
|
178
|
+
return vuln_date
|
|
179
|
+
elif finding_date:
|
|
180
|
+
return finding_date
|
|
181
|
+
# No datetime objects, lets try the epoch integers
|
|
182
|
+
if fallback_vuln_date:
|
|
183
|
+
fallback_vuln_date = normalize_timestamp(fallback_vuln_date)
|
|
184
|
+
return datetime.fromtimestamp(fallback_vuln_date)
|
|
185
|
+
elif fallback_finding_date:
|
|
186
|
+
fallback_finding_date = normalize_timestamp(fallback_finding_date)
|
|
187
|
+
return datetime.fromtimestamp(fallback_finding_date)
|
|
188
|
+
else:
|
|
189
|
+
return datetime.now()
|
|
190
|
+
|
|
191
|
+
def _parse_finding_data(self, finding: "SecurityFinding", vuln: Optional["Vulnerability"] = None) -> dict:
|
|
156
192
|
"""
|
|
157
193
|
Parse the data from the SecurityFinding object
|
|
158
194
|
|
|
@@ -164,16 +200,20 @@ class Mapper:
|
|
|
164
200
|
|
|
165
201
|
finding_data = {
|
|
166
202
|
"cve": None,
|
|
167
|
-
"first_seen":
|
|
168
|
-
"last_seen":
|
|
203
|
+
"first_seen": self._determine_date("first_seen_time_dt", getattr(finding, "finding", None), vuln),
|
|
204
|
+
"last_seen": self._determine_date("last_seen_time_dt", getattr(finding, "finding", None), vuln),
|
|
169
205
|
"plugin_id": vuln.cve.uid if vuln else finding.finding.product_uid,
|
|
170
|
-
"severity":
|
|
206
|
+
"severity": vuln.severity if vuln and getattr(vuln, "severity") else finding.severity_id,
|
|
171
207
|
"remediation": getattr(vuln, "remediation") if vuln else finding.finding.remediation.desc,
|
|
172
208
|
}
|
|
173
209
|
if vuln:
|
|
174
210
|
finding_data["cve"] = vuln.cve.uid
|
|
175
211
|
else:
|
|
176
212
|
finding_data["cve"] = finding.finding.title if "cve" in finding.finding.title.lower() else None
|
|
213
|
+
try:
|
|
214
|
+
finding_data["severity"] = int(finding_data["severity"])
|
|
215
|
+
except ValueError:
|
|
216
|
+
finding_data["severity"] = 0
|
|
177
217
|
if isinstance(finding_data["remediation"], Remediation):
|
|
178
218
|
finding_data["remediation"] = finding_data["remediation"].desc
|
|
179
219
|
elif isinstance(finding_data["remediation"], dict):
|
|
@@ -227,9 +267,9 @@ class Mapper:
|
|
|
227
267
|
"""
|
|
228
268
|
base = vuln if vuln else finding.finding
|
|
229
269
|
finding_data = self._parse_finding_data(finding, vuln)
|
|
230
|
-
if resource
|
|
231
|
-
dns =
|
|
232
|
-
ip_address =
|
|
270
|
+
if resource_data := getattr(resource, "data"):
|
|
271
|
+
dns = resource_data.get("hostname")
|
|
272
|
+
ip_address = resource_data.get("ipv4")
|
|
233
273
|
else:
|
|
234
274
|
dns = resource.uid if vuln else None
|
|
235
275
|
ip_address = None
|
|
@@ -700,10 +700,7 @@ class SynqlyModel(BaseModel, ABC):
|
|
|
700
700
|
if query_filter:
|
|
701
701
|
query_filter = self.validate_filters(query_filter)
|
|
702
702
|
integration_data: list = []
|
|
703
|
-
fetch_res = func
|
|
704
|
-
filter=query_filter,
|
|
705
|
-
limit=limit,
|
|
706
|
-
)
|
|
703
|
+
fetch_res = self._fetch_data_with_retries(func=func, limit=limit, filter=query_filter)
|
|
707
704
|
self.logger.info(f"Received {len(fetch_res.result)} record(s) from {self.integration_name}.")
|
|
708
705
|
integration_data.extend(fetch_res.result)
|
|
709
706
|
# check and handle pagination
|
|
@@ -711,24 +708,49 @@ class SynqlyModel(BaseModel, ABC):
|
|
|
711
708
|
try:
|
|
712
709
|
# fetch.cursor can be an int as a string, or a continuation token
|
|
713
710
|
while int(fetch_res.cursor) == len(integration_data):
|
|
714
|
-
fetch_res =
|
|
715
|
-
filter=query_filter
|
|
716
|
-
limit=limit,
|
|
717
|
-
cursor=fetch_res.cursor,
|
|
711
|
+
fetch_res = self._fetch_data_with_retries(
|
|
712
|
+
func=func, limit=limit, cursor=fetch_res.cursor, filter=query_filter
|
|
718
713
|
)
|
|
719
714
|
integration_data.extend(fetch_res.result)
|
|
720
715
|
except ValueError:
|
|
721
716
|
while fetch_res.cursor:
|
|
722
|
-
fetch_res =
|
|
723
|
-
filter=query_filter
|
|
724
|
-
limit=limit,
|
|
725
|
-
cursor=fetch_res.cursor,
|
|
717
|
+
fetch_res = self._fetch_data_with_retries(
|
|
718
|
+
func=func, limit=limit, cursor=fetch_res.cursor, filter=query_filter
|
|
726
719
|
)
|
|
727
720
|
integration_data.extend(fetch_res.result)
|
|
728
721
|
self.logger.info(f"Received {len(integration_data)} record(s) from {self.integration_name}...")
|
|
729
722
|
self.logger.info(f"Fetched {len(integration_data)} total record(s) from {self.integration_name}...")
|
|
730
723
|
return integration_data
|
|
731
724
|
|
|
725
|
+
def _fetch_data_with_retries(
|
|
726
|
+
self, func: Callable, limit: int, cursor: Union[str, int, None] = None, filter: Optional[str] = None
|
|
727
|
+
) -> Any:
|
|
728
|
+
"""
|
|
729
|
+
Fetches data from the integration using the provided function and handles pagination
|
|
730
|
+
|
|
731
|
+
:param Callable func: The function to fetch data from the integration
|
|
732
|
+
:param int limit: The limit of records to fetch
|
|
733
|
+
:param Optional[str] filter: The filter to apply to the data
|
|
734
|
+
:return: The data from the integration
|
|
735
|
+
:rtype: Any
|
|
736
|
+
"""
|
|
737
|
+
import time
|
|
738
|
+
|
|
739
|
+
retries = 0
|
|
740
|
+
sleep_timers = [10, 20, 40]
|
|
741
|
+
while retries < 3:
|
|
742
|
+
try:
|
|
743
|
+
if cursor:
|
|
744
|
+
return func(limit=limit, filter=filter, cursor=cursor)
|
|
745
|
+
else:
|
|
746
|
+
return func(limit=limit, filter=filter)
|
|
747
|
+
except Exception as e:
|
|
748
|
+
self.logger.error(f"Error fetching data with retries: {e}")
|
|
749
|
+
self.logger.error(f"Retrying in {sleep_timers[retries]} seconds...")
|
|
750
|
+
time.sleep(sleep_timers[retries])
|
|
751
|
+
retries += 1
|
|
752
|
+
error_and_exit("Failed to fetch data after 3 retries")
|
|
753
|
+
|
|
732
754
|
def run_integration_sync(self, *args, **kwargs) -> None:
|
|
733
755
|
"""
|
|
734
756
|
Runs the sync process for the integration
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
regscale/__init__.py,sha256=ZygAIkX6Nbjag1czWdQa-yP-GM1mBE_9ss21Xh__JFc,34
|
|
2
|
-
regscale/_version.py,sha256=
|
|
2
|
+
regscale/_version.py,sha256=Lq40cZd2OT7sJZZWQh9y8KbuzbrUJbNhz2k2NIgwDVs,1198
|
|
3
3
|
regscale/regscale.py,sha256=4LzcbkBxPh23cCLANVEEr6uNoZ0sebHec0N-VJm5_vA,31480
|
|
4
4
|
regscale/airflow/__init__.py,sha256=yMwN0Bz4JbM0nl5qY_hPegxo_O2ilhTOL9PY5Njhn-s,270
|
|
5
5
|
regscale/airflow/click_dags.py,sha256=H3SUR5jkvInNMv1gu-VG-Ja_H-kH145CpQYNalWNAbE,4520
|
|
@@ -57,7 +57,7 @@ regscale/core/app/internal/workflow.py,sha256=SpgYk1QyzdilVLOK1fFzaKhdLspumaugf5
|
|
|
57
57
|
regscale/core/app/utils/XMLIR.py,sha256=M_RrCsbjznihatkucCKw6dPgHTPQczXyqIdUXWhuCLI,8328
|
|
58
58
|
regscale/core/app/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
59
59
|
regscale/core/app/utils/api_handler.py,sha256=T1meKw6Yi3ZAgRbQ1xuKDVh9Q9B8mbMqqN_LrSwIlAM,11765
|
|
60
|
-
regscale/core/app/utils/app_utils.py,sha256=
|
|
60
|
+
regscale/core/app/utils/app_utils.py,sha256=k_HEO4cFIddZMUtr56Z8A5NEjLz1Tl8vl2c3pqjXKvc,38652
|
|
61
61
|
regscale/core/app/utils/file_utils.py,sha256=x7cqYPxJ-PgSb2lX_K6zhdqyGQjOCmr04lnqdBQV3hI,9269
|
|
62
62
|
regscale/core/app/utils/parser_utils.py,sha256=aBEgcFwbJMD-ARf3wzf-tyWwR6NHvzEcdYcPMm8hGqo,2533
|
|
63
63
|
regscale/core/app/utils/pickle_file_handler.py,sha256=iMdv4N8z00TB5LyPdxIcLKNRpDQVWQ8ZQWAqCKpqmF0,1695
|
|
@@ -145,7 +145,7 @@ regscale/integrations/commercial/aqua/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCe
|
|
|
145
145
|
regscale/integrations/commercial/aqua/aqua.py,sha256=bdwqyir9ztGRwqZlWBQIHjtBEo2utSy5HJoraAx823I,2656
|
|
146
146
|
regscale/integrations/commercial/aws/__init__.py,sha256=Pii3CMGvIwZnTSenuvDvuybWXBtIRdGyvF02sykzg1A,203
|
|
147
147
|
regscale/integrations/commercial/aws/cli.py,sha256=Q2QlUcbYRzZzg9VZ5RDOTdVkkWc4UFYX7f5cMNlOZMY,14853
|
|
148
|
-
regscale/integrations/commercial/aws/scanner.py,sha256=
|
|
148
|
+
regscale/integrations/commercial/aws/scanner.py,sha256=2XtHT3En5VoFYt-qGnIsNenThofZHkzC3fbJwHA6gPI,56765
|
|
149
149
|
regscale/integrations/commercial/aws/inventory/__init__.py,sha256=nBWBRs_lTbp3tfCcnmN855qQpnXtwyJ5miTXlD7Uhcs,4302
|
|
150
150
|
regscale/integrations/commercial/aws/inventory/base.py,sha256=KL1Ntz0h0WGDu84LQf3y92uLl9a0sl4yIFi6-ZIFAMI,2068
|
|
151
151
|
regscale/integrations/commercial/aws/inventory/resources/__init__.py,sha256=wP8TMIixWGCn2rBNFW6XzhME-xO8kpxi9edMUJgpso4,523
|
|
@@ -182,7 +182,7 @@ regscale/integrations/commercial/mappings/csf_controls.json,sha256=EHOLWrnFr0oRs
|
|
|
182
182
|
regscale/integrations/commercial/mappings/nist_800_53_r5_controls.json,sha256=Vuh8RkKhX84U8VG2zoLG94QL7mvWIF28M-u8B4paxgw,123879
|
|
183
183
|
regscale/integrations/commercial/microsoft_defender/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
184
184
|
regscale/integrations/commercial/microsoft_defender/defender.py,sha256=JQLdSiGMuDFGXH8wdb3NQXuobcBprg1PR11OEOEBYyQ,51702
|
|
185
|
-
regscale/integrations/commercial/microsoft_defender/defender_api.py,sha256=
|
|
185
|
+
regscale/integrations/commercial/microsoft_defender/defender_api.py,sha256=GJf0H-4BacSLNtCXFU1Yb02mYS-jVuX40Z75bn6UqjQ,29434
|
|
186
186
|
regscale/integrations/commercial/microsoft_defender/defender_constants.py,sha256=pYIVii1ouy3FYM58UbAdlcYdVoC54vEv0M2FjFk0XmU,9516
|
|
187
187
|
regscale/integrations/commercial/microsoft_defender/defender_scanner.py,sha256=gUTtbv-yB2gDa3xXZpx1Ygq0hqa77I28516UOrwvla4,10615
|
|
188
188
|
regscale/integrations/commercial/nessus/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -208,9 +208,9 @@ regscale/integrations/commercial/sarif/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JC
|
|
|
208
208
|
regscale/integrations/commercial/sarif/sairf_importer.py,sha256=gCuDsybT0jbhCtQLJW0L88hLxUpWIgatVERU4D6_9Xc,17886
|
|
209
209
|
regscale/integrations/commercial/sarif/sarif_converter.py,sha256=3KJ7GBt8iJzTKdlUNq5rRx9JaoIHcESdbQim7AfhvNk,1910
|
|
210
210
|
regscale/integrations/commercial/sicura/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
211
|
-
regscale/integrations/commercial/sicura/api.py,sha256=
|
|
211
|
+
regscale/integrations/commercial/sicura/api.py,sha256=dUpLcMgOVTxmfit7Mt118o6y_nQy1nwMLEbbW7euRYw,33982
|
|
212
212
|
regscale/integrations/commercial/sicura/commands.py,sha256=bDphozdUeuEVwspIjqBCOrQUIGAIFJpmg8ltzh3i8kc,2052
|
|
213
|
-
regscale/integrations/commercial/sicura/scanner.py,sha256=
|
|
213
|
+
regscale/integrations/commercial/sicura/scanner.py,sha256=3n0OLvD0n-i1BRG4ZHIJOEVO0xj_IYEJ1h0YBvtKG3U,19046
|
|
214
214
|
regscale/integrations/commercial/sicura/variables.py,sha256=FOdXj5bTtmsAYJYLdLxYMalKhkP1l0bWjA5bCmvgvdU,676
|
|
215
215
|
regscale/integrations/commercial/stig_mapper_integration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
216
216
|
regscale/integrations/commercial/stig_mapper_integration/click_commands.py,sha256=tLD9WObChb4NBd_sWnX05QPqXbiXOzdAp-v5YAObuDc,1200
|
|
@@ -229,10 +229,10 @@ regscale/integrations/commercial/tenablev2/__init__.py,sha256=UpSY_oww83kz9c7amd
|
|
|
229
229
|
regscale/integrations/commercial/tenablev2/authenticate.py,sha256=VPTmxaVCaah2gJYNeU9P1KoQ734ohGQ-wcVy6JfqDTE,1247
|
|
230
230
|
regscale/integrations/commercial/tenablev2/cis_parsers.py,sha256=7F6OSgYXSKMNpEyyWxPilt1u9SZRuQY21Qbp9fGbD9o,17167
|
|
231
231
|
regscale/integrations/commercial/tenablev2/cis_scanner.py,sha256=uMuE48-ZfYSMyFBdJsPgR-biV7OtGYV64-2QZBwKsn0,17550
|
|
232
|
-
regscale/integrations/commercial/tenablev2/commands.py,sha256=
|
|
232
|
+
regscale/integrations/commercial/tenablev2/commands.py,sha256=r7TnD1Aqk2qaIy8xx9baSErnbH5EQwrEHgu2QDfUwIE,32605
|
|
233
233
|
regscale/integrations/commercial/tenablev2/jsonl_scanner.py,sha256=6dv92JslX_p_N6vuwCj4hj1OPy935a-ZjPz0dsWaXuw,83577
|
|
234
234
|
regscale/integrations/commercial/tenablev2/sc_scanner.py,sha256=WQ7ctneHz3fYOrR_GvVUJL3BuKNoN515y7pG8ATMjOM,24102
|
|
235
|
-
regscale/integrations/commercial/tenablev2/scanner.py,sha256=
|
|
235
|
+
regscale/integrations/commercial/tenablev2/scanner.py,sha256=MEEyFKEdQdV8QUQUwL3eK7aLMvJppdACj2Mt7JZ4bv4,21462
|
|
236
236
|
regscale/integrations/commercial/tenablev2/stig_parsers.py,sha256=xv68Vk7BhTIAM5RZqlCRK3fOd2qcVTGgtTM3DFiuhuY,7780
|
|
237
237
|
regscale/integrations/commercial/tenablev2/sync_compliance.py,sha256=_7_VwJm2xHUk-4Pzaz-ywQ3FNuMgRUn9IlRW3m9e97M,22083
|
|
238
238
|
regscale/integrations/commercial/tenablev2/utils.py,sha256=_MmvcR71PmvH4dQ1k4M-q4PYAg0EE_aQ9w4cUdP7SwE,3359
|
|
@@ -248,7 +248,7 @@ regscale/integrations/commercial/wizv2/file_cleanup.py,sha256=ENBO9RDXL2kyHkBYaS
|
|
|
248
248
|
regscale/integrations/commercial/wizv2/issue.py,sha256=fTYRTpf1bjWfPe1MgKhUkv7-ahQzib4hDGJVCTbvDpI,46238
|
|
249
249
|
regscale/integrations/commercial/wizv2/reports.py,sha256=GTP_bNGqxofKNEucDfbbE5RmjIEmMZgZLZT_sYdi0Ew,8794
|
|
250
250
|
regscale/integrations/commercial/wizv2/sbom.py,sha256=gdjB33PG67LrZXZUji7KCLjJ_CuiXE5nX_EcACo-DNk,4471
|
|
251
|
-
regscale/integrations/commercial/wizv2/scanner.py,sha256=
|
|
251
|
+
regscale/integrations/commercial/wizv2/scanner.py,sha256=JREqiYYS-ZZUgg7gEzLdYzYh7tlILB6_OBjFYpxXshE,95413
|
|
252
252
|
regscale/integrations/commercial/wizv2/variables.py,sha256=SdMZyKsAn-JxjVNMCWA6Im4h_7Sb2JlJ3vS6aorzHpc,3812
|
|
253
253
|
regscale/integrations/commercial/wizv2/compliance/__init__.py,sha256=t0WhxpC75lVQ1P_abMlyrTqXJKXGI4ZRp9C-5_gF4A0,377
|
|
254
254
|
regscale/integrations/commercial/wizv2/compliance/helpers.py,sha256=HXSFgYtYDE6TdpbEYxvqaz4s673oaveurnyuuG5lgV8,22983
|
|
@@ -271,7 +271,7 @@ regscale/integrations/integration/integration.py,sha256=pr_fbqBieYbqp3PdBjuqKuZC
|
|
|
271
271
|
regscale/integrations/integration/inventory.py,sha256=gHL1a6VSV3zf4DTmksEy8qXNrqhIun8TwLxhRpuEMqY,341
|
|
272
272
|
regscale/integrations/integration/issue.py,sha256=HaCF_5F_U_E5ecYlMgOZiM-yhXnt7OLj47OAJkf9X3g,3507
|
|
273
273
|
regscale/integrations/public/__init__.py,sha256=oohbRYt88NZyMoFvQGrx6kVQROZrxAwlKIumL2yUh2g,3348
|
|
274
|
-
regscale/integrations/public/cci_importer.py,sha256=
|
|
274
|
+
regscale/integrations/public/cci_importer.py,sha256=MZLX1YlaVCiVgDiFZkQV-0iHmBqkuT_vSadbDUCDLdw,31494
|
|
275
275
|
regscale/integrations/public/cisa.py,sha256=EE2rN4GWWEk5VLt4iMVwGMYB6yYPxe6KyW_tLs8dDmA,21870
|
|
276
276
|
regscale/integrations/public/criticality_updater.py,sha256=bekadBBJkym5Dd9JZFNQmY3I0e1xgBvxkyVwgCNOKus,2806
|
|
277
277
|
regscale/integrations/public/emass.py,sha256=culHHuXUlVYkB6DcVcnUvpBzU1eRyyVGgsJ3KqC8HOw,13672
|
|
@@ -336,12 +336,12 @@ regscale/models/app_models/mapping.py,sha256=tga2kCsEZT-YvnJIgiHy_qRcFp25Xzk0Ykb
|
|
|
336
336
|
regscale/models/app_models/pipeline.py,sha256=qzrkQvvW6d8rqbBjMR8wkT2obez0tnKyY_TxtxLh6VE,909
|
|
337
337
|
regscale/models/integration_models/CCI_List.xml,sha256=qwHzCrZ3KQnLLmrF6J9dE_trhVcUdIw-7WFTtvPmNLM,3226054
|
|
338
338
|
regscale/models/integration_models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
339
|
-
regscale/models/integration_models/aqua.py,sha256=
|
|
339
|
+
regscale/models/integration_models/aqua.py,sha256=MI_qltODiERdGpmwoRD7_U1ISmBMl30mjpPf8brjdhQ,10717
|
|
340
340
|
regscale/models/integration_models/azure_alerts.py,sha256=2etrpvcxa7jVQrc98bJlVGd3xPcw-YwJ65c3pfSf0uA,8408
|
|
341
341
|
regscale/models/integration_models/base64.py,sha256=sxV6O5qY1_TstJENX5jBPsSdQwmA83-NNhgJFunXiZE,570
|
|
342
342
|
regscale/models/integration_models/burp.py,sha256=FBEBkH3U0Q8vq71FFoWnvgLRF5Hkr9GYmQFmNNHFrVk,16932
|
|
343
343
|
regscale/models/integration_models/burp_models.py,sha256=UytDTAcCaxyu-knFkm_mEUH6UmWK3OTXKSC9Sc6OjVs,3669
|
|
344
|
-
regscale/models/integration_models/cisa_kev_data.json,sha256=
|
|
344
|
+
regscale/models/integration_models/cisa_kev_data.json,sha256=g9yH6zg8DARdu4A1E4VvQJ5pGGffuCZRpsd2RkhwjGY,1306997
|
|
345
345
|
regscale/models/integration_models/defender_data.py,sha256=jsAcjKxiGmumGerj7xSWkFd6r__YpuKDnYX5o7xHDiE,2844
|
|
346
346
|
regscale/models/integration_models/defenderimport.py,sha256=Ze4kgwns-IYPyO7sBjEzW8PXWlxwU-DAo2fIyRcTC3k,6242
|
|
347
347
|
regscale/models/integration_models/drf.py,sha256=Aq7AdLa_CH97NrnR-CxaFI22JjVN9uCxVN7Z-BBUaNU,18896
|
|
@@ -368,22 +368,22 @@ regscale/models/integration_models/axonius_models/connectors/assets.py,sha256=6m
|
|
|
368
368
|
regscale/models/integration_models/ecr_models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
369
369
|
regscale/models/integration_models/ecr_models/data.py,sha256=l28DCidXar1JygYBQZL9MYenQA9N-Cx3Skf51IOjZcw,1017
|
|
370
370
|
regscale/models/integration_models/ecr_models/ecr.py,sha256=oAkQ-SDS3Mjrn291dh9qF5LaRYGFJnmuNY28UyrzIfg,7293
|
|
371
|
-
regscale/models/integration_models/flat_file_importer/__init__.py,sha256=
|
|
371
|
+
regscale/models/integration_models/flat_file_importer/__init__.py,sha256=8RNe5LU_mHvO4bH2wO_1d2pijy2s4n7nhpjN25xZF2o,40633
|
|
372
372
|
regscale/models/integration_models/sbom/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
373
373
|
regscale/models/integration_models/sbom/cyclone_dx.py,sha256=0pFR0BWBrF5c8_cC_8mj2MXvNOMHOdHbBYXvTVfFAh8,4058
|
|
374
374
|
regscale/models/integration_models/synqly_models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
375
|
-
regscale/models/integration_models/synqly_models/capabilities.json,sha256=
|
|
375
|
+
regscale/models/integration_models/synqly_models/capabilities.json,sha256=oV1EzsM5z2abuVWhoxcgJ7Sg1mT6DQ7sNtJPbYwS330,442978
|
|
376
376
|
regscale/models/integration_models/synqly_models/connector_types.py,sha256=8nxptkTexpskySnmL0obNAff_iu_fx6tJ7i1-4hJvao,461
|
|
377
377
|
regscale/models/integration_models/synqly_models/filter_parser.py,sha256=8rdnHH7gW1A_uWRTexZXzCH-HzRVy5nlvFgtc7ztcsQ,12160
|
|
378
|
-
regscale/models/integration_models/synqly_models/ocsf_mapper.py,sha256=
|
|
378
|
+
regscale/models/integration_models/synqly_models/ocsf_mapper.py,sha256=3M1O8yz0jBRav30lK8BU1xUL5STixetRSpIp5bWhRzg,18746
|
|
379
379
|
regscale/models/integration_models/synqly_models/param.py,sha256=Xt5Zm6lC_VkLj7LF2qXo72TJZHysqttsp5ai0NCf1po,2643
|
|
380
|
-
regscale/models/integration_models/synqly_models/synqly_model.py,sha256=
|
|
380
|
+
regscale/models/integration_models/synqly_models/synqly_model.py,sha256=RPxieh3r9dVdkt7IliiNEqEqvhbXv3UFuEEZ4-MNqGc,37965
|
|
381
381
|
regscale/models/integration_models/synqly_models/tenants.py,sha256=kewIZw-iv18bNXJGG3ghwuFJ4CK5iXQhn_x2-xvV0iM,1078
|
|
382
382
|
regscale/models/integration_models/synqly_models/connectors/__init__.py,sha256=J3YS7KXLnTPRzeM3lUQpy6HKH7CxPPsWCB-sPXSWcYA,189
|
|
383
383
|
regscale/models/integration_models/synqly_models/connectors/assets.py,sha256=HHNIAVh5pRuJe8sStqhFEc6VnX2wT0FcY5178nbQgkQ,3705
|
|
384
384
|
regscale/models/integration_models/synqly_models/connectors/edr.py,sha256=kio3uoEYubCHretpDOJqxdwmzid1IzbVYz0BF64zeL0,5547
|
|
385
385
|
regscale/models/integration_models/synqly_models/connectors/ticketing.py,sha256=yRBuCkRAVfa_C91r3WqJ9gxrQsoD0qV9cY48YXpJl70,25358
|
|
386
|
-
regscale/models/integration_models/synqly_models/connectors/vulnerabilities.py,sha256=
|
|
386
|
+
regscale/models/integration_models/synqly_models/connectors/vulnerabilities.py,sha256=7fsPHtWSrHxlqAXGURvQ4VWunmAs-acz7O8ABHshdBw,8240
|
|
387
387
|
regscale/models/integration_models/tenable_models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
388
388
|
regscale/models/integration_models/tenable_models/integration.py,sha256=lplL8zmjTFuhLreW-4y7G1fiCOBgzNAaATq800jgTQc,10271
|
|
389
389
|
regscale/models/integration_models/tenable_models/models.py,sha256=dmG7btkN4YkDWwnfW5Ldc3tWEAGjPiaRgJjrqMOkPEU,15846
|
|
@@ -559,7 +559,7 @@ tests/regscale/integrations/commercial/test_jira.py,sha256=oyPdDpjh4MiKlUYN14Za9
|
|
|
559
559
|
tests/regscale/integrations/commercial/test_npm_audit.py,sha256=g8Dyvb3hmYPKgTF6l7MNKnuiBEStK5tM8jFbs594IBQ,988
|
|
560
560
|
tests/regscale/integrations/commercial/test_okta.py,sha256=J3bBdotRRkIqdsEVLZLyt5PBI5u_dpmxXZnVFuSG1bs,47149
|
|
561
561
|
tests/regscale/integrations/commercial/test_sarif_converter.py,sha256=uONCJEfiV2flUIDa-iwFd_h5RnHSaFHoyvNrXtcOhVU,11251
|
|
562
|
-
tests/regscale/integrations/commercial/test_sicura.py,sha256=
|
|
562
|
+
tests/regscale/integrations/commercial/test_sicura.py,sha256=FaY0uOOKf7zyd2ejLtg07hMRIHDapi5n4qvxBc1s6MM,13192
|
|
563
563
|
tests/regscale/integrations/commercial/test_snow.py,sha256=LKAeme78hl0VzzLP-rXZnA5-3CCBrJLgYUlxOW2hYnM,16076
|
|
564
564
|
tests/regscale/integrations/commercial/test_sonarcloud.py,sha256=IB3nD9KbkTBXJgjF4RujUod54VUI0CMYanqoQ40suBk,15291
|
|
565
565
|
tests/regscale/integrations/commercial/test_sqlserver.py,sha256=TktSuFoyLUmdimRxoN8wxBQwr75igWxA8mN83Isnuvw,7119
|
|
@@ -592,7 +592,7 @@ tests/regscale/integrations/commercial/wizv2/test_wiz_control_normalization.py,s
|
|
|
592
592
|
tests/regscale/integrations/commercial/wizv2/test_wiz_findings_comprehensive.py,sha256=zieuADKOAlBjPPlUkgSvMMZOr4CvnIZTl_0MvsyK4XA,14955
|
|
593
593
|
tests/regscale/integrations/commercial/wizv2/test_wiz_inventory_comprehensive.py,sha256=2vEB9Hz_M1D2YQyZC3fD6RJCeXlRbUT3PRsu3DDek-A,27089
|
|
594
594
|
tests/regscale/integrations/commercial/wizv2/test_wiz_status_mapping.py,sha256=ZUeRHUt547FV0svfiGEIwyRuItoTDKtMeJFvBWuhWhg,6967
|
|
595
|
-
tests/regscale/integrations/commercial/wizv2/test_wizv2.py,sha256=
|
|
595
|
+
tests/regscale/integrations/commercial/wizv2/test_wizv2.py,sha256=WoRyyrJLW6Nnie1G6McWZc24OAe0A2KYhqXMyOiOSnw,66522
|
|
596
596
|
tests/regscale/integrations/commercial/wizv2/test_wizv2_utils.py,sha256=U3qOibYbzF1adPPdpTbqyeWCT6t8cRaLy__o9F8mLO0,25182
|
|
597
597
|
tests/regscale/integrations/commercial/wizv2/compliance/__init__.py,sha256=_ceZ5sfxe2B6jHQuisE8iYg_G68IkArHYq1oTC9Ede0,47
|
|
598
598
|
tests/regscale/integrations/commercial/wizv2/compliance/test_helpers.py,sha256=0fuC9cuSSXzWeRrm9Y0KC7uOZsOPpiOz48m_C8nF6lg,35411
|
|
@@ -610,7 +610,7 @@ tests/regscale/integrations/commercial/wizv2/utils/__init__.py,sha256=PIKcAU5kcq
|
|
|
610
610
|
tests/regscale/integrations/commercial/wizv2/utils/test_main.py,sha256=VExH4ORw3C4KBzZiQwwtRpeGnsQhl5r0FMk0wD6OCBo,60749
|
|
611
611
|
tests/regscale/integrations/public/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
612
612
|
tests/regscale/integrations/public/test_alienvault.py,sha256=epxuflNgibIl1aYCU0FTVXXFWJbiqt0mYBV4HVaZYuw,9211
|
|
613
|
-
tests/regscale/integrations/public/test_cci.py,sha256=
|
|
613
|
+
tests/regscale/integrations/public/test_cci.py,sha256=Xtyuwv1N8wTgvnUs7oWkWwp7yOC3MO77gyqOKFXC5mI,44314
|
|
614
614
|
tests/regscale/integrations/public/test_cisa.py,sha256=onfmI-8Nuhr7g0C87gweGoWhAubcqkmammRUD8QCQFE,41376
|
|
615
615
|
tests/regscale/integrations/public/test_emass.py,sha256=fDjQcsiXFhWGB399fikfW_khCrixB3nEL3cBlAm4XbQ,21797
|
|
616
616
|
tests/regscale/integrations/public/test_fedramp.py,sha256=ppVsyj-zQRq5isH0Ht1_s9jrJUSBJSs9y976-LDHpwE,70161
|
|
@@ -635,9 +635,9 @@ tests/regscale/models/test_regscale_model.py,sha256=ZsrEZkC4EtdIsoQuayn1xv2gEGcV
|
|
|
635
635
|
tests/regscale/models/test_report.py,sha256=IqUq7C__a1_q_mLaz0PE9Lq6fHggBsB14-AzEYNBxLw,4666
|
|
636
636
|
tests/regscale/models/test_tenable_integrations.py,sha256=y1qaW77H094VSGHjZdlvF66UCt-nPEib9Mv3cdwbM94,32435
|
|
637
637
|
tests/regscale/models/test_user_model.py,sha256=e9olv28qBApgnvK6hFHOgXjUC-pkaV8aGDirEIWASL4,4427
|
|
638
|
-
regscale_cli-6.27.0.
|
|
639
|
-
regscale_cli-6.27.0.
|
|
640
|
-
regscale_cli-6.27.0.
|
|
641
|
-
regscale_cli-6.27.0.
|
|
642
|
-
regscale_cli-6.27.0.
|
|
643
|
-
regscale_cli-6.27.0.
|
|
638
|
+
regscale_cli-6.27.2.0.dist-info/LICENSE,sha256=ytNhYQ9Rmhj_m-EX2pPq9Ld6tH5wrqqDYg-fCf46WDU,1076
|
|
639
|
+
regscale_cli-6.27.2.0.dist-info/METADATA,sha256=urTKR5zkhFizHfI1rxRo29oWv7HRbGHOxLSVbO8U_Ts,34231
|
|
640
|
+
regscale_cli-6.27.2.0.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
|
641
|
+
regscale_cli-6.27.2.0.dist-info/entry_points.txt,sha256=cLOaIP1eRv1yZ2u7BvpE3aB4x3kDrDwkpeisKOu33z8,269
|
|
642
|
+
regscale_cli-6.27.2.0.dist-info/top_level.txt,sha256=Uv8VUCAdxRm70bgrD4YNEJUmDhBThad_1aaEFGwRByc,15
|
|
643
|
+
regscale_cli-6.27.2.0.dist-info/RECORD,,
|
|
@@ -522,6 +522,35 @@ class TestWizVulnerabilityIntegration(unittest.TestCase):
|
|
|
522
522
|
severity = WizVulnerabilityIntegration.get_issue_severity("Unknown")
|
|
523
523
|
self.assertEqual(severity, regscale_models.IssueSeverity.Low)
|
|
524
524
|
|
|
525
|
+
def test_get_issue_severity_none_maps_to_not_assigned(self, mock_parent_init):
|
|
526
|
+
"""Test REG-17981: Handle NONE severity from Wiz config findings."""
|
|
527
|
+
severity = WizVulnerabilityIntegration.get_issue_severity("None")
|
|
528
|
+
self.assertEqual(severity, regscale_models.IssueSeverity.NotAssigned)
|
|
529
|
+
|
|
530
|
+
@patch("regscale.integrations.commercial.wizv2.scanner.WizVulnerabilityIntegration.authenticate")
|
|
531
|
+
def test_should_process_finding_by_severity_none_treated_as_informational(
|
|
532
|
+
self, mock_authenticate, mock_parent_init
|
|
533
|
+
):
|
|
534
|
+
"""Test REG-17981: NONE severity should be treated as informational for filtering."""
|
|
535
|
+
mock_authenticate.return_value = None
|
|
536
|
+
integration = WizVulnerabilityIntegration(plan_id=self.plan_id)
|
|
537
|
+
self._initialize_scanner_attributes(integration)
|
|
538
|
+
integration.app.config["scanners"] = {"wiz": {"minimumSeverity": "low"}}
|
|
539
|
+
# NONE severity should be filtered out when min is "low" (treated as informational)
|
|
540
|
+
self.assertFalse(integration.should_process_finding_by_severity("NONE"))
|
|
541
|
+
|
|
542
|
+
@patch("regscale.integrations.commercial.wizv2.scanner.WizVulnerabilityIntegration.authenticate")
|
|
543
|
+
def test_should_process_finding_by_severity_none_allowed_with_informational(
|
|
544
|
+
self, mock_authenticate, mock_parent_init
|
|
545
|
+
):
|
|
546
|
+
"""Test REG-17981: NONE severity should be allowed when min severity is informational."""
|
|
547
|
+
mock_authenticate.return_value = None
|
|
548
|
+
integration = WizVulnerabilityIntegration(plan_id=self.plan_id)
|
|
549
|
+
self._initialize_scanner_attributes(integration)
|
|
550
|
+
integration.app.config["scanners"] = {"wiz": {"minimumSeverity": "informational"}}
|
|
551
|
+
# NONE severity should be processed when min is "informational"
|
|
552
|
+
self.assertTrue(integration.should_process_finding_by_severity("NONE"))
|
|
553
|
+
|
|
525
554
|
@patch("regscale.integrations.commercial.wizv2.scanner.WizVulnerabilityIntegration.authenticate")
|
|
526
555
|
def test_should_process_finding_by_severity_critical(self, mock_authenticate, mock_parent_init):
|
|
527
556
|
mock_authenticate.return_value = None
|
|
@@ -687,6 +716,63 @@ class TestWizVulnerabilityIntegration(unittest.TestCase):
|
|
|
687
716
|
asset_id = integration.get_asset_id_from_node(node, WizVulnerabilityType.VULNERABILITY)
|
|
688
717
|
self.assertIsNone(asset_id)
|
|
689
718
|
|
|
719
|
+
@patch("regscale.integrations.commercial.wizv2.scanner.WizVulnerabilityIntegration.authenticate")
|
|
720
|
+
def test_get_asset_id_with_none_value_returns_none(self, mock_authenticate, mock_parent_init):
|
|
721
|
+
"""Test REG-17981: Handle None value for asset container without AttributeError."""
|
|
722
|
+
from regscale.integrations.commercial.wizv2.core.constants import WizVulnerabilityType
|
|
723
|
+
|
|
724
|
+
mock_authenticate.return_value = None
|
|
725
|
+
integration = WizVulnerabilityIntegration(plan_id=self.plan_id)
|
|
726
|
+
node = {"vulnerableAsset": None}
|
|
727
|
+
asset_id = integration.get_asset_id_from_node(node, WizVulnerabilityType.VULNERABILITY)
|
|
728
|
+
self.assertIsNone(asset_id)
|
|
729
|
+
|
|
730
|
+
@patch("regscale.integrations.commercial.wizv2.scanner.WizVulnerabilityIntegration.authenticate")
|
|
731
|
+
def test_get_asset_id_with_none_resource_returns_none(self, mock_authenticate, mock_parent_init):
|
|
732
|
+
"""Test REG-17981: Handle None value for resource field without AttributeError."""
|
|
733
|
+
from regscale.integrations.commercial.wizv2.core.constants import WizVulnerabilityType
|
|
734
|
+
|
|
735
|
+
mock_authenticate.return_value = None
|
|
736
|
+
integration = WizVulnerabilityIntegration(plan_id=self.plan_id)
|
|
737
|
+
node = {"resource": None}
|
|
738
|
+
asset_id = integration.get_asset_id_from_node(node, WizVulnerabilityType.CONFIGURATION)
|
|
739
|
+
self.assertIsNone(asset_id)
|
|
740
|
+
|
|
741
|
+
@patch("regscale.integrations.commercial.wizv2.scanner.WizVulnerabilityIntegration.authenticate")
|
|
742
|
+
def test_get_asset_id_with_non_dict_value_returns_none(self, mock_authenticate, mock_parent_init):
|
|
743
|
+
"""Test REG-17981: Handle non-dict value for asset container without AttributeError."""
|
|
744
|
+
from regscale.integrations.commercial.wizv2.core.constants import WizVulnerabilityType
|
|
745
|
+
|
|
746
|
+
mock_authenticate.return_value = None
|
|
747
|
+
integration = WizVulnerabilityIntegration(plan_id=self.plan_id)
|
|
748
|
+
# Test with a string value instead of dict
|
|
749
|
+
node = {"vulnerableAsset": "not-a-dict"}
|
|
750
|
+
asset_id = integration.get_asset_id_from_node(node, WizVulnerabilityType.VULNERABILITY)
|
|
751
|
+
self.assertIsNone(asset_id)
|
|
752
|
+
|
|
753
|
+
@patch("regscale.integrations.commercial.wizv2.scanner.WizVulnerabilityIntegration.authenticate")
|
|
754
|
+
def test_get_provider_unique_id_with_none_value_returns_none(self, mock_authenticate, mock_parent_init):
|
|
755
|
+
"""Test REG-17981: Handle None value in get_provider_unique_id_from_node without AttributeError."""
|
|
756
|
+
from regscale.integrations.commercial.wizv2.core.constants import WizVulnerabilityType
|
|
757
|
+
|
|
758
|
+
mock_authenticate.return_value = None
|
|
759
|
+
integration = WizVulnerabilityIntegration(plan_id=self.plan_id)
|
|
760
|
+
node = {"vulnerableAsset": None}
|
|
761
|
+
provider_id = integration.get_provider_unique_id_from_node(node, WizVulnerabilityType.VULNERABILITY)
|
|
762
|
+
self.assertIsNone(provider_id)
|
|
763
|
+
|
|
764
|
+
@patch("regscale.integrations.commercial.wizv2.scanner.WizVulnerabilityIntegration.authenticate")
|
|
765
|
+
def test_get_provider_unique_id_with_non_dict_returns_none(self, mock_authenticate, mock_parent_init):
|
|
766
|
+
"""Test REG-17981: Handle non-dict value in get_provider_unique_id_from_node without AttributeError."""
|
|
767
|
+
from regscale.integrations.commercial.wizv2.core.constants import WizVulnerabilityType
|
|
768
|
+
|
|
769
|
+
mock_authenticate.return_value = None
|
|
770
|
+
integration = WizVulnerabilityIntegration(plan_id=self.plan_id)
|
|
771
|
+
# Test with a list value instead of dict
|
|
772
|
+
node = {"vulnerableAsset": ["not", "a", "dict"]}
|
|
773
|
+
provider_id = integration.get_provider_unique_id_from_node(node, WizVulnerabilityType.VULNERABILITY)
|
|
774
|
+
self.assertIsNone(provider_id)
|
|
775
|
+
|
|
690
776
|
@patch("regscale.integrations.commercial.wizv2.scanner.WizVulnerabilityIntegration.authenticate")
|
|
691
777
|
def test_get_provider_unique_id_standard(self, mock_authenticate, mock_parent_init):
|
|
692
778
|
from regscale.integrations.commercial.wizv2.core.constants import WizVulnerabilityType
|