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,413 @@
1
+ #!/usr/bin/env python3
2
+
3
+ """Click BaseModels."""
4
+
5
+ import contextlib
6
+ import inspect
7
+ from typing import Any, List, Optional, Union, Callable, Tuple, Dict
8
+
9
+ import click
10
+ import click.core
11
+ from pydantic import BaseModel, ConfigDict, field_validator
12
+
13
+ from regscale.models.inspect_models import SignatureModel
14
+ from regscale.core.lazy_group import LazyGroup
15
+
16
+
17
+ class ClickOption(BaseModel):
18
+ """A BaseModel based on a click object
19
+ This is the simplest unit in the click hierarchy, representing an option that can be passed to a command.
20
+ """
21
+
22
+ model_config = ConfigDict(extra="ignore", arbitrary_types_allowed=True)
23
+
24
+ name: str
25
+ value: Any = None
26
+ default: Any = None
27
+ option: Optional[Union[click.core.Option, dict]] = None
28
+ type: Optional[str] = None
29
+ help: Optional[str] = None
30
+ prompt: Optional[str] = None
31
+ confirmation_prompt: Optional[bool] = None
32
+ is_flag: Optional[bool] = None
33
+ is_bool_flag: Optional[bool] = None
34
+ count: Optional[int] = None
35
+ allow_from_autoenv: Optional[bool] = None
36
+ expose_value: Optional[bool] = None
37
+ is_eager: Optional[bool] = None
38
+ callback: Optional[Union[str, Any]] = None
39
+ callback_signature: Optional[Any] = None
40
+
41
+ @field_validator("option")
42
+ def _check_option(cls, var: Any) -> Any:
43
+ """
44
+ Check if option is a click.Option or dict
45
+
46
+ :param Any var: The option to check
47
+ :return: The option
48
+ :rtype: Any
49
+ """
50
+ if not isinstance(var, (dict, click.core.Option)):
51
+ raise TypeError("option must be a click.Option or dict")
52
+ return var
53
+
54
+ @classmethod
55
+ def from_option(
56
+ cls,
57
+ option: click.core.Option,
58
+ include_callback: bool = True,
59
+ include_option: bool = False,
60
+ ) -> "ClickOption":
61
+ """
62
+ Build a ClickOption class from a click.Option
63
+
64
+ :param click.core.Option option: The click.Option to convert
65
+ :param bool include_callback: Whether to include the callback, defaults to True
66
+ :param bool include_option: Whether to include the option, defaults to False
67
+ :return: A ClickOption object
68
+ :rtype: ClickOption
69
+ """
70
+ data = {
71
+ "option": option if include_option else option.__dict__,
72
+ "help": option.help,
73
+ "name": option.name,
74
+ "default": option.default,
75
+ "type": str(option.type),
76
+ "prompt": option.prompt,
77
+ "confirmation_prompt": option.confirmation_prompt,
78
+ "is_flag": option.is_flag,
79
+ "is_bool_flag": option.is_bool_flag,
80
+ "count": option.count,
81
+ "allow_from_autoenv": option.allow_from_autoenv,
82
+ "expose_value": option.expose_value,
83
+ "is_eager": option.is_eager,
84
+ "callback": (option.callback if include_callback else option.callback.__qualname__),
85
+ }
86
+ # get the signature of the callback,
87
+ if option.callback is not None:
88
+ sig = inspect.signature(option.callback)
89
+ data["callback_signature"] = {
90
+ "parameters": [
91
+ {
92
+ "name": name,
93
+ "default": (param.default if param.default is not inspect.Parameter.empty else None),
94
+ "kind": param.kind,
95
+ "annotation": (param.annotation if param.annotation is not inspect.Parameter.empty else None),
96
+ }
97
+ for name, param in sig.parameters.items()
98
+ ],
99
+ "return_annotation": (
100
+ sig.return_annotation if sig.return_annotation is not inspect.Signature.empty else None
101
+ ),
102
+ }
103
+ return cls(**data)
104
+
105
+ @property
106
+ def required(self) -> bool:
107
+ """
108
+ Make sure it is a required parameter.
109
+
110
+ :return: True if required, False otherwise
111
+ :rtype: bool
112
+ """
113
+ return self.prompt is False and self.default is None
114
+
115
+
116
+ class ClickCommand(BaseModel):
117
+ model_config = ConfigDict(extra="ignore", arbitrary_types_allowed=True)
118
+
119
+ name: str
120
+ command: Optional[click.core.Command] = None
121
+ help: Optional[str] = None
122
+ options_metavar: Optional[str] = None
123
+ context_settings: Optional[Any] = None
124
+ params: Dict[str, ClickOption]
125
+ callback: Optional[Union[str, Any]] = None
126
+ signatures: Optional[SignatureModel] = None
127
+
128
+ @field_validator("command")
129
+ def _check_command(cls, var: Any) -> Any:
130
+ """
131
+ Validate a click.Command
132
+
133
+ :param Any var: The command to validate
134
+ :return: The command
135
+ :rtype: Any
136
+ """
137
+ if var is None:
138
+ return var
139
+ if not isinstance(var, (click.Command, click.core.Command)):
140
+ print(f"command must be a click.Command not {type(var)}")
141
+ return var
142
+
143
+ @classmethod
144
+ def from_command(
145
+ cls,
146
+ command: click.core.Command,
147
+ include_callback: bool = True,
148
+ include_command: bool = False,
149
+ ) -> "ClickCommand":
150
+ """
151
+ Generate ClickCommand from a click.Command
152
+
153
+ :param click.core.Command command: The click.Command to convert
154
+ :param bool include_callback: Whether to include the callback, defaults to True
155
+ :param bool include_command: Whether to include the command, defaults to False
156
+ :return: A ClickCommand object
157
+ :rtype: ClickCommand
158
+ """
159
+ data = {
160
+ "command": command if include_command else None,
161
+ "name": command.name,
162
+ "help": command.help,
163
+ "options_metavar": command.options_metavar,
164
+ "context_settings": command.context_settings,
165
+ "params": {
166
+ param.name: ClickOption.from_option(param, include_callback)
167
+ for param in command.params
168
+ if isinstance(param, click.Option)
169
+ },
170
+ "signature": SignatureModel.from_callable(command=command.name, fn=command.callback),
171
+ "callback": (command.callback if include_callback else command.callback.__qualname__),
172
+ }
173
+ return cls(**data)
174
+
175
+ def _execute(self, *args, **kwargs) -> Optional[Any]:
176
+ """
177
+ Execute the click command while suppressing SystemExit to prevent Airflow from exiting
178
+
179
+ :param args: The arguments to pass to the command
180
+ :param kwargs: The keyword arguments to pass to the command
181
+ :return: The result of the command
182
+ :rtype: Optional[Any]
183
+ """
184
+ if not isinstance(self.callback, Callable):
185
+ raise RuntimeWarning("Callable not configured as callback")
186
+ with contextlib.suppress(SystemExit):
187
+ return self.callback(*args, **kwargs)
188
+
189
+ def _validate_params(self, *args, **kwargs) -> Tuple[list, dict]:
190
+ """
191
+ Validate the params and represent them as a dict of key value pairs
192
+
193
+ :param args: The arguments to validate
194
+ :param kwargs: The keyword arguments to validate
195
+ :return: A tuple of the validated args and kwargs
196
+ :rtype: Tuple[list, dict]
197
+ """
198
+ # iterate and get the expected list of params, if they are not Optional
199
+ param_values = []
200
+ param_dict = {}
201
+ for i, param in enumerate(self.params):
202
+ if args and i < len(args):
203
+ # process positional arguments first
204
+ param_values.append(args[i])
205
+ elif kwargs and param in kwargs:
206
+ # process keyword arguments
207
+ param_dict[param] = kwargs[param]
208
+ elif self.params[param].default is not None:
209
+ # use default for param if provided
210
+ param_dict[param] = self.params[param].default
211
+ else:
212
+ raise ValueError(f"Missing required argument {param}")
213
+ return param_values, param_dict
214
+
215
+ def call(self, *args, **kwargs) -> Optional[Any]:
216
+ """
217
+ Call the callable for the command
218
+
219
+ :param args: The arguments to pass to the command
220
+ :param kwargs: The keyword arguments to pass to the command
221
+ :return: The result of the command
222
+ :rtype: Optional[Any]
223
+ """
224
+ param_values, param_dict = self._validate_params(*args, **kwargs)
225
+ return self._execute(*param_values, **param_dict)
226
+
227
+ def return_cli_commands(self):
228
+ """
229
+ Return a list of all cli_commands independent of hierarchy
230
+
231
+ :return: A list of all cli_commands
232
+ :rtype: list
233
+ """
234
+ cli_commands = []
235
+ for param in self.params:
236
+ if isinstance(param, ClickCommand):
237
+ cli_commands.extend(param.return_cli_commands())
238
+ else:
239
+ cli_commands.append(param)
240
+ return cli_commands
241
+
242
+ @property
243
+ def param_defaults(self) -> dict:
244
+ """Return a dictionary with basic defaults for the parameters
245
+ :return: A dict in the following form:
246
+ >>> {
247
+ "has_default": bool,
248
+ "default": option.default,
249
+ "required": bool,
250
+ "prompt": bool
251
+ }
252
+
253
+ for all options required by Click.
254
+ :rtype: dict
255
+ """
256
+ return {
257
+ option.name: {
258
+ "has_default": bool(option.default),
259
+ "default": option.default,
260
+ "required": option.required,
261
+ "prompt": option.prompt,
262
+ }
263
+ for _, option in self.params.items()
264
+ }
265
+
266
+ def get_callback_args(self, putative_params: dict) -> dict:
267
+ """Get the callback arguments from the dag_run configuration.
268
+
269
+ :param dict putative_params: The dag_run configuration and op_kwargs dictionary.
270
+ :return: A dictionary where each key is a parameter name and each value is either the default
271
+ value of the parameter (if it has one and if the parameter is not present in dag_run_conf),
272
+ or the value from dag_run_conf.
273
+ :rtype: dict
274
+ """
275
+ callback_args = {}
276
+
277
+ if self.callback is not None and self.signatures is not None:
278
+ for _, param in self.signatures.parameters.items():
279
+ param_name = param.name
280
+ param_default = param.default
281
+ if param_name in putative_params:
282
+ callback_args[param_name] = putative_params[param_name]
283
+ elif param_default is not inspect.Parameter.empty:
284
+ callback_args[param_name] = param_default
285
+
286
+ return callback_args
287
+
288
+ @property
289
+ def parameters(self) -> List[str]:
290
+ """
291
+ Return a list of parameters expected by this command
292
+
293
+ :return: A list of parameters
294
+ :rtype: List[str]
295
+ """
296
+ signatures = self.signatures or []
297
+ params = self.params or []
298
+ return [param.name if hasattr(param, "name") else param for param in signatures] + [
299
+ param.name if hasattr(param, "name") else param for param in params
300
+ ]
301
+
302
+ @property
303
+ def defaults(self) -> Dict[str, Any]:
304
+ """
305
+ Return a dictionary of the defaults for each parameter
306
+
307
+ :return: A dictionary of the defaults for each parameter
308
+ :rtype: Dict[str, Any]
309
+ """
310
+ return {param_name: option.default for param_name, option in self.params.items() if option.default is not None}
311
+
312
+
313
+ class ClickGroup(BaseModel):
314
+ """BaseModel representation of a click Group"""
315
+
316
+ model_config = ConfigDict(extra="ignore", arbitrary_types_allowed=True)
317
+
318
+ name: str
319
+ group_name: str
320
+ # This double-quoted ClickGroup is a forward reference to allow for nested groups
321
+ commands: Dict[str, Union[ClickCommand, "ClickGroup"]]
322
+
323
+ @classmethod
324
+ def from_lazy_group(
325
+ cls,
326
+ cli: click.Group,
327
+ group: LazyGroup,
328
+ prefix: Optional[str] = None,
329
+ include_callback: bool = True,
330
+ ) -> "ClickGroup":
331
+ """
332
+ Define a ClickGroup based on a LazyGroup group
333
+
334
+ :param click.Group cli: The click.Group object, used for context and fetching click commands from LazyGroup
335
+ :param LazyGroup group: The LazyGroup object to convert to a ClickGroup
336
+ :param str prefix: The prefix to add to the group name
337
+ :param bool include_callback: Whether to include the callback for the group
338
+ :return: A ClickGroup object
339
+ :rtype: ClickGroup
340
+ """
341
+ prefix = f"{prefix}__{group.name}" if prefix else f"{group.name}"
342
+ data = {
343
+ "name": prefix,
344
+ "group_name": group.name,
345
+ "commands": {},
346
+ }
347
+ for cmd_name in group.lazy_subcommands.keys():
348
+ cmd = group.get_command(cli.context_class, cmd_name) # noqa
349
+ if not cmd:
350
+ continue
351
+ if isinstance(cmd, click.core.Group):
352
+ data["commands"][cmd.name] = cls.from_group(cmd, include_callback) # noqa
353
+ elif isinstance(cmd, click.core.Command):
354
+ data["commands"][cmd.name] = ClickCommand.from_command(cmd, include_callback)
355
+ return cls(**data)
356
+
357
+ @classmethod
358
+ def from_group(
359
+ cls,
360
+ group: click.Group,
361
+ prefix: Optional[str] = None,
362
+ include_callback: bool = True,
363
+ ) -> "ClickGroup":
364
+ """
365
+ Define a ClickGroup based on a click.Group group
366
+
367
+ :param click.Group group: The click.Group object to convert to a ClickGroup
368
+ :param str prefix: The prefix to add to the group name
369
+ :param bool include_callback: Whether to include the callback for the group
370
+ :return: A ClickGroup object
371
+ :rtype: ClickGroup
372
+ """
373
+ prefix = f"{prefix}__{group.name}" if prefix else f"{group.name}"
374
+ data = {
375
+ "name": prefix,
376
+ "group_name": group.name,
377
+ "commands": {},
378
+ }
379
+ for cmd_name, cmd in group.commands.items():
380
+ if not cmd:
381
+ continue
382
+ if isinstance(cmd, LazyGroup):
383
+ data["commands"][cmd_name] = cls.from_lazy_group(
384
+ group, cmd, prefix=prefix, include_callback=include_callback
385
+ )
386
+ elif isinstance(cmd, click.core.Group):
387
+ data["commands"][cmd.name] = cls.from_group(cmd, include_callback)
388
+ elif isinstance(cmd, click.core.Command):
389
+ data["commands"][cmd.name] = ClickCommand.from_command(cmd, include_callback)
390
+ return cls(**data)
391
+
392
+ def flatten(self, prefix: str = "") -> dict:
393
+ """
394
+ Flatten the group to a dictionary of commands.
395
+
396
+ :param str prefix: The prefix to add to the group name
397
+ :return: A dictionary of commands
398
+ :rtype: dict
399
+ """
400
+ commands = {}
401
+
402
+ def _flatten(group_: Union[ClickCommand, "ClickGroup"], prefix_: str = ""):
403
+ for cmd in group_.commands:
404
+ # flake8: noqa: F821
405
+ if isinstance(cmd, ClickCommand):
406
+ cmd_name = f"{prefix_}__{cmd.name}" if prefix_ else cmd.name
407
+ commands[cmd_name] = cmd
408
+ elif isinstance(cmd, ClickGroup):
409
+ new_prefix = f"{prefix_}__{cmd.group_name}" if prefix_ else cmd.group_name
410
+ _flatten(cmd, new_prefix)
411
+
412
+ _flatten(self, prefix)
413
+ return commands
@@ -0,0 +1,154 @@
1
+ """Create the AppConfig objects."""
2
+
3
+ from typing import Optional
4
+ from inspect import getmembers, currentframe, isclass
5
+ from pydantic import BaseModel, create_model, SecretStr
6
+ from regscale.models.platform import RegScaleAuth
7
+
8
+
9
+ class Provider(BaseModel):
10
+ """A provider class"""
11
+
12
+ provider: str
13
+
14
+ def __getitem__(self, item):
15
+ """Override the default getitem to modify the config dict object."""
16
+ self.__dict__.get(item)
17
+
18
+ def __setitem__(self, key, value):
19
+ """Override the default setitem to modify the config dict object."""
20
+ self.__dict__[key] = value
21
+
22
+ def refresh(self):
23
+ """Refresh this providers data"""
24
+ # TODO - implement the refresh method
25
+ raise NotImplementedError("coming soon!")
26
+
27
+
28
+ providers = {
29
+ "AdProvider": {
30
+ "adAccessToken": (str, ...),
31
+ "adAuthUrl": (str, ...),
32
+ "adClientSecret": (SecretStr, ...),
33
+ "adClientId": (SecretStr, ...),
34
+ "adGraphURL": (str, ...),
35
+ },
36
+ "Azure365Provider": {
37
+ "azure365AccessToken": (str, ...),
38
+ "azure365ClientId": (SecretStr, ...),
39
+ "azure365TenantId": (str, ...),
40
+ },
41
+ "AzureCloudProvider": {
42
+ "azureCloudAccessToken": (SecretStr, ...),
43
+ "azureCloudClientId": (str, ...),
44
+ "azureCloudTenantId": (str, ...),
45
+ "azureCloudSubscriptionId": (SecretStr, ...),
46
+ },
47
+ "CisaProvider": {
48
+ "cisaKev": (
49
+ str,
50
+ "https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json",
51
+ ),
52
+ "cisa_alerts": (str, "https://www.cisa.gov/uscert/ncas/alerts/"),
53
+ "cisa_kev": (
54
+ str,
55
+ "https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json",
56
+ ),
57
+ },
58
+ "DependabotProvider": {
59
+ "dependabotId": (SecretStr, ...),
60
+ "dependabotOwner": (str, ...),
61
+ "dependabotRepo": (str, ...),
62
+ "dependabotToken": (SecretStr, ...),
63
+ },
64
+ "JiraProvider": {
65
+ "jiraApiToken": (SecretStr, ...),
66
+ "jiraUrl": (str, ...),
67
+ "jirUserName": (str, ...),
68
+ },
69
+ "OktaProvider": {
70
+ "oktaApiToken": (SecretStr, ...),
71
+ "oktaClientId": (str, ...),
72
+ "oktaUrl": (str, ...),
73
+ },
74
+ "QualysProvider": {
75
+ "qualysURL": (str, ...),
76
+ "qualysUserName": (str, ...),
77
+ "qualysPassword": (SecretStr, ...),
78
+ },
79
+ "SnowProvider": {
80
+ "snowPassword": (SecretStr, ...),
81
+ "snowUserName": (str, ...),
82
+ "snowUrl": (str, ...),
83
+ },
84
+ "SonarProvider": {
85
+ "sonarToken": (SecretStr, ...),
86
+ },
87
+ "TenableProvider": {
88
+ # FIXME - [sic] in mistake below, key is lowercase
89
+ "tenableAccesskey": (SecretStr, ...),
90
+ "tenableSecretkey": (SecretStr, ...),
91
+ "tenableUrl": (str, "https://sc.tenable.online"),
92
+ },
93
+ "WizProvider": {
94
+ "wizAccessToken": (SecretStr, ...),
95
+ "wizAuthUrl": (str, "https://auth.wiz.io/oauth/token"),
96
+ "wizExcludes": (str, ""),
97
+ "wizReportAge": (int, 15),
98
+ },
99
+ }
100
+
101
+ # the above dict is itemized, and the key for each dict is assigned
102
+ # a new class with the sub-dict as kwargs to the Provider class
103
+ # the tuple of each sub-dict key defines the type and the default
104
+ # if ... is supplied, there is no default and it is required
105
+ for provider_name, fields in providers.items():
106
+ # Add or override fields in the provider's dictionary
107
+ updated_fields = {}
108
+ for field_name, (field_type, default_value) in fields.items():
109
+ # Use the field_type and default_value from the tuple
110
+ if default_value is ...: # Checking if the field is required
111
+ updated_fields[field_name] = (field_type, ...)
112
+ else:
113
+ updated_fields[field_name] = (field_type, default_value)
114
+
115
+ # Add the 'provider' field with its type and value
116
+ provider_key = provider_name.split("Provider")[0].lower()
117
+ updated_fields["provider"] = (str, provider_key)
118
+
119
+ # Create the model with the updated fields
120
+ globals()[provider_name] = create_model(provider_name, **updated_fields, __base__=Provider)
121
+
122
+
123
+ class Providers(BaseModel):
124
+ pass
125
+
126
+
127
+ # generate a hidden dict of classes for all classes currently defined
128
+ _all_classes = {name: obj for name, obj in getmembers(currentframe().f_globals) if isclass(obj)}
129
+ # iterate over the provider keys, and add an Optional dynamically created provider class
130
+ for provider in providers.keys():
131
+ if provider in _all_classes:
132
+ Providers.__annotations__[provider.split("Provider")[0].lower()] = Optional[_all_classes[provider]]
133
+ # now any provider class is a parameter to Providers, so
134
+ # providers = Providers(wiz=WizProvider(...), ad=AdProvider(...))
135
+ # providers.wiz.wizAccessToken will access the access token in the providers class
136
+
137
+
138
+ class AppConfig(BaseModel):
139
+ """The AppConfig object will be used to generate the config for platform interaction"""
140
+
141
+ auth: RegScaleAuth
142
+ config: Optional[dict] = None # TODO - Spec this as a BaseModel too
143
+ providers: Optional[Providers] = None # TODO - spec providers and implement
144
+ # with the providers we can access values like AppConfig.providers.wiz.wizAccessToken
145
+
146
+ @property
147
+ def token(self):
148
+ return self.auth.token
149
+
150
+ @classmethod
151
+ def populate(cls):
152
+ """Class method to populate the AppConfig class"""
153
+ # TODO implement method for retrieving config from platform
154
+ return cls()
@@ -0,0 +1,67 @@
1
+ <style>
2
+ h1 {
3
+ color: #0A63B3;
4
+ font-size: 1.51rem;
5
+ font-family: Roboto, "Open Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
6
+ font-family-monospace: Roboto, "Montserrat", Georgia, "Times New Roman", Times, serif;
7
+ font-weight: normal;
8
+ margin-bottom: -10px;
9
+ }
10
+ table {
11
+ font-family: Roboto, "Open Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
12
+ font-family-monospace: Roboto, "Montserrat", Georgia, "Times New Roman", Times, serif;
13
+ margin: 5px;
14
+ border-collapse: collapse;
15
+ border-color: 0;
16
+ color: #404E67;
17
+ }
18
+ th {
19
+ border-bottom: 1px solid #E2EBF3;
20
+ padding: 10px 15px;
21
+ font-family: Roboto, "Open Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
22
+ font-family-monospace: Roboto, "Montserrat", Georgia, "Times New Roman", Times, serif;
23
+ font-weight: 600;
24
+ font-size: 1rem;
25
+ color: #404E67;
26
+ }
27
+ tr, td {
28
+ background-color: white;
29
+ color: #404E67;
30
+ font-size: 14px;
31
+ font-family: Roboto, "Open Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
32
+ font-family-monospace: Roboto, "Montserrat", Georgia, "Times New Roman", Times, serif;
33
+ font-weight: 400;
34
+ padding: 10px;
35
+ text-align: center;
36
+ border-bottom: 1px solid #E2EBF3;
37
+ }
38
+ a {
39
+ mso-hide: all;
40
+ text-align: center;
41
+ font-size: 14px;
42
+ font-weight: 450;
43
+ background-color: #1DC3EB;
44
+ color: white;
45
+ border: 1px solid #22C2DC;
46
+ border-radius: 5px;
47
+ margin: 2px;
48
+ padding: 5px 10px;
49
+ text-decoration: none;
50
+ transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
51
+ box-shadow: 1px 2px 5px 1px rgba(0, 0, 0, 0.11);
52
+ }
53
+ a:active {
54
+ background-color: yellow;
55
+ }
56
+ a:hover {
57
+ background-color: #4CD5E7;
58
+ color: #FAF9F6;
59
+ }
60
+ a:visited {
61
+ color: #FFFFFF;
62
+ background-color: #A8B8C7;
63
+ }
64
+ a:visited:hover {
65
+ background-color:#79848F;
66
+ }
67
+ </style>
@@ -0,0 +1,8 @@
1
+ """Demonstrate the hierarchy via ClickGroup."""
2
+
3
+ from regscale.regscale import cli
4
+ from regscale.models.click_models import ClickGroup
5
+
6
+
7
+ REGSCALE_CLI = ClickGroup.from_group(cli, prefix="regscale")
8
+ REGSCALE_CLI_FLAT = REGSCALE_CLI.flatten()