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.
- regscale/__init__.py +1 -0
- regscale/airflow/__init__.py +9 -0
- regscale/airflow/azure/__init__.py +9 -0
- regscale/airflow/azure/cli.py +89 -0
- regscale/airflow/azure/upload_dags.py +116 -0
- regscale/airflow/click_dags.py +127 -0
- regscale/airflow/click_mixins.py +82 -0
- regscale/airflow/config.py +25 -0
- regscale/airflow/factories/__init__.py +0 -0
- regscale/airflow/factories/connections.py +58 -0
- regscale/airflow/factories/workflows.py +78 -0
- regscale/airflow/hierarchy.py +88 -0
- regscale/airflow/operators/__init__.py +0 -0
- regscale/airflow/operators/click.py +36 -0
- regscale/airflow/sensors/__init__.py +0 -0
- regscale/airflow/sensors/sql.py +107 -0
- regscale/airflow/sessions/__init__.py +0 -0
- regscale/airflow/sessions/sql/__init__.py +3 -0
- regscale/airflow/sessions/sql/queries.py +64 -0
- regscale/airflow/sessions/sql/sql_server_queries.py +248 -0
- regscale/airflow/tasks/__init__.py +0 -0
- regscale/airflow/tasks/branches.py +22 -0
- regscale/airflow/tasks/cli.py +116 -0
- regscale/airflow/tasks/click.py +73 -0
- regscale/airflow/tasks/debugging.py +9 -0
- regscale/airflow/tasks/groups.py +116 -0
- regscale/airflow/tasks/init.py +60 -0
- regscale/airflow/tasks/states.py +47 -0
- regscale/airflow/tasks/workflows.py +36 -0
- regscale/ansible/__init__.py +9 -0
- regscale/core/__init__.py +0 -0
- regscale/core/app/__init__.py +3 -0
- regscale/core/app/api.py +571 -0
- regscale/core/app/application.py +665 -0
- regscale/core/app/internal/__init__.py +136 -0
- regscale/core/app/internal/admin_actions.py +230 -0
- regscale/core/app/internal/assessments_editor.py +873 -0
- regscale/core/app/internal/catalog.py +316 -0
- regscale/core/app/internal/comparison.py +459 -0
- regscale/core/app/internal/control_editor.py +571 -0
- regscale/core/app/internal/encrypt.py +79 -0
- regscale/core/app/internal/evidence.py +1240 -0
- regscale/core/app/internal/file_uploads.py +151 -0
- regscale/core/app/internal/healthcheck.py +66 -0
- regscale/core/app/internal/login.py +305 -0
- regscale/core/app/internal/migrations.py +240 -0
- regscale/core/app/internal/model_editor.py +1701 -0
- regscale/core/app/internal/poam_editor.py +632 -0
- regscale/core/app/internal/workflow.py +105 -0
- regscale/core/app/logz.py +74 -0
- regscale/core/app/utils/XMLIR.py +258 -0
- regscale/core/app/utils/__init__.py +0 -0
- regscale/core/app/utils/api_handler.py +358 -0
- regscale/core/app/utils/app_utils.py +1110 -0
- regscale/core/app/utils/catalog_utils/__init__.py +0 -0
- regscale/core/app/utils/catalog_utils/common.py +91 -0
- regscale/core/app/utils/catalog_utils/compare_catalog.py +193 -0
- regscale/core/app/utils/catalog_utils/diagnostic_catalog.py +97 -0
- regscale/core/app/utils/catalog_utils/download_catalog.py +103 -0
- regscale/core/app/utils/catalog_utils/update_catalog.py +718 -0
- regscale/core/app/utils/catalog_utils/update_catalog_v2.py +1378 -0
- regscale/core/app/utils/catalog_utils/update_catalog_v3.py +1272 -0
- regscale/core/app/utils/catalog_utils/update_plans.py +334 -0
- regscale/core/app/utils/file_utils.py +238 -0
- regscale/core/app/utils/parser_utils.py +81 -0
- regscale/core/app/utils/pickle_file_handler.py +57 -0
- regscale/core/app/utils/regscale_utils.py +319 -0
- regscale/core/app/utils/report_utils.py +119 -0
- regscale/core/app/utils/variables.py +226 -0
- regscale/core/decorators.py +31 -0
- regscale/core/lazy_group.py +65 -0
- regscale/core/login.py +63 -0
- regscale/core/server/__init__.py +0 -0
- regscale/core/server/flask_api.py +473 -0
- regscale/core/server/helpers.py +373 -0
- regscale/core/server/rest.py +64 -0
- regscale/core/server/static/css/bootstrap.css +6030 -0
- regscale/core/server/static/css/bootstrap.min.css +6 -0
- regscale/core/server/static/css/main.css +176 -0
- regscale/core/server/static/images/regscale-cli.svg +49 -0
- regscale/core/server/static/images/regscale.svg +38 -0
- regscale/core/server/templates/base.html +74 -0
- regscale/core/server/templates/index.html +43 -0
- regscale/core/server/templates/login.html +28 -0
- regscale/core/server/templates/make_base64.html +22 -0
- regscale/core/server/templates/upload_STIG.html +109 -0
- regscale/core/server/templates/upload_STIG_result.html +26 -0
- regscale/core/server/templates/upload_ssp.html +144 -0
- regscale/core/server/templates/upload_ssp_result.html +128 -0
- regscale/core/static/__init__.py +0 -0
- regscale/core/static/regex.py +14 -0
- regscale/core/utils/__init__.py +117 -0
- regscale/core/utils/click_utils.py +13 -0
- regscale/core/utils/date.py +238 -0
- regscale/core/utils/graphql.py +254 -0
- regscale/core/utils/urls.py +23 -0
- regscale/dev/__init__.py +6 -0
- regscale/dev/analysis.py +454 -0
- regscale/dev/cli.py +235 -0
- regscale/dev/code_gen.py +492 -0
- regscale/dev/dirs.py +69 -0
- regscale/dev/docs.py +384 -0
- regscale/dev/monitoring.py +26 -0
- regscale/dev/profiling.py +216 -0
- regscale/exceptions/__init__.py +4 -0
- regscale/exceptions/license_exception.py +7 -0
- regscale/exceptions/validation_exception.py +9 -0
- regscale/integrations/__init__.py +1 -0
- regscale/integrations/commercial/__init__.py +486 -0
- regscale/integrations/commercial/ad.py +433 -0
- regscale/integrations/commercial/amazon/__init__.py +0 -0
- regscale/integrations/commercial/amazon/common.py +106 -0
- regscale/integrations/commercial/aqua/__init__.py +0 -0
- regscale/integrations/commercial/aqua/aqua.py +91 -0
- regscale/integrations/commercial/aws/__init__.py +6 -0
- regscale/integrations/commercial/aws/cli.py +322 -0
- regscale/integrations/commercial/aws/inventory/__init__.py +110 -0
- regscale/integrations/commercial/aws/inventory/base.py +64 -0
- regscale/integrations/commercial/aws/inventory/resources/__init__.py +19 -0
- regscale/integrations/commercial/aws/inventory/resources/compute.py +234 -0
- regscale/integrations/commercial/aws/inventory/resources/containers.py +113 -0
- regscale/integrations/commercial/aws/inventory/resources/database.py +101 -0
- regscale/integrations/commercial/aws/inventory/resources/integration.py +237 -0
- regscale/integrations/commercial/aws/inventory/resources/networking.py +253 -0
- regscale/integrations/commercial/aws/inventory/resources/security.py +240 -0
- regscale/integrations/commercial/aws/inventory/resources/storage.py +91 -0
- regscale/integrations/commercial/aws/scanner.py +823 -0
- regscale/integrations/commercial/azure/__init__.py +0 -0
- regscale/integrations/commercial/azure/common.py +32 -0
- regscale/integrations/commercial/azure/intune.py +488 -0
- regscale/integrations/commercial/azure/scanner.py +49 -0
- regscale/integrations/commercial/burp.py +78 -0
- regscale/integrations/commercial/cpe.py +144 -0
- regscale/integrations/commercial/crowdstrike.py +1117 -0
- regscale/integrations/commercial/defender.py +1511 -0
- regscale/integrations/commercial/dependabot.py +210 -0
- regscale/integrations/commercial/durosuite/__init__.py +0 -0
- regscale/integrations/commercial/durosuite/api.py +1546 -0
- regscale/integrations/commercial/durosuite/process_devices.py +101 -0
- regscale/integrations/commercial/durosuite/scanner.py +637 -0
- regscale/integrations/commercial/durosuite/variables.py +21 -0
- regscale/integrations/commercial/ecr.py +90 -0
- regscale/integrations/commercial/gcp/__init__.py +237 -0
- regscale/integrations/commercial/gcp/auth.py +96 -0
- regscale/integrations/commercial/gcp/control_tests.py +238 -0
- regscale/integrations/commercial/gcp/variables.py +18 -0
- regscale/integrations/commercial/gitlab.py +332 -0
- regscale/integrations/commercial/grype.py +165 -0
- regscale/integrations/commercial/ibm.py +90 -0
- regscale/integrations/commercial/import_all/__init__.py +0 -0
- regscale/integrations/commercial/import_all/import_all_cmd.py +467 -0
- regscale/integrations/commercial/import_all/scan_file_fingerprints.json +27 -0
- regscale/integrations/commercial/jira.py +1046 -0
- regscale/integrations/commercial/mappings/__init__.py +0 -0
- regscale/integrations/commercial/mappings/csf_controls.json +713 -0
- regscale/integrations/commercial/mappings/nist_800_53_r5_controls.json +1516 -0
- regscale/integrations/commercial/nessus/__init__.py +0 -0
- regscale/integrations/commercial/nessus/nessus_utils.py +429 -0
- regscale/integrations/commercial/nessus/scanner.py +416 -0
- regscale/integrations/commercial/nexpose.py +90 -0
- regscale/integrations/commercial/okta.py +798 -0
- regscale/integrations/commercial/opentext/__init__.py +0 -0
- regscale/integrations/commercial/opentext/click.py +99 -0
- regscale/integrations/commercial/opentext/scanner.py +143 -0
- regscale/integrations/commercial/prisma.py +91 -0
- regscale/integrations/commercial/qualys.py +1462 -0
- regscale/integrations/commercial/salesforce.py +980 -0
- regscale/integrations/commercial/sap/__init__.py +0 -0
- regscale/integrations/commercial/sap/click.py +31 -0
- regscale/integrations/commercial/sap/sysdig/__init__.py +0 -0
- regscale/integrations/commercial/sap/sysdig/click.py +57 -0
- regscale/integrations/commercial/sap/sysdig/sysdig_scanner.py +190 -0
- regscale/integrations/commercial/sap/tenable/__init__.py +0 -0
- regscale/integrations/commercial/sap/tenable/click.py +49 -0
- regscale/integrations/commercial/sap/tenable/scanner.py +196 -0
- regscale/integrations/commercial/servicenow.py +1756 -0
- regscale/integrations/commercial/sicura/__init__.py +0 -0
- regscale/integrations/commercial/sicura/api.py +855 -0
- regscale/integrations/commercial/sicura/commands.py +73 -0
- regscale/integrations/commercial/sicura/scanner.py +481 -0
- regscale/integrations/commercial/sicura/variables.py +16 -0
- regscale/integrations/commercial/snyk.py +90 -0
- regscale/integrations/commercial/sonarcloud.py +260 -0
- regscale/integrations/commercial/sqlserver.py +369 -0
- regscale/integrations/commercial/stig_mapper_integration/__init__.py +0 -0
- regscale/integrations/commercial/stig_mapper_integration/click_commands.py +38 -0
- regscale/integrations/commercial/stig_mapper_integration/mapping_engine.py +353 -0
- regscale/integrations/commercial/stigv2/__init__.py +0 -0
- regscale/integrations/commercial/stigv2/ckl_parser.py +349 -0
- regscale/integrations/commercial/stigv2/click_commands.py +95 -0
- regscale/integrations/commercial/stigv2/stig_integration.py +202 -0
- regscale/integrations/commercial/synqly/__init__.py +0 -0
- regscale/integrations/commercial/synqly/assets.py +46 -0
- regscale/integrations/commercial/synqly/ticketing.py +132 -0
- regscale/integrations/commercial/synqly/vulnerabilities.py +223 -0
- regscale/integrations/commercial/synqly_jira.py +840 -0
- regscale/integrations/commercial/tenablev2/__init__.py +0 -0
- regscale/integrations/commercial/tenablev2/authenticate.py +31 -0
- regscale/integrations/commercial/tenablev2/click.py +1584 -0
- regscale/integrations/commercial/tenablev2/scanner.py +504 -0
- regscale/integrations/commercial/tenablev2/stig_parsers.py +140 -0
- regscale/integrations/commercial/tenablev2/utils.py +78 -0
- regscale/integrations/commercial/tenablev2/variables.py +17 -0
- regscale/integrations/commercial/trivy.py +162 -0
- regscale/integrations/commercial/veracode.py +96 -0
- regscale/integrations/commercial/wizv2/WizDataMixin.py +97 -0
- regscale/integrations/commercial/wizv2/__init__.py +0 -0
- regscale/integrations/commercial/wizv2/click.py +429 -0
- regscale/integrations/commercial/wizv2/constants.py +1001 -0
- regscale/integrations/commercial/wizv2/issue.py +361 -0
- regscale/integrations/commercial/wizv2/models.py +112 -0
- regscale/integrations/commercial/wizv2/parsers.py +339 -0
- regscale/integrations/commercial/wizv2/sbom.py +115 -0
- regscale/integrations/commercial/wizv2/scanner.py +416 -0
- regscale/integrations/commercial/wizv2/utils.py +796 -0
- regscale/integrations/commercial/wizv2/variables.py +39 -0
- regscale/integrations/commercial/wizv2/wiz_auth.py +159 -0
- regscale/integrations/commercial/xray.py +91 -0
- regscale/integrations/integration/__init__.py +2 -0
- regscale/integrations/integration/integration.py +26 -0
- regscale/integrations/integration/inventory.py +17 -0
- regscale/integrations/integration/issue.py +100 -0
- regscale/integrations/integration_override.py +149 -0
- regscale/integrations/public/__init__.py +103 -0
- regscale/integrations/public/cisa.py +641 -0
- regscale/integrations/public/criticality_updater.py +70 -0
- regscale/integrations/public/emass.py +411 -0
- regscale/integrations/public/emass_slcm_import.py +697 -0
- regscale/integrations/public/fedramp/__init__.py +0 -0
- regscale/integrations/public/fedramp/appendix_parser.py +548 -0
- regscale/integrations/public/fedramp/click.py +479 -0
- regscale/integrations/public/fedramp/components.py +714 -0
- regscale/integrations/public/fedramp/docx_parser.py +259 -0
- regscale/integrations/public/fedramp/fedramp_cis_crm.py +1124 -0
- regscale/integrations/public/fedramp/fedramp_common.py +3181 -0
- regscale/integrations/public/fedramp/fedramp_docx.py +388 -0
- regscale/integrations/public/fedramp/fedramp_five.py +2343 -0
- regscale/integrations/public/fedramp/fedramp_traversal.py +138 -0
- regscale/integrations/public/fedramp/import_fedramp_r4_ssp.py +279 -0
- regscale/integrations/public/fedramp/import_workbook.py +495 -0
- regscale/integrations/public/fedramp/inventory_items.py +244 -0
- regscale/integrations/public/fedramp/mappings/__init__.py +0 -0
- regscale/integrations/public/fedramp/mappings/fedramp_r4_parts.json +7388 -0
- regscale/integrations/public/fedramp/mappings/fedramp_r5_params.json +8636 -0
- regscale/integrations/public/fedramp/mappings/fedramp_r5_parts.json +9605 -0
- regscale/integrations/public/fedramp/mappings/system_roles.py +34 -0
- regscale/integrations/public/fedramp/mappings/user.py +175 -0
- regscale/integrations/public/fedramp/mappings/values.py +141 -0
- regscale/integrations/public/fedramp/markdown_parser.py +150 -0
- regscale/integrations/public/fedramp/metadata.py +689 -0
- regscale/integrations/public/fedramp/models/__init__.py +59 -0
- regscale/integrations/public/fedramp/models/leveraged_auth_new.py +168 -0
- regscale/integrations/public/fedramp/models/poam_importer.py +522 -0
- regscale/integrations/public/fedramp/parts_mapper.py +107 -0
- regscale/integrations/public/fedramp/poam/__init__.py +0 -0
- regscale/integrations/public/fedramp/poam/scanner.py +851 -0
- regscale/integrations/public/fedramp/properties.py +201 -0
- regscale/integrations/public/fedramp/reporting.py +84 -0
- regscale/integrations/public/fedramp/resources.py +496 -0
- regscale/integrations/public/fedramp/rosetta.py +110 -0
- regscale/integrations/public/fedramp/ssp_logger.py +87 -0
- regscale/integrations/public/fedramp/system_characteristics.py +922 -0
- regscale/integrations/public/fedramp/system_control_implementations.py +582 -0
- regscale/integrations/public/fedramp/system_implementation.py +190 -0
- regscale/integrations/public/fedramp/xml_utils.py +87 -0
- regscale/integrations/public/nist_catalog.py +275 -0
- regscale/integrations/public/oscal.py +1946 -0
- regscale/integrations/public/otx.py +169 -0
- regscale/integrations/scanner_integration.py +2692 -0
- regscale/integrations/variables.py +25 -0
- regscale/models/__init__.py +7 -0
- regscale/models/app_models/__init__.py +5 -0
- regscale/models/app_models/catalog_compare.py +213 -0
- regscale/models/app_models/click.py +252 -0
- regscale/models/app_models/datetime_encoder.py +21 -0
- regscale/models/app_models/import_validater.py +321 -0
- regscale/models/app_models/mapping.py +260 -0
- regscale/models/app_models/pipeline.py +37 -0
- regscale/models/click_models.py +413 -0
- regscale/models/config.py +154 -0
- regscale/models/email_style.css +67 -0
- regscale/models/hierarchy.py +8 -0
- regscale/models/inspect_models.py +79 -0
- regscale/models/integration_models/__init__.py +0 -0
- regscale/models/integration_models/amazon_models/__init__.py +0 -0
- regscale/models/integration_models/amazon_models/inspector.py +262 -0
- regscale/models/integration_models/amazon_models/inspector_scan.py +206 -0
- regscale/models/integration_models/aqua.py +247 -0
- regscale/models/integration_models/azure_alerts.py +255 -0
- regscale/models/integration_models/base64.py +23 -0
- regscale/models/integration_models/burp.py +433 -0
- regscale/models/integration_models/burp_models.py +128 -0
- regscale/models/integration_models/cisa_kev_data.json +19333 -0
- regscale/models/integration_models/defender_data.py +93 -0
- regscale/models/integration_models/defenderimport.py +143 -0
- regscale/models/integration_models/drf.py +443 -0
- regscale/models/integration_models/ecr_models/__init__.py +0 -0
- regscale/models/integration_models/ecr_models/data.py +69 -0
- regscale/models/integration_models/ecr_models/ecr.py +239 -0
- regscale/models/integration_models/flat_file_importer.py +1079 -0
- regscale/models/integration_models/grype_import.py +247 -0
- regscale/models/integration_models/ibm.py +126 -0
- regscale/models/integration_models/implementation_results.py +85 -0
- regscale/models/integration_models/nexpose.py +140 -0
- regscale/models/integration_models/prisma.py +202 -0
- regscale/models/integration_models/qualys.py +720 -0
- regscale/models/integration_models/qualys_scanner.py +160 -0
- regscale/models/integration_models/sbom/__init__.py +0 -0
- regscale/models/integration_models/sbom/cyclone_dx.py +139 -0
- regscale/models/integration_models/send_reminders.py +620 -0
- regscale/models/integration_models/snyk.py +155 -0
- regscale/models/integration_models/synqly_models/__init__.py +0 -0
- regscale/models/integration_models/synqly_models/capabilities.json +1 -0
- regscale/models/integration_models/synqly_models/connector_types.py +22 -0
- regscale/models/integration_models/synqly_models/connectors/__init__.py +7 -0
- regscale/models/integration_models/synqly_models/connectors/assets.py +97 -0
- regscale/models/integration_models/synqly_models/connectors/ticketing.py +583 -0
- regscale/models/integration_models/synqly_models/connectors/vulnerabilities.py +169 -0
- regscale/models/integration_models/synqly_models/ocsf_mapper.py +331 -0
- regscale/models/integration_models/synqly_models/param.py +72 -0
- regscale/models/integration_models/synqly_models/synqly_model.py +733 -0
- regscale/models/integration_models/synqly_models/tenants.py +39 -0
- regscale/models/integration_models/tenable_models/__init__.py +0 -0
- regscale/models/integration_models/tenable_models/integration.py +187 -0
- regscale/models/integration_models/tenable_models/models.py +513 -0
- regscale/models/integration_models/trivy_import.py +231 -0
- regscale/models/integration_models/veracode.py +217 -0
- regscale/models/integration_models/xray.py +135 -0
- regscale/models/locking.py +100 -0
- regscale/models/platform.py +110 -0
- regscale/models/regscale_models/__init__.py +67 -0
- regscale/models/regscale_models/assessment.py +570 -0
- regscale/models/regscale_models/assessment_plan.py +52 -0
- regscale/models/regscale_models/asset.py +567 -0
- regscale/models/regscale_models/asset_mapping.py +190 -0
- regscale/models/regscale_models/case.py +42 -0
- regscale/models/regscale_models/catalog.py +261 -0
- regscale/models/regscale_models/cci.py +46 -0
- regscale/models/regscale_models/change.py +167 -0
- regscale/models/regscale_models/checklist.py +372 -0
- regscale/models/regscale_models/comment.py +49 -0
- regscale/models/regscale_models/compliance_settings.py +112 -0
- regscale/models/regscale_models/component.py +412 -0
- regscale/models/regscale_models/component_mapping.py +65 -0
- regscale/models/regscale_models/control.py +38 -0
- regscale/models/regscale_models/control_implementation.py +1128 -0
- regscale/models/regscale_models/control_objective.py +261 -0
- regscale/models/regscale_models/control_parameter.py +100 -0
- regscale/models/regscale_models/control_test.py +34 -0
- regscale/models/regscale_models/control_test_plan.py +75 -0
- regscale/models/regscale_models/control_test_result.py +52 -0
- regscale/models/regscale_models/custom_field.py +245 -0
- regscale/models/regscale_models/data.py +109 -0
- regscale/models/regscale_models/data_center.py +40 -0
- regscale/models/regscale_models/deviation.py +203 -0
- regscale/models/regscale_models/email.py +97 -0
- regscale/models/regscale_models/evidence.py +47 -0
- regscale/models/regscale_models/evidence_mapping.py +40 -0
- regscale/models/regscale_models/facility.py +59 -0
- regscale/models/regscale_models/file.py +382 -0
- regscale/models/regscale_models/filetag.py +37 -0
- regscale/models/regscale_models/form_field_value.py +94 -0
- regscale/models/regscale_models/group.py +169 -0
- regscale/models/regscale_models/implementation_objective.py +335 -0
- regscale/models/regscale_models/implementation_option.py +275 -0
- regscale/models/regscale_models/implementation_role.py +33 -0
- regscale/models/regscale_models/incident.py +177 -0
- regscale/models/regscale_models/interconnection.py +43 -0
- regscale/models/regscale_models/issue.py +1176 -0
- regscale/models/regscale_models/leveraged_authorization.py +125 -0
- regscale/models/regscale_models/line_of_inquiry.py +52 -0
- regscale/models/regscale_models/link.py +205 -0
- regscale/models/regscale_models/meta_data.py +64 -0
- regscale/models/regscale_models/mixins/__init__.py +0 -0
- regscale/models/regscale_models/mixins/parent_cache.py +124 -0
- regscale/models/regscale_models/module.py +224 -0
- regscale/models/regscale_models/modules.py +191 -0
- regscale/models/regscale_models/objective.py +14 -0
- regscale/models/regscale_models/parameter.py +87 -0
- regscale/models/regscale_models/ports_protocol.py +81 -0
- regscale/models/regscale_models/privacy.py +89 -0
- regscale/models/regscale_models/profile.py +50 -0
- regscale/models/regscale_models/profile_link.py +68 -0
- regscale/models/regscale_models/profile_mapping.py +124 -0
- regscale/models/regscale_models/project.py +63 -0
- regscale/models/regscale_models/property.py +278 -0
- regscale/models/regscale_models/question.py +85 -0
- regscale/models/regscale_models/questionnaire.py +87 -0
- regscale/models/regscale_models/questionnaire_instance.py +177 -0
- regscale/models/regscale_models/rbac.py +132 -0
- regscale/models/regscale_models/reference.py +86 -0
- regscale/models/regscale_models/regscale_model.py +1643 -0
- regscale/models/regscale_models/requirement.py +29 -0
- regscale/models/regscale_models/risk.py +274 -0
- regscale/models/regscale_models/sbom.py +54 -0
- regscale/models/regscale_models/scan_history.py +436 -0
- regscale/models/regscale_models/search.py +53 -0
- regscale/models/regscale_models/security_control.py +132 -0
- regscale/models/regscale_models/security_plan.py +204 -0
- regscale/models/regscale_models/software_inventory.py +159 -0
- regscale/models/regscale_models/stake_holder.py +64 -0
- regscale/models/regscale_models/stig.py +647 -0
- regscale/models/regscale_models/supply_chain.py +152 -0
- regscale/models/regscale_models/system_role.py +188 -0
- regscale/models/regscale_models/system_role_external_assignment.py +40 -0
- regscale/models/regscale_models/tag.py +37 -0
- regscale/models/regscale_models/tag_mapping.py +19 -0
- regscale/models/regscale_models/task.py +133 -0
- regscale/models/regscale_models/threat.py +196 -0
- regscale/models/regscale_models/user.py +175 -0
- regscale/models/regscale_models/user_group.py +55 -0
- regscale/models/regscale_models/vulnerability.py +242 -0
- regscale/models/regscale_models/vulnerability_mapping.py +162 -0
- regscale/models/regscale_models/workflow.py +55 -0
- regscale/models/regscale_models/workflow_action.py +34 -0
- regscale/models/regscale_models/workflow_instance.py +269 -0
- regscale/models/regscale_models/workflow_instance_step.py +114 -0
- regscale/models/regscale_models/workflow_template.py +58 -0
- regscale/models/regscale_models/workflow_template_step.py +45 -0
- regscale/regscale.py +815 -0
- regscale/utils/__init__.py +7 -0
- regscale/utils/b64conversion.py +14 -0
- regscale/utils/click_utils.py +118 -0
- regscale/utils/decorators.py +48 -0
- regscale/utils/dict_utils.py +59 -0
- regscale/utils/files.py +79 -0
- regscale/utils/fxns.py +30 -0
- regscale/utils/graphql_client.py +113 -0
- regscale/utils/lists.py +16 -0
- regscale/utils/numbers.py +12 -0
- regscale/utils/shell.py +148 -0
- regscale/utils/string.py +121 -0
- regscale/utils/synqly_utils.py +165 -0
- regscale/utils/threading/__init__.py +8 -0
- regscale/utils/threading/threadhandler.py +131 -0
- regscale/utils/threading/threadsafe_counter.py +47 -0
- regscale/utils/threading/threadsafe_dict.py +242 -0
- regscale/utils/threading/threadsafe_list.py +83 -0
- regscale/utils/version.py +104 -0
- regscale/validation/__init__.py +0 -0
- regscale/validation/address.py +37 -0
- regscale/validation/record.py +48 -0
- regscale/visualization/__init__.py +5 -0
- regscale/visualization/click.py +34 -0
- regscale_cli-6.16.0.0.dist-info/LICENSE +21 -0
- regscale_cli-6.16.0.0.dist-info/METADATA +659 -0
- regscale_cli-6.16.0.0.dist-info/RECORD +481 -0
- regscale_cli-6.16.0.0.dist-info/WHEEL +5 -0
- regscale_cli-6.16.0.0.dist-info/entry_points.txt +6 -0
- regscale_cli-6.16.0.0.dist-info/top_level.txt +2 -0
- tests/fixtures/__init__.py +2 -0
- tests/fixtures/api.py +87 -0
- tests/fixtures/models.py +91 -0
- tests/fixtures/test_fixture.py +144 -0
- tests/mocks/__init__.py +0 -0
- tests/mocks/objects.py +3 -0
- tests/mocks/response.py +32 -0
- tests/mocks/xml.py +13 -0
- tests/regscale/__init__.py +0 -0
- tests/regscale/core/__init__.py +0 -0
- tests/regscale/core/test_api.py +232 -0
- tests/regscale/core/test_app.py +406 -0
- tests/regscale/core/test_login.py +37 -0
- tests/regscale/core/test_logz.py +66 -0
- tests/regscale/core/test_sbom_generator.py +87 -0
- tests/regscale/core/test_validation_utils.py +163 -0
- tests/regscale/core/test_version.py +78 -0
- tests/regscale/models/__init__.py +0 -0
- tests/regscale/models/test_asset.py +71 -0
- tests/regscale/models/test_config.py +26 -0
- tests/regscale/models/test_control_implementation.py +27 -0
- tests/regscale/models/test_import.py +97 -0
- tests/regscale/models/test_issue.py +36 -0
- tests/regscale/models/test_mapping.py +52 -0
- tests/regscale/models/test_platform.py +31 -0
- tests/regscale/models/test_regscale_model.py +346 -0
- tests/regscale/models/test_report.py +32 -0
- tests/regscale/models/test_tenable_integrations.py +118 -0
- tests/regscale/models/test_user_model.py +121 -0
- tests/regscale/test_about.py +19 -0
- tests/regscale/test_authorization.py +65 -0
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""Model for a RegScale Component"""
|
|
4
|
+
import logging
|
|
5
|
+
from enum import Enum
|
|
6
|
+
from typing import Optional, Any, Union, List, cast, Dict
|
|
7
|
+
|
|
8
|
+
from pydantic import ConfigDict, Field
|
|
9
|
+
from requests import Response
|
|
10
|
+
|
|
11
|
+
from regscale.core.app.api import Api
|
|
12
|
+
from regscale.core.app.application import Application
|
|
13
|
+
from regscale.core.app.utils.app_utils import get_current_datetime
|
|
14
|
+
from regscale.models.regscale_models.mixins.parent_cache import PlanCacheMixin
|
|
15
|
+
from regscale.models.regscale_models.regscale_model import RegScaleModel, T
|
|
16
|
+
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class ComponentType(str, Enum):
|
|
21
|
+
"""Component Type Enum"""
|
|
22
|
+
|
|
23
|
+
Hardware = "hardware"
|
|
24
|
+
Software = "software"
|
|
25
|
+
Service = "service"
|
|
26
|
+
Policy = "policy"
|
|
27
|
+
Process = "process"
|
|
28
|
+
Procedure = "procedure"
|
|
29
|
+
ComplianceArtifact = "compliance artifact"
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class ComponentStatus(str, Enum):
|
|
33
|
+
"""Component Status Enum"""
|
|
34
|
+
|
|
35
|
+
DraftPending = "Draft/Pending"
|
|
36
|
+
Active = "Active"
|
|
37
|
+
InactiveRetired = "Inactive/Retired"
|
|
38
|
+
Cancelled = "Cancelled"
|
|
39
|
+
UndergoingMajorModification = "Undergoing Major Modification"
|
|
40
|
+
Other = "Other"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class ComponentList(RegScaleModel):
|
|
44
|
+
id: Optional[int]
|
|
45
|
+
title: Optional[str]
|
|
46
|
+
status: Optional[str]
|
|
47
|
+
exclude: Optional[bool]
|
|
48
|
+
componentType: Optional[str]
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class Component(RegScaleModel):
|
|
52
|
+
"""Component Model"""
|
|
53
|
+
|
|
54
|
+
_module_slug = "components"
|
|
55
|
+
_unique_fields = [
|
|
56
|
+
["title", "securityPlansId"],
|
|
57
|
+
]
|
|
58
|
+
_parent_id_field = "securityPlansId"
|
|
59
|
+
|
|
60
|
+
title: str
|
|
61
|
+
description: str
|
|
62
|
+
componentType: Union[ComponentType, str]
|
|
63
|
+
status: Union[ComponentStatus, str] = ComponentStatus.Active
|
|
64
|
+
id: int = 0
|
|
65
|
+
securityPlansId: Optional[int] = None
|
|
66
|
+
defaultAssessmentDays: int = 0
|
|
67
|
+
purpose: Optional[str] = None
|
|
68
|
+
cmmcAssetType: Optional[str] = None
|
|
69
|
+
createdById: str = Field(default_factory=RegScaleModel.get_user_id)
|
|
70
|
+
dateCreated: str = Field(default_factory=get_current_datetime)
|
|
71
|
+
lastUpdatedById: str = Field(default_factory=RegScaleModel.get_user_id)
|
|
72
|
+
dateLastUpdated: str = Field(default_factory=get_current_datetime)
|
|
73
|
+
uuid: Optional[str] = None
|
|
74
|
+
componentOwnerId: str = Field(default_factory=RegScaleModel.get_user_id)
|
|
75
|
+
cmmcExclusion: bool = False
|
|
76
|
+
externalId: Optional[str] = None
|
|
77
|
+
isPublic: bool = True
|
|
78
|
+
riskCategorization: Optional[str] = None
|
|
79
|
+
|
|
80
|
+
@staticmethod
|
|
81
|
+
def _get_additional_endpoints() -> ConfigDict:
|
|
82
|
+
"""
|
|
83
|
+
Get additional endpoints for the Components model.
|
|
84
|
+
|
|
85
|
+
:return: A dictionary of additional endpoints
|
|
86
|
+
:rtype: ConfigDict
|
|
87
|
+
"""
|
|
88
|
+
return ConfigDict( # type: ignore
|
|
89
|
+
get_list="/api/{model_slug}/getList",
|
|
90
|
+
get_all_by_parent="/api/{model_slug}/getAllByParent/{intParentID}",
|
|
91
|
+
get_count="/api/{model_slug}/getCount",
|
|
92
|
+
graph="/api/{model_slug}/graph",
|
|
93
|
+
graph_by_date="/api/{model_slug}/graphByDate/{strGroupBy}",
|
|
94
|
+
report="/api/{model_slug}/report/{strReport}",
|
|
95
|
+
filter_components="/api/{model_slug}/filterComponents",
|
|
96
|
+
filter_component_dashboard="/api/{model_slug}/filterComponentDashboard",
|
|
97
|
+
query_by_custom_field="/api/{model_slug}/queryByCustomField/{strFieldName}/{strValue}",
|
|
98
|
+
get="/api/{model_slug}/find/{id}",
|
|
99
|
+
evidence="/api/{model_slug}/evidence/{intID}",
|
|
100
|
+
find_by_guid="/api/{model_slug}/findByGUID/{strGUID}",
|
|
101
|
+
find_by_external_id="/api/{model_slug}/findByExternalId/{strID}",
|
|
102
|
+
get_titles="/api/{model_slug}/getTitles",
|
|
103
|
+
main_dashboard="/api/{model_slug}/mainDashboard/{intYear}",
|
|
104
|
+
component_dashboard="/api/{model_slug}/componentDashboard/{intYear}",
|
|
105
|
+
oscal="/api/{model_slug}/oscal/{intID}",
|
|
106
|
+
statusboard="/api/{model_slug}/statusboard/{intID}/{strSearch}/{intPage}/{pageSize}",
|
|
107
|
+
emass_export="/api/{model_slug}/emassExport/{intID}",
|
|
108
|
+
mega_api="/api/{model_slug}/megaAPI/{intId}",
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
def __eq__(self, other: "Component") -> bool:
|
|
112
|
+
"""
|
|
113
|
+
Check if two Component objects are equal
|
|
114
|
+
|
|
115
|
+
:param Component other: Component object to compare
|
|
116
|
+
:return: True if equal, False if not
|
|
117
|
+
:rtype: bool
|
|
118
|
+
"""
|
|
119
|
+
return (
|
|
120
|
+
self.title == other.title
|
|
121
|
+
and self.description == other.description
|
|
122
|
+
and self.componentType == other.componentType
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
def __hash__(self) -> int:
|
|
126
|
+
"""
|
|
127
|
+
Hash a Component object
|
|
128
|
+
|
|
129
|
+
:return: Hashed Component object
|
|
130
|
+
:rtype: int
|
|
131
|
+
"""
|
|
132
|
+
return hash((self.title, self.description, self.componentType))
|
|
133
|
+
|
|
134
|
+
def __getitem__(self, key: Any) -> Any:
|
|
135
|
+
"""
|
|
136
|
+
Get attribute from Pipeline
|
|
137
|
+
|
|
138
|
+
:param Any key: Key to get value for
|
|
139
|
+
:return: value of provided key
|
|
140
|
+
:rtype: Any
|
|
141
|
+
"""
|
|
142
|
+
if getattr(self, key) == "None":
|
|
143
|
+
return None
|
|
144
|
+
return getattr(self, key)
|
|
145
|
+
|
|
146
|
+
def __setitem__(self, key: Any, value: Any) -> None:
|
|
147
|
+
"""
|
|
148
|
+
Set attribute in Pipeline with provided key
|
|
149
|
+
|
|
150
|
+
:param Any key: Key to change to provided value
|
|
151
|
+
:param Any value: New value for provided Key
|
|
152
|
+
:rtype: None
|
|
153
|
+
"""
|
|
154
|
+
return setattr(self, key, value)
|
|
155
|
+
|
|
156
|
+
@staticmethod
|
|
157
|
+
def get_components_from_ssp(app: Application, ssp_id: int) -> list[dict]:
|
|
158
|
+
"""
|
|
159
|
+
Get all components for a given SSP
|
|
160
|
+
|
|
161
|
+
:param Application app: Application instance
|
|
162
|
+
:param int ssp_id: RegScale SSP
|
|
163
|
+
:return: List of component dictionaries
|
|
164
|
+
:rtype: list[dict]
|
|
165
|
+
"""
|
|
166
|
+
api = Api()
|
|
167
|
+
existing_res = api.get(app.config["domain"] + f"/api/components/getAllByParent/{ssp_id}")
|
|
168
|
+
existing_res.raise_for_status()
|
|
169
|
+
return existing_res.json()
|
|
170
|
+
|
|
171
|
+
@classmethod
|
|
172
|
+
def get_map(cls, plan_id: int, key_field: str = "title") -> dict[str, "Component"]:
|
|
173
|
+
"""
|
|
174
|
+
Get the component map for the component and cache it in Redis
|
|
175
|
+
|
|
176
|
+
:param int plan_id: Security Plan ID
|
|
177
|
+
:param str key_field: Key field to use, defaults to "componentId"
|
|
178
|
+
:return: Component Map
|
|
179
|
+
:rtype: dict[str, "Component"]
|
|
180
|
+
"""
|
|
181
|
+
search_data = f"""query {{
|
|
182
|
+
componentMappings(skip: 0, take: 50, where: {{component: {{securityPlansId: {{eq: {plan_id}}} }} }}) {{
|
|
183
|
+
items {{
|
|
184
|
+
id
|
|
185
|
+
component {{
|
|
186
|
+
{cls.build_graphql_fields()}
|
|
187
|
+
}}
|
|
188
|
+
}}
|
|
189
|
+
totalCount
|
|
190
|
+
pageInfo {{
|
|
191
|
+
hasNextPage
|
|
192
|
+
}}
|
|
193
|
+
}}
|
|
194
|
+
}}"""
|
|
195
|
+
response = cls._get_api_handler().graph(query=search_data)
|
|
196
|
+
components = cast(List["Component"], cls._handle_graph_response(response, child="component"))
|
|
197
|
+
return_components = {}
|
|
198
|
+
for component in components:
|
|
199
|
+
identifier = getattr(component, key_field, None)
|
|
200
|
+
if identifier:
|
|
201
|
+
return_components[identifier] = component
|
|
202
|
+
|
|
203
|
+
return return_components
|
|
204
|
+
|
|
205
|
+
@classmethod
|
|
206
|
+
def get_list(cls) -> List[ComponentList]: # type: ignore
|
|
207
|
+
"""
|
|
208
|
+
Retrieves a list of items for the model.
|
|
209
|
+
|
|
210
|
+
:return: A list of items or None
|
|
211
|
+
:rtype: List[ComponentList]
|
|
212
|
+
"""
|
|
213
|
+
response = cls._get_api_handler().get(
|
|
214
|
+
endpoint=cls.get_endpoint("get_list").format(model_slug=cls.get_module_slug())
|
|
215
|
+
)
|
|
216
|
+
if not response or response.status_code in [204, 404]:
|
|
217
|
+
return []
|
|
218
|
+
if response and response.ok:
|
|
219
|
+
return [ComponentList(**item) for item in response.json()]
|
|
220
|
+
return []
|
|
221
|
+
|
|
222
|
+
@classmethod
|
|
223
|
+
def filter_components(cls, params: Dict) -> List["Component"]:
|
|
224
|
+
"""
|
|
225
|
+
Retrieves a list of items for the model.
|
|
226
|
+
|
|
227
|
+
:param Dict params: The parameters to filter the components
|
|
228
|
+
:return: A list of Components or None
|
|
229
|
+
:rtype: List[Component]
|
|
230
|
+
"""
|
|
231
|
+
response = cls._get_api_handler().post(
|
|
232
|
+
endpoint=cls.get_endpoint("filter_components").format(
|
|
233
|
+
model_slug=cls.get_module_slug(),
|
|
234
|
+
),
|
|
235
|
+
data=params,
|
|
236
|
+
)
|
|
237
|
+
if not response or response.status_code in [204, 404]:
|
|
238
|
+
return []
|
|
239
|
+
if response and response.ok:
|
|
240
|
+
items = response.json().get("items")
|
|
241
|
+
return list(filter(None, [cls.get_object(object_id=item.get("id")) for item in items]))
|
|
242
|
+
return []
|
|
243
|
+
|
|
244
|
+
@classmethod
|
|
245
|
+
def get_sort_position_dict(cls) -> dict:
|
|
246
|
+
"""
|
|
247
|
+
Overrides the base method.
|
|
248
|
+
|
|
249
|
+
:return: dict The sort position in the list of properties
|
|
250
|
+
:rtype: dict
|
|
251
|
+
"""
|
|
252
|
+
return {
|
|
253
|
+
"id": 1,
|
|
254
|
+
"title": 2,
|
|
255
|
+
"description": 3,
|
|
256
|
+
"purpose": 4,
|
|
257
|
+
"componentType": 5,
|
|
258
|
+
"status": 6,
|
|
259
|
+
"defaultAssessmentDays": 7,
|
|
260
|
+
"cmmcAssetType": 9,
|
|
261
|
+
"cmmcExclusion": 10,
|
|
262
|
+
"componentOwnerId": 11,
|
|
263
|
+
"isPublic": 12,
|
|
264
|
+
"tenantsId": 13,
|
|
265
|
+
"securityPlansId": 14,
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
@classmethod
|
|
269
|
+
def get_enum_values(cls, field_name: str) -> list:
|
|
270
|
+
"""
|
|
271
|
+
Overrides the base method.
|
|
272
|
+
|
|
273
|
+
:param str field_name: The property name to provide enum values for
|
|
274
|
+
:return: list of strings
|
|
275
|
+
:rtype: list
|
|
276
|
+
"""
|
|
277
|
+
if field_name == "componentType":
|
|
278
|
+
return [component_type.value for component_type in ComponentType]
|
|
279
|
+
if field_name == "status":
|
|
280
|
+
return [status.value for status in ComponentStatus]
|
|
281
|
+
return cls.get_bool_enums(field_name)
|
|
282
|
+
|
|
283
|
+
@classmethod
|
|
284
|
+
def get_lookup_field(cls, field_name: str) -> str:
|
|
285
|
+
"""
|
|
286
|
+
Overrides the base method.
|
|
287
|
+
|
|
288
|
+
:param str field_name: The property name to provide enum values for
|
|
289
|
+
:return: str the field name to look up
|
|
290
|
+
:rtype: str
|
|
291
|
+
"""
|
|
292
|
+
return "user" if field_name == "componentOwnerId" else ""
|
|
293
|
+
|
|
294
|
+
@classmethod
|
|
295
|
+
def is_date_field(cls, field_name: str) -> bool:
|
|
296
|
+
"""
|
|
297
|
+
Overrides the base method.
|
|
298
|
+
|
|
299
|
+
:param str field_name: The property name to provide enum values for
|
|
300
|
+
:return: bool if the field should be formatted as a date
|
|
301
|
+
:rtype: bool
|
|
302
|
+
"""
|
|
303
|
+
return False
|
|
304
|
+
|
|
305
|
+
@classmethod
|
|
306
|
+
def create_new_connecting_model(cls, instance: Any) -> Any:
|
|
307
|
+
"""
|
|
308
|
+
Overrides the base method.
|
|
309
|
+
|
|
310
|
+
:param Any instance: The instance to create a new connecting model for when loading new records.
|
|
311
|
+
:return Any:
|
|
312
|
+
:rtype Any:
|
|
313
|
+
"""
|
|
314
|
+
connecting_model = ComponentMapping(
|
|
315
|
+
securityPlanId=instance.securityPlansId, componentId=instance.id, isPublic=instance.isPublic
|
|
316
|
+
)
|
|
317
|
+
return connecting_model.create()
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
class ComponentMapping(RegScaleModel, PlanCacheMixin["ComponentMapping"]):
|
|
321
|
+
"""Component Mapping Model"""
|
|
322
|
+
|
|
323
|
+
_module_slug = "componentmapping"
|
|
324
|
+
_unique_fields = [
|
|
325
|
+
["componentId", "securityPlanId"],
|
|
326
|
+
]
|
|
327
|
+
|
|
328
|
+
componentId: int
|
|
329
|
+
securityPlanId: int
|
|
330
|
+
id: int = 0
|
|
331
|
+
uuid: Optional[str] = None
|
|
332
|
+
dateCreated: Optional[str] = None
|
|
333
|
+
lastUpdatedById: Optional[str] = None
|
|
334
|
+
dateLastUpdated: Optional[str] = None
|
|
335
|
+
TenantId: Optional[int] = 1
|
|
336
|
+
isPublic: bool = True
|
|
337
|
+
|
|
338
|
+
@staticmethod
|
|
339
|
+
def _get_additional_endpoints() -> ConfigDict:
|
|
340
|
+
"""
|
|
341
|
+
Get additional endpoints for the ComponentMappings model.
|
|
342
|
+
|
|
343
|
+
:return: A dictionary of additional endpoints
|
|
344
|
+
:rtype: ConfigDict
|
|
345
|
+
"""
|
|
346
|
+
return ConfigDict( # type: ignore
|
|
347
|
+
find_mapping="/api/{model_slug}/findMappings/{intID}",
|
|
348
|
+
get_mappings_as_components="/api/{model_slug}/getMappingsAsComponents/{intID}",
|
|
349
|
+
get_mappings_as_security_plans="/api/{model_slug}/getMappingsAsSecurityPlans/{intID}",
|
|
350
|
+
)
|
|
351
|
+
|
|
352
|
+
def find_by_unique(self, **kwargs: dict) -> Optional["ComponentMapping"]: # type: ignore
|
|
353
|
+
"""
|
|
354
|
+
Find a ComponentMapping by its unique fields
|
|
355
|
+
|
|
356
|
+
:param dict **kwargs: Additional Keyword Arguments
|
|
357
|
+
:raises ValueError: If componentId or securityPlanId are not populated
|
|
358
|
+
:return: ComponentMapping object, if found
|
|
359
|
+
:rtype: Optional[ComponentMapping]
|
|
360
|
+
"""
|
|
361
|
+
|
|
362
|
+
if not self.componentId or not self.securityPlanId:
|
|
363
|
+
raise ValueError("Component ID and Security Plan ID are required")
|
|
364
|
+
mappings: list[ComponentMapping] = self.find_mappings(self.securityPlanId)
|
|
365
|
+
for mapping in mappings:
|
|
366
|
+
# Check if all unique fields match
|
|
367
|
+
all_fields_match = all(getattr(mapping, key) == getattr(self, key) for key in self._unique_fields)
|
|
368
|
+
if all_fields_match:
|
|
369
|
+
return mapping
|
|
370
|
+
return None
|
|
371
|
+
|
|
372
|
+
@classmethod
|
|
373
|
+
def find_mappings(cls, security_plan_id: int) -> List[T]:
|
|
374
|
+
"""
|
|
375
|
+
Find mappings for a given component
|
|
376
|
+
|
|
377
|
+
:param int security_plan_id: Security Plan ID
|
|
378
|
+
:return: List of mappings
|
|
379
|
+
:rtype: List[T]
|
|
380
|
+
"""
|
|
381
|
+
return cls._handle_list_response(
|
|
382
|
+
cls._get_api_handler().get(
|
|
383
|
+
cls.get_endpoint("get_mappings_as_components").format(
|
|
384
|
+
intID=security_plan_id,
|
|
385
|
+
)
|
|
386
|
+
),
|
|
387
|
+
security_plan_id=security_plan_id,
|
|
388
|
+
)
|
|
389
|
+
|
|
390
|
+
@classmethod
|
|
391
|
+
def _handle_list_response(cls, response: Response, security_plan_id: int) -> List[T]: # type: ignore
|
|
392
|
+
"""
|
|
393
|
+
Handle list response
|
|
394
|
+
|
|
395
|
+
:param Response response: Response from API
|
|
396
|
+
:param int security_plan_id: Security Plan ID
|
|
397
|
+
:return: List of ComponentMappings as RegScale model objects
|
|
398
|
+
:rtype: List[T]
|
|
399
|
+
"""
|
|
400
|
+
if not response or response.status_code in [204, 404]:
|
|
401
|
+
return []
|
|
402
|
+
if response.ok:
|
|
403
|
+
json_response = response.json()
|
|
404
|
+
if isinstance(json_response, dict):
|
|
405
|
+
json_response = json_response.get("items", [])
|
|
406
|
+
return cast(
|
|
407
|
+
List[T],
|
|
408
|
+
[cls(securityPlanId=security_plan_id, **o) for o in json_response],
|
|
409
|
+
)
|
|
410
|
+
else:
|
|
411
|
+
logger.error(f"Failed to get {cls.get_module_slug()} for {cls.__name__}")
|
|
412
|
+
return []
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"""This module contains the ComponentMapping model."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from typing import Optional, Dict
|
|
5
|
+
|
|
6
|
+
from pydantic import Field, ConfigDict
|
|
7
|
+
|
|
8
|
+
from regscale.core.app.utils.app_utils import get_current_datetime
|
|
9
|
+
from regscale.models.regscale_models.regscale_model import RegScaleModel
|
|
10
|
+
from regscale.models.regscale_models.mixins.parent_cache import PlanCacheMixin
|
|
11
|
+
|
|
12
|
+
logger = logging.getLogger(__name__)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ComponentMapping(RegScaleModel, PlanCacheMixin["ComponentMapping"]):
|
|
16
|
+
_module_slug = "componentmapping"
|
|
17
|
+
_parent_id_field = "securityPlanId"
|
|
18
|
+
_unique_fields = [
|
|
19
|
+
["componentId", "securityPlanId"],
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
# New class attributes
|
|
23
|
+
_graph_query_name = "componentMappings"
|
|
24
|
+
_graph_plan_id_path = "securityPlanId"
|
|
25
|
+
|
|
26
|
+
id: int = 0
|
|
27
|
+
uuid: Optional[str] = None
|
|
28
|
+
securityPlanId: int
|
|
29
|
+
componentId: int
|
|
30
|
+
createdById: str = Field(default_factory=RegScaleModel.get_user_id)
|
|
31
|
+
dateCreated: str = Field(default_factory=get_current_datetime)
|
|
32
|
+
lastUpdatedById: str = Field(default_factory=RegScaleModel.get_user_id)
|
|
33
|
+
dateLastUpdated: str = Field(default_factory=get_current_datetime)
|
|
34
|
+
tenantsId: int = 1
|
|
35
|
+
isPublic: bool = True
|
|
36
|
+
|
|
37
|
+
@staticmethod
|
|
38
|
+
def _get_additional_endpoints() -> ConfigDict:
|
|
39
|
+
"""
|
|
40
|
+
Get additional endpoints for the ComponentMapping model.
|
|
41
|
+
|
|
42
|
+
:return: A dictionary of additional endpoints
|
|
43
|
+
:rtype: ConfigDict
|
|
44
|
+
"""
|
|
45
|
+
return ConfigDict(get_all_by_parent="/api/{model_slug}/getMappingsAsComponents/{intParentID}")
|
|
46
|
+
|
|
47
|
+
@classmethod
|
|
48
|
+
def cast_list_object(
|
|
49
|
+
cls,
|
|
50
|
+
item: Dict,
|
|
51
|
+
parent_id: Optional[int] = None,
|
|
52
|
+
parent_module: Optional[str] = None,
|
|
53
|
+
) -> "ComponentMapping":
|
|
54
|
+
"""
|
|
55
|
+
Cast list of items to class instances.
|
|
56
|
+
|
|
57
|
+
:param Dict item: item to cast
|
|
58
|
+
:param Optional[int] parent_id: Parent ID, defaults to None
|
|
59
|
+
:param Optional[str] parent_module: Parent module, defaults to None
|
|
60
|
+
:return: Class instance created from the item
|
|
61
|
+
:rtype: "ComponentMapping"
|
|
62
|
+
"""
|
|
63
|
+
item["securityPlanId"] = parent_id
|
|
64
|
+
item["id"] = item["mappingId"]
|
|
65
|
+
return cls(**item)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""Model for a RegScale Security Control"""
|
|
4
|
+
|
|
5
|
+
# standard python imports
|
|
6
|
+
from typing import Optional
|
|
7
|
+
|
|
8
|
+
from regscale.models.regscale_models.regscale_model import RegScaleModel
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# from regscale.core.app.api import Api
|
|
12
|
+
# from regscale.core.app.application import Application
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Control(RegScaleModel):
|
|
16
|
+
"""RegScale Control class"""
|
|
17
|
+
|
|
18
|
+
_module_slug = "controls"
|
|
19
|
+
|
|
20
|
+
id: int = 0
|
|
21
|
+
isPublic: bool = True
|
|
22
|
+
uuid: Optional[str] = None
|
|
23
|
+
controlId: Optional[str] = None
|
|
24
|
+
sortId: Optional[str] = None
|
|
25
|
+
controlType: Optional[str] = None
|
|
26
|
+
title: Optional[str] = None
|
|
27
|
+
description: Optional[str] = None
|
|
28
|
+
references: Optional[str] = None
|
|
29
|
+
relatedControls: Optional[str] = None
|
|
30
|
+
subControls: Optional[str] = None
|
|
31
|
+
enhancements: Optional[str] = None
|
|
32
|
+
family: Optional[str] = None
|
|
33
|
+
weight: Optional[int] = None
|
|
34
|
+
catalogueID: Optional[int] = None
|
|
35
|
+
archived: bool = False
|
|
36
|
+
lastUpdatedById: Optional[str] = None
|
|
37
|
+
dateLastUpdated: Optional[str] = None
|
|
38
|
+
tenantsId: Optional[int] = None
|