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,163 @@
|
|
|
1
|
+
from random import randint, random
|
|
2
|
+
from unittest.mock import Mock
|
|
3
|
+
|
|
4
|
+
import pytest
|
|
5
|
+
|
|
6
|
+
from regscale.integrations.integration_override import IntegrationOverride
|
|
7
|
+
from regscale.models.integration_models.tenable_models.models import Family, Repository, Severity, TenableAsset
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@pytest.fixture
|
|
11
|
+
def random_local_ip():
|
|
12
|
+
"""
|
|
13
|
+
Returns a random local ip address
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
# ip
|
|
17
|
+
return f"192.168.{randint(0, 255)}.{randint(0, 255)}"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@pytest.fixture
|
|
21
|
+
def tenable_asset(random_local_ip):
|
|
22
|
+
return TenableAsset(
|
|
23
|
+
pluginID="1234",
|
|
24
|
+
severity=Severity(id="high", name="High", description="High"),
|
|
25
|
+
hasBeenMitigated="false",
|
|
26
|
+
acceptRisk="false",
|
|
27
|
+
recastRisk="false",
|
|
28
|
+
ip=random_local_ip,
|
|
29
|
+
uuid="test-uuid",
|
|
30
|
+
port="80",
|
|
31
|
+
protocol="tcp",
|
|
32
|
+
pluginName="Test Plugin",
|
|
33
|
+
firstSeen="2024-01-01",
|
|
34
|
+
lastSeen="2024-01-02",
|
|
35
|
+
exploitAvailable="true",
|
|
36
|
+
exploitEase="easy",
|
|
37
|
+
exploitFrameworks="test",
|
|
38
|
+
synopsis="test",
|
|
39
|
+
description="test",
|
|
40
|
+
solution="test",
|
|
41
|
+
seeAlso="test",
|
|
42
|
+
riskFactor="High",
|
|
43
|
+
stigSeverity="High",
|
|
44
|
+
vprScore="9.0",
|
|
45
|
+
vprContext="test",
|
|
46
|
+
baseScore="9.0",
|
|
47
|
+
temporalScore="9.0",
|
|
48
|
+
cvssVector="test",
|
|
49
|
+
cvssV3BaseScore="9.0",
|
|
50
|
+
cvssV3TemporalScore="9.0",
|
|
51
|
+
cvssV3Vector="test",
|
|
52
|
+
cpe="test",
|
|
53
|
+
vulnPubDate="2024-01-01",
|
|
54
|
+
patchPubDate="2024-01-01",
|
|
55
|
+
pluginPubDate="2024-01-01",
|
|
56
|
+
pluginModDate="2024-01-01",
|
|
57
|
+
checkType="test",
|
|
58
|
+
version="1.0",
|
|
59
|
+
cve="CVE-2024-1234",
|
|
60
|
+
bid="1234",
|
|
61
|
+
xref="test",
|
|
62
|
+
pluginText="test",
|
|
63
|
+
dnsName="test.example.com",
|
|
64
|
+
macAddress="00:11:22:33:44:55",
|
|
65
|
+
netbiosName="TEST",
|
|
66
|
+
operatingSystem="Linux",
|
|
67
|
+
ips=random_local_ip,
|
|
68
|
+
recastRiskRuleComment="test",
|
|
69
|
+
acceptRiskRuleComment="test",
|
|
70
|
+
hostUniqueness="test",
|
|
71
|
+
acrScore="9.0",
|
|
72
|
+
keyDrivers="test",
|
|
73
|
+
uniqueness="test",
|
|
74
|
+
family=Family(id="1", name="Test Family", type="Test Type"),
|
|
75
|
+
repository=Repository(id="rep", name="Test", description="Test", dataFormat="Test"),
|
|
76
|
+
pluginInfo="test",
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def test_field_map_validation_with_dict(tenable_asset, random_local_ip):
|
|
81
|
+
app = Mock()
|
|
82
|
+
app.config = {"uniqueOverride": {"asset": ["ipAddress"]}}
|
|
83
|
+
override = IntegrationOverride(app)
|
|
84
|
+
|
|
85
|
+
dict_cases = [
|
|
86
|
+
({"ipv4": random_local_ip}, random_local_ip),
|
|
87
|
+
({}, None),
|
|
88
|
+
({"ipv4": None}, None),
|
|
89
|
+
({"other_field": "value"}, None),
|
|
90
|
+
]
|
|
91
|
+
|
|
92
|
+
for test_input, expected in dict_cases:
|
|
93
|
+
assert override.field_map_validation(test_input, "asset") == expected
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def test_field_map_validation_with_tenable_asset(tenable_asset, random_local_ip):
|
|
97
|
+
app = Mock()
|
|
98
|
+
app.config = {"uniqueOverride": {"asset": ["ipAddress"]}}
|
|
99
|
+
override = IntegrationOverride(app)
|
|
100
|
+
|
|
101
|
+
assert override.field_map_validation(tenable_asset, "asset") == random_local_ip
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def test_field_map_validation_with_multiple_fields(random_local_ip):
|
|
105
|
+
app = Mock()
|
|
106
|
+
app.config = {"uniqueOverride": {"asset": ["ipAddress", "macAddress", "hostname"]}}
|
|
107
|
+
override = IntegrationOverride(app)
|
|
108
|
+
dict_obj = {"ipv4": random_local_ip, "mac": "00:11:22:33:44:55", "hostname": "test.example.com"}
|
|
109
|
+
assert override.field_map_validation(dict_obj, "asset") == random_local_ip
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def test_field_map_validation_with_empty_and_invalid_configs(random_local_ip):
|
|
113
|
+
app = Mock()
|
|
114
|
+
dict_obj = {"ipv4": random_local_ip, "mac": "00:11:22:33:44:55", "hostname": "test.example.com"}
|
|
115
|
+
|
|
116
|
+
# Invalid configs here
|
|
117
|
+
config_cases = [
|
|
118
|
+
({}, None),
|
|
119
|
+
({"uniqueOverride": {}}, None),
|
|
120
|
+
({"uniqueOverride": {"asset": []}}, None),
|
|
121
|
+
({"uniqueOverride": None}, None),
|
|
122
|
+
({"uniqueOverride": {"issue": ["title"]}}, None), # issue is not supported yet ..
|
|
123
|
+
({"uniqueOverride": {"invalid_type": ["ipAddress"]}}, None),
|
|
124
|
+
({"uniqueOverride": {"asset": [None]}}, None),
|
|
125
|
+
]
|
|
126
|
+
|
|
127
|
+
for config, expected in config_cases:
|
|
128
|
+
app.config = config
|
|
129
|
+
override = IntegrationOverride(app)
|
|
130
|
+
try:
|
|
131
|
+
key = next(iter(config.get("uniqueOverride", {})), None)
|
|
132
|
+
except TypeError:
|
|
133
|
+
key = None
|
|
134
|
+
assert override.field_map_validation(dict_obj, key) == expected
|
|
135
|
+
del override
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def test_field_map_validation_with_multiple_fields_for_multiple_integrations(random_local_ip):
|
|
139
|
+
app = Mock()
|
|
140
|
+
app.config = {"uniqueOverride": {"asset": ["ipAddress"]}}
|
|
141
|
+
override = IntegrationOverride(app)
|
|
142
|
+
|
|
143
|
+
dict_obj = {"ipv4": random_local_ip, "mac": "00:11:22:33:44:55", "hostname": "test.example.com"}
|
|
144
|
+
assert override.field_map_validation(dict_obj, "invalid_type") is None
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def test_field_map_validation_with_invalid_model_types(random_local_ip):
|
|
148
|
+
app = Mock()
|
|
149
|
+
app.config = {"uniqueOverride": {"asset": ["ipAddress"]}}
|
|
150
|
+
override = IntegrationOverride(app)
|
|
151
|
+
dict_obj = {"ipv4": random_local_ip, "mac": "00:11:22:33:44:55", "hostname": "test.example.com"}
|
|
152
|
+
|
|
153
|
+
assert override.field_map_validation(dict_obj, "invalid_type") is None
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def test_field_map_validation_with_non_dict_non_model_objects():
|
|
157
|
+
app = Mock()
|
|
158
|
+
app.config = {"uniqueOverride": {"asset": ["ipAddress"]}}
|
|
159
|
+
override = IntegrationOverride(app)
|
|
160
|
+
|
|
161
|
+
invalid_objects = [None, "string", 123, ["list"]]
|
|
162
|
+
for obj in invalid_objects:
|
|
163
|
+
assert override.field_map_validation(obj, "asset") is None
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"""Tests for the version module."""
|
|
2
|
+
|
|
3
|
+
from unittest.mock import patch
|
|
4
|
+
import pytest
|
|
5
|
+
import logging
|
|
6
|
+
from regscale.utils.version import RegscaleVersion
|
|
7
|
+
|
|
8
|
+
logger = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@patch.object(RegscaleVersion, "get_platform_version", return_value="1.0.0.0")
|
|
12
|
+
def test_get_platform_version(mock_get_platform_version):
|
|
13
|
+
"""Test get_platform_version method."""
|
|
14
|
+
version = RegscaleVersion.get_platform_version()
|
|
15
|
+
assert isinstance(version, str) and RegscaleVersion.is_valid_version(version)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@pytest.mark.parametrize(
|
|
19
|
+
"version, expected",
|
|
20
|
+
[
|
|
21
|
+
("1.0", True),
|
|
22
|
+
("1.0.0", True),
|
|
23
|
+
("1.0.0.0", True),
|
|
24
|
+
("1.0.0.0.0", False),
|
|
25
|
+
("1.a.0", False),
|
|
26
|
+
("1.0.a", False),
|
|
27
|
+
("a.b.c", False),
|
|
28
|
+
("1.0.0-alpha", False),
|
|
29
|
+
("dev", False),
|
|
30
|
+
("localdev", False),
|
|
31
|
+
("1337-2024-10-25", False),
|
|
32
|
+
],
|
|
33
|
+
)
|
|
34
|
+
def test_is_valid_version(version, expected):
|
|
35
|
+
"""Test is_valid_version method."""
|
|
36
|
+
assert RegscaleVersion.is_valid_version(version) == expected
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@pytest.mark.parametrize(
|
|
40
|
+
"version1, version2, dev_is_latest, expected",
|
|
41
|
+
[
|
|
42
|
+
("1.0.0", "1.0.1", True, False),
|
|
43
|
+
("1.2.0", "1.0.1", True, True),
|
|
44
|
+
("2.0.0", "1.9.9", True, True),
|
|
45
|
+
("2.0.0", "42069-2013-07-14", True, True),
|
|
46
|
+
("42069-2013-07-14", "2.0.0", True, True),
|
|
47
|
+
("dev", "1.0.1", True, True),
|
|
48
|
+
("1.0.0", "dev", True, False),
|
|
49
|
+
("dev", "dev", True, True),
|
|
50
|
+
("localdev", "1.0.1", True, True),
|
|
51
|
+
("1.0.0", "localdev", True, False),
|
|
52
|
+
("localdev", "localdev", True, True),
|
|
53
|
+
("Unknown", "1.0.1", True, True),
|
|
54
|
+
("1.0.0", "Unknown", True, False),
|
|
55
|
+
("Unknown", "Unknown", True, True),
|
|
56
|
+
],
|
|
57
|
+
)
|
|
58
|
+
def test_compare_versions(version1, version2, dev_is_latest, expected):
|
|
59
|
+
"""Test compare_versions method."""
|
|
60
|
+
assert RegscaleVersion.compare_versions(version1, version2, dev_is_latest) == expected
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@pytest.mark.parametrize(
|
|
64
|
+
"minimum_version, dev_is_latest, expected",
|
|
65
|
+
[
|
|
66
|
+
("1.0.0.0", True, True),
|
|
67
|
+
("2.0.0", True, False),
|
|
68
|
+
("dev", True, False),
|
|
69
|
+
("dev", False, True),
|
|
70
|
+
("localdev", True, False),
|
|
71
|
+
("Unknown", True, False),
|
|
72
|
+
("1337-2024-10-25", True, True),
|
|
73
|
+
],
|
|
74
|
+
)
|
|
75
|
+
@patch.object(RegscaleVersion, "get_platform_version", return_value="1.0.0")
|
|
76
|
+
def test_meets_minimum_version(mock_get_platform_version, minimum_version, dev_is_latest, expected):
|
|
77
|
+
"""Test meets_minimum_version method."""
|
|
78
|
+
assert RegscaleVersion.meets_minimum_version(minimum_version, dev_is_latest) == expected
|
|
File without changes
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from tests import CLITestFixture
|
|
4
|
+
from regscale.core.app.utils.app_utils import get_current_datetime
|
|
5
|
+
from regscale.models import Search
|
|
6
|
+
from regscale.models.regscale_models.asset import Asset
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TestAssets(CLITestFixture):
|
|
10
|
+
bad_ssp_id = 10000
|
|
11
|
+
good_ssp_id = 3
|
|
12
|
+
regscale_module = "securityplans"
|
|
13
|
+
|
|
14
|
+
# Can we create an instance of the Asset class?
|
|
15
|
+
@staticmethod
|
|
16
|
+
def test_asset_instance():
|
|
17
|
+
asset = Asset(
|
|
18
|
+
host_name="host.example.com",
|
|
19
|
+
name="Host Name",
|
|
20
|
+
type="Other",
|
|
21
|
+
ipAddress="1.1.1.1",
|
|
22
|
+
parentId=1,
|
|
23
|
+
parentModule="securityplans",
|
|
24
|
+
assetOwnerId="asdfasdf",
|
|
25
|
+
status="Active (On Network)",
|
|
26
|
+
assetType="Virtual Machine (VM)",
|
|
27
|
+
dateCreated=get_current_datetime(),
|
|
28
|
+
dateLastUpdated=get_current_datetime(),
|
|
29
|
+
createdById="asdfasdf",
|
|
30
|
+
lastUpdatedById="asdfasdf",
|
|
31
|
+
assetCategory="Hardware",
|
|
32
|
+
scanningTool="Rando Scanner",
|
|
33
|
+
isPublic=True,
|
|
34
|
+
tenantsId=0,
|
|
35
|
+
)
|
|
36
|
+
assert isinstance(asset, Asset)
|
|
37
|
+
|
|
38
|
+
@staticmethod
|
|
39
|
+
def test_bad_asset():
|
|
40
|
+
asset = Asset(
|
|
41
|
+
host_name="host.example.com",
|
|
42
|
+
name="Host Name",
|
|
43
|
+
type="Other",
|
|
44
|
+
ipAddress="1.1.1.1",
|
|
45
|
+
parentId=1,
|
|
46
|
+
parentModule="securityplans",
|
|
47
|
+
assetOwnerId="asdfasdf",
|
|
48
|
+
status="Active (On Network)",
|
|
49
|
+
assetType="Virtual Machine (VM)",
|
|
50
|
+
dateCreated=get_current_datetime(),
|
|
51
|
+
dateLastUpdated=get_current_datetime(),
|
|
52
|
+
createdById="asdfasdf",
|
|
53
|
+
lastUpdatedById="asdfasdf",
|
|
54
|
+
assetCategory="Hardware",
|
|
55
|
+
scanningTool="Rando Scanner",
|
|
56
|
+
isPublic=True,
|
|
57
|
+
tenantsId=0,
|
|
58
|
+
fqdn=0, # Bad attribute
|
|
59
|
+
)
|
|
60
|
+
# Check if an attribute error is raised
|
|
61
|
+
with pytest.raises(AttributeError):
|
|
62
|
+
asset.model_fields_set
|
|
63
|
+
|
|
64
|
+
def test_assets_by_search(self):
|
|
65
|
+
empty_search = Search(parentID=self.bad_ssp_id, module=self.regscale_module, sort="id")
|
|
66
|
+
search = Search(parentID=self.good_ssp_id, module=self.regscale_module, sort="id")
|
|
67
|
+
# this will return an empty list
|
|
68
|
+
no_assets = Asset.get_all_by_search(empty_search)
|
|
69
|
+
assets = Asset.get_all_by_search(search)
|
|
70
|
+
assert no_assets == []
|
|
71
|
+
assert len(assets) > 0
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""Test Providers and the AppConfig objects."""
|
|
2
|
+
|
|
3
|
+
import inspect
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
from regscale.models import config
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def test_Provider():
|
|
11
|
+
"""Test the Provider class"""
|
|
12
|
+
results = config.Provider(provider="fake_provider")
|
|
13
|
+
assert results.provider == "fake_provider"
|
|
14
|
+
results.__setitem__("key", "value")
|
|
15
|
+
assert results.key == "value"
|
|
16
|
+
with pytest.raises(NotImplementedError):
|
|
17
|
+
results.refresh()
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def test_provider_class_creation():
|
|
21
|
+
"""Test that the provider classes are created."""
|
|
22
|
+
providers = list(config.providers.keys())
|
|
23
|
+
# Get a list of all classes in the module
|
|
24
|
+
all_classes = [name for name, obj in inspect.getmembers(config) if inspect.isclass(obj)]
|
|
25
|
+
for provider in providers:
|
|
26
|
+
assert provider in all_classes, f"{provider} is not defined"
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
from unittest.mock import MagicMock, patch
|
|
3
|
+
|
|
4
|
+
from regscale.models import ControlImplementation
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class TestControlImplementation(unittest.TestCase):
|
|
8
|
+
@patch("regscale.models.regscale_models.control_implementation.ControlImplementation._get_api_handler().get")
|
|
9
|
+
def test_get_control_map_by_plan_lower_case_keys(self, mock_get):
|
|
10
|
+
# Create a mock response object with 'ok' attribute and 'json' method
|
|
11
|
+
mock_response = MagicMock()
|
|
12
|
+
mock_response.ok = True
|
|
13
|
+
mock_response.json.return_value = [
|
|
14
|
+
{"control": {"controlId": "CA-1"}, "id": 1},
|
|
15
|
+
{"control": {"controlId": "AC-6"}, "id": 2},
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
mock_get.return_value = mock_response
|
|
19
|
+
|
|
20
|
+
# Expected result should have lower case control IDs as keys
|
|
21
|
+
expected_result = {"ca-1": 1, "ac-6": 2}
|
|
22
|
+
|
|
23
|
+
# Call the method under test
|
|
24
|
+
result = ControlImplementation.get_control_label_map_by_plan(plan_id=123)
|
|
25
|
+
|
|
26
|
+
# Assert that the result matches the expected result
|
|
27
|
+
self.assertEqual(result, expected_result)
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import tempfile
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
from regscale.core.app.api import Api
|
|
8
|
+
from regscale.core.app.utils.catalog_utils.download_catalog import get_new_catalog
|
|
9
|
+
from regscale.core.app.utils.catalog_utils.update_catalog_v2 import import_catalog
|
|
10
|
+
from regscale.models.app_models.catalog_compare import CatalogCompare
|
|
11
|
+
from regscale.models.regscale_models import Catalog
|
|
12
|
+
from tests.fixtures.test_fixture import CLITestFixture
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class TestImport(CLITestFixture):
|
|
16
|
+
"""
|
|
17
|
+
Test for AWS integration
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
@pytest.fixture(autouse=False)
|
|
21
|
+
def setup(self, catalog_id):
|
|
22
|
+
# Setup code goes here. This will execute before each test method.
|
|
23
|
+
print("Setting up before test")
|
|
24
|
+
my_dir = tempfile.mkdtemp()
|
|
25
|
+
api = Api()
|
|
26
|
+
# You can initialize variables, create necessary objects, or set up any necessary preconditions for the test here.
|
|
27
|
+
data = CatalogCompare.get_master_catalogs(api=api)
|
|
28
|
+
# download json file with requests
|
|
29
|
+
for catalog in data["catalogs"]:
|
|
30
|
+
if catalog["downloadURL"] and catalog["title"] == "Australian Information Security Manual (ISM)":
|
|
31
|
+
url = catalog["downloadURL"]
|
|
32
|
+
name = Path(catalog["downloadURL"]).name
|
|
33
|
+
cat = get_new_catalog(url=url)
|
|
34
|
+
with open(Path(tempfile.gettempdir()) / my_dir / name, "w") as f:
|
|
35
|
+
json.dump(cat, f)
|
|
36
|
+
catalog_id["name"] = name
|
|
37
|
+
catalog_id["file"] = Path(tempfile.gettempdir()) / my_dir / name
|
|
38
|
+
break
|
|
39
|
+
# Download a bad file
|
|
40
|
+
bad_url = (
|
|
41
|
+
"https://gist.githubusercontent.com/moredip/4165313/raw/ad00ee5bc70016a70976736d5cdf0463d5f7ea15/test.json"
|
|
42
|
+
)
|
|
43
|
+
bad_name = Path(bad_url).name
|
|
44
|
+
bad_cat = get_new_catalog(url=bad_url)
|
|
45
|
+
catalog_id["bad_name"] = "Invalid JSON"
|
|
46
|
+
catalog_id["bad_file"] = Path(tempfile.gettempdir()) / my_dir / bad_name
|
|
47
|
+
with open(catalog_id["bad_file"], "w") as bad_file:
|
|
48
|
+
json.dump(bad_cat, bad_file)
|
|
49
|
+
|
|
50
|
+
@pytest.fixture(scope="module")
|
|
51
|
+
def catalog_id(self):
|
|
52
|
+
return {}
|
|
53
|
+
|
|
54
|
+
@pytest.fixture(autouse=False)
|
|
55
|
+
def teardown(self, catalog_id):
|
|
56
|
+
yield # This is where the test function will execute
|
|
57
|
+
# Teardown code goes here. This will execute after each test method.
|
|
58
|
+
print("Tearing down after test")
|
|
59
|
+
|
|
60
|
+
if cat_id := catalog_id.get("id"):
|
|
61
|
+
if cat := Catalog.get_object(cat_id):
|
|
62
|
+
assert cat.delete() is True
|
|
63
|
+
|
|
64
|
+
def test_import_catalog_invalid(self, setup, catalog_id):
|
|
65
|
+
# Arrange
|
|
66
|
+
catalog_path = Path(catalog_id["bad_file"])
|
|
67
|
+
|
|
68
|
+
# Act
|
|
69
|
+
res = import_catalog(catalog_path)
|
|
70
|
+
# Assert
|
|
71
|
+
assert res.json()["success"] is False
|
|
72
|
+
|
|
73
|
+
# @pytest.skip("Skipping test because the API keeps timing out even in the application.")
|
|
74
|
+
def test_import_catalog_valid(self, setup, teardown, catalog_id):
|
|
75
|
+
# Arrange
|
|
76
|
+
catalog_path = Path(catalog_id["file"])
|
|
77
|
+
# change the catalog name to include the name of the test run id
|
|
78
|
+
with open(catalog_path, "r", encoding="utf-8") as infile:
|
|
79
|
+
data = json.load(infile)
|
|
80
|
+
with open(catalog_path, "w", encoding="utf-8") as outfile:
|
|
81
|
+
current_title = data["catalog"]["title"]
|
|
82
|
+
data["catalog"]["title"] = self.title_prefix + current_title
|
|
83
|
+
json.dump(data, outfile, indent=4)
|
|
84
|
+
|
|
85
|
+
# Act
|
|
86
|
+
res = import_catalog(catalog_path)
|
|
87
|
+
if res.status_code == 400 and res.text == "Catalog already exists":
|
|
88
|
+
pytest.skip("Catalog already exists. Most likely due to another test. Skipping import.")
|
|
89
|
+
# Assert
|
|
90
|
+
assert res.json()["success"] is True
|
|
91
|
+
cat_id = res.json()["catalogId"]
|
|
92
|
+
catalog_id["id"] = cat_id
|
|
93
|
+
assert cat_id is not None
|
|
94
|
+
|
|
95
|
+
# delete the catalog
|
|
96
|
+
new_cat = Catalog.get_object(cat_id)
|
|
97
|
+
assert new_cat.delete() is True
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from regscale.core.app.utils.app_utils import get_current_datetime
|
|
4
|
+
from regscale.models.regscale_models.issue import Issue, IssueSeverity, IssueStatus
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def test_bad_issue_instance():
|
|
8
|
+
issue = Issue(
|
|
9
|
+
id=1,
|
|
10
|
+
title="Test Issue",
|
|
11
|
+
severityLevel=IssueSeverity.NotAssigned,
|
|
12
|
+
status=IssueStatus.Draft,
|
|
13
|
+
description="This is a test issue",
|
|
14
|
+
parentId=1,
|
|
15
|
+
parentModule="securityplans",
|
|
16
|
+
pluginId=1,
|
|
17
|
+
dateCreated=get_current_datetime(),
|
|
18
|
+
)
|
|
19
|
+
# Assert issue.model_fields_set raises an AttributeError
|
|
20
|
+
with pytest.raises(AttributeError):
|
|
21
|
+
issue.model_fields_set
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def test_good_issue_instance():
|
|
25
|
+
issue = Issue(
|
|
26
|
+
id=1,
|
|
27
|
+
title="Test Issue",
|
|
28
|
+
severityLevel=IssueSeverity.NotAssigned,
|
|
29
|
+
status=IssueStatus.Draft,
|
|
30
|
+
description="This is a test issue",
|
|
31
|
+
parentId=1,
|
|
32
|
+
parentModule="securityplans",
|
|
33
|
+
pluginId=str(1),
|
|
34
|
+
dateCreated=get_current_datetime(),
|
|
35
|
+
)
|
|
36
|
+
assert isinstance(issue, Issue)
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from regscale.models.app_models.mapping import Mapping
|
|
2
|
+
import json
|
|
3
|
+
|
|
4
|
+
MAPPING_TEMPLATE = {
|
|
5
|
+
"mapping": {
|
|
6
|
+
"Pickles": "Pickles",
|
|
7
|
+
"IP Address": "IP Address",
|
|
8
|
+
"Hostname": "Hostname",
|
|
9
|
+
"OS": "OS",
|
|
10
|
+
"Vulnerability Title": "Vulnerability Title",
|
|
11
|
+
"Vulnerability ID": "Vulnerability ID",
|
|
12
|
+
"CVSSv2 Score": "CVSSv2 Score",
|
|
13
|
+
"CVSSv3 Score": "CVSSv3 Score",
|
|
14
|
+
"Description": "Description",
|
|
15
|
+
"Proof": "Proof",
|
|
16
|
+
"Solution": "Solution",
|
|
17
|
+
"CVEs": "CVEs",
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def test_mapping_validation():
|
|
23
|
+
"""
|
|
24
|
+
Test the Mapping class validation
|
|
25
|
+
"""
|
|
26
|
+
expected_field_names = [
|
|
27
|
+
"IP Address",
|
|
28
|
+
"Hostname",
|
|
29
|
+
"OS",
|
|
30
|
+
"Vulnerability Title",
|
|
31
|
+
"Vulnerability ID",
|
|
32
|
+
"CVSSv2 Score",
|
|
33
|
+
"CVSSv3 Score",
|
|
34
|
+
"Description",
|
|
35
|
+
"Proof",
|
|
36
|
+
"Solution",
|
|
37
|
+
"CVEs",
|
|
38
|
+
]
|
|
39
|
+
mapping = Mapping(mapping=MAPPING_TEMPLATE["mapping"], expected_field_names=expected_field_names)
|
|
40
|
+
|
|
41
|
+
assert mapping
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def test_mapping_no_validation():
|
|
45
|
+
"""
|
|
46
|
+
Test the Mapping class validation
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
expected_field_names = ["Pickles"]
|
|
50
|
+
mapping = Mapping(mapping=MAPPING_TEMPLATE["mapping"], expected_field_names=expected_field_names)
|
|
51
|
+
|
|
52
|
+
assert mapping
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""Test the platform module."""
|
|
2
|
+
|
|
3
|
+
from unittest.mock import patch
|
|
4
|
+
|
|
5
|
+
from regscale.core.app.api import Api
|
|
6
|
+
from regscale.core.app.application import Application
|
|
7
|
+
from regscale.models import platform
|
|
8
|
+
|
|
9
|
+
PATH = "regscale.models.platform"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@patch(f"{PATH}.get_regscale_token", return_value=("billy", "zane"))
|
|
13
|
+
def test_RegScaleAuth_model_behaves(mock_get_regscale_token):
|
|
14
|
+
"""The RegScaleAuth BaseModel class does lots of things, let's test them."""
|
|
15
|
+
api = Api()
|
|
16
|
+
un = "funkenstein"
|
|
17
|
+
pw = "groovin'tothewaveoftheflag"
|
|
18
|
+
domain = "disinfo.org"
|
|
19
|
+
model = platform.RegScaleAuth.authenticate(
|
|
20
|
+
api=api,
|
|
21
|
+
username=un,
|
|
22
|
+
password=pw,
|
|
23
|
+
domain=domain,
|
|
24
|
+
)
|
|
25
|
+
mock_get_regscale_token.assert_called_once()
|
|
26
|
+
assert isinstance(model, platform.RegScaleAuth)
|
|
27
|
+
assert model.token == "Bearer zane"
|
|
28
|
+
assert model.user_id == "billy"
|
|
29
|
+
assert model.username == un
|
|
30
|
+
assert model.password.get_secret_value() == pw
|
|
31
|
+
assert model.domain == domain
|