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,226 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""Utility functions and classes for handling application variables"""
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
import os
|
|
7
|
+
import re
|
|
8
|
+
import sys
|
|
9
|
+
from typing import Any, Callable, Dict, Optional, Tuple, Type
|
|
10
|
+
|
|
11
|
+
logger = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class RsVariableType:
|
|
15
|
+
"""
|
|
16
|
+
Configuration variable type
|
|
17
|
+
|
|
18
|
+
:param Type var_type: The data type of the configuration variable
|
|
19
|
+
:param str example: An example value for the configuration variable
|
|
20
|
+
:param Optional[bool] required: A flag indicating if the configuration variable is required, defaults to True
|
|
21
|
+
:param Optional[bool] sensitive: A flag indicating if the configuration variable is sensitive, defaults to False
|
|
22
|
+
:param Optional[Any] default: A default value for the configuration variable, defaults to None
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
def __init__(
|
|
26
|
+
self,
|
|
27
|
+
var_type: Type,
|
|
28
|
+
example: str,
|
|
29
|
+
required: Optional[bool] = True,
|
|
30
|
+
sensitive: Optional[bool] = False,
|
|
31
|
+
default: Optional[Any] = None,
|
|
32
|
+
) -> None:
|
|
33
|
+
self.type = var_type
|
|
34
|
+
self.example = example
|
|
35
|
+
self.required = required
|
|
36
|
+
self.sensitive = sensitive
|
|
37
|
+
self.default = default
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class RsVariableClassProperty:
|
|
41
|
+
"""
|
|
42
|
+
Class property for retrieving configuration variables
|
|
43
|
+
|
|
44
|
+
:param Callable getter: The getter function for the property
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
def __init__(self, getter: Callable):
|
|
48
|
+
self.getter = getter
|
|
49
|
+
self.name = None # Will store the attribute name
|
|
50
|
+
|
|
51
|
+
def __set_name__(self, owner: Any, name: str) -> None:
|
|
52
|
+
"""
|
|
53
|
+
Sets the name of the property when it's assigned to a class
|
|
54
|
+
|
|
55
|
+
:param Any owner: The class that owns this property
|
|
56
|
+
:param str name: The name of the property
|
|
57
|
+
"""
|
|
58
|
+
self.name = name
|
|
59
|
+
|
|
60
|
+
def __get__(self, obj: Any, cls: Optional[type] = None) -> Any:
|
|
61
|
+
"""
|
|
62
|
+
Retrieves the value using the getter when the property is accessed
|
|
63
|
+
|
|
64
|
+
:param Any obj: The object instance
|
|
65
|
+
:param Optional[type] cls: The class instance, defaults to None
|
|
66
|
+
:return: The value of the property
|
|
67
|
+
:rtype: Any
|
|
68
|
+
"""
|
|
69
|
+
if obj is None:
|
|
70
|
+
# Class-level access
|
|
71
|
+
return self.getter(cls)
|
|
72
|
+
|
|
73
|
+
# Instance-level access
|
|
74
|
+
if not hasattr(obj, f"_{self.name}"):
|
|
75
|
+
# Initialize the instance-specific value
|
|
76
|
+
value = self.getter(cls)
|
|
77
|
+
setattr(obj, f"_{self.name}", value)
|
|
78
|
+
return getattr(obj, f"_{self.name}")
|
|
79
|
+
|
|
80
|
+
def __set__(self, obj: Any, value: Any) -> None:
|
|
81
|
+
"""
|
|
82
|
+
Sets the value for an instance
|
|
83
|
+
|
|
84
|
+
:param Any obj: The object instance
|
|
85
|
+
:param Any value: The value to set
|
|
86
|
+
"""
|
|
87
|
+
setattr(obj, f"_{self.name}", value)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class RsVariablesMeta(type):
|
|
91
|
+
"""
|
|
92
|
+
Metaclass for creating RsVariables classes with properties for each configuration variable.
|
|
93
|
+
|
|
94
|
+
Example::
|
|
95
|
+
|
|
96
|
+
.. code-block:: python
|
|
97
|
+
|
|
98
|
+
>>>class GcpVariables(metaclass=RsVariablesMeta):
|
|
99
|
+
>>> # Define class-level attributes with type annotations and examples
|
|
100
|
+
>>> gcpProjectId: RsVariableType(str, "000000000000")
|
|
101
|
+
>>> gcpCredentials: RsVariableType(str, "path/to/credentials.json", sensitive=True)
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
def __new__(cls, name: str, bases: Tuple[type, ...], attrs: Dict[str, Any]):
|
|
105
|
+
"""
|
|
106
|
+
Creates new RsVariables class with properties for each configuration variable
|
|
107
|
+
|
|
108
|
+
:param str name: The name of the class
|
|
109
|
+
:param Tuple[type, ...] bases: The base classes of the class
|
|
110
|
+
:param Dict[str, Any] attrs: The attributes of the class
|
|
111
|
+
:return: The new RsVariables class
|
|
112
|
+
"""
|
|
113
|
+
for attr, config_type in attrs.get("__annotations__", {}).items():
|
|
114
|
+
if isinstance(config_type, RsVariableType):
|
|
115
|
+
# Create a property for each configuration attribute
|
|
116
|
+
getter = cls.create_getter(attr, config_type)
|
|
117
|
+
attrs[attr] = RsVariableClassProperty(getter)
|
|
118
|
+
|
|
119
|
+
# Add an __init__ method to initialize instance attributes
|
|
120
|
+
def __init__(self):
|
|
121
|
+
# Initialize all properties to trigger the getters
|
|
122
|
+
for attr in self.__class__.__annotations__:
|
|
123
|
+
if isinstance(self.__class__.__annotations__[attr], RsVariableType):
|
|
124
|
+
getattr(self, attr)
|
|
125
|
+
|
|
126
|
+
attrs["__init__"] = __init__
|
|
127
|
+
return super(RsVariablesMeta, cls).__new__(cls, name, bases, attrs)
|
|
128
|
+
|
|
129
|
+
@staticmethod
|
|
130
|
+
def create_getter(attr: str, config_type: RsVariableType) -> Callable:
|
|
131
|
+
"""
|
|
132
|
+
Creates a getter function for each property
|
|
133
|
+
|
|
134
|
+
:param str attr: The name of the attribute
|
|
135
|
+
:param RsVariableType config_type: The type of the attribute
|
|
136
|
+
:return: The getter function for the attribute
|
|
137
|
+
:rtype: Callable
|
|
138
|
+
"""
|
|
139
|
+
|
|
140
|
+
def getter(cls: type) -> Any:
|
|
141
|
+
return RsVariablesMeta.fetch_config_value(attr, config_type)
|
|
142
|
+
|
|
143
|
+
return getter
|
|
144
|
+
|
|
145
|
+
@classmethod
|
|
146
|
+
def fetch_config_value(cls, attr_name: str, config_type: RsVariableType) -> Any:
|
|
147
|
+
"""
|
|
148
|
+
Fetches, processes, and returns the configuration value for a given attribute
|
|
149
|
+
|
|
150
|
+
:param str attr_name: The name of the attribute
|
|
151
|
+
:param RsVariableType config_type: The type of the attribute
|
|
152
|
+
:raises ValueError: If a required configuration is missing and the script is not running interactively
|
|
153
|
+
:return: The processed configuration value
|
|
154
|
+
:rtype: Any
|
|
155
|
+
"""
|
|
156
|
+
from regscale.core.app.application import Application
|
|
157
|
+
|
|
158
|
+
app = Application()
|
|
159
|
+
# Check Environment variable first (case-insensitive), then init.yaml
|
|
160
|
+
config_value = next((os.environ[key] for key in os.environ if key.lower() == attr_name.lower()), None)
|
|
161
|
+
if config_value is None:
|
|
162
|
+
config_value = next((value for key, value in app.config.items() if key.lower() == attr_name.lower()), "")
|
|
163
|
+
processed_value = cls.replace_text_inside_brackets(config_value)
|
|
164
|
+
if config_type.sensitive:
|
|
165
|
+
logger.debug(f"Configuration for '{attr_name}' set to: ******")
|
|
166
|
+
else:
|
|
167
|
+
logger.debug(f"Configuration for '{attr_name}' set to: {processed_value}")
|
|
168
|
+
|
|
169
|
+
if processed_value == "":
|
|
170
|
+
if config_type.required and config_type.default is None:
|
|
171
|
+
if sys.stdin.isatty():
|
|
172
|
+
prompt_message = (
|
|
173
|
+
f"\033[91mREQUIRED: {attr_name} not set in init.yaml or environment variable.\033[0m \n"
|
|
174
|
+
f"Enter value for {attr_name} (e.g., {config_type.example}):"
|
|
175
|
+
)
|
|
176
|
+
processed_value = input(prompt_message)
|
|
177
|
+
else:
|
|
178
|
+
error_message = (
|
|
179
|
+
f"Required configuration '{attr_name}' is missing and script is not running interactively."
|
|
180
|
+
)
|
|
181
|
+
logger.error(error_message)
|
|
182
|
+
raise ValueError(error_message)
|
|
183
|
+
|
|
184
|
+
if config_type.sensitive:
|
|
185
|
+
logger.info(f"Configuration for '{attr_name}' saved to init.yaml: ******")
|
|
186
|
+
else:
|
|
187
|
+
logger.info(f"Configuration for '{attr_name}' saved to init.yaml: {processed_value}")
|
|
188
|
+
# Save the config value
|
|
189
|
+
app.config[attr_name] = processed_value
|
|
190
|
+
app.save_config(app.config)
|
|
191
|
+
elif config_type.default is not None:
|
|
192
|
+
processed_value = config_type.default
|
|
193
|
+
logger.debug(f"Using default value for '{attr_name}': {processed_value}")
|
|
194
|
+
try:
|
|
195
|
+
if config_type.type == dict:
|
|
196
|
+
# Handle dictionary values - assume the input is a string representation of a dict
|
|
197
|
+
import ast
|
|
198
|
+
|
|
199
|
+
typed_value = ast.literal_eval(processed_value) if processed_value else {}
|
|
200
|
+
elif config_type.type == bool:
|
|
201
|
+
if isinstance(processed_value, str):
|
|
202
|
+
typed_value = processed_value.lower() in ["true", "1", "yes"]
|
|
203
|
+
elif isinstance(processed_value, bool):
|
|
204
|
+
typed_value = processed_value
|
|
205
|
+
else:
|
|
206
|
+
typed_value = config_type.type(processed_value)
|
|
207
|
+
except (ValueError, SyntaxError):
|
|
208
|
+
logger.error(f"Failed to cast '{attr_name}' to {config_type.type.__name__}. Using original value.")
|
|
209
|
+
typed_value = processed_value
|
|
210
|
+
return typed_value
|
|
211
|
+
|
|
212
|
+
@staticmethod
|
|
213
|
+
def replace_text_inside_brackets(text: str, replacement: str = "") -> str:
|
|
214
|
+
"""
|
|
215
|
+
Removes text inside brackets from a given string
|
|
216
|
+
|
|
217
|
+
:param str text: The string to remove text from
|
|
218
|
+
:param str replacement: The replacement text
|
|
219
|
+
:return: The string with text inside brackets removed
|
|
220
|
+
:rtype: str
|
|
221
|
+
"""
|
|
222
|
+
# if string
|
|
223
|
+
if not isinstance(text, str):
|
|
224
|
+
return text
|
|
225
|
+
pattern = "<[^>]*>"
|
|
226
|
+
return re.sub(pattern, replacement, text)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Decorators for the regscale package
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Any, Type, Dict
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def singleton(cls: Type[Any]) -> Type[Any]:
|
|
9
|
+
"""
|
|
10
|
+
Singleton decorator to ensure a class only has one instance.
|
|
11
|
+
|
|
12
|
+
:param Type[Any] cls: The class to be decorated as a singleton.
|
|
13
|
+
:return: The singleton instance of the class.
|
|
14
|
+
:rtype: Type[Any]
|
|
15
|
+
"""
|
|
16
|
+
instances: Dict[Type[Any], Any] = {}
|
|
17
|
+
|
|
18
|
+
def get_instance(*args: Any, **kwargs: Any) -> Any:
|
|
19
|
+
"""
|
|
20
|
+
Get the singleton instance of the class.
|
|
21
|
+
|
|
22
|
+
:param Any *args: Positional arguments to instantiate the class.
|
|
23
|
+
:param Any **kwargs: Keyword arguments to instantiate the class.
|
|
24
|
+
:return: The singleton instance of the class.
|
|
25
|
+
:rtype: Any
|
|
26
|
+
"""
|
|
27
|
+
if cls not in instances:
|
|
28
|
+
instances[cls] = cls(*args, **kwargs)
|
|
29
|
+
return instances[cls]
|
|
30
|
+
|
|
31
|
+
return get_instance # type: ignore
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Class to allow lazy loading of click commands
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import importlib
|
|
6
|
+
import click
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class LazyGroup(click.Group):
|
|
10
|
+
"""
|
|
11
|
+
Class to allow lazy loading of click commands
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
def __init__(self, *args, lazy_subcommands=None, **kwargs):
|
|
15
|
+
super().__init__(*args, **kwargs)
|
|
16
|
+
# lazy_subcommands is a map of the form:
|
|
17
|
+
#
|
|
18
|
+
# {command-name} -> {module-name}.{command-object-name}
|
|
19
|
+
#
|
|
20
|
+
self.lazy_subcommands = lazy_subcommands or {}
|
|
21
|
+
|
|
22
|
+
def list_commands(self, ctx) -> list:
|
|
23
|
+
"""
|
|
24
|
+
Return the list of commands
|
|
25
|
+
|
|
26
|
+
:param ctx: The click context
|
|
27
|
+
:return: The list of commands
|
|
28
|
+
:rtype: list
|
|
29
|
+
"""
|
|
30
|
+
base = super().list_commands(ctx)
|
|
31
|
+
lazy = sorted(self.lazy_subcommands.keys())
|
|
32
|
+
return base + lazy
|
|
33
|
+
|
|
34
|
+
def get_command(self, ctx, cmd_name) -> click.BaseCommand:
|
|
35
|
+
"""
|
|
36
|
+
Get the command from the context
|
|
37
|
+
|
|
38
|
+
:param ctx: The click context
|
|
39
|
+
:param cmd_name: The command name
|
|
40
|
+
:return: The command
|
|
41
|
+
:rtype: click.BaseCommand
|
|
42
|
+
"""
|
|
43
|
+
if cmd_name in self.lazy_subcommands:
|
|
44
|
+
return self._lazy_load(cmd_name)
|
|
45
|
+
return super().get_command(ctx, cmd_name)
|
|
46
|
+
|
|
47
|
+
def _lazy_load(self, cmd_name) -> click.BaseCommand:
|
|
48
|
+
"""
|
|
49
|
+
Lazy load the command
|
|
50
|
+
|
|
51
|
+
:param cmd_name: The command name
|
|
52
|
+
:return: The command
|
|
53
|
+
:rtype: click.BaseCommand
|
|
54
|
+
"""
|
|
55
|
+
# lazily loading a command, first get the module name and attribute name
|
|
56
|
+
import_path = self.lazy_subcommands[cmd_name]
|
|
57
|
+
modname, cmd_object_name = import_path.rsplit(".", 1)
|
|
58
|
+
# do the import
|
|
59
|
+
mod = importlib.import_module(modname)
|
|
60
|
+
# get the Command object from that module
|
|
61
|
+
cmd_object = getattr(mod, cmd_object_name)
|
|
62
|
+
# check the result to make debugging easier
|
|
63
|
+
if not isinstance(cmd_object, click.BaseCommand):
|
|
64
|
+
raise ValueError(f"Lazy loading of {import_path} failed by returning " "a non-command object")
|
|
65
|
+
return cmd_object
|
regscale/core/login.py
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"""Provide low-level, basic login."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import logging
|
|
5
|
+
from os import getenv
|
|
6
|
+
from typing import Optional, Tuple
|
|
7
|
+
from urllib.parse import urljoin
|
|
8
|
+
|
|
9
|
+
from regscale.core.app.api import Api
|
|
10
|
+
from regscale.core.app.utils.app_utils import error_and_exit
|
|
11
|
+
|
|
12
|
+
logger = logging.getLogger("regscale")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def get_regscale_token(
|
|
16
|
+
api: Api,
|
|
17
|
+
username: str = getenv("REGSCALE_USER"),
|
|
18
|
+
password: str = getenv("REGSCALE_PASSWORD"),
|
|
19
|
+
domain: str = getenv("REGSCALE_DOMAIN"),
|
|
20
|
+
mfa_token: Optional[str] = "",
|
|
21
|
+
) -> Tuple[str, str]:
|
|
22
|
+
"""
|
|
23
|
+
Authenticate with RegScale and return a token
|
|
24
|
+
|
|
25
|
+
:param Api api: API Object to use for authentication
|
|
26
|
+
:param str username: a string defaulting to the envar REGSCALE_USERNAME
|
|
27
|
+
:param str password: a string defaulting to the envar REGSCALE_PASSWORD
|
|
28
|
+
:param str domain: a string representing the RegScale domain, checks environment REGSCALE_DOMAIN
|
|
29
|
+
:param Optional[str] mfa_token: MFA token to login with
|
|
30
|
+
:raises EnvironmentError: if domain is not passed or retrieved
|
|
31
|
+
:return: a tuple of user_id and auth_token
|
|
32
|
+
:rtype: Tuple[str, str]
|
|
33
|
+
"""
|
|
34
|
+
if domain is None:
|
|
35
|
+
raise EnvironmentError("REGSCALE_DOMAIN must be set if not passed as parameter.")
|
|
36
|
+
if username is None:
|
|
37
|
+
raise EnvironmentError("REGSCALE_USERNAME must be set if not passed as parameter.")
|
|
38
|
+
if password is None:
|
|
39
|
+
raise EnvironmentError("REGSCALE_PASSWORD must be set if not passed as parameter.")
|
|
40
|
+
|
|
41
|
+
auth = { # TODO - HTTP Basic Auth an minimum
|
|
42
|
+
"userName": username,
|
|
43
|
+
"password": password,
|
|
44
|
+
"oldPassword": "",
|
|
45
|
+
"mfaToken": mfa_token,
|
|
46
|
+
}
|
|
47
|
+
logger.info("Logging into: %s", domain)
|
|
48
|
+
# suggest structuring the login paths so that they all exist in one place
|
|
49
|
+
url = urljoin(domain, "/api/authentication/login")
|
|
50
|
+
response = api.post(url=url, json=auth, headers={})
|
|
51
|
+
error_msg = "Unable to authenticate with RegScale. Please check your credentials."
|
|
52
|
+
logger.info(response.url)
|
|
53
|
+
if response.status_code == 200:
|
|
54
|
+
response_dict = response.json()
|
|
55
|
+
elif response.status_code == 403:
|
|
56
|
+
error_and_exit(error_msg)
|
|
57
|
+
elif response.status_code == 400 and mfa_token == "":
|
|
58
|
+
error_and_exit(error_msg[:-1] + " and/or if an MFA token is required.")
|
|
59
|
+
else:
|
|
60
|
+
error_and_exit(f"{error_msg}\n{response.status_code}: {response.text}")
|
|
61
|
+
if isinstance(response_dict, str):
|
|
62
|
+
response_dict = json.loads(response_dict)
|
|
63
|
+
return response_dict["id"], response_dict["auth_token"]
|
|
File without changes
|