regscale-cli 6.16.0.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.

Files changed (481) hide show
  1. regscale/__init__.py +1 -0
  2. regscale/airflow/__init__.py +9 -0
  3. regscale/airflow/azure/__init__.py +9 -0
  4. regscale/airflow/azure/cli.py +89 -0
  5. regscale/airflow/azure/upload_dags.py +116 -0
  6. regscale/airflow/click_dags.py +127 -0
  7. regscale/airflow/click_mixins.py +82 -0
  8. regscale/airflow/config.py +25 -0
  9. regscale/airflow/factories/__init__.py +0 -0
  10. regscale/airflow/factories/connections.py +58 -0
  11. regscale/airflow/factories/workflows.py +78 -0
  12. regscale/airflow/hierarchy.py +88 -0
  13. regscale/airflow/operators/__init__.py +0 -0
  14. regscale/airflow/operators/click.py +36 -0
  15. regscale/airflow/sensors/__init__.py +0 -0
  16. regscale/airflow/sensors/sql.py +107 -0
  17. regscale/airflow/sessions/__init__.py +0 -0
  18. regscale/airflow/sessions/sql/__init__.py +3 -0
  19. regscale/airflow/sessions/sql/queries.py +64 -0
  20. regscale/airflow/sessions/sql/sql_server_queries.py +248 -0
  21. regscale/airflow/tasks/__init__.py +0 -0
  22. regscale/airflow/tasks/branches.py +22 -0
  23. regscale/airflow/tasks/cli.py +116 -0
  24. regscale/airflow/tasks/click.py +73 -0
  25. regscale/airflow/tasks/debugging.py +9 -0
  26. regscale/airflow/tasks/groups.py +116 -0
  27. regscale/airflow/tasks/init.py +60 -0
  28. regscale/airflow/tasks/states.py +47 -0
  29. regscale/airflow/tasks/workflows.py +36 -0
  30. regscale/ansible/__init__.py +9 -0
  31. regscale/core/__init__.py +0 -0
  32. regscale/core/app/__init__.py +3 -0
  33. regscale/core/app/api.py +571 -0
  34. regscale/core/app/application.py +665 -0
  35. regscale/core/app/internal/__init__.py +136 -0
  36. regscale/core/app/internal/admin_actions.py +230 -0
  37. regscale/core/app/internal/assessments_editor.py +873 -0
  38. regscale/core/app/internal/catalog.py +316 -0
  39. regscale/core/app/internal/comparison.py +459 -0
  40. regscale/core/app/internal/control_editor.py +571 -0
  41. regscale/core/app/internal/encrypt.py +79 -0
  42. regscale/core/app/internal/evidence.py +1240 -0
  43. regscale/core/app/internal/file_uploads.py +151 -0
  44. regscale/core/app/internal/healthcheck.py +66 -0
  45. regscale/core/app/internal/login.py +305 -0
  46. regscale/core/app/internal/migrations.py +240 -0
  47. regscale/core/app/internal/model_editor.py +1701 -0
  48. regscale/core/app/internal/poam_editor.py +632 -0
  49. regscale/core/app/internal/workflow.py +105 -0
  50. regscale/core/app/logz.py +74 -0
  51. regscale/core/app/utils/XMLIR.py +258 -0
  52. regscale/core/app/utils/__init__.py +0 -0
  53. regscale/core/app/utils/api_handler.py +358 -0
  54. regscale/core/app/utils/app_utils.py +1110 -0
  55. regscale/core/app/utils/catalog_utils/__init__.py +0 -0
  56. regscale/core/app/utils/catalog_utils/common.py +91 -0
  57. regscale/core/app/utils/catalog_utils/compare_catalog.py +193 -0
  58. regscale/core/app/utils/catalog_utils/diagnostic_catalog.py +97 -0
  59. regscale/core/app/utils/catalog_utils/download_catalog.py +103 -0
  60. regscale/core/app/utils/catalog_utils/update_catalog.py +718 -0
  61. regscale/core/app/utils/catalog_utils/update_catalog_v2.py +1378 -0
  62. regscale/core/app/utils/catalog_utils/update_catalog_v3.py +1272 -0
  63. regscale/core/app/utils/catalog_utils/update_plans.py +334 -0
  64. regscale/core/app/utils/file_utils.py +238 -0
  65. regscale/core/app/utils/parser_utils.py +81 -0
  66. regscale/core/app/utils/pickle_file_handler.py +57 -0
  67. regscale/core/app/utils/regscale_utils.py +319 -0
  68. regscale/core/app/utils/report_utils.py +119 -0
  69. regscale/core/app/utils/variables.py +226 -0
  70. regscale/core/decorators.py +31 -0
  71. regscale/core/lazy_group.py +65 -0
  72. regscale/core/login.py +63 -0
  73. regscale/core/server/__init__.py +0 -0
  74. regscale/core/server/flask_api.py +473 -0
  75. regscale/core/server/helpers.py +373 -0
  76. regscale/core/server/rest.py +64 -0
  77. regscale/core/server/static/css/bootstrap.css +6030 -0
  78. regscale/core/server/static/css/bootstrap.min.css +6 -0
  79. regscale/core/server/static/css/main.css +176 -0
  80. regscale/core/server/static/images/regscale-cli.svg +49 -0
  81. regscale/core/server/static/images/regscale.svg +38 -0
  82. regscale/core/server/templates/base.html +74 -0
  83. regscale/core/server/templates/index.html +43 -0
  84. regscale/core/server/templates/login.html +28 -0
  85. regscale/core/server/templates/make_base64.html +22 -0
  86. regscale/core/server/templates/upload_STIG.html +109 -0
  87. regscale/core/server/templates/upload_STIG_result.html +26 -0
  88. regscale/core/server/templates/upload_ssp.html +144 -0
  89. regscale/core/server/templates/upload_ssp_result.html +128 -0
  90. regscale/core/static/__init__.py +0 -0
  91. regscale/core/static/regex.py +14 -0
  92. regscale/core/utils/__init__.py +117 -0
  93. regscale/core/utils/click_utils.py +13 -0
  94. regscale/core/utils/date.py +238 -0
  95. regscale/core/utils/graphql.py +254 -0
  96. regscale/core/utils/urls.py +23 -0
  97. regscale/dev/__init__.py +6 -0
  98. regscale/dev/analysis.py +454 -0
  99. regscale/dev/cli.py +235 -0
  100. regscale/dev/code_gen.py +492 -0
  101. regscale/dev/dirs.py +69 -0
  102. regscale/dev/docs.py +384 -0
  103. regscale/dev/monitoring.py +26 -0
  104. regscale/dev/profiling.py +216 -0
  105. regscale/exceptions/__init__.py +4 -0
  106. regscale/exceptions/license_exception.py +7 -0
  107. regscale/exceptions/validation_exception.py +9 -0
  108. regscale/integrations/__init__.py +1 -0
  109. regscale/integrations/commercial/__init__.py +486 -0
  110. regscale/integrations/commercial/ad.py +433 -0
  111. regscale/integrations/commercial/amazon/__init__.py +0 -0
  112. regscale/integrations/commercial/amazon/common.py +106 -0
  113. regscale/integrations/commercial/aqua/__init__.py +0 -0
  114. regscale/integrations/commercial/aqua/aqua.py +91 -0
  115. regscale/integrations/commercial/aws/__init__.py +6 -0
  116. regscale/integrations/commercial/aws/cli.py +322 -0
  117. regscale/integrations/commercial/aws/inventory/__init__.py +110 -0
  118. regscale/integrations/commercial/aws/inventory/base.py +64 -0
  119. regscale/integrations/commercial/aws/inventory/resources/__init__.py +19 -0
  120. regscale/integrations/commercial/aws/inventory/resources/compute.py +234 -0
  121. regscale/integrations/commercial/aws/inventory/resources/containers.py +113 -0
  122. regscale/integrations/commercial/aws/inventory/resources/database.py +101 -0
  123. regscale/integrations/commercial/aws/inventory/resources/integration.py +237 -0
  124. regscale/integrations/commercial/aws/inventory/resources/networking.py +253 -0
  125. regscale/integrations/commercial/aws/inventory/resources/security.py +240 -0
  126. regscale/integrations/commercial/aws/inventory/resources/storage.py +91 -0
  127. regscale/integrations/commercial/aws/scanner.py +823 -0
  128. regscale/integrations/commercial/azure/__init__.py +0 -0
  129. regscale/integrations/commercial/azure/common.py +32 -0
  130. regscale/integrations/commercial/azure/intune.py +488 -0
  131. regscale/integrations/commercial/azure/scanner.py +49 -0
  132. regscale/integrations/commercial/burp.py +78 -0
  133. regscale/integrations/commercial/cpe.py +144 -0
  134. regscale/integrations/commercial/crowdstrike.py +1117 -0
  135. regscale/integrations/commercial/defender.py +1511 -0
  136. regscale/integrations/commercial/dependabot.py +210 -0
  137. regscale/integrations/commercial/durosuite/__init__.py +0 -0
  138. regscale/integrations/commercial/durosuite/api.py +1546 -0
  139. regscale/integrations/commercial/durosuite/process_devices.py +101 -0
  140. regscale/integrations/commercial/durosuite/scanner.py +637 -0
  141. regscale/integrations/commercial/durosuite/variables.py +21 -0
  142. regscale/integrations/commercial/ecr.py +90 -0
  143. regscale/integrations/commercial/gcp/__init__.py +237 -0
  144. regscale/integrations/commercial/gcp/auth.py +96 -0
  145. regscale/integrations/commercial/gcp/control_tests.py +238 -0
  146. regscale/integrations/commercial/gcp/variables.py +18 -0
  147. regscale/integrations/commercial/gitlab.py +332 -0
  148. regscale/integrations/commercial/grype.py +165 -0
  149. regscale/integrations/commercial/ibm.py +90 -0
  150. regscale/integrations/commercial/import_all/__init__.py +0 -0
  151. regscale/integrations/commercial/import_all/import_all_cmd.py +467 -0
  152. regscale/integrations/commercial/import_all/scan_file_fingerprints.json +27 -0
  153. regscale/integrations/commercial/jira.py +1046 -0
  154. regscale/integrations/commercial/mappings/__init__.py +0 -0
  155. regscale/integrations/commercial/mappings/csf_controls.json +713 -0
  156. regscale/integrations/commercial/mappings/nist_800_53_r5_controls.json +1516 -0
  157. regscale/integrations/commercial/nessus/__init__.py +0 -0
  158. regscale/integrations/commercial/nessus/nessus_utils.py +429 -0
  159. regscale/integrations/commercial/nessus/scanner.py +416 -0
  160. regscale/integrations/commercial/nexpose.py +90 -0
  161. regscale/integrations/commercial/okta.py +798 -0
  162. regscale/integrations/commercial/opentext/__init__.py +0 -0
  163. regscale/integrations/commercial/opentext/click.py +99 -0
  164. regscale/integrations/commercial/opentext/scanner.py +143 -0
  165. regscale/integrations/commercial/prisma.py +91 -0
  166. regscale/integrations/commercial/qualys.py +1462 -0
  167. regscale/integrations/commercial/salesforce.py +980 -0
  168. regscale/integrations/commercial/sap/__init__.py +0 -0
  169. regscale/integrations/commercial/sap/click.py +31 -0
  170. regscale/integrations/commercial/sap/sysdig/__init__.py +0 -0
  171. regscale/integrations/commercial/sap/sysdig/click.py +57 -0
  172. regscale/integrations/commercial/sap/sysdig/sysdig_scanner.py +190 -0
  173. regscale/integrations/commercial/sap/tenable/__init__.py +0 -0
  174. regscale/integrations/commercial/sap/tenable/click.py +49 -0
  175. regscale/integrations/commercial/sap/tenable/scanner.py +196 -0
  176. regscale/integrations/commercial/servicenow.py +1756 -0
  177. regscale/integrations/commercial/sicura/__init__.py +0 -0
  178. regscale/integrations/commercial/sicura/api.py +855 -0
  179. regscale/integrations/commercial/sicura/commands.py +73 -0
  180. regscale/integrations/commercial/sicura/scanner.py +481 -0
  181. regscale/integrations/commercial/sicura/variables.py +16 -0
  182. regscale/integrations/commercial/snyk.py +90 -0
  183. regscale/integrations/commercial/sonarcloud.py +260 -0
  184. regscale/integrations/commercial/sqlserver.py +369 -0
  185. regscale/integrations/commercial/stig_mapper_integration/__init__.py +0 -0
  186. regscale/integrations/commercial/stig_mapper_integration/click_commands.py +38 -0
  187. regscale/integrations/commercial/stig_mapper_integration/mapping_engine.py +353 -0
  188. regscale/integrations/commercial/stigv2/__init__.py +0 -0
  189. regscale/integrations/commercial/stigv2/ckl_parser.py +349 -0
  190. regscale/integrations/commercial/stigv2/click_commands.py +95 -0
  191. regscale/integrations/commercial/stigv2/stig_integration.py +202 -0
  192. regscale/integrations/commercial/synqly/__init__.py +0 -0
  193. regscale/integrations/commercial/synqly/assets.py +46 -0
  194. regscale/integrations/commercial/synqly/ticketing.py +132 -0
  195. regscale/integrations/commercial/synqly/vulnerabilities.py +223 -0
  196. regscale/integrations/commercial/synqly_jira.py +840 -0
  197. regscale/integrations/commercial/tenablev2/__init__.py +0 -0
  198. regscale/integrations/commercial/tenablev2/authenticate.py +31 -0
  199. regscale/integrations/commercial/tenablev2/click.py +1584 -0
  200. regscale/integrations/commercial/tenablev2/scanner.py +504 -0
  201. regscale/integrations/commercial/tenablev2/stig_parsers.py +140 -0
  202. regscale/integrations/commercial/tenablev2/utils.py +78 -0
  203. regscale/integrations/commercial/tenablev2/variables.py +17 -0
  204. regscale/integrations/commercial/trivy.py +162 -0
  205. regscale/integrations/commercial/veracode.py +96 -0
  206. regscale/integrations/commercial/wizv2/WizDataMixin.py +97 -0
  207. regscale/integrations/commercial/wizv2/__init__.py +0 -0
  208. regscale/integrations/commercial/wizv2/click.py +429 -0
  209. regscale/integrations/commercial/wizv2/constants.py +1001 -0
  210. regscale/integrations/commercial/wizv2/issue.py +361 -0
  211. regscale/integrations/commercial/wizv2/models.py +112 -0
  212. regscale/integrations/commercial/wizv2/parsers.py +339 -0
  213. regscale/integrations/commercial/wizv2/sbom.py +115 -0
  214. regscale/integrations/commercial/wizv2/scanner.py +416 -0
  215. regscale/integrations/commercial/wizv2/utils.py +796 -0
  216. regscale/integrations/commercial/wizv2/variables.py +39 -0
  217. regscale/integrations/commercial/wizv2/wiz_auth.py +159 -0
  218. regscale/integrations/commercial/xray.py +91 -0
  219. regscale/integrations/integration/__init__.py +2 -0
  220. regscale/integrations/integration/integration.py +26 -0
  221. regscale/integrations/integration/inventory.py +17 -0
  222. regscale/integrations/integration/issue.py +100 -0
  223. regscale/integrations/integration_override.py +149 -0
  224. regscale/integrations/public/__init__.py +103 -0
  225. regscale/integrations/public/cisa.py +641 -0
  226. regscale/integrations/public/criticality_updater.py +70 -0
  227. regscale/integrations/public/emass.py +411 -0
  228. regscale/integrations/public/emass_slcm_import.py +697 -0
  229. regscale/integrations/public/fedramp/__init__.py +0 -0
  230. regscale/integrations/public/fedramp/appendix_parser.py +548 -0
  231. regscale/integrations/public/fedramp/click.py +479 -0
  232. regscale/integrations/public/fedramp/components.py +714 -0
  233. regscale/integrations/public/fedramp/docx_parser.py +259 -0
  234. regscale/integrations/public/fedramp/fedramp_cis_crm.py +1124 -0
  235. regscale/integrations/public/fedramp/fedramp_common.py +3181 -0
  236. regscale/integrations/public/fedramp/fedramp_docx.py +388 -0
  237. regscale/integrations/public/fedramp/fedramp_five.py +2343 -0
  238. regscale/integrations/public/fedramp/fedramp_traversal.py +138 -0
  239. regscale/integrations/public/fedramp/import_fedramp_r4_ssp.py +279 -0
  240. regscale/integrations/public/fedramp/import_workbook.py +495 -0
  241. regscale/integrations/public/fedramp/inventory_items.py +244 -0
  242. regscale/integrations/public/fedramp/mappings/__init__.py +0 -0
  243. regscale/integrations/public/fedramp/mappings/fedramp_r4_parts.json +7388 -0
  244. regscale/integrations/public/fedramp/mappings/fedramp_r5_params.json +8636 -0
  245. regscale/integrations/public/fedramp/mappings/fedramp_r5_parts.json +9605 -0
  246. regscale/integrations/public/fedramp/mappings/system_roles.py +34 -0
  247. regscale/integrations/public/fedramp/mappings/user.py +175 -0
  248. regscale/integrations/public/fedramp/mappings/values.py +141 -0
  249. regscale/integrations/public/fedramp/markdown_parser.py +150 -0
  250. regscale/integrations/public/fedramp/metadata.py +689 -0
  251. regscale/integrations/public/fedramp/models/__init__.py +59 -0
  252. regscale/integrations/public/fedramp/models/leveraged_auth_new.py +168 -0
  253. regscale/integrations/public/fedramp/models/poam_importer.py +522 -0
  254. regscale/integrations/public/fedramp/parts_mapper.py +107 -0
  255. regscale/integrations/public/fedramp/poam/__init__.py +0 -0
  256. regscale/integrations/public/fedramp/poam/scanner.py +851 -0
  257. regscale/integrations/public/fedramp/properties.py +201 -0
  258. regscale/integrations/public/fedramp/reporting.py +84 -0
  259. regscale/integrations/public/fedramp/resources.py +496 -0
  260. regscale/integrations/public/fedramp/rosetta.py +110 -0
  261. regscale/integrations/public/fedramp/ssp_logger.py +87 -0
  262. regscale/integrations/public/fedramp/system_characteristics.py +922 -0
  263. regscale/integrations/public/fedramp/system_control_implementations.py +582 -0
  264. regscale/integrations/public/fedramp/system_implementation.py +190 -0
  265. regscale/integrations/public/fedramp/xml_utils.py +87 -0
  266. regscale/integrations/public/nist_catalog.py +275 -0
  267. regscale/integrations/public/oscal.py +1946 -0
  268. regscale/integrations/public/otx.py +169 -0
  269. regscale/integrations/scanner_integration.py +2692 -0
  270. regscale/integrations/variables.py +25 -0
  271. regscale/models/__init__.py +7 -0
  272. regscale/models/app_models/__init__.py +5 -0
  273. regscale/models/app_models/catalog_compare.py +213 -0
  274. regscale/models/app_models/click.py +252 -0
  275. regscale/models/app_models/datetime_encoder.py +21 -0
  276. regscale/models/app_models/import_validater.py +321 -0
  277. regscale/models/app_models/mapping.py +260 -0
  278. regscale/models/app_models/pipeline.py +37 -0
  279. regscale/models/click_models.py +413 -0
  280. regscale/models/config.py +154 -0
  281. regscale/models/email_style.css +67 -0
  282. regscale/models/hierarchy.py +8 -0
  283. regscale/models/inspect_models.py +79 -0
  284. regscale/models/integration_models/__init__.py +0 -0
  285. regscale/models/integration_models/amazon_models/__init__.py +0 -0
  286. regscale/models/integration_models/amazon_models/inspector.py +262 -0
  287. regscale/models/integration_models/amazon_models/inspector_scan.py +206 -0
  288. regscale/models/integration_models/aqua.py +247 -0
  289. regscale/models/integration_models/azure_alerts.py +255 -0
  290. regscale/models/integration_models/base64.py +23 -0
  291. regscale/models/integration_models/burp.py +433 -0
  292. regscale/models/integration_models/burp_models.py +128 -0
  293. regscale/models/integration_models/cisa_kev_data.json +19333 -0
  294. regscale/models/integration_models/defender_data.py +93 -0
  295. regscale/models/integration_models/defenderimport.py +143 -0
  296. regscale/models/integration_models/drf.py +443 -0
  297. regscale/models/integration_models/ecr_models/__init__.py +0 -0
  298. regscale/models/integration_models/ecr_models/data.py +69 -0
  299. regscale/models/integration_models/ecr_models/ecr.py +239 -0
  300. regscale/models/integration_models/flat_file_importer.py +1079 -0
  301. regscale/models/integration_models/grype_import.py +247 -0
  302. regscale/models/integration_models/ibm.py +126 -0
  303. regscale/models/integration_models/implementation_results.py +85 -0
  304. regscale/models/integration_models/nexpose.py +140 -0
  305. regscale/models/integration_models/prisma.py +202 -0
  306. regscale/models/integration_models/qualys.py +720 -0
  307. regscale/models/integration_models/qualys_scanner.py +160 -0
  308. regscale/models/integration_models/sbom/__init__.py +0 -0
  309. regscale/models/integration_models/sbom/cyclone_dx.py +139 -0
  310. regscale/models/integration_models/send_reminders.py +620 -0
  311. regscale/models/integration_models/snyk.py +155 -0
  312. regscale/models/integration_models/synqly_models/__init__.py +0 -0
  313. regscale/models/integration_models/synqly_models/capabilities.json +1 -0
  314. regscale/models/integration_models/synqly_models/connector_types.py +22 -0
  315. regscale/models/integration_models/synqly_models/connectors/__init__.py +7 -0
  316. regscale/models/integration_models/synqly_models/connectors/assets.py +97 -0
  317. regscale/models/integration_models/synqly_models/connectors/ticketing.py +583 -0
  318. regscale/models/integration_models/synqly_models/connectors/vulnerabilities.py +169 -0
  319. regscale/models/integration_models/synqly_models/ocsf_mapper.py +331 -0
  320. regscale/models/integration_models/synqly_models/param.py +72 -0
  321. regscale/models/integration_models/synqly_models/synqly_model.py +733 -0
  322. regscale/models/integration_models/synqly_models/tenants.py +39 -0
  323. regscale/models/integration_models/tenable_models/__init__.py +0 -0
  324. regscale/models/integration_models/tenable_models/integration.py +187 -0
  325. regscale/models/integration_models/tenable_models/models.py +513 -0
  326. regscale/models/integration_models/trivy_import.py +231 -0
  327. regscale/models/integration_models/veracode.py +217 -0
  328. regscale/models/integration_models/xray.py +135 -0
  329. regscale/models/locking.py +100 -0
  330. regscale/models/platform.py +110 -0
  331. regscale/models/regscale_models/__init__.py +67 -0
  332. regscale/models/regscale_models/assessment.py +570 -0
  333. regscale/models/regscale_models/assessment_plan.py +52 -0
  334. regscale/models/regscale_models/asset.py +567 -0
  335. regscale/models/regscale_models/asset_mapping.py +190 -0
  336. regscale/models/regscale_models/case.py +42 -0
  337. regscale/models/regscale_models/catalog.py +261 -0
  338. regscale/models/regscale_models/cci.py +46 -0
  339. regscale/models/regscale_models/change.py +167 -0
  340. regscale/models/regscale_models/checklist.py +372 -0
  341. regscale/models/regscale_models/comment.py +49 -0
  342. regscale/models/regscale_models/compliance_settings.py +112 -0
  343. regscale/models/regscale_models/component.py +412 -0
  344. regscale/models/regscale_models/component_mapping.py +65 -0
  345. regscale/models/regscale_models/control.py +38 -0
  346. regscale/models/regscale_models/control_implementation.py +1128 -0
  347. regscale/models/regscale_models/control_objective.py +261 -0
  348. regscale/models/regscale_models/control_parameter.py +100 -0
  349. regscale/models/regscale_models/control_test.py +34 -0
  350. regscale/models/regscale_models/control_test_plan.py +75 -0
  351. regscale/models/regscale_models/control_test_result.py +52 -0
  352. regscale/models/regscale_models/custom_field.py +245 -0
  353. regscale/models/regscale_models/data.py +109 -0
  354. regscale/models/regscale_models/data_center.py +40 -0
  355. regscale/models/regscale_models/deviation.py +203 -0
  356. regscale/models/regscale_models/email.py +97 -0
  357. regscale/models/regscale_models/evidence.py +47 -0
  358. regscale/models/regscale_models/evidence_mapping.py +40 -0
  359. regscale/models/regscale_models/facility.py +59 -0
  360. regscale/models/regscale_models/file.py +382 -0
  361. regscale/models/regscale_models/filetag.py +37 -0
  362. regscale/models/regscale_models/form_field_value.py +94 -0
  363. regscale/models/regscale_models/group.py +169 -0
  364. regscale/models/regscale_models/implementation_objective.py +335 -0
  365. regscale/models/regscale_models/implementation_option.py +275 -0
  366. regscale/models/regscale_models/implementation_role.py +33 -0
  367. regscale/models/regscale_models/incident.py +177 -0
  368. regscale/models/regscale_models/interconnection.py +43 -0
  369. regscale/models/regscale_models/issue.py +1176 -0
  370. regscale/models/regscale_models/leveraged_authorization.py +125 -0
  371. regscale/models/regscale_models/line_of_inquiry.py +52 -0
  372. regscale/models/regscale_models/link.py +205 -0
  373. regscale/models/regscale_models/meta_data.py +64 -0
  374. regscale/models/regscale_models/mixins/__init__.py +0 -0
  375. regscale/models/regscale_models/mixins/parent_cache.py +124 -0
  376. regscale/models/regscale_models/module.py +224 -0
  377. regscale/models/regscale_models/modules.py +191 -0
  378. regscale/models/regscale_models/objective.py +14 -0
  379. regscale/models/regscale_models/parameter.py +87 -0
  380. regscale/models/regscale_models/ports_protocol.py +81 -0
  381. regscale/models/regscale_models/privacy.py +89 -0
  382. regscale/models/regscale_models/profile.py +50 -0
  383. regscale/models/regscale_models/profile_link.py +68 -0
  384. regscale/models/regscale_models/profile_mapping.py +124 -0
  385. regscale/models/regscale_models/project.py +63 -0
  386. regscale/models/regscale_models/property.py +278 -0
  387. regscale/models/regscale_models/question.py +85 -0
  388. regscale/models/regscale_models/questionnaire.py +87 -0
  389. regscale/models/regscale_models/questionnaire_instance.py +177 -0
  390. regscale/models/regscale_models/rbac.py +132 -0
  391. regscale/models/regscale_models/reference.py +86 -0
  392. regscale/models/regscale_models/regscale_model.py +1643 -0
  393. regscale/models/regscale_models/requirement.py +29 -0
  394. regscale/models/regscale_models/risk.py +274 -0
  395. regscale/models/regscale_models/sbom.py +54 -0
  396. regscale/models/regscale_models/scan_history.py +436 -0
  397. regscale/models/regscale_models/search.py +53 -0
  398. regscale/models/regscale_models/security_control.py +132 -0
  399. regscale/models/regscale_models/security_plan.py +204 -0
  400. regscale/models/regscale_models/software_inventory.py +159 -0
  401. regscale/models/regscale_models/stake_holder.py +64 -0
  402. regscale/models/regscale_models/stig.py +647 -0
  403. regscale/models/regscale_models/supply_chain.py +152 -0
  404. regscale/models/regscale_models/system_role.py +188 -0
  405. regscale/models/regscale_models/system_role_external_assignment.py +40 -0
  406. regscale/models/regscale_models/tag.py +37 -0
  407. regscale/models/regscale_models/tag_mapping.py +19 -0
  408. regscale/models/regscale_models/task.py +133 -0
  409. regscale/models/regscale_models/threat.py +196 -0
  410. regscale/models/regscale_models/user.py +175 -0
  411. regscale/models/regscale_models/user_group.py +55 -0
  412. regscale/models/regscale_models/vulnerability.py +242 -0
  413. regscale/models/regscale_models/vulnerability_mapping.py +162 -0
  414. regscale/models/regscale_models/workflow.py +55 -0
  415. regscale/models/regscale_models/workflow_action.py +34 -0
  416. regscale/models/regscale_models/workflow_instance.py +269 -0
  417. regscale/models/regscale_models/workflow_instance_step.py +114 -0
  418. regscale/models/regscale_models/workflow_template.py +58 -0
  419. regscale/models/regscale_models/workflow_template_step.py +45 -0
  420. regscale/regscale.py +815 -0
  421. regscale/utils/__init__.py +7 -0
  422. regscale/utils/b64conversion.py +14 -0
  423. regscale/utils/click_utils.py +118 -0
  424. regscale/utils/decorators.py +48 -0
  425. regscale/utils/dict_utils.py +59 -0
  426. regscale/utils/files.py +79 -0
  427. regscale/utils/fxns.py +30 -0
  428. regscale/utils/graphql_client.py +113 -0
  429. regscale/utils/lists.py +16 -0
  430. regscale/utils/numbers.py +12 -0
  431. regscale/utils/shell.py +148 -0
  432. regscale/utils/string.py +121 -0
  433. regscale/utils/synqly_utils.py +165 -0
  434. regscale/utils/threading/__init__.py +8 -0
  435. regscale/utils/threading/threadhandler.py +131 -0
  436. regscale/utils/threading/threadsafe_counter.py +47 -0
  437. regscale/utils/threading/threadsafe_dict.py +242 -0
  438. regscale/utils/threading/threadsafe_list.py +83 -0
  439. regscale/utils/version.py +104 -0
  440. regscale/validation/__init__.py +0 -0
  441. regscale/validation/address.py +37 -0
  442. regscale/validation/record.py +48 -0
  443. regscale/visualization/__init__.py +5 -0
  444. regscale/visualization/click.py +34 -0
  445. regscale_cli-6.16.0.0.dist-info/LICENSE +21 -0
  446. regscale_cli-6.16.0.0.dist-info/METADATA +659 -0
  447. regscale_cli-6.16.0.0.dist-info/RECORD +481 -0
  448. regscale_cli-6.16.0.0.dist-info/WHEEL +5 -0
  449. regscale_cli-6.16.0.0.dist-info/entry_points.txt +6 -0
  450. regscale_cli-6.16.0.0.dist-info/top_level.txt +2 -0
  451. tests/fixtures/__init__.py +2 -0
  452. tests/fixtures/api.py +87 -0
  453. tests/fixtures/models.py +91 -0
  454. tests/fixtures/test_fixture.py +144 -0
  455. tests/mocks/__init__.py +0 -0
  456. tests/mocks/objects.py +3 -0
  457. tests/mocks/response.py +32 -0
  458. tests/mocks/xml.py +13 -0
  459. tests/regscale/__init__.py +0 -0
  460. tests/regscale/core/__init__.py +0 -0
  461. tests/regscale/core/test_api.py +232 -0
  462. tests/regscale/core/test_app.py +406 -0
  463. tests/regscale/core/test_login.py +37 -0
  464. tests/regscale/core/test_logz.py +66 -0
  465. tests/regscale/core/test_sbom_generator.py +87 -0
  466. tests/regscale/core/test_validation_utils.py +163 -0
  467. tests/regscale/core/test_version.py +78 -0
  468. tests/regscale/models/__init__.py +0 -0
  469. tests/regscale/models/test_asset.py +71 -0
  470. tests/regscale/models/test_config.py +26 -0
  471. tests/regscale/models/test_control_implementation.py +27 -0
  472. tests/regscale/models/test_import.py +97 -0
  473. tests/regscale/models/test_issue.py +36 -0
  474. tests/regscale/models/test_mapping.py +52 -0
  475. tests/regscale/models/test_platform.py +31 -0
  476. tests/regscale/models/test_regscale_model.py +346 -0
  477. tests/regscale/models/test_report.py +32 -0
  478. tests/regscale/models/test_tenable_integrations.py +118 -0
  479. tests/regscale/models/test_user_model.py +121 -0
  480. tests/regscale/test_about.py +19 -0
  481. tests/regscale/test_authorization.py +65 -0
