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,433 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """Integrate Azure Active Directory in RegScale"""
4
+
5
+
6
+ # standard python imports
7
+ from json import JSONDecodeError
8
+ from pathlib import Path
9
+
10
+ import click
11
+
12
+ from regscale import __version__
13
+ from regscale.core.app.logz import create_logger
14
+ from regscale.core.app.utils.app_utils import (
15
+ check_file_path,
16
+ check_license,
17
+ error_and_exit,
18
+ save_data_to,
19
+ )
20
+ from regscale.models.regscale_models.user import User
21
+
22
+ logger = create_logger()
23
+ new_users = []
24
+ remove_users = []
25
+
26
+ ######################################################################################################
27
+ #
28
+ # Microsoft MSAL Documentation:
29
+ # https://learn.microsoft.com/en-us/python/api/overview/azure/active-directory?view=azure-python
30
+ # Microsoft AD Github Repo:
31
+ # https://github.com/AzureAD/microsoft-authentication-library-for-python
32
+ #
33
+ ######################################################################################################
34
+
35
+
36
+ # Create group to handle Active Directory processing
37
+ @click.group()
38
+ def ad():
39
+ """Performs directory and user synchronization functions with Azure Active Directory."""
40
+ check_license()
41
+
42
+
43
+ @ad.command()
44
+ def authenticate():
45
+ """Obtains an access token using the credentials provided."""
46
+ # authenticate the user
47
+ get_access_token()
48
+
49
+
50
+ # Get Active Directory groups
51
+ @ad.command(name="list_groups")
52
+ def list_groups():
53
+ """Prints the lists of available RegScale groups the CLI can read."""
54
+ # authenticate the user
55
+ get_access_token()
56
+
57
+ # list all groups
58
+ list_ad_groups()
59
+
60
+
61
+ # Sync RegScale admins from Active Directory
62
+ @ad.command(name="sync_admins")
63
+ def sync_admins():
64
+ """Syncs members of the RegScale-admins group and assigns roles."""
65
+ # authenticate the user
66
+ get_access_token()
67
+
68
+ # set the Microsoft Graph Endpoint
69
+ get_group("RegScale-admin")
70
+
71
+
72
+ # Sync RegScale general users from Active Directory
73
+ @ad.command(name="sync_general")
74
+ def sync_general():
75
+ """Syncs members of the RegScale-general group and assigns roles."""
76
+ # authenticate the user
77
+ get_access_token()
78
+
79
+ # set the Microsoft Graph Endpoint
80
+ get_group("RegScale-general")
81
+
82
+
83
+ # Sync RegScale read only from Active Directory
84
+ @ad.command(name="sync_readonly")
85
+ def sync_readonly():
86
+ """Syncs members of the RegScale-readonly group and assigns roles."""
87
+ # authenticate the user
88
+ get_access_token()
89
+
90
+ # set the Microsoft Graph Endpoint
91
+ get_group("RegScale-readonly")
92
+
93
+
94
+ # Supporting Functions
95
+ def get_access_token() -> dict:
96
+ """
97
+ Function to authenticate in Active Directory and updates init.yaml with the returned JWT
98
+
99
+ :return: JWT from Azure Directory
100
+ :rtype: dict
101
+ """
102
+ import msal
103
+ from regscale.core.app.application import Application
104
+
105
+ app = Application()
106
+
107
+ # get the config from the application
108
+ config = app.config
109
+
110
+ # generate the endpoint
111
+ auth_url = config["adAuthUrl"] + config["adTenantId"]
112
+ graph_url = config["adGraphUrl"]
113
+ version = __version__
114
+
115
+ # configure the Microsoft MSAL library to authenticate and gain an access token
116
+ ad_app = msal.ConfidentialClientApplication(
117
+ client_id=config["adClientId"],
118
+ app_name="RegScale CLI",
119
+ app_version=version,
120
+ authority=auth_url,
121
+ client_credential=config["adClientSecret"],
122
+ )
123
+
124
+ # use MSAL to get the token (no caching for security)
125
+ try:
126
+ token = ad_app.acquire_token_for_client(scopes=graph_url)
127
+ config["adAccessToken"] = "Bearer " + token["access_token"]
128
+
129
+ # write the changes back to file
130
+ app.save_config(config)
131
+ logger.info("Azure AD Login Successful!")
132
+ logger.info("Init.yaml file updated successfully with the access token.")
133
+ except JSONDecodeError as ex:
134
+ error_and_exit(f"Unable to authenticate to Azure AD.\nError: {ex}")
135
+ except KeyError as ex:
136
+ error_and_exit(f"Unable to obtain access token! Please verify credentials.\nError: {ex}\n{token}")
137
+ # return the result
138
+ return token
139
+
140
+
141
+ def list_ad_groups() -> None:
142
+ """
143
+ Function that lists all RegScale groups in Active Directory
144
+
145
+ :rtype: None
146
+ """
147
+ from regscale.core.app.api import Api
148
+ from regscale.core.app.application import Application
149
+
150
+ app = Application()
151
+ api = Api()
152
+
153
+ # load the config from YAML
154
+ config = app.config
155
+
156
+ # trim the URL
157
+ graph_url = config["adGraphUrl"].replace(".default", "")
158
+
159
+ # set the endpoint
160
+ groups_url = f"{graph_url}v1.0/groups?$filter=startswith(displayName,'RegScale')"
161
+
162
+ # configure the headers for the API call
163
+ ad_headers = {"Authorization": config["adAccessToken"]}
164
+
165
+ # get the AD group info
166
+ logger.info("Fetching relevant AD Groups from Azure for RegScale.")
167
+ try:
168
+ groups_response = api.get(url=groups_url, headers=ad_headers)
169
+ groups_data = groups_response.json()
170
+ except JSONDecodeError as ex:
171
+ error_and_exit(f"Unable to retrieve group information from Azure Active Directory.\n{ex}")
172
+ # loop through the groups and log the results
173
+ if "value" in groups_data:
174
+ for g in groups_data["value"]:
175
+ logger.info("GROUP: " + g["displayName"])
176
+ logger.info("%s total group(s) retrieved.", len(groups_data["value"]))
177
+ elif "error" in groups_data:
178
+ try:
179
+ error_and_exit(f'{groups_data["error"]["code"]}: {groups_data["error"]["message"]}')
180
+ except Exception as ex:
181
+ error_and_exit(f"Unknown Error! {ex}\nData: {groups_data}")
182
+
183
+ # verify artifacts directory exists
184
+ check_file_path("artifacts")
185
+
186
+ # save group data to a json file
187
+ save_data_to(
188
+ file=Path("./artifacts/RegScale-AD-groups.json"),
189
+ data=groups_data,
190
+ )
191
+
192
+
193
+ # retrieves the RegScale groups from Azure AD
194
+ # flake8: noqa: C901
195
+ def get_group(str_group: str) -> None:
196
+ """
197
+ Syncs members of the RegScale-admins group and assigns appropriate roles
198
+
199
+ :param str str_group: RegScale user group
200
+ :rtype: None
201
+ """
202
+ from regscale.core.app.api import Api
203
+ from regscale.core.app.application import Application
204
+
205
+ # initialize app and api
206
+ app = Application()
207
+ api = Api()
208
+
209
+ # see if readonly
210
+ b_read_only = True if str_group == "RegScale-readonly" else False
211
+
212
+ # load the config from app
213
+ config = app.config
214
+
215
+ # trim the Graph URL
216
+ str_graph_url = config["adGraphUrl"].replace(".default", "")
217
+
218
+ # set the Microsoft Graph Endpoint
219
+ if str_group == "RegScale-admin":
220
+ groups_url = f"{str_graph_url}v1.0/groups?$filter=startswith(displayName,'RegScale-admin')"
221
+ elif str_group == "RegScale-general":
222
+ groups_url = f"{str_graph_url}v1.0/groups?$filter=startswith(displayName,'RegScale-general')"
223
+ elif str_group == "RegScale-readonly":
224
+ groups_url = f"{str_graph_url}v1.0/groups?$filter=startswith(displayName,'RegScale-readonly')"
225
+ else:
226
+ error_and_exit(f"Unknown RegScale group ({str_group}) requested for sync")
227
+
228
+ # set up the headers for the api call
229
+ ad_headers = {"Authorization": config["adAccessToken"]}
230
+
231
+ # get the AD group info
232
+ logger.info("Fetching relevant AD Groups from Azure for RegScale.")
233
+ try:
234
+ groups_response = api.get(groups_url, headers=ad_headers)
235
+ groups_data = groups_response.json()
236
+ except JSONDecodeError as ex:
237
+ error_and_exit(f"Unable to retrieve group information from Azure Active Directory.\n{ex}")
238
+ # verify artifacts directory exists
239
+ check_file_path("artifacts")
240
+
241
+ # save group data to json file
242
+ save_data_to(
243
+ file=Path(f"./artifacts/adGroupList-{str_group}.json"),
244
+ data=groups_data,
245
+ )
246
+
247
+ # loop through each group to find admins
248
+ if len(groups_data) == 0:
249
+ error_and_exit(f"{str_group} group has not been setup yet in Azure AD.")
250
+ else:
251
+ # get group info
252
+ if "value" in groups_data:
253
+ found_group = groups_data["value"][0]
254
+ group_id = found_group["id"]
255
+ else:
256
+ # error handling (log error)
257
+ if "error" in groups_data:
258
+ try:
259
+ error_and_exit(f'{groups_data["error"]["code"]}: {groups_data["error"]["message"]}')
260
+ except Exception as ex:
261
+ error_and_exit(f"Unknown Error! {ex}\nData: {groups_data}")
262
+
263
+ # get AD group members
264
+ members_url = f"{str_graph_url}v1.0/groups/{group_id}/members"
265
+
266
+ # get the member list for the AD group
267
+ logger.info("Fetching the list of members for this AD group - %s", str(group_id))
268
+ try:
269
+ member_response = api.get(members_url, headers=ad_headers)
270
+ member_data = member_response.json()
271
+ except JSONDecodeError:
272
+ error_and_exit(f"Unable to retrieve member list for Azure Active Directory group - {group_id}.")
273
+ # verify artifacts directory exists
274
+ check_file_path("artifacts")
275
+
276
+ # save member data to json file
277
+ save_data_to(
278
+ file=Path(f"./artifacts/adMemberList-{group_id}.json"),
279
+ data=member_data,
280
+ )
281
+ logger.info(member_data)
282
+ # retrieve the list of RegScale users
283
+ url_users = f'{config["domain"]}/api/accounts/getList'
284
+ try:
285
+ user_response = api.get(url_users)
286
+ user_data = user_response.json()
287
+ except JSONDecodeError:
288
+ error_and_exit("Unable to retrieve user list from RegScale.")
289
+
290
+ # retrieve the list of RegScale roles
291
+ url_roles = f'{config["domain"]}/api/accounts/getRoles'
292
+ try:
293
+ role_response = api.get(url_roles)
294
+ role_data = role_response.json()
295
+ except JSONDecodeError:
296
+ error_and_exit("Unable to retrieve roles from RegScale.")
297
+
298
+ # loop through the members of the AD group (create new user if not in RegScale)
299
+ for m in member_data["value"]:
300
+ # see if it exists
301
+ member_found = False
302
+ for u in user_data:
303
+ if "externalId" in u and m["id"] == u["externalId"]:
304
+ member_found = True
305
+
306
+ # handle new user flow
307
+ if not member_found:
308
+ # create a new user
309
+ new_user = User(
310
+ userName=m["userPrincipalName"],
311
+ email=m["mail"],
312
+ firstName=m["givenName"],
313
+ lastName=m["surname"],
314
+ workPhone=m["mobilePhone"],
315
+ activated=True,
316
+ jobTitle=m["jobTitle"],
317
+ tenantId=1,
318
+ ldapUser=True,
319
+ externalId=m["id"],
320
+ readOnly=b_read_only,
321
+ )
322
+ new_users.append(new_user.dict())
323
+ # loop through the users (disable if not in AD group)
324
+ for u in user_data:
325
+ if "externalId" in u:
326
+ disable_flag = True
327
+ for m in member_data["value"]:
328
+ if m["id"] == u["externalId"]:
329
+ disable_flag = False
330
+ if disable_flag:
331
+ remove_users.append(u)
332
+ # write out new user list to file
333
+ save_data_to(file=Path("./artifacts/newUsers.json"), data=new_users)
334
+
335
+ # write out disabled user list to file
336
+ save_data_to(file=Path("./artifacts/removeUsers.json"), data=remove_users)
337
+
338
+ # Logging
339
+ logger.info("%s new user(s) to process.", str(len(new_users)))
340
+
341
+ # loop through each user
342
+ regscale_new = []
343
+ for us in new_users:
344
+ # add new users in bulk
345
+ url_new_users = f'{config["domain"]}/api/accounts/azureAD'
346
+ try:
347
+ new_user = api.post(url_new_users, json=us)
348
+ user_new = {"id": new_user.text}
349
+ regscale_new.append(user_new)
350
+ logger.info("User created or updated: %s", us["userName"])
351
+ except Exception as ex:
352
+ error_and_exit(f"Unable to create new user {us['userName']}.\nError: {ex}")
353
+
354
+ # write out new user list to file
355
+ save_data_to(
356
+ file=Path("./artifacts/newRegScaleUsers.json"),
357
+ data=regscale_new,
358
+ )
359
+
360
+ # set the role
361
+ user_role = ""
362
+ if str_group == "RegScale-admin":
363
+ user_role = "Administrator"
364
+ elif str_group == "RegScale-general":
365
+ user_role = "GeneralUser"
366
+ elif str_group == "RegScale-readonly":
367
+ user_role = "ReadOnly"
368
+
369
+ # set the RegScale role based on the AD group
370
+ regscale_role = None
371
+ for role in role_data:
372
+ if role["name"] == user_role:
373
+ regscale_role = role
374
+ if role is None:
375
+ error_and_exit(f"Unable to locate RegScale role for group: {str_group}.")
376
+
377
+ # loop through the users and assign roles
378
+ int_roles = 0
379
+ for us in regscale_new:
380
+ # check the role
381
+ url_check_role = f'{config["domain"]}/api/accounts/checkRole/{us["id"]}/{regscale_role["id"]}'
382
+ try:
383
+ role_check = api.get(url=url_check_role)
384
+ str_check = role_check.text
385
+ except Exception as ex:
386
+ error_and_exit(f"Unable to check role: {us['id']}, {regscale_role['id']}.\nError: {ex}")
387
+
388
+ # add the role
389
+ if str_check == "false":
390
+ # add the role
391
+ url_assign_role = config["domain"] + "/api/accounts/assignRole/"
392
+ # role assignment object
393
+ assign = {"roleId": regscale_role["id"], "userId": us["id"]}
394
+ try:
395
+ api.post(url=url_assign_role, json=assign)
396
+ int_roles += 1
397
+ except Exception as ex:
398
+ error_and_exit(f"Unable to assign role: {us['id']}/{regscale_role['id']}.\nError: {ex}")
399
+
400
+ # output results
401
+ if int_roles > 0:
402
+ logger.info("Total Roles Assigned: %s.", str(int_roles))
403
+
404
+ # loop through and remove users
405
+ int_removals = 0
406
+ for us in remove_users:
407
+ # check the role
408
+ url_check_role = f'{config["domain"]}/api/accounts/checkRole/{us["id"]}/{regscale_role["id"]}'
409
+ try:
410
+ role_check = api.get(url=url_check_role)
411
+ str_check = role_check.text
412
+ except Exception as ex:
413
+ error_and_exit(f"Unable to check role: {us['id']}/{regscale_role['id']}.\nError: {ex}")
414
+
415
+ # add the role
416
+ if str_check == "true":
417
+ # remove the role
418
+ url_remove_role = f'{config["domain"]}/api/accounts/deleteRole/{us["id"]}/{regscale_role["id"]}'
419
+ try:
420
+ api.delete(url=url_remove_role)
421
+ int_removals += 1
422
+ except Exception as ex:
423
+ error_and_exit(f"Unable to remove role: {us['id']}/{regscale_role['id']}.\nError: {ex}")
424
+
425
+ # deactivate the user if they were in this role
426
+ url_deactivate = f'{config["domain"]}/api/accounts/changeUserStatus/{us["id"]}/false'
427
+ try:
428
+ api.get(url_deactivate)
429
+ logger.warning("%s account deactivated.", us["userName"])
430
+ except Exception as ex:
431
+ error_and_exit(f"Unable to check role: {us['id']}/{regscale_role['id']}.\nError: {ex}")
432
+ # output results
433
+ logger.info(str(int_removals) + " users had roles removed and accounts disabled.")
File without changes
@@ -0,0 +1,106 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """RegScale AWS Integrations"""
4
+ import re
5
+ from datetime import datetime, timedelta
6
+ from typing import Any, Optional, Tuple
7
+
8
+ from botocore.client import BaseClient
9
+ from botocore.exceptions import ClientError
10
+ from dateutil import parser
11
+
12
+ from regscale.core.app.utils.app_utils import create_logger
13
+
14
+
15
+ def check_finding_severity(comment: Optional[str]) -> str:
16
+ """Check the severity of the finding
17
+
18
+ :param Optional[str] comment: Comment from AWS Security Hub finding
19
+ :return: Severity of the finding
20
+ :rtype: str
21
+ """
22
+ result = ""
23
+ match = re.search(r"(?<=Finding Severity: ).*", comment)
24
+ if match:
25
+ severity = match.group()
26
+ result = severity # Output: "High"
27
+ return result
28
+
29
+
30
+ def get_due_date(earliest_date_performed: datetime, days: int) -> datetime:
31
+ """Returns the due date for an issue
32
+
33
+ :param datetime earliest_date_performed: Earliest date performed
34
+ :param int days: Days to add to the earliest date performed
35
+ :return: Due date
36
+ :rtype: datetime
37
+ """
38
+ fmt = "%Y-%m-%dT%H:%M:%S.%fZ"
39
+ try:
40
+ due_date = datetime.strptime(earliest_date_performed, fmt) + timedelta(days=days)
41
+ except ValueError:
42
+ # Try to determine the date format from a string
43
+ due_date = parser.parse(earliest_date_performed) + timedelta(days)
44
+ return due_date
45
+
46
+
47
+ def determine_status_and_results(finding: Any) -> Tuple[str, Optional[str]]:
48
+ """
49
+ Determine Status and Results
50
+
51
+ :param Any finding: AWS Finding
52
+ :return: Status and Results
53
+ :rtype: Tuple[str, Optional[str]]
54
+ """
55
+ status = "Pass"
56
+ results = None
57
+ if "Compliance" in finding.keys():
58
+ status = "Fail" if finding["Compliance"]["Status"] == "FAILED" else "Pass"
59
+ results = ", ".join(finding["Compliance"]["RelatedRequirements"])
60
+ if "FindingProviderFields" in finding.keys():
61
+ status = (
62
+ "Fail"
63
+ if finding["FindingProviderFields"]["Severity"]["Label"] in ["CRITICAL", "HIGH", "MEDIUM", "LOW"]
64
+ else "Pass"
65
+ )
66
+ if "PatchSummary" in finding.keys() and not results:
67
+ results = (
68
+ f"{finding['PatchSummary']['MissingCount']} Missing Patch(s) of "
69
+ "{finding['PatchSummary']['InstalledCount']}"
70
+ )
71
+ return status, results
72
+
73
+
74
+ def get_comments(finding: dict) -> str:
75
+ """
76
+ Get Comments
77
+
78
+ :param dict finding: AWS Finding
79
+ :return: Comments
80
+ :rtype: str
81
+ """
82
+ try:
83
+ return (
84
+ finding["Remediation"]["Recommendation"]["Text"]
85
+ + "<br></br>"
86
+ + finding["Remediation"]["Recommendation"]["Url"]
87
+ + "<br></br>"
88
+ + f"""Finding Severity: {finding["FindingProviderFields"]["Severity"]["Label"]}"""
89
+ )
90
+ except KeyError:
91
+ return "No remediation recommendation available"
92
+
93
+
94
+ def fetch_aws_findings(aws_client: BaseClient) -> list:
95
+ """Fetch AWS Findings
96
+
97
+ :param BaseClient aws_client: AWS Security Hub Client
98
+ :return: AWS Findings
99
+ :rtype: list
100
+ """
101
+ findings = []
102
+ try:
103
+ findings = aws_client.get_findings()["Findings"]
104
+ except ClientError as cex:
105
+ create_logger().error("Unexpected error: %s", cex)
106
+ return findings
File without changes
@@ -0,0 +1,91 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """Aqua RegScale integration"""
4
+ from datetime import datetime
5
+ from os import PathLike
6
+ from typing import Optional
7
+
8
+ import click
9
+
10
+ from regscale.models.integration_models.aqua import Aqua
11
+ from regscale.models.integration_models.flat_file_importer import FlatFileImporter
12
+
13
+
14
+ @click.group()
15
+ def aqua():
16
+ """Performs actions on Aqua Scanner artifacts."""
17
+ pass
18
+
19
+
20
+ @aqua.command(name="import_aqua")
21
+ @FlatFileImporter.common_scanner_options(
22
+ message="File path to the folder containing Aqua .csv files to process to RegScale.",
23
+ prompt="File path for Aqua files",
24
+ import_name="aqua",
25
+ )
26
+ def import_aqua(
27
+ folder_path: PathLike[str],
28
+ regscale_ssp_id: int,
29
+ scan_date: datetime,
30
+ mappings_path: PathLike[str],
31
+ disable_mapping: bool,
32
+ s3_bucket: str,
33
+ s3_prefix: str,
34
+ aws_profile: str,
35
+ upload_file: bool,
36
+ ):
37
+ """
38
+ Import Aqua scan data to RegScale
39
+ """
40
+ import_aqua_scan(
41
+ folder_path,
42
+ regscale_ssp_id,
43
+ scan_date,
44
+ mappings_path,
45
+ disable_mapping,
46
+ s3_bucket,
47
+ s3_prefix,
48
+ aws_profile,
49
+ upload_file,
50
+ )
51
+
52
+
53
+ def import_aqua_scan(
54
+ folder_path: PathLike[str],
55
+ regscale_ssp_id: int,
56
+ scan_date: datetime,
57
+ mappings_path: PathLike[str],
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
+ Import Aqua scans, vulnerabilities and assets to RegScale from Aqua files
66
+
67
+ :param PathLike[str] folder_path: File path to the folder containing Aqua .csv files to process to RegScale
68
+ :param int regscale_ssp_id: The RegScale SSP ID
69
+ :param datetime scan_date: The date of the scan
70
+ :param PathLike[str] mappings_path: The path to the mappings file
71
+ :param bool disable_mapping: Whether to disable custom mappings
72
+ :param str s3_bucket: The S3 bucket to download the files from
73
+ :param str s3_prefix: The S3 prefix to download the files from
74
+ :param str aws_profile: The AWS profile to use for S3 access
75
+ :param Optional[bool] upload_file: Whether to upload the file to RegScale after processing, defaults to True
76
+ :rtype: None
77
+ """
78
+ FlatFileImporter.import_files(
79
+ import_type=Aqua,
80
+ import_name="Aqua",
81
+ file_types=[".csv", ".xlsx"],
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,6 @@
1
+ """RegScale AWS Integration Package."""
2
+
3
+ from .cli import awsv2
4
+ from .inventory import AWSInventoryCollector, collect_all_inventory
5
+
6
+ __all__ = ["AWSInventoryCollector", "collect_all_inventory", "awsv2"]