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,169 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module contains the Group model class that represents a group in the RegScale application.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
from typing import Optional, List, Tuple, cast
|
|
7
|
+
|
|
8
|
+
from pydantic import ConfigDict, Field
|
|
9
|
+
|
|
10
|
+
from regscale.core.app.utils.app_utils import get_current_datetime
|
|
11
|
+
from regscale.models import RegScaleModel, User, T, deprecated
|
|
12
|
+
from regscale.models.regscale_models.user_group import UserGroup
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Group(RegScaleModel):
|
|
18
|
+
_module_slug = "groups"
|
|
19
|
+
|
|
20
|
+
id: Optional[int] = None
|
|
21
|
+
name: Optional[str] = None
|
|
22
|
+
userGroups: Optional[List[UserGroup]] = None
|
|
23
|
+
activated: Optional[bool] = True
|
|
24
|
+
createdById: Optional[str] = Field(default_factory=RegScaleModel.get_user_id)
|
|
25
|
+
dateCreated: Optional[str] = Field(default_factory=get_current_datetime)
|
|
26
|
+
lastUpdatedById: Optional[str] = Field(default_factory=RegScaleModel.get_user_id)
|
|
27
|
+
isPublic: Optional[bool] = True
|
|
28
|
+
dateLastUpdated: Optional[str] = Field(default_factory=get_current_datetime)
|
|
29
|
+
tenantsId: Optional[int] = 1
|
|
30
|
+
|
|
31
|
+
@staticmethod
|
|
32
|
+
def _get_additional_endpoints() -> ConfigDict:
|
|
33
|
+
"""
|
|
34
|
+
Get additional endpoints for the Group model.
|
|
35
|
+
|
|
36
|
+
:return: A dictionary of additional endpoints
|
|
37
|
+
:rtype: ConfigDict
|
|
38
|
+
"""
|
|
39
|
+
return ConfigDict(
|
|
40
|
+
get_groups="/api/{model_slug}",
|
|
41
|
+
change_group_status="/api/{model_slug}/changeGroupStatus/{id}/{strActivated}",
|
|
42
|
+
find_groups_by_user="/api/{model_slug}/findGroupsByUser/{strUser}",
|
|
43
|
+
filter_groups="/api/{model_slug}/filterGroups/{strName}/{strActivated}/{strSortBy}/{strDirection}/{intPage}/{intPageSize}",
|
|
44
|
+
find_users_by_group="/api/{model_slug}/findUsersByGroup/{intGroupId}",
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
@classmethod
|
|
48
|
+
@deprecated("Use UserGroup.get_users_by_group instead")
|
|
49
|
+
def get_users_in_group(cls, name: str) -> Tuple[List[User], int]:
|
|
50
|
+
"""
|
|
51
|
+
Get a list of users in a group.
|
|
52
|
+
|
|
53
|
+
:param str name: The name of the group
|
|
54
|
+
:return: A list of users
|
|
55
|
+
:rtype: Tuple[List[User], int]
|
|
56
|
+
"""
|
|
57
|
+
group_list_resp = cls._get_api_handler().get(
|
|
58
|
+
endpoint=cls.get_endpoint("get_groups").format(model_slug=cls._module_slug)
|
|
59
|
+
)
|
|
60
|
+
group_id = 0
|
|
61
|
+
if group_list_resp and group_list_resp.ok:
|
|
62
|
+
group_list = group_list_resp.json()
|
|
63
|
+
for group in group_list:
|
|
64
|
+
if group.get("name") == name:
|
|
65
|
+
group_id = group.get("id")
|
|
66
|
+
break
|
|
67
|
+
|
|
68
|
+
response = cls._get_api_handler().get(
|
|
69
|
+
endpoint=cls.get_endpoint("find_users_by_group").format(model_slug=cls._module_slug, intGroupId=group_id)
|
|
70
|
+
)
|
|
71
|
+
if response and response.ok:
|
|
72
|
+
users = [User(**user) for user in response.json()]
|
|
73
|
+
for user in users:
|
|
74
|
+
# add delegates to users list
|
|
75
|
+
users.extend(user.get_delegates(user.id))
|
|
76
|
+
return users, group_id
|
|
77
|
+
else:
|
|
78
|
+
logger.error(f"Failed to get users in group {name}")
|
|
79
|
+
return [], group_id
|
|
80
|
+
|
|
81
|
+
@classmethod
|
|
82
|
+
def get_group_by_name(cls, name: str) -> Optional["Group"]:
|
|
83
|
+
"""
|
|
84
|
+
Get a group by name
|
|
85
|
+
:param name: The name of the group
|
|
86
|
+
:return: The group
|
|
87
|
+
:rtype: Optional[Group]
|
|
88
|
+
"""
|
|
89
|
+
response = cls._get_api_handler().get(
|
|
90
|
+
endpoint=cls.get_endpoint("get_groups").format(model_slug=cls._module_slug)
|
|
91
|
+
)
|
|
92
|
+
if response and response.ok:
|
|
93
|
+
group_list = response.json()
|
|
94
|
+
for group in group_list:
|
|
95
|
+
if group.get("name") == name:
|
|
96
|
+
return cls(**group)
|
|
97
|
+
else:
|
|
98
|
+
cls.log_response_error(response=response)
|
|
99
|
+
return None
|
|
100
|
+
|
|
101
|
+
@classmethod
|
|
102
|
+
def get_group_list(cls) -> List["Group"]:
|
|
103
|
+
"""
|
|
104
|
+
Get a list of groups
|
|
105
|
+
:return: A list of groups
|
|
106
|
+
:rtype: List[Group]
|
|
107
|
+
"""
|
|
108
|
+
response = cls._get_api_handler().get(
|
|
109
|
+
endpoint=cls.get_endpoint("get_groups").format(model_slug=cls._module_slug)
|
|
110
|
+
)
|
|
111
|
+
return cast(List[T], cls._handle_list_response(response))
|
|
112
|
+
|
|
113
|
+
@classmethod
|
|
114
|
+
def find_groups_by_user(cls, user: str) -> List["Group"]:
|
|
115
|
+
"""
|
|
116
|
+
Find groups by user
|
|
117
|
+
:param user: The user ID
|
|
118
|
+
:return: A list of groups
|
|
119
|
+
:rtype: List[Group]
|
|
120
|
+
"""
|
|
121
|
+
response = cls._get_api_handler().get(
|
|
122
|
+
endpoint=cls.get_endpoint("find_groups_by_user").format(model_slug=cls._module_slug, strUser=user)
|
|
123
|
+
)
|
|
124
|
+
return cast(List[T], cls._handle_list_response(response))
|
|
125
|
+
|
|
126
|
+
@classmethod
|
|
127
|
+
def filter_groups(
|
|
128
|
+
cls, name: str, activated: str, sort_by: str, direction: str, page: int, page_size: int
|
|
129
|
+
) -> List["Group"]:
|
|
130
|
+
"""
|
|
131
|
+
Filter groups
|
|
132
|
+
:param name: The name of the group
|
|
133
|
+
:param activated: The activation status
|
|
134
|
+
:param sort_by: The field to sort by
|
|
135
|
+
:param direction: The sort direction
|
|
136
|
+
:param page: The page number
|
|
137
|
+
:param page_size: The page size
|
|
138
|
+
:return: A list of groups
|
|
139
|
+
:rtype: List[Group]
|
|
140
|
+
"""
|
|
141
|
+
response = cls._get_api_handler().get(
|
|
142
|
+
endpoint=cls.get_endpoint("filter_groups").format(
|
|
143
|
+
model_slug=cls._module_slug,
|
|
144
|
+
strName=name,
|
|
145
|
+
strActivated=activated,
|
|
146
|
+
strSortBy=sort_by,
|
|
147
|
+
strDirection=direction,
|
|
148
|
+
intPage=page,
|
|
149
|
+
intPageSize=page_size,
|
|
150
|
+
)
|
|
151
|
+
)
|
|
152
|
+
return cast(List[T], cls._handle_list_response(response))
|
|
153
|
+
|
|
154
|
+
@classmethod
|
|
155
|
+
def find_users_by_group(cls, group_id: int) -> List[User]:
|
|
156
|
+
"""
|
|
157
|
+
Find users by group
|
|
158
|
+
:param group_id: The group ID
|
|
159
|
+
:return: A list of users
|
|
160
|
+
:rtype: List[User]
|
|
161
|
+
"""
|
|
162
|
+
response = cls._get_api_handler().get(
|
|
163
|
+
endpoint=cls.get_endpoint("find_users_by_group").format(model_slug=cls._module_slug, intGroupId=group_id)
|
|
164
|
+
)
|
|
165
|
+
if response and response.ok:
|
|
166
|
+
return [User(**o) for o in response.json()]
|
|
167
|
+
else:
|
|
168
|
+
cls.log_response_error(response=response)
|
|
169
|
+
return []
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""Dataclass for Implementation Objective in the application"""
|
|
4
|
+
import logging
|
|
5
|
+
import uuid
|
|
6
|
+
from dataclasses import asdict
|
|
7
|
+
from enum import Enum
|
|
8
|
+
from logging import Logger
|
|
9
|
+
from typing import Any, Optional, Union, Dict
|
|
10
|
+
|
|
11
|
+
import requests
|
|
12
|
+
from pydantic import Field, ConfigDict
|
|
13
|
+
from requests import Response
|
|
14
|
+
|
|
15
|
+
from regscale.core.app.api import Api
|
|
16
|
+
from regscale.core.app.application import Application
|
|
17
|
+
from regscale.core.app.logz import create_logger
|
|
18
|
+
from regscale.core.app.utils.app_utils import get_current_datetime
|
|
19
|
+
from regscale.models.regscale_models.regscale_model import RegScaleModel
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
logger = logging.getLogger("regscale")
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class ImplementationStatus(str, Enum):
|
|
26
|
+
"""
|
|
27
|
+
Implementation Status
|
|
28
|
+
:param Enum: Enum
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
FULLY_IMPLEMENTED = "Fully Implemented"
|
|
32
|
+
PARTIALLY_IMPLEMENTED = "Partially Implemented"
|
|
33
|
+
NOT_IMPLEMENTED = "Not Implemented"
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class ImplementationObjectiveResponsibility(str, Enum):
|
|
37
|
+
"""
|
|
38
|
+
Responsibility Enum
|
|
39
|
+
:param Enum: Enum
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
PROVIDER = "Provider"
|
|
43
|
+
PROVIDER_SYSTEM_SPECIFIC = "Provider (System Specific)"
|
|
44
|
+
HYBRID = "Hybrid"
|
|
45
|
+
CUSTOMER = "Customer"
|
|
46
|
+
CUSTOMER_CONFIGURED = "Customer Configured"
|
|
47
|
+
SHARED = "Shared"
|
|
48
|
+
INHERITED = "Inherited"
|
|
49
|
+
NOT_APPLICABLE = "Not Applicable"
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class ImplementationObjective(RegScaleModel):
|
|
53
|
+
"""
|
|
54
|
+
RegScale Implementation Objective
|
|
55
|
+
Represents a row in the ImplementationObjectives table in the database.
|
|
56
|
+
|
|
57
|
+
Relationships:
|
|
58
|
+
- ImplementationId -> ControlImplementation (1:1)
|
|
59
|
+
- ObjectiveId -> ControlObjective (0..1:1) [optional]
|
|
60
|
+
- OptionId -> ImplementationOption (1:1)
|
|
61
|
+
- SecurityControlId -> SecurityControls (0..1:1) [optional]
|
|
62
|
+
- CreatedBy, LastUpdatedBy -> AspNetUsers (1:1) [FKs]
|
|
63
|
+
- TenantsId -> Tenants (1:1) [inherited]
|
|
64
|
+
- AuthorizationId -> LeveragedAuthorizations (0..1:1) [optional]
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
_module_slug = "implementationObjectives"
|
|
68
|
+
_get_objects_for_list = True # TODO: Fix API to return securityControlId
|
|
69
|
+
_unique_fields = [
|
|
70
|
+
["implementationId", "objectiveId"],
|
|
71
|
+
]
|
|
72
|
+
_parent_id_field = "implementationId"
|
|
73
|
+
|
|
74
|
+
id: int = 0
|
|
75
|
+
securityControlId: int
|
|
76
|
+
uuid: str = Field(default_factory=lambda: str(uuid.uuid4())) # Required
|
|
77
|
+
notes: Optional[str] = None
|
|
78
|
+
implementationId: int # Required, FK to ControlImplementation
|
|
79
|
+
optionId: Optional[int] = None # no longer Required, FK to ImplementationOption
|
|
80
|
+
inherited: Optional[bool] = False
|
|
81
|
+
status: Optional[Union[str, ImplementationStatus]] = ImplementationStatus.NOT_IMPLEMENTED # Not Required
|
|
82
|
+
objectiveId: Optional[int] = None # Optional, FK to ControlObjective
|
|
83
|
+
createdById: Optional[str] = Field(default_factory=RegScaleModel.get_user_id)
|
|
84
|
+
lastUpdatedById: Optional[str] = Field(default_factory=RegScaleModel.get_user_id)
|
|
85
|
+
# statement Should be required, represents the implementation statement
|
|
86
|
+
statement: Optional[str] = None
|
|
87
|
+
dateLastAssessed: str = Field(default_factory=get_current_datetime) # Required
|
|
88
|
+
dateCreated: str = Field(default_factory=get_current_datetime) # Required
|
|
89
|
+
dateLastUpdated: str = Field(default_factory=get_current_datetime) # Required
|
|
90
|
+
isPublic: bool = True # Required
|
|
91
|
+
parentObjectiveId: Optional[int] = None
|
|
92
|
+
authorizationId: Optional[int] = None
|
|
93
|
+
responsibility: Optional[str] = None
|
|
94
|
+
cloudResponsibility: Optional[str] = None
|
|
95
|
+
customerResponsibility: Optional[str] = None
|
|
96
|
+
|
|
97
|
+
def __init__(self, **data: Any):
|
|
98
|
+
# returned by bad api values for securityControlId corrected with validator
|
|
99
|
+
# Map 'controlId' to 'securityControlId' internally
|
|
100
|
+
if "controlId" in data:
|
|
101
|
+
data["securityControlId"] = data.pop("controlId")
|
|
102
|
+
super().__init__(**data)
|
|
103
|
+
|
|
104
|
+
@staticmethod
|
|
105
|
+
def _get_additional_endpoints() -> ConfigDict:
|
|
106
|
+
"""
|
|
107
|
+
Get additional endpoints for the ImplementationObjectives model, using {model_slug} as a placeholder for the model slug.
|
|
108
|
+
|
|
109
|
+
:return: Additional endpoints for the ImplementationObjective
|
|
110
|
+
:rtype: ConfigDict
|
|
111
|
+
"""
|
|
112
|
+
return ConfigDict( # type: ignore
|
|
113
|
+
get_all_by_parent="/api/{model_slug}/getByControl/{intParentID}",
|
|
114
|
+
get_by_control="/api/{model_slug}/getByControl/{intControl}",
|
|
115
|
+
get_assessment="/api/{model_slug}/getAssessment/{intControl}/{intObjective}",
|
|
116
|
+
batch_create="/api/{model_slug}/batchCreate",
|
|
117
|
+
merge="/api/{model_slug}/merge/{implementationID}/{securityControlID}",
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
@classmethod
|
|
121
|
+
def merge_objectives(cls, implementationId: int, securityControlId: int) -> Dict:
|
|
122
|
+
"""
|
|
123
|
+
Merge objectives for a given implementation and security control
|
|
124
|
+
|
|
125
|
+
:param int implementationId: Implementation ID
|
|
126
|
+
:param int securityControlId: Security Control ID
|
|
127
|
+
:return: Merged objectives
|
|
128
|
+
:rtype: Dict
|
|
129
|
+
"""
|
|
130
|
+
|
|
131
|
+
response = cls._get_api_handler().get(
|
|
132
|
+
endpoint=cls.get_endpoint("merge").format(
|
|
133
|
+
implementationID=implementationId, securityControlID=securityControlId
|
|
134
|
+
)
|
|
135
|
+
)
|
|
136
|
+
if response and response.ok:
|
|
137
|
+
return response.json()
|
|
138
|
+
|
|
139
|
+
# pydantic provides __eq__ method
|
|
140
|
+
def __eq__(self, other: "ImplementationObjective") -> bool:
|
|
141
|
+
"""
|
|
142
|
+
Check if two ImplementationObjective objects are equal
|
|
143
|
+
|
|
144
|
+
:param ImplementationObjective other: ImplementationObjective object to compare to
|
|
145
|
+
:return: True if equal, False if not equal
|
|
146
|
+
:rtype: bool
|
|
147
|
+
"""
|
|
148
|
+
if isinstance(other, ImplementationObjective):
|
|
149
|
+
return (
|
|
150
|
+
getattr(self, "notes", None) == getattr(other, "notes", None)
|
|
151
|
+
and getattr(self, "implementationId", None) == getattr(other, "implementationId", None)
|
|
152
|
+
and getattr(self, "objectiveId", None) == getattr(other, "objectiveId", None)
|
|
153
|
+
and getattr(self, "optionId", None) == getattr(other, "optionId", None)
|
|
154
|
+
and getattr(self, "statement", None) == getattr(other, "statement", None)
|
|
155
|
+
)
|
|
156
|
+
return False
|
|
157
|
+
|
|
158
|
+
def __hash__(self) -> hash:
|
|
159
|
+
"""
|
|
160
|
+
Hash a ImplementationObjective object
|
|
161
|
+
|
|
162
|
+
:return: Hash of ImplementationObjective object
|
|
163
|
+
:rtype: hash
|
|
164
|
+
"""
|
|
165
|
+
return hash((self.implementationId, self.objectiveId))
|
|
166
|
+
|
|
167
|
+
@classmethod
|
|
168
|
+
def get_by_control(
|
|
169
|
+
cls,
|
|
170
|
+
implementation_id: int,
|
|
171
|
+
) -> list["ImplementationObjective"]:
|
|
172
|
+
"""
|
|
173
|
+
Get a list of implementation options by control id and security plan id
|
|
174
|
+
|
|
175
|
+
:param int implementation_id: Implementation Control ID
|
|
176
|
+
:return: A list of implementation options
|
|
177
|
+
:rtype: list[ImplementationObjective]
|
|
178
|
+
"""
|
|
179
|
+
response = cls._get_api_handler().get(
|
|
180
|
+
endpoint=cls.get_endpoint("get_by_control").format(intControl=implementation_id),
|
|
181
|
+
)
|
|
182
|
+
if response and response.ok:
|
|
183
|
+
return [cls(**obj) for obj in response.json()]
|
|
184
|
+
return []
|
|
185
|
+
|
|
186
|
+
@property
|
|
187
|
+
def logger(self) -> Logger:
|
|
188
|
+
"""
|
|
189
|
+
Logger implementation for a dataclass
|
|
190
|
+
|
|
191
|
+
:return: logger object
|
|
192
|
+
:rtype: Logger
|
|
193
|
+
"""
|
|
194
|
+
logger = create_logger()
|
|
195
|
+
return logger
|
|
196
|
+
|
|
197
|
+
@staticmethod
|
|
198
|
+
def fetch_by_security_control(
|
|
199
|
+
app: Application,
|
|
200
|
+
security_control_id: int,
|
|
201
|
+
) -> list["ImplementationObjective"]:
|
|
202
|
+
"""
|
|
203
|
+
Fetch list of all implementation objectives in RegScale via API
|
|
204
|
+
|
|
205
|
+
:param Application app: Application Instance
|
|
206
|
+
:param int security_control_id: Security Control ID # in RegScale
|
|
207
|
+
:return: List of security controls from RegScale
|
|
208
|
+
:rtype: list[ImplementationObjective]
|
|
209
|
+
"""
|
|
210
|
+
api = Api()
|
|
211
|
+
logger = create_logger()
|
|
212
|
+
query = """
|
|
213
|
+
query {
|
|
214
|
+
implementationObjectives (
|
|
215
|
+
take: 50,
|
|
216
|
+
skip: 0,
|
|
217
|
+
where: { securityControlId: {eq: placeholder }, })
|
|
218
|
+
{
|
|
219
|
+
items {
|
|
220
|
+
id,
|
|
221
|
+
uuid,
|
|
222
|
+
notes,
|
|
223
|
+
optionId,
|
|
224
|
+
implementationId,
|
|
225
|
+
securityControlId,
|
|
226
|
+
objectiveId,
|
|
227
|
+
status
|
|
228
|
+
}
|
|
229
|
+
totalCount
|
|
230
|
+
pageInfo {
|
|
231
|
+
hasNextPage
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
""".replace(
|
|
236
|
+
"placeholder", str(security_control_id)
|
|
237
|
+
)
|
|
238
|
+
results = []
|
|
239
|
+
data = api.graph(query=query)
|
|
240
|
+
if "implementationObjectives" in data.keys():
|
|
241
|
+
try:
|
|
242
|
+
results.extend(data["implementationObjectives"]["items"])
|
|
243
|
+
except requests.exceptions.JSONDecodeError:
|
|
244
|
+
logger.warning(
|
|
245
|
+
"Unable to find control implementation objectives for control %i.",
|
|
246
|
+
security_control_id,
|
|
247
|
+
)
|
|
248
|
+
return [ImplementationObjective(**obj) for obj in results]
|
|
249
|
+
|
|
250
|
+
@staticmethod
|
|
251
|
+
def update_objective(
|
|
252
|
+
app: Application,
|
|
253
|
+
obj: Any,
|
|
254
|
+
) -> Response:
|
|
255
|
+
"""
|
|
256
|
+
Update a single implementation objective
|
|
257
|
+
|
|
258
|
+
:param Application app: Application Instance
|
|
259
|
+
:param Any obj: Implementation Objective
|
|
260
|
+
:return: Response from RegScale API
|
|
261
|
+
:rtype: Response
|
|
262
|
+
"""
|
|
263
|
+
if isinstance(obj, ImplementationObjective):
|
|
264
|
+
obj = asdict(obj)
|
|
265
|
+
api = Api(retry=10)
|
|
266
|
+
return api.put(
|
|
267
|
+
url=app.config["domain"] + f"/api/implementationObjectives/{obj['id']}",
|
|
268
|
+
json=obj,
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
@staticmethod
|
|
272
|
+
def insert_objective(
|
|
273
|
+
app: Application,
|
|
274
|
+
obj: Any,
|
|
275
|
+
) -> Response:
|
|
276
|
+
"""
|
|
277
|
+
Update a single implementation objective
|
|
278
|
+
|
|
279
|
+
:param Application app: Application Instance
|
|
280
|
+
:param Any obj: Implementation Objective
|
|
281
|
+
:return: Response from RegScale API
|
|
282
|
+
:rtype: Response
|
|
283
|
+
"""
|
|
284
|
+
if isinstance(obj, ImplementationObjective):
|
|
285
|
+
obj = asdict(obj)
|
|
286
|
+
api = Api(retry=10)
|
|
287
|
+
res = api.post(url=app.config["domain"] + "/api/implementationObjectives", json=obj)
|
|
288
|
+
return res
|
|
289
|
+
|
|
290
|
+
@classmethod
|
|
291
|
+
def fetch_implementation_objectives(
|
|
292
|
+
cls, app: Application, control_id: int, query_type: Optional[str] = "implementation"
|
|
293
|
+
) -> list[dict]:
|
|
294
|
+
"""
|
|
295
|
+
Fetch list of implementation objectives by control id
|
|
296
|
+
|
|
297
|
+
:param Application app: Application Instance
|
|
298
|
+
:param int control_id: Implementation Control ID
|
|
299
|
+
:param Optional[str] query_type: Query Type for GraphQL query
|
|
300
|
+
:return: A list of Implementation Objectives as a dictionary
|
|
301
|
+
:rtype: list[dict]
|
|
302
|
+
"""
|
|
303
|
+
graph_query = """
|
|
304
|
+
query {
|
|
305
|
+
implementationObjectives (skip: 0, take: 50, where: {securityControlId: {eq: placeholder}}) {
|
|
306
|
+
items {
|
|
307
|
+
id
|
|
308
|
+
notes
|
|
309
|
+
optionId
|
|
310
|
+
objectiveId
|
|
311
|
+
implementationId
|
|
312
|
+
securityControlId
|
|
313
|
+
status
|
|
314
|
+
}
|
|
315
|
+
totalCount
|
|
316
|
+
pageInfo {
|
|
317
|
+
hasNextPage
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
""".replace(
|
|
322
|
+
"placeholder", str(control_id)
|
|
323
|
+
)
|
|
324
|
+
results: list[Any] = []
|
|
325
|
+
api = Api()
|
|
326
|
+
if query_type != "implementation":
|
|
327
|
+
results = cls._get_api_handler().graph(graph_query)
|
|
328
|
+
else:
|
|
329
|
+
res = api.get(url=app.config["domain"] + f"/api/implementationObjectives/getByControl/{control_id}")
|
|
330
|
+
if res.ok:
|
|
331
|
+
try:
|
|
332
|
+
results = res.json()
|
|
333
|
+
except requests.exceptions.JSONDecodeError:
|
|
334
|
+
logger.warning("Unable to find control implementation objectives.")
|
|
335
|
+
return results
|