@@ -0,0 +1,467 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """Command to bulk import scans by folder path."""
4
+ import csv
5
+ import hashlib
6
+ import json
7
+ import logging
8
+ import os
9
+ import re
10
+ import shutil
11
+ import time
12
+ import xml.etree.ElementTree as ET
13
+ from datetime import datetime
14
+ from os import PathLike
15
+ from typing import Optional, Union
16
+
17
+ import click
18
+ import pandas as pd
19
+ from pathlib import Path
20
+
21
+ from regscale.core.app.utils.file_utils import download_from_s3, get_files_by_folder
22
+ from regscale.models.integration_models.flat_file_importer import FlatFileImporter
23
+
24
+ logger = logging.getLogger("regscale")
25
+
26
+ FINGERPRINT_FILE_PATH = "regscale/integrations/commercial/import_all/scan_file_fingerprints.json"
27
+ EXCLUDE_MAPPING = ["burp", "nessus"] # Scan types that do not support custom mappings
28
+
29
+
30
+ @click.group(name="import_all")
31
+ def import_all():
32
+ """
33
+ Import scans, vulnerabilities and assets to RegScale from scan export files
34
+ """
35
+
36
+
37
+ @import_all.command(name="run")
38
+ @FlatFileImporter.common_scanner_options(
39
+ message="Folder path containing scan files to process to RegScale.",
40
+ prompt="Folder path containing scan files",
41
+ import_name="all",
42
+ )
43
+ def import_all(
44
+ folder_path: PathLike[str],
45
+ regscale_ssp_id: int,
46
+ scan_date: datetime,
47
+ mappings_path: Path,
48
+ disable_mapping: bool,
49
+ s3_bucket: str,
50
+ s3_prefix: str,
51
+ aws_profile: str,
52
+ upload_file: bool,
53
+ ):
54
+ """
55
+ Import scans, vulnerabilities and assets to RegScale from scan export files
56
+ """
57
+ if s3_bucket:
58
+ # Download files from S3 to folder_path
59
+ download_from_s3(s3_bucket, s3_prefix, folder_path, aws_profile)
60
+
61
+ import_all_scans(
62
+ folder_path=folder_path,
63
+ regscale_ssp_id=regscale_ssp_id,
64
+ scan_date=scan_date,
65
+ upload_file=upload_file,
66
+ )
67
+
68
+
69
+ def import_all_scans(
70
+ folder_path: PathLike[str],
71
+ regscale_ssp_id: int,
72
+ scan_date: datetime,
73
+ mappings_path: Optional[Path] = None,
74
+ disable_mapping: bool = False,
75
+ upload_file: Optional[bool] = True,
76
+ ):
77
+ """
78
+ Imports all scan files from a specified folder and processes them according to their scan type.
79
+
80
+ :param PathLike[str] folder_path: The path to the folder containing scan files.
81
+ :param int regscale_ssp_id: The RegScale SSP ID to associate with the scans.
82
+ :param datetime scan_date: The date of the scans.
83
+ :param Path mappings_path: The path to a custom mappings file.
84
+ :param bool disable_mapping: Flag to disable custom mapping prompts.
85
+ :param Optional[bool] upload_file: Whether to upload the file to RegScale after processing, defaults to True
86
+ """
87
+ from regscale.integrations.commercial.aqua.aqua import import_aqua
88
+ from regscale.integrations.commercial.aws.cli import import_scans as import_aws
89
+ from regscale.integrations.commercial.burp import import_burp
90
+ from regscale.integrations.commercial.defender import import_alerts
91
+ from regscale.integrations.commercial.ecr import import_ecr
92
+ from regscale.integrations.commercial.grype import import_scans as import_grype_scans
93
+ from regscale.integrations.commercial.ibm import import_appscan
94
+ from regscale.integrations.commercial.nexpose import import_nexpose
95
+ from regscale.integrations.commercial.opentext.click import import_file as import_opentext_file
96
+ from regscale.integrations.commercial.prisma import import_prisma
97
+ from regscale.integrations.commercial.qualys import import_scans as import_qualys
98
+ from regscale.integrations.commercial.snyk import import_snyk
99
+ from regscale.integrations.commercial.tenablev2.click import import_nessus
100
+ from regscale.integrations.commercial.trivy import import_scans as import_trivy_scans
101
+ from regscale.integrations.commercial.veracode import import_veracode
102
+ from regscale.integrations.commercial.xray import import_xray
103
+
104
+ import_functions = {
105
+ "aqua": {"function": import_aqua, "custom_mapping": mappings_path},
106
+ "aws": {"function": import_aws, "custom_mapping": mappings_path},
107
+ "burp": {"function": import_burp, "custom_mapping": mappings_path},
108
+ "defender": {"function": import_alerts, "custom_mapping": mappings_path},
109
+ "ecr": {"function": import_ecr, "custom_mapping": mappings_path},
110
+ "grype": {"function": import_grype_scans, "custom_mapping": mappings_path},
111
+ "ibm": {"function": import_appscan, "custom_mapping": mappings_path},
112
+ "nessus": {"function": import_nessus, "custom_mapping": mappings_path},
113
+ "nexpose": {"function": import_nexpose, "custom_mapping": mappings_path},
114
+ "opentext": {"function": import_opentext_file, "custom_mapping": mappings_path},
115
+ "prisma": {"function": import_prisma, "custom_mapping": mappings_path},
116
+ "qualys": {"function": import_qualys, "custom_mapping": mappings_path},
117
+ "snyk": {"function": import_snyk, "custom_mapping": mappings_path},
118
+ "trivy": {"function": import_trivy_scans, "custom_mapping": mappings_path},
119
+ "veracode": {"function": import_veracode, "custom_mapping": mappings_path},
120
+ "xray": {"function": import_xray, "custom_mapping": mappings_path},
121
+ }
122
+
123
+ scans = set_scans(
124
+ get_files_by_folder(
125
+ str(folder_path),
126
+ exclude_non_scan_files=True,
127
+ file_excludes=[".DS_Store", "~", ".zip", "mapping.json", ".md", ".burp", ".html"],
128
+ directory_excludes=["processed"],
129
+ ),
130
+ load_fingerprints(FINGERPRINT_FILE_PATH),
131
+ )
132
+ move_files(scans, str(folder_path))
133
+
134
+ scan_folders = {}
135
+ for scan_type in set(scans.values()):
136
+ scan_folder = os.path.join(folder_path, scan_type)
137
+ scan_folders[scan_type] = scan_folder
138
+
139
+ logger.debug(json.dumps(scan_folders, indent=2))
140
+
141
+ imports_to_process = {}
142
+ for scan_type, import_function in import_functions.items():
143
+ if scan_type in scan_folders:
144
+ imports_to_process[scan_type] = import_function
145
+
146
+ # Ask for any custom mappings
147
+ if input("Do you have any custom mapping files? (y/n): ").strip().lower() == "y" and not disable_mapping:
148
+ imports_to_process = set_custom_mappings(imports_to_process)
149
+
150
+ # Show user summary of what will be imported and ask for confirmation before starting imports
151
+ scan_counts = {scan_type: list(scans.values()).count(scan_type) for scan_type in set(scans.values())}
152
+ total_files = sum(scan_counts.values())
153
+ for scan_type, count in scan_counts.items():
154
+ print(f"{scan_type}: {count} files")
155
+ if input(f"Do you want to proceed with processing {total_files} scan file(s)? (y/n): ").strip().lower() != "y":
156
+ print("Aborting scan processing.")
157
+ else:
158
+ import_scans(imports_to_process, scan_folders, regscale_ssp_id, scan_date, upload_file)
159
+
160
+
161
+ def import_scans(
162
+ imports_to_process: dict, scan_folders: dict, regscale_ssp_id: int, scan_date: datetime, upload_file: bool
163
+ ) -> None:
164
+ """
165
+ Imports scans by invoking specified processing functions for each scan type.
166
+ :param dict imports_to_process: A dictionary where keys are scan types and values are dictionaries
167
+ containing the processing function and custom mapping path.
168
+ Example: {
169
+ "scan_type_1": {
170
+ "function": click_function_1,
171
+ "custom_mapping": "path/to/custom_mapping_1"
172
+ },
173
+ "scan_type_2": {
174
+ "function": click_function_2,
175
+ "custom_mapping": None
176
+ }
177
+ }
178
+ :param dict scan_folders: A dictionary where keys are scan types and values are folder paths
179
+ containing the scans for each type.
180
+ Example: {
181
+ "scan_type_1": "path/to/scan_folder_1",
182
+ "scan_type_2": "path/to/scan_folder_2"
183
+ }
184
+ :param int regscale_ssp_id: The RegScale SSP (System Security Plan) ID to associate with the scans.
185
+ :param datetime scan_date: The date of the scans in 'YYYY-MM-DD' format.
186
+ :param bool upload_file: Whether to upload the file to RegScale after processing
187
+ :rtype: None
188
+ """
189
+
190
+ ctx = click.get_current_context()
191
+
192
+ for scan_type, import_detail in imports_to_process.items():
193
+ kwargs = {"folder_path": scan_folders[scan_type]}
194
+ click_function = import_detail["function"]
195
+ kwargs["scan_date"] = scan_date
196
+ kwargs["regscale_ssp_id"] = regscale_ssp_id
197
+ # make sure upload_file and mappings_path are passed if the function requires them
198
+ for param in click_function.params:
199
+ if param.name == "mappings_path":
200
+ kwargs[param.name] = import_detail.get("custom_mapping") or Path.cwd() / "mappings" / scan_type
201
+ elif param.name == "upload_file":
202
+ kwargs[param.name] = upload_file
203
+ ctx.invoke(
204
+ click_function,
205
+ **kwargs,
206
+ )
207
+ logger.info("Waiting before processing the next scan...")
208
+ time.sleep(5)
209
+
210
+
211
+ def set_custom_mappings(imports_to_process: dict) -> dict:
212
+ """
213
+ Prompts the user to provide custom mapping files for each scan type in the given imports.
214
+ :param dict imports_to_process: A dictionary where keys are scan types and values are dictionaries containing
215
+ the processing function and custom mapping path.
216
+ :return: The updated dictionary with custom mapping file paths added for each scan type, if provided by the user.
217
+ :rtype: dict
218
+ """
219
+
220
+ for scan_type, import_detail in imports_to_process.items():
221
+ if scan_type not in EXCLUDE_MAPPING:
222
+ if input(f"Do you have a custom mapping file for {scan_type}? (y/n): ").strip().lower() == "y":
223
+ import_detail["custom_mapping"] = input(f"Enter the mapping file path for {scan_type}: ").strip()
224
+ return imports_to_process
225
+
226
+
227
+ def set_scans(file_list: list, fingerprints: dict) -> dict:
228
+ """
229
+ Set scans for a list of files based on their fingerprints.
230
+ This function takes a list of file paths and a dictionary of fingerprints,
231
+ and returns a dictionary mapping each file path to its corresponding scan type.
232
+ If a file's fingerprint is not found in the provided fingerprints, it adds the
233
+ fingerprint and reloads the fingerprints from the fingerprint file path.
234
+
235
+ :param list file_list: A list of file paths to be scanned.
236
+ :param dict fingerprints: A dictionary where keys are file hashes and values are scan types.
237
+ :return: A dictionary mapping file paths to their corresponding scan types.
238
+ :rtype: dict
239
+ """
240
+
241
+ scans = {}
242
+ for file_path in file_list:
243
+ file_hash = get_fingerprint_hash(file_path)
244
+ scan_type = fingerprints.get(file_hash)
245
+ if scan_type is None or not scan_type:
246
+ add_fingerprint(file_hash, file_path)
247
+ fingerprints = load_fingerprints(FINGERPRINT_FILE_PATH)
248
+ scan_type = fingerprints.get(file_hash)
249
+ if scan_type:
250
+ scans[file_path] = scan_type
251
+ return scans
252
+
253
+
254
+ def move_files(scans: dict, folder_path: str):
255
+ """
256
+ Moves files to designated folders based on their scan type.
257
+
258
+ :param dict scans: A dictionary where keys are file paths and values are scan types.
259
+ :param str folder_path: The base folder path where files will be moved.
260
+ """
261
+
262
+ for file_path, scan_type in scans.items():
263
+ scan_folder = os.path.join(folder_path, scan_type)
264
+ if not os.path.exists(scan_folder):
265
+ os.makedirs(scan_folder)
266
+ destination_path = os.path.join(scan_folder, os.path.basename(file_path))
267
+ shutil.move(file_path, destination_path)
268
+
269
+
270
+ def fingerprint_csv(file_path: str) -> str:
271
+ """
272
+ Generates a SHA-256 fingerprint of the CSV file headers.
273
+ This function reads the headers of a CSV file, sorts them, and then
274
+ generates a SHA-256 hash of the concatenated header string.
275
+
276
+ :param str file_path: The path to the CSV file.
277
+ :return: The SHA-256 hash of the sorted CSV headers.
278
+ :rtype: str
279
+ """
280
+
281
+ with open(file_path, newline="") as csvfile:
282
+ reader = csv.reader(csvfile)
283
+ headers = next(reader)
284
+ headers_str = ",".join(sorted(headers))
285
+ return hashlib.sha256(headers_str.encode()).hexdigest()
286
+
287
+
288
+ def fingerprint_json(file_path: str) -> str:
289
+ """
290
+ Generates a SHA-256 fingerprint of the JSON file's keys.
291
+ This function reads a JSON file from the given file path, extracts the keys from the JSON data,
292
+ and generates a SHA-256 hash of the keys.
293
+
294
+ :param str file_path: The path to the JSON file.
295
+ :return: The SHA-256 hash of the JSON keys.
296
+ :rtype: str
297
+ """
298
+
299
+ with open(file_path) as f:
300
+ keys = []
301
+ data = json.load(f)
302
+ if isinstance(data, list) and data:
303
+ keys = list_keys(data[0])
304
+ elif isinstance(data, dict):
305
+ keys = list_keys(data)
306
+ keys_str = str(keys)
307
+ return hashlib.sha256(keys_str.encode()).hexdigest()
308
+
309
+
310
+ def list_keys(d: Union[dict, list], parent_key: Optional[str] = "") -> list:
311
+ """
312
+ Recursively lists all keys in a nested dictionary or list structure.
313
+
314
+ :param Union[dict, list] d: The dictionary or list to traverse.
315
+ :param Optional[str] parent_key: The base key to prepend to each key.
316
+ :return: A list of keys (or indices) found in the nested structure.
317
+ :rtype: list
318
+ """
319
+
320
+ keys = []
321
+ if isinstance(d, dict):
322
+ for k, v in d.items():
323
+ full_key = f"{parent_key}.{k}" if parent_key else k
324
+ if "findings[1]" in full_key:
325
+ break
326
+ keys.append(k)
327
+ keys.extend(list_keys(v, full_key))
328
+ elif isinstance(d, list):
329
+ for i, item in enumerate(d):
330
+ full_key = f"{parent_key}[{i}]"
331
+ if "findings[1]" in full_key:
332
+ break
333
+ keys.append(i)
334
+ keys.extend(list_keys(item, full_key))
335
+ return keys
336
+
337
+
338
+ def fingerprint_xml(file_path: str) -> str:
339
+ """
340
+ Generates a SHA-256 fingerprint for the root element of an XML file.
341
+
342
+ :param str file_path: The path to the XML file.
343
+ :return: The SHA-256 hash of the root element of the XML file.
344
+ :rtype: str
345
+ """
346
+ pattern = r" at 0x[0-9a-fA-F]+"
347
+ tree = ET.parse(file_path)
348
+ root_element = re.sub(pattern, "", str(tree.getroot()))
349
+ return hashlib.sha256(root_element.encode()).hexdigest()
350
+
351
+
352
+ def fingerprint_xlsx(file_path: str) -> str:
353
+ """
354
+ Generates a SHA-256 fingerprint for the headers of an Excel file.
355
+ This function reads an Excel file from the given file path, extracts the headers,
356
+ sorts them, concatenates them into a single string, and then computes the SHA-256
357
+ hash of that string.
358
+
359
+ :param str file_path: The path to the Excel file.
360
+ :return: The SHA-256 hash of the sorted headers.
361
+ :rtype: str
362
+ """
363
+
364
+ df = pd.read_excel(file_path)
365
+ headers = df.columns.tolist()
366
+ headers_str = ",".join(sorted(headers))
367
+ return hashlib.sha256(headers_str.encode()).hexdigest()
368
+
369
+
370
+ def get_fingerprint_hash(file_path: str) -> str:
371
+ """
372
+ Generate a fingerprint hash for a given file based on its extension.
373
+ Supported file extensions:
374
+ - .csv: Calls the fingerprint_csv function.
375
+ - .json: Calls the fingerprint_json function.
376
+ - .xml, .nessus: Calls the fingerprint_xml function.
377
+ - .xlsx: Calls the fingerprint_xlsx function.
378
+
379
+ :param str file_path: The path to the file for which the fingerprint hash is to be generated.
380
+ :return: The fingerprint hash of the file if the file extension is supported, otherwise None.
381
+ :rtype: str
382
+ """
383
+
384
+ file_hash = None
385
+ if file_path.endswith(".csv"):
386
+ file_hash = fingerprint_csv(file_path)
387
+ elif file_path.endswith(".json"):
388
+ file_hash = fingerprint_json(file_path)
389
+ elif file_path.endswith(".xml") or file_path.endswith(".nessus"):
390
+ file_hash = fingerprint_xml(file_path)
391
+ elif file_path.endswith(".xlsx"):
392
+ file_hash = fingerprint_xlsx(file_path)
393
+
394
+ return file_hash or ""
395
+
396
+
397
+ def add_fingerprint(file_hash: str, file_path: str) -> None:
398
+ """
399
+ Adds a fingerprint entry for a given file hash and file path.
400
+ This function prompts the user to select a scan type from a list of supported scans
401
+ and associates the selected scan type with the provided file hash. The updated
402
+ fingerprints are then saved to the fingerprint file.
403
+
404
+ :param str file_hash: The hash of the file to add a fingerprint for.
405
+ :param str file_path: The path of the file to add a fingerprint for.
406
+ :rtype: None
407
+ """
408
+
409
+ supported_scans = [
410
+ "SKIP FILE",
411
+ "aws",
412
+ "aqua",
413
+ "burp",
414
+ "defender",
415
+ "ecr",
416
+ "grype",
417
+ "ibm",
418
+ "nessus",
419
+ "nexpose",
420
+ "opentext",
421
+ "prisma",
422
+ "qualys",
423
+ "snyk",
424
+ "trivy",
425
+ "veracode",
426
+ "xray",
427
+ ]
428
+ fingerprints = load_fingerprints(FINGERPRINT_FILE_PATH)
429
+
430
+ for i, scan in enumerate(supported_scans, 1):
431
+ print(f"{i}. {scan}")
432
+ choice = int(input(f"Enter the scan type number for file {file_path}: "))
433
+ if 2 <= choice <= len(supported_scans):
434
+ scan_type = supported_scans[choice - 1]
435
+ elif choice == 1:
436
+ print("Skipping file.")
437
+ return
438
+ else:
439
+ print("Invalid choice. Skipping file.")
440
+ return
441
+ fingerprints[file_hash] = scan_type
442
+ with open(FINGERPRINT_FILE_PATH, "w") as f:
443
+ json.dump(fingerprints, f, indent=2)
444
+
445
+
446
+ def load_fingerprints(fingerprint_file_path: str) -> dict:
447
+ """
448
+ Load fingerprints from a JSON file.
449
+ This function reads a JSON file containing fingerprints and returns them as a dictionary.
450
+ If the file does not exist, it will load the default fingerprints file from the RegScale CLI Package.
451
+
452
+ :param str fingerprint_file_path: The path to the JSON file containing fingerprints.
453
+ :return: A dictionary containing the fingerprints if the file exists, otherwise an empty dictionary.
454
+ :rtype: dict
455
+ """
456
+ if os.path.exists(fingerprint_file_path):
457
+ with open(fingerprint_file_path, "r") as f:
458
+ fingerprints = json.load(f)
459
+ return fingerprints
460
+ else:
461
+ import importlib.resources as pkg_resources
462
+
463
+ with pkg_resources.open_text(
464
+ "regscale.integrations.commercial.import_all", "scan_file_fingerprints.json"
465
+ ) as file:
466
+ fingerprints = json.load(file)
467
+ return fingerprints
@@ -0,0 +1,27 @@
1
+ {
2
+ "3a425a4276c76a35e95864c08ff6d15689f6e05a4ae4fc45327d60411ea73cc7": "qualys",
3
+ "98abfaf1088f22e495bd6579445c465767f8d15af0c3e515db522c78428ea563": "prisma",
4
+ "604039b457dc467501f67e501652fb7cf401d42241bf516baf0635bf53bb21dd": "prisma",
5
+ "560883c9663477e21f0a9daf4335dc3506c60805ffb748270e8c36529b09a477": "prisma",
6
+ "993cefe39c7872b1b9475540a931e82d0acae26489194f29ec1075d18e63838a": "ecr",
7
+ "d4079c72eeaf2e41f47810e6f4580b5490f9a714f5cf7e0dbd43bb2da7289f0e": "ecr",
8
+ "4859fdd53830975f775c6218d516e53ab9929815408cefead39daa9e21ce01b5": "ecr",
9
+ "250ec705f509ba7c7062db771bd099005bbede1cb91a9f2726f829663ed04a7c": "snyk",
10
+ "264b5b1701c690e193c9ebbf7238f2f7e4724f519c53fd212f2b1c54d59cc1d0": "veracode",
11
+ "2f0149daff3d4bb7d869ee24336306c467399f66009149c2328b5e184dc86de1": "aqua",
12
+ "5a81c499e15786dbf364b1a80efe87204fadb30160ffdf16c99aa1115530e91c": "aqua",
13
+ "16e93222a3e5acf1c7f155bb4b1d2ca335abb6e92c2a8db3ba55212f05d32380": "nexpose",
14
+ "b963e090de916d23e8aa6010f792050b809194c141c3b4810cd8f118ce4c227e": "aws",
15
+ "4b9545c76a28c068f50e12c979c381a4bcd88a7ba1efb97be59406982e5597e9": "nessus",
16
+ "ee42d9946a756fa4d091f5fe988a0f3bfeb9ba0732dd631381e09f98d2be1ef6": "defender",
17
+ "8eb0b87f22e9a923315a450f123804553b3797ea2611b668d5fd996e827d5df2": "xray",
18
+ "72119792341edf640feb713a9bf8c2110268aae56cc5cb55a189941fdee66547": "prisma",
19
+ "3e9bd42202c49eee018dfdd250e88617329b0fdf2c919b4d4010e820d61571fc": "veracode",
20
+ "5d48ffb396e2e8a8a5a9811352a8c551c9f4315d631f248d078cf4e71a75f948": "ibm",
21
+ "51a83bea058347e4e13d26b7d61686bbef19c116f583bf3218eb60e40c813250": "prisma",
22
+ "b6c2b4a942f4c66c4f88f9934e7e39c7682504133055611fde6eb4f5e56ead68": "aws",
23
+ "a8b6803104eb886d7a9c8fec1e98ee185d1630222dd4f4fb93711010ad02a51a": "burp",
24
+ "b34ae012e05bb979e134bf88df53ff7e08955fc3d004612a4b0927f99b4652e6": "opentext",
25
+ "24574a348b59fac3dd7e1838f670cde43d6cf78f2d5f32d15ca2fec55e19bac7": "trivy",
26
+ "1361a3045ebf0c83eda2f96e25799139dbe7ed2ad7017daadee11eaefd75beac": "grype"
27
+ }