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,39 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """Wiz Variables"""
4
+
5
+ from regscale.core.app.utils.variables import RsVariableType, RsVariablesMeta
6
+
7
+
8
+ class WizVariables(metaclass=RsVariablesMeta):
9
+ """
10
+ Wiz Variables class to define class-level attributes with type annotations and examples
11
+ """
12
+
13
+ # Define class-level attributes with type annotations and examples
14
+ wizFullPullLimitHours: RsVariableType(int, 8) # type: ignore
15
+ wizUrl: RsVariableType(str, "https://api.us27.app.wiz.io/graphql", required=False) # type: ignore
16
+ wizIssueFilterBy: RsVariableType(
17
+ str,
18
+ '{"projectId": ["xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"], "type": ["API_GATEWAY"]}',
19
+ default={},
20
+ required=False,
21
+ ) # type: ignore
22
+ wizInventoryFilterBy: RsVariableType(
23
+ str,
24
+ '{"projectId": ["xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"], "type": ["API_GATEWAY"]}',
25
+ default="""{"type":
26
+ [ "API_GATEWAY", "BACKUP_SERVICE", "CDN", "CICD_SERVICE", "CLOUD_LOG_CONFIGURATION",
27
+ "CLOUD_ORGANIZATION", "CONTAINER", "CONTAINER_IMAGE", "CONTAINER_REGISTRY", "CONTAINER_SERVICE",
28
+ "CONTROLLER_REVISION", "DATABASE", "DATA_WORKLOAD", "DB_SERVER", "DOMAIN", "EMAIL_SERVICE", "ENCRYPTION_KEY",
29
+ "FILE_SYSTEM_SERVICE", "FIREWALL", "GATEWAY", "KUBERNETES_CLUSTER", "LOAD_BALANCER",
30
+ "MANAGED_CERTIFICATE", "MESSAGING_SERVICE", "NAMESPACE", "NETWORK_INTERFACE", "PRIVATE_ENDPOINT",
31
+ "PRIVATE_LINK", "RAW_ACCESS_POLICY", "REGISTERED_DOMAIN", "RESOURCE_GROUP", "SECRET",
32
+ "SECRET_CONTAINER", "SERVERLESS", "SERVERLESS_PACKAGE", "SERVICE_ACCOUNT", "SERVICE_CONFIGURATION",
33
+ "STORAGE_ACCOUNT", "SUBNET", "SUBSCRIPTION", "VIRTUAL_DESKTOP", "VIRTUAL_MACHINE",
34
+ "VIRTUAL_MACHINE_IMAGE", "VIRTUAL_NETWORK", "VOLUME", "WEB_SERVICE" ] }""",
35
+ ) # type: ignore
36
+ wizAccessToken: RsVariableType(str, "", sensitive=True, required=False) # type: ignore
37
+ wizClientId: RsVariableType(str, "", sensitive=True) # type: ignore
38
+ wizClientSecret: RsVariableType(str, "", sensitive=True) # type: ignore
39
+ wizLastInventoryPull: RsVariableType(str, "2022-01-01T00:00:00Z", required=False) # type: ignore
@@ -0,0 +1,159 @@
1
+ """Wiz Authentication Module"""
2
+
3
+ from typing import Optional
4
+
5
+ import requests
6
+
7
+ from regscale.core.app.api import Api
8
+ from regscale.core.app.logz import create_logger
9
+ from regscale.core.app.utils.app_utils import (
10
+ error_and_exit,
11
+ check_license,
12
+ )
13
+ from regscale.integrations.commercial.wizv2.variables import WizVariables
14
+
15
+ logger = create_logger()
16
+ AUTH0_URLS = [
17
+ "https://auth.wiz.io/oauth/token",
18
+ "https://auth0.gov.wiz.io/oauth/token",
19
+ "https://auth0.test.wiz.io/oauth/token",
20
+ "https://auth0.demo.wiz.io/oauth/token",
21
+ "https://auth.gov.wiz.io/oauth/token",
22
+ ]
23
+ COGNITO_URLS = [
24
+ "https://auth.app.wiz.io/oauth/token",
25
+ "https://auth.test.wiz.io/oauth/token",
26
+ "https://auth.demo.wiz.io/oauth/token",
27
+ "https://auth.app.wiz.us/oauth/token",
28
+ ]
29
+
30
+
31
+ def wiz_authenticate(client_id: Optional[str] = None, client_secret: Optional[str] = None) -> Optional[str]:
32
+ """
33
+ Authenticate to Wiz
34
+
35
+ :param Optional[str] client_id: Wiz client ID, defaults to None
36
+ :param Optional[str] client_secret: Wiz client secret, defaults to None
37
+ :raises ValueError: No Wiz Client ID provided in system environment or CLI command
38
+ :return: token
39
+ :rtype: Optional[str]
40
+ """
41
+ app = check_license()
42
+ api = Api()
43
+ # Login with service account to retrieve a 24hr access token that updates YAML file
44
+ logger.info("Authenticating - Loading configuration from init.yaml file")
45
+
46
+ # load the config from YAML
47
+ config = app.config
48
+
49
+ # get secrets
50
+ client_id = WizVariables.wizClientId if client_id is None else client_id
51
+ if not client_id:
52
+ raise ValueError("No Wiz Client ID provided in system environment or CLI command.")
53
+ client_secret = WizVariables.wizClientSecret if client_secret is None else client_secret
54
+ if not client_secret:
55
+ raise ValueError("No Wiz Client Secret provided in system environment or CLI command.")
56
+ wiz_auth_url = config.get("wizAuthUrl")
57
+ if not wiz_auth_url:
58
+ error_and_exit("No Wiz Authentication URL provided in the init.yaml file.")
59
+
60
+ # login and get token
61
+ logger.info("Attempting to retrieve OAuth token from Wiz.io.")
62
+ token, scope = get_token(
63
+ api=api,
64
+ client_id=client_id,
65
+ client_secret=client_secret,
66
+ token_url=wiz_auth_url,
67
+ )
68
+
69
+ # assign values
70
+
71
+ config["wizAccessToken"] = token
72
+ config["wizScope"] = scope
73
+
74
+ # write our the result to YAML
75
+ # write the changes back to file
76
+ app.save_config(config)
77
+ return token
78
+
79
+
80
+ def get_token(api: Api, client_id: str, client_secret: str, token_url: str) -> tuple[str, str]:
81
+ """
82
+ Return Wiz.io token
83
+
84
+ :param Api api: api instance
85
+ :param str client_id: Wiz client ID
86
+ :param str client_secret: Wiz client secret
87
+ :param str token_url: token url
88
+ :return: tuple of token and scope
89
+ :rtype: tuple[str, str]
90
+ """
91
+ app = api.app
92
+ config = api.config
93
+ status_code = 500
94
+ logger.info("Getting a token")
95
+ response = api.post(
96
+ url=token_url,
97
+ headers={"Content-Type": "application/x-www-form-urlencoded"},
98
+ json=None,
99
+ data=generate_authentication_params(client_id, client_secret, token_url),
100
+ )
101
+ if response.ok:
102
+ status_code = 200
103
+ logger.debug(response.reason)
104
+ # If response is unauthorized, try the first cognito url
105
+ if response.status_code == requests.codes.unauthorized:
106
+ try:
107
+ response = api.post(
108
+ url=COGNITO_URLS[0],
109
+ headers={"Content-Type": "application/x-www-form-urlencoded"},
110
+ json=None,
111
+ data=generate_authentication_params(client_id, client_secret, COGNITO_URLS[0]),
112
+ )
113
+ if response.ok:
114
+ status_code = 200
115
+ logger.info(
116
+ "Successfully authenticated using the authorization url: %s, now updating init.yaml..",
117
+ COGNITO_URLS[0],
118
+ )
119
+ config["wizAuthUrl"] = COGNITO_URLS[0]
120
+ app.save_config(config)
121
+ except requests.RequestException:
122
+ error_and_exit(f"Wiz Authentication: {response.reason}")
123
+ if status_code != requests.codes.ok:
124
+ error_and_exit(f"Error authenticating to Wiz [{response.status_code}] - {response.text}")
125
+ response_json = response.json()
126
+ token = response_json.get("access_token")
127
+ scope = response_json.get("scope")
128
+ if not token:
129
+ error_and_exit(f'Could not retrieve token from Wiz: {response_json.get("message")}')
130
+ logger.info("SUCCESS: Wiz.io access token successfully retrieved.")
131
+ return token, scope
132
+
133
+
134
+ def generate_authentication_params(client_id: str, client_secret: str, token_url: str) -> dict:
135
+ """
136
+ Create the Correct Parameter format based on URL
137
+
138
+ :param str client_id: Wiz Client ID
139
+ :param str client_secret: Wiz Client Secret
140
+ :param str token_url: Wiz URL
141
+ :raises Exception: A generic exception if token_url provided is invalid
142
+ :return: Dictionary containing authentication parameters
143
+ :rtype: dict
144
+ """
145
+ if token_url in AUTH0_URLS:
146
+ return {
147
+ "grant_type": "client_credentials",
148
+ "audience": "beyond-api",
149
+ "client_id": client_id,
150
+ "client_secret": client_secret,
151
+ }
152
+ if token_url in COGNITO_URLS:
153
+ return {
154
+ "grant_type": "client_credentials",
155
+ "audience": "wiz-api",
156
+ "client_id": client_id,
157
+ "client_secret": client_secret,
158
+ }
159
+ raise ValueError("Invalid Token URL")
@@ -0,0 +1,91 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """xray RegScale integration"""
4
+ from datetime import datetime
5
+ from os import PathLike
6
+ from typing import Optional
7
+
8
+ import click
9
+ from pathlib import Path
10
+
11
+ from regscale.models.integration_models.flat_file_importer import FlatFileImporter
12
+ from regscale.models.integration_models.xray import XRay
13
+
14
+
15
+ @click.group()
16
+ def xray():
17
+ """Performs actions on xray files."""
18
+
19
+
20
+ @xray.command(name="import_xray")
21
+ @FlatFileImporter.common_scanner_options(
22
+ message="File path to the folder containing JFrog XRay .json files to process to RegScale.",
23
+ prompt="File path for JFrog XRay files",
24
+ import_name="xray",
25
+ )
26
+ def import_xray(
27
+ folder_path: PathLike[str],
28
+ regscale_ssp_id: int,
29
+ scan_date: datetime,
30
+ mappings_path: Path,
31
+ disable_mapping: bool,
32
+ s3_bucket: str,
33
+ s3_prefix: str,
34
+ aws_profile: str,
35
+ upload_file: bool,
36
+ ) -> None:
37
+ """
38
+ Import JFrog XRay scans, vulnerabilities and assets to RegScale from XRay .json files
39
+ """
40
+ import_xray_files(
41
+ folder_path=folder_path,
42
+ regscale_ssp_id=regscale_ssp_id,
43
+ scan_date=scan_date,
44
+ mappings_path=mappings_path,
45
+ disable_mapping=disable_mapping,
46
+ s3_bucket=s3_bucket,
47
+ s3_prefix=s3_prefix,
48
+ aws_profile=aws_profile,
49
+ upload_file=upload_file,
50
+ )
51
+
52
+
53
+ def import_xray_files(
54
+ folder_path: PathLike[str],
55
+ regscale_ssp_id: int,
56
+ scan_date: datetime,
57
+ mappings_path: Path,
58
+ disable_mapping: bool,
59
+ s3_bucket: str,
60
+ s3_prefix: str,
61
+ aws_profile: str,
62
+ upload_file: Optional[bool] = True,
63
+ ) -> None:
64
+ """
65
+ Function to import XRay files to RegScale as assets and vulnerabilities
66
+
67
+ :param PathLike[str] folder_path: Path to the folder containing XRay files
68
+ :param int regscale_ssp_id: RegScale SSP ID
69
+ :param datetime scan_date: Scan date
70
+ :param Path mappings_path: Path to the header mapping file
71
+ :param bool disable_mapping: Disable mapping
72
+ :param str s3_bucket: S3 bucket to download the files from
73
+ :param str s3_prefix: S3 prefix to download the files from
74
+ :param str aws_profile: AWS profile to use for S3 access
75
+ :param Optional[bool] upload_file: Whether to upload the file to RegScale after processing, default: True
76
+ :rtype: None
77
+ """
78
+ FlatFileImporter.import_files(
79
+ import_type=XRay,
80
+ import_name="XRay",
81
+ file_types=".json",
82
+ folder_path=folder_path,
83
+ regscale_ssp_id=regscale_ssp_id,
84
+ scan_date=scan_date,
85
+ mappings_path=mappings_path,
86
+ disable_mapping=disable_mapping,
87
+ s3_bucket=s3_bucket,
88
+ s3_prefix=s3_prefix,
89
+ aws_profile=aws_profile,
90
+ upload_file=upload_file,
91
+ )
@@ -0,0 +1,2 @@
1
+ from .integration import Integration
2
+ from .inventory import Inventory
@@ -0,0 +1,26 @@
1
+ from abc import abstractmethod
2
+ from regscale.core.app.application import Application
3
+
4
+
5
+ class Integration(Application):
6
+ """
7
+ Base class for all integrations
8
+ """
9
+
10
+ def __init__(self, **kwargs):
11
+ super().__init__()
12
+ for key, value in kwargs.items():
13
+ setattr(self, key, value)
14
+
15
+ def __repr__(self):
16
+ return f"{self.__class__.__name__}"
17
+
18
+ def __str__(self):
19
+ return f"{self.__class__.__name__}"
20
+
21
+ @abstractmethod
22
+ def authenticate(self, **kwargs):
23
+ """
24
+ Authenticate to the integration
25
+ """
26
+ pass
@@ -0,0 +1,17 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+
4
+ class Inventory(ABC):
5
+ def __init__(
6
+ self,
7
+ **kwargs,
8
+ ):
9
+ for key, value in kwargs.items():
10
+ setattr(self, key, value)
11
+
12
+ @abstractmethod
13
+ def pull(self):
14
+ """
15
+ Pull inventory from an Integration platform into RegScale
16
+ """
17
+ pass
@@ -0,0 +1,100 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ Integration issue module
5
+ """
6
+ from abc import ABC, abstractmethod
7
+ from datetime import time
8
+ from time import sleep
9
+ from typing import Callable, Dict, List, Set
10
+
11
+ from regscale.core.app.application import Application
12
+ from regscale.core.app.utils.app_utils import get_current_datetime
13
+ from regscale.models import Issue, Vulnerability
14
+
15
+
16
+ class IntegrationIssue(ABC):
17
+ """
18
+ Integration issue class
19
+ """
20
+
21
+ # TOMOO This needs to be refactored to use ScannerIntegration.
22
+ # ScannerIntegration will have to be refactored to handle missing field mappings
23
+
24
+ def __init__(
25
+ self,
26
+ **kwargs,
27
+ ):
28
+ for key, value in kwargs.items():
29
+ setattr(self, key, value)
30
+
31
+ @abstractmethod
32
+ def pull(self):
33
+ """
34
+ Pull inventory from an Integration platform into RegScale
35
+ """
36
+
37
+ def create_issues(
38
+ self,
39
+ issues: list[Issue],
40
+ ):
41
+ """
42
+ Create issues in RegScale
43
+
44
+ :param list[Issue] issues: list of issues to create
45
+ """
46
+ Issue.batch_create(items=issues)
47
+
48
+ @staticmethod
49
+ def create_or_update_issues(
50
+ issues: list[Issue],
51
+ parent_id: int,
52
+ parent_module: str,
53
+ ):
54
+ """
55
+ Create issues in RegScale
56
+
57
+ :param list[Issue] issues: list of issues to create or update
58
+ :param int parent_id: parent id
59
+ :param str parent_module: parent module
60
+ """
61
+ existing_issues: List[Issue] = Issue.get_all_by_parent(parent_id=parent_id, parent_module=parent_module)
62
+ # otherIdentifier is the real key with coalfire/fedramp
63
+ insert_issues = [
64
+ item for item in issues if item.otherIdentifier not in {iss.otherIdentifier for iss in existing_issues}
65
+ ]
66
+ update_issues: List[Issue] = []
67
+ for issue in issues:
68
+ if issue.otherIdentifier in {iss.otherIdentifier for iss in existing_issues}:
69
+ # get index of the issue
70
+ issue.id = [iss for iss in existing_issues if iss.otherIdentifier == issue.otherIdentifier].pop().id
71
+ # update the update_issues list
72
+ update_issues.append(issue)
73
+ if insert_issues:
74
+ Issue.batch_create(items=insert_issues)
75
+ if update_issues:
76
+ Issue.batch_update(items=list(update_issues))
77
+
78
+ @staticmethod
79
+ def close_issues(issue_vuln_map: Dict[int, Dict[int, List[Vulnerability]]]) -> None:
80
+ """
81
+ Close issues in RegScale based on the newest vulnerabilities
82
+
83
+ :param Dict[int, Dict[int, List[Vulnerability]]] issue_vuln_map: map of issues to
84
+ vulnerabilities by way of assets!
85
+ """
86
+
87
+ update_issues: List[Issue] = []
88
+ for key in issue_vuln_map.keys():
89
+ # close existing_issues in RegScale if they are no longer relevant
90
+ for asset_key in issue_vuln_map[key].keys():
91
+ vulns = issue_vuln_map[key][asset_key]
92
+ if not [vuln for vuln in vulns if str(vuln.severity or "").lower() in ["moderate", "high", "critical"]]:
93
+ # Close issue
94
+ update_issue = Issue.get_object(object_id=key)
95
+ if update_issue:
96
+ update_issue.status = "Closed"
97
+ update_issue.dateCompleted = get_current_datetime()
98
+ update_issues.append(update_issue)
99
+ if update_issues:
100
+ Issue.batch_update(items=update_issues)
@@ -0,0 +1,149 @@
1
+ """
2
+ A simple singleton class that loads custom integration mappings, if available
3
+ """
4
+
5
+ from regscale.core.app.application import Application
6
+
7
+ # pylint: disable=C0415
8
+
9
+
10
+ class IntegrationOverride:
11
+ """
12
+ Custom Mapping class for findings
13
+ """
14
+
15
+ from threading import Lock
16
+ from typing import Any, Optional
17
+
18
+ _instance = None
19
+ _lock = Lock() # Ensures thread safety for singleton instance creation
20
+
21
+ def __new__(cls, *args, **kwargs):
22
+ if not cls._instance:
23
+ with cls._lock:
24
+ if not cls._instance: # Double-checked locking
25
+ cls._instance = super(IntegrationOverride, cls).__new__(cls)
26
+ return cls._instance
27
+
28
+ def __init__(self, app):
29
+ from rich.console import Console
30
+
31
+ config = app.config
32
+ self.app = app
33
+ self.mapping = self._get_mapping(config)
34
+ if not hasattr(self, "_initialized"):
35
+ self.console = Console()
36
+ self._log_mappings()
37
+ self._initialized = True
38
+
39
+ def _log_mappings(self):
40
+ """
41
+ Notify the user that overrides are found
42
+ """
43
+ from rich.table import Table
44
+
45
+ table = Table(title="Custom Integration Mappings", show_header=True, header_style="bold magenta")
46
+ table.add_column("Integration", width=12, style="cyan")
47
+ table.add_column("Field", width=12, style="orange3") # Ensure this color is supported
48
+ table.add_column("Mapped Value", width=20, style="red")
49
+
50
+ for integration, fields in self.mapping.items():
51
+ for field, value in fields.items():
52
+ if value != "default":
53
+ table.add_row(integration, field, value)
54
+
55
+ if table.row_count > 0:
56
+ self.console.print(table)
57
+
58
+ def _get_mapping(self, config: dict) -> dict:
59
+ """
60
+ Loads the mapping configuration from the application config.
61
+
62
+ :param dict config: The application configuration
63
+ :return: The mapping configuration
64
+ :rtype: dict
65
+ """
66
+ return config.get("findingFromMapping", {})
67
+
68
+ def load(self, integration: Optional[str], field_name: Optional[str]) -> Optional[str]:
69
+ """
70
+ Retrieves the mapped field name for a given integration and field name.
71
+
72
+ :param Optional[str] integration: The integration name
73
+ :param Optional[str] field_name: The field name
74
+ :return: The mapped field name
75
+ :rtype: Optional[str]
76
+ """
77
+ if integration and self.mapping_exists(integration, field_name):
78
+ integration_map = self.mapping.get(integration.lower(), {})
79
+ return integration_map.get(field_name.lower())
80
+ return None
81
+
82
+ def mapping_exists(self, integration: str, field_name: str) -> bool:
83
+ """
84
+ Checks if a mapping exists for a given integration and field name.
85
+
86
+ :param str integration: The integration name
87
+ :param str field_name: The field name
88
+ :return: Whether the mapping exists
89
+ :rtype: bool
90
+ """
91
+ the_map = self.mapping.get(integration.lower())
92
+ return the_map and field_name.lower() in the_map and the_map.get(field_name.lower()) != "default"
93
+
94
+ def field_map_validation(self, obj: Any, model_type: str) -> Optional[str]:
95
+ """
96
+ Validate a field mapping between a RegScale object/dictionary and dataset.
97
+
98
+ :param Any obj: The object to validate
99
+ :param str model_type: The model type, ie. asset, issue, etc.
100
+ :return: The validated field
101
+ :rtype: Optional[str]
102
+ """
103
+ match = None
104
+ try:
105
+ unique_override = self.app.config.get("uniqueOverride", {}).get(model_type, [])
106
+ if not unique_override:
107
+ return match
108
+
109
+ regscale_field = unique_override[0]
110
+ if not regscale_field:
111
+ return match
112
+
113
+ regscale_to_obj_mapping = {
114
+ # Tenable SC -> RegScale object -> RegScale field
115
+ "tenableasset": {
116
+ "asset": {
117
+ "ipAddress": "ip",
118
+ "name": "dnsName",
119
+ "dns": "dnsName",
120
+ "fqdn": "dnsName",
121
+ }
122
+ },
123
+ # dict key -> RegScale object -> RegScale field. This could grow to be quite large.
124
+ "dict": {
125
+ "asset": {
126
+ "ipAddress": "ipv4",
127
+ "name": "fqdn",
128
+ "dns": "fqdn",
129
+ "fqdn": "fqdn",
130
+ }
131
+ },
132
+ }
133
+ # The type an associated fields we are able to override. Limited for now.
134
+ supported_fields = {"asset": {"ipAddress", "name", "fqdn", "dns"}}
135
+ if regscale_field not in supported_fields.get(model_type.lower(), set()):
136
+ return match
137
+
138
+ model = obj.__class__.__name__.lower()
139
+ mapped_field = regscale_to_obj_mapping.get(model, {}).get(model_type, {}).get(regscale_field)
140
+ if not mapped_field:
141
+ return match
142
+
143
+ if isinstance(obj, dict):
144
+ match = obj.get(mapped_field)
145
+ elif hasattr(obj, mapped_field):
146
+ match = getattr(obj, mapped_field)
147
+ except (KeyError, AttributeError, IndexError, TypeError) as e:
148
+ self.app.logger.warning("Error parsing uniqueOverride: %s", str(e))
149
+ return match
@@ -0,0 +1,103 @@
1
+ """
2
+ Public commands for the RegScale CLI
3
+ """
4
+
5
+ import click
6
+ from regscale.core.lazy_group import LazyGroup
7
+
8
+
9
+ @click.group(
10
+ cls=LazyGroup,
11
+ lazy_subcommands={
12
+ "import_docx": "regscale.integrations.public.fedramp.click.load_fedramp_docx",
13
+ "import_oscal": "regscale.integrations.public.fedramp.click.load_fedramp_oscal",
14
+ "import_ssp_xml": "regscale.integrations.public.fedramp.click.import_fedramp_ssp_xml",
15
+ "import_appendix_a": "regscale.integrations.public.fedramp.click.load_fedramp_appendix_a",
16
+ "import_inventory": "regscale.integrations.public.fedramp.click.import_fedramp_inventory",
17
+ "import_poam": "regscale.integrations.public.fedramp.click.import_fedramp_poam_template",
18
+ "import_drf": "regscale.integrations.public.fedramp.click.import_drf",
19
+ "import_cis_crm": "regscale.integrations.public.fedramp.click.import_ciscrm",
20
+ },
21
+ name="fedramp",
22
+ )
23
+ def fedramp():
24
+ """Performs bulk processing of FedRAMP files (Upload trusted data only)."""
25
+ pass
26
+
27
+
28
+ @click.group(
29
+ cls=LazyGroup,
30
+ lazy_subcommands={
31
+ "ingest_pulses": "regscale.integrations.public.otx.ingest_pulses",
32
+ },
33
+ name="alienvault",
34
+ )
35
+ def alienvault():
36
+ """AlienVault OTX Integration to load pulses to RegScale."""
37
+ pass
38
+
39
+
40
+ @click.group(
41
+ cls=LazyGroup,
42
+ lazy_subcommands={
43
+ "ingest_cisa_kev": "regscale.integrations.public.cisa.ingest_cisa_kev",
44
+ "ingest_cisa_alerts": "regscale.integrations.public.cisa.ingest_cisa_alerts",
45
+ },
46
+ name="cisa",
47
+ )
48
+ def cisa():
49
+ """Performs administrative actions on the RegScale platform."""
50
+ pass
51
+
52
+
53
+ @click.group(
54
+ cls=LazyGroup,
55
+ lazy_subcommands={
56
+ "import": "regscale.integrations.public.criticality_updater.update_control_criticality",
57
+ },
58
+ name="criticality_updater",
59
+ )
60
+ def criticality_updater():
61
+ """
62
+ Update the criticality of security controls in the catalog.
63
+ """
64
+
65
+
66
+ @click.group(
67
+ cls=LazyGroup,
68
+ lazy_subcommands={
69
+ "populate_controls": "regscale.integrations.public.emass.populate_workbook",
70
+ "import_slcm": "regscale.integrations.public.emass.import_slcm",
71
+ },
72
+ name="emass",
73
+ )
74
+ def emass():
75
+ """Performs bulk processing of eMASS files (Upload trusted data only)."""
76
+ pass
77
+
78
+
79
+ @click.group(
80
+ cls=LazyGroup,
81
+ lazy_subcommands={
82
+ "sort_control_ids": "regscale.integrations.public.nist_catalog.sort_control_ids",
83
+ },
84
+ name="nist",
85
+ )
86
+ def nist():
87
+ """Sort the controls of a catalog in RegScale."""
88
+ pass
89
+
90
+
91
+ @click.group(
92
+ cls=LazyGroup,
93
+ lazy_subcommands={
94
+ "version": "regscale.integrations.public.oscal.version",
95
+ "component": "regscale.integrations.public.oscal.upload_component",
96
+ "profile": "regscale.integrations.public.oscal.profile",
97
+ "catalog": "regscale.integrations.public.oscal.catalog",
98
+ },
99
+ name="oscal",
100
+ )
101
+ def oscal():
102
+ """Performs bulk processing of OSCAL files."""
103
+ pass