regscale-cli 6.25.1.0__py3-none-any.whl → 6.27.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of regscale-cli might be problematic. Click here for more details.

Files changed (146) hide show
  1. regscale/_version.py +1 -1
  2. regscale/airflow/hierarchy.py +2 -2
  3. regscale/core/app/application.py +19 -4
  4. regscale/core/app/internal/evidence.py +419 -2
  5. regscale/core/app/internal/login.py +0 -1
  6. regscale/core/app/utils/catalog_utils/common.py +1 -1
  7. regscale/dev/code_gen.py +24 -20
  8. regscale/integrations/commercial/jira.py +367 -126
  9. regscale/integrations/commercial/qualys/__init__.py +7 -8
  10. regscale/integrations/commercial/qualys/scanner.py +8 -3
  11. regscale/integrations/commercial/sicura/api.py +14 -13
  12. regscale/integrations/commercial/sicura/commands.py +8 -2
  13. regscale/integrations/commercial/sicura/scanner.py +49 -39
  14. regscale/integrations/commercial/stigv2/ckl_parser.py +5 -5
  15. regscale/integrations/commercial/synqly/assets.py +17 -0
  16. regscale/integrations/commercial/synqly/vulnerabilities.py +45 -28
  17. regscale/integrations/commercial/tenablev2/cis_parsers.py +453 -0
  18. regscale/integrations/commercial/tenablev2/cis_scanner.py +447 -0
  19. regscale/integrations/commercial/tenablev2/commands.py +142 -1
  20. regscale/integrations/commercial/tenablev2/scanner.py +0 -1
  21. regscale/integrations/commercial/tenablev2/stig_parsers.py +113 -57
  22. regscale/integrations/commercial/wizv2/WizDataMixin.py +1 -1
  23. regscale/integrations/commercial/wizv2/click.py +64 -79
  24. regscale/integrations/commercial/wizv2/compliance/__init__.py +15 -0
  25. regscale/integrations/commercial/wizv2/{policy_compliance_helpers.py → compliance/helpers.py} +78 -60
  26. regscale/integrations/commercial/wizv2/compliance_report.py +161 -165
  27. regscale/integrations/commercial/wizv2/core/__init__.py +133 -0
  28. regscale/integrations/commercial/wizv2/{async_client.py → core/client.py} +3 -3
  29. regscale/integrations/commercial/wizv2/{constants.py → core/constants.py} +1 -17
  30. regscale/integrations/commercial/wizv2/core/file_operations.py +237 -0
  31. regscale/integrations/commercial/wizv2/fetchers/__init__.py +11 -0
  32. regscale/integrations/commercial/wizv2/{data_fetcher.py → fetchers/policy_assessment.py} +5 -9
  33. regscale/integrations/commercial/wizv2/issue.py +1 -1
  34. regscale/integrations/commercial/wizv2/models/__init__.py +0 -0
  35. regscale/integrations/commercial/wizv2/parsers/__init__.py +34 -0
  36. regscale/integrations/commercial/wizv2/{parsers.py → parsers/main.py} +1 -1
  37. regscale/integrations/commercial/wizv2/processors/__init__.py +11 -0
  38. regscale/integrations/commercial/wizv2/{finding_processor.py → processors/finding.py} +1 -1
  39. regscale/integrations/commercial/wizv2/reports.py +1 -1
  40. regscale/integrations/commercial/wizv2/sbom.py +1 -1
  41. regscale/integrations/commercial/wizv2/scanner.py +39 -99
  42. regscale/integrations/commercial/wizv2/utils/__init__.py +48 -0
  43. regscale/integrations/commercial/wizv2/{utils.py → utils/main.py} +116 -61
  44. regscale/integrations/commercial/wizv2/variables.py +89 -3
  45. regscale/integrations/compliance_integration.py +60 -41
  46. regscale/integrations/control_matcher.py +377 -0
  47. regscale/integrations/due_date_handler.py +14 -8
  48. regscale/integrations/milestone_manager.py +291 -0
  49. regscale/integrations/public/__init__.py +1 -0
  50. regscale/integrations/public/cci_importer.py +37 -38
  51. regscale/integrations/public/fedramp/click.py +60 -2
  52. regscale/integrations/public/fedramp/docx_parser.py +10 -1
  53. regscale/integrations/public/fedramp/fedramp_cis_crm.py +393 -340
  54. regscale/integrations/public/fedramp/fedramp_five.py +1 -1
  55. regscale/integrations/public/fedramp/poam_export_v5.py +888 -0
  56. regscale/integrations/scanner_integration.py +277 -153
  57. regscale/models/integration_models/cisa_kev_data.json +282 -9
  58. regscale/models/integration_models/nexpose.py +36 -10
  59. regscale/models/integration_models/qualys.py +3 -4
  60. regscale/models/integration_models/synqly_models/capabilities.json +1 -1
  61. regscale/models/integration_models/synqly_models/connectors/vulnerabilities.py +24 -7
  62. regscale/models/integration_models/synqly_models/synqly_model.py +8 -1
  63. regscale/models/locking.py +12 -8
  64. regscale/models/platform.py +1 -2
  65. regscale/models/regscale_models/control_implementation.py +47 -22
  66. regscale/models/regscale_models/issue.py +256 -95
  67. regscale/models/regscale_models/milestone.py +1 -1
  68. regscale/models/regscale_models/regscale_model.py +6 -1
  69. regscale/templates/__init__.py +0 -0
  70. {regscale_cli-6.25.1.0.dist-info → regscale_cli-6.27.0.0.dist-info}/METADATA +1 -17
  71. {regscale_cli-6.25.1.0.dist-info → regscale_cli-6.27.0.0.dist-info}/RECORD +145 -65
  72. tests/regscale/integrations/commercial/__init__.py +0 -0
  73. tests/regscale/integrations/commercial/conftest.py +28 -0
  74. tests/regscale/integrations/commercial/microsoft_defender/__init__.py +1 -0
  75. tests/regscale/integrations/commercial/microsoft_defender/test_defender.py +1517 -0
  76. tests/regscale/integrations/commercial/microsoft_defender/test_defender_api.py +1748 -0
  77. tests/regscale/integrations/commercial/microsoft_defender/test_defender_constants.py +327 -0
  78. tests/regscale/integrations/commercial/microsoft_defender/test_defender_scanner.py +487 -0
  79. tests/regscale/integrations/commercial/test_aws.py +3731 -0
  80. tests/regscale/integrations/commercial/test_burp.py +48 -0
  81. tests/regscale/integrations/commercial/test_crowdstrike.py +49 -0
  82. tests/regscale/integrations/commercial/test_dependabot.py +341 -0
  83. tests/regscale/integrations/commercial/test_gcp.py +1543 -0
  84. tests/regscale/integrations/commercial/test_gitlab.py +549 -0
  85. tests/regscale/integrations/commercial/test_ip_mac_address_length.py +84 -0
  86. tests/regscale/integrations/commercial/test_jira.py +2204 -0
  87. tests/regscale/integrations/commercial/test_npm_audit.py +42 -0
  88. tests/regscale/integrations/commercial/test_okta.py +1228 -0
  89. tests/regscale/integrations/commercial/test_sarif_converter.py +251 -0
  90. tests/regscale/integrations/commercial/test_sicura.py +350 -0
  91. tests/regscale/integrations/commercial/test_snow.py +423 -0
  92. tests/regscale/integrations/commercial/test_sonarcloud.py +394 -0
  93. tests/regscale/integrations/commercial/test_sqlserver.py +186 -0
  94. tests/regscale/integrations/commercial/test_stig.py +33 -0
  95. tests/regscale/integrations/commercial/test_stig_mapper.py +153 -0
  96. tests/regscale/integrations/commercial/test_stigv2.py +406 -0
  97. tests/regscale/integrations/commercial/test_wiz.py +1365 -0
  98. tests/regscale/integrations/commercial/test_wiz_inventory.py +256 -0
  99. tests/regscale/integrations/commercial/wizv2/__init__.py +339 -0
  100. tests/regscale/integrations/commercial/wizv2/compliance/__init__.py +1 -0
  101. tests/regscale/integrations/commercial/wizv2/compliance/test_helpers.py +903 -0
  102. tests/regscale/integrations/commercial/wizv2/core/__init__.py +1 -0
  103. tests/regscale/integrations/commercial/wizv2/core/test_auth.py +701 -0
  104. tests/regscale/integrations/commercial/wizv2/core/test_client.py +1037 -0
  105. tests/regscale/integrations/commercial/wizv2/core/test_file_operations.py +989 -0
  106. tests/regscale/integrations/commercial/wizv2/fetchers/__init__.py +1 -0
  107. tests/regscale/integrations/commercial/wizv2/fetchers/test_policy_assessment.py +805 -0
  108. tests/regscale/integrations/commercial/wizv2/parsers/__init__.py +1 -0
  109. tests/regscale/integrations/commercial/wizv2/parsers/test_main.py +1153 -0
  110. tests/regscale/integrations/commercial/wizv2/processors/__init__.py +1 -0
  111. tests/regscale/integrations/commercial/wizv2/processors/test_finding.py +671 -0
  112. tests/regscale/integrations/commercial/wizv2/test_WizDataMixin.py +537 -0
  113. tests/regscale/integrations/commercial/wizv2/test_click_comprehensive.py +851 -0
  114. tests/regscale/integrations/commercial/wizv2/test_compliance_report_comprehensive.py +910 -0
  115. tests/regscale/integrations/commercial/wizv2/test_compliance_report_normalization.py +138 -0
  116. tests/regscale/integrations/commercial/wizv2/test_file_cleanup.py +283 -0
  117. tests/regscale/integrations/commercial/wizv2/test_file_operations.py +260 -0
  118. tests/regscale/integrations/commercial/wizv2/test_issue.py +343 -0
  119. tests/regscale/integrations/commercial/wizv2/test_issue_comprehensive.py +1203 -0
  120. tests/regscale/integrations/commercial/wizv2/test_reports.py +497 -0
  121. tests/regscale/integrations/commercial/wizv2/test_sbom.py +643 -0
  122. tests/regscale/integrations/commercial/wizv2/test_scanner_comprehensive.py +805 -0
  123. tests/regscale/integrations/commercial/wizv2/test_wiz_click_client_id.py +165 -0
  124. tests/regscale/integrations/commercial/wizv2/test_wiz_compliance_report.py +1394 -0
  125. tests/regscale/integrations/commercial/wizv2/test_wiz_compliance_unit.py +341 -0
  126. tests/regscale/integrations/commercial/wizv2/test_wiz_control_normalization.py +138 -0
  127. tests/regscale/integrations/commercial/wizv2/test_wiz_findings_comprehensive.py +364 -0
  128. tests/regscale/integrations/commercial/wizv2/test_wiz_inventory_comprehensive.py +644 -0
  129. tests/regscale/integrations/commercial/wizv2/test_wiz_status_mapping.py +149 -0
  130. tests/regscale/integrations/commercial/wizv2/test_wizv2.py +1132 -0
  131. tests/regscale/integrations/commercial/wizv2/test_wizv2_utils.py +519 -0
  132. tests/regscale/integrations/commercial/wizv2/utils/__init__.py +1 -0
  133. tests/regscale/integrations/commercial/wizv2/utils/test_main.py +1523 -0
  134. tests/regscale/integrations/public/fedramp/__init__.py +1 -0
  135. tests/regscale/integrations/public/fedramp/test_poam_export_v5.py +1293 -0
  136. tests/regscale/integrations/public/test_fedramp.py +301 -0
  137. tests/regscale/integrations/test_control_matcher.py +1397 -0
  138. tests/regscale/integrations/test_control_matching.py +155 -0
  139. tests/regscale/integrations/test_milestone_manager.py +408 -0
  140. tests/regscale/models/test_issue.py +378 -1
  141. regscale/integrations/commercial/wizv2/policy_compliance.py +0 -3543
  142. /regscale/integrations/commercial/wizv2/{wiz_auth.py → core/auth.py} +0 -0
  143. {regscale_cli-6.25.1.0.dist-info → regscale_cli-6.27.0.0.dist-info}/LICENSE +0 -0
  144. {regscale_cli-6.25.1.0.dist-info → regscale_cli-6.27.0.0.dist-info}/WHEEL +0 -0
  145. {regscale_cli-6.25.1.0.dist-info → regscale_cli-6.27.0.0.dist-info}/entry_points.txt +0 -0
  146. {regscale_cli-6.25.1.0.dist-info → regscale_cli-6.27.0.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,149 @@
1
+ """
2
+ Unit tests for Wiz status mapping functionality.
3
+ Tests that Wiz issue statuses are correctly mapped to RegScale IssueStatus.
4
+ """
5
+
6
+ from unittest.mock import Mock, patch
7
+
8
+ import pytest
9
+
10
+ from regscale.integrations.commercial.wizv2.issue import WizIssue
11
+ from regscale.integrations.commercial.wizv2.scanner import WizVulnerabilityIntegration
12
+ from regscale.models import IssueStatus
13
+
14
+
15
+ class TestWizStatusMapping:
16
+ """Test class for Wiz status mapping functionality."""
17
+
18
+ @pytest.fixture
19
+ def mock_app(self):
20
+ """Create a mock app with config."""
21
+ app = Mock()
22
+ app.config = {}
23
+ return app
24
+
25
+ @pytest.fixture
26
+ def wiz_integration(self, mock_app):
27
+ """Create a WizVulnerabilityIntegration instance."""
28
+ with patch("regscale.integrations.scanner_integration.ScannerIntegration.__init__"):
29
+ integration = WizVulnerabilityIntegration(app=mock_app, plan_id=1)
30
+ integration.app = mock_app
31
+ integration._compliance_settings = None
32
+ return integration
33
+
34
+ @pytest.fixture
35
+ def wiz_issue_integration(self, mock_app):
36
+ """Create a WizIssue instance."""
37
+ with patch("regscale.integrations.scanner_integration.ScannerIntegration.__init__"):
38
+ integration = WizIssue(app=mock_app, plan_id=1)
39
+ integration.app = mock_app
40
+ integration._compliance_settings = None
41
+ return integration
42
+
43
+ def test_default_status_mapping_open_statuses(self, wiz_integration):
44
+ """Test that OPEN and IN_PROGRESS statuses map to IssueStatus.Open."""
45
+ open_statuses = ["OPEN", "Open", "open", "IN_PROGRESS", "In_Progress", "in_progress"]
46
+
47
+ for status in open_statuses:
48
+ result = wiz_integration._get_default_issue_status_mapping(status)
49
+ assert result == IssueStatus.Open, f"Status '{status}' should map to Open, got {result}"
50
+
51
+ def test_default_status_mapping_closed_statuses(self, wiz_integration):
52
+ """Test that RESOLVED and REJECTED statuses map to IssueStatus.Closed."""
53
+ closed_statuses = ["RESOLVED", "Resolved", "resolved", "REJECTED", "Rejected", "rejected"]
54
+
55
+ for status in closed_statuses:
56
+ result = wiz_integration._get_default_issue_status_mapping(status)
57
+ assert result == IssueStatus.Closed, f"Status '{status}' should map to Closed, got {result}"
58
+
59
+ def test_default_status_mapping_unknown_status(self, wiz_integration):
60
+ """Test that unknown statuses default to IssueStatus.Open."""
61
+ unknown_statuses = ["UNKNOWN", "PENDING", "WEIRD_STATUS", ""]
62
+
63
+ for status in unknown_statuses:
64
+ result = wiz_integration._get_default_issue_status_mapping(status)
65
+ assert result == IssueStatus.Open, f"Unknown status '{status}' should default to Open, got {result}"
66
+
67
+ def test_map_status_to_issue_status_without_compliance_settings(self, wiz_integration):
68
+ """Test status mapping without compliance settings (uses default mapping)."""
69
+ # Ensure no compliance settings
70
+ wiz_integration._compliance_settings = None
71
+
72
+ test_cases = [
73
+ ("OPEN", IssueStatus.Open),
74
+ ("IN_PROGRESS", IssueStatus.Open),
75
+ ("RESOLVED", IssueStatus.Closed),
76
+ ("REJECTED", IssueStatus.Closed),
77
+ ("UNKNOWN", IssueStatus.Open),
78
+ ]
79
+
80
+ for wiz_status, expected in test_cases:
81
+ result = wiz_integration.map_status_to_issue_status(wiz_status)
82
+ assert result == expected, f"Status '{wiz_status}' should map to {expected}, got {result}"
83
+
84
+ def test_map_status_to_issue_status_with_compliance_settings(self, wiz_integration):
85
+ """Test status mapping with compliance settings."""
86
+ # Mock compliance settings
87
+ mock_compliance = Mock()
88
+ mock_compliance.get_field_labels.return_value = ["Open", "In Progress", "Closed", "Resolved"]
89
+ wiz_integration._compliance_settings = mock_compliance
90
+
91
+ # Test that IN_PROGRESS still maps to Open even with compliance settings
92
+ result = wiz_integration.map_status_to_issue_status("IN_PROGRESS")
93
+ assert result == IssueStatus.Open, "IN_PROGRESS should map to Open with compliance settings"
94
+
95
+ # Test other statuses
96
+ result = wiz_integration.map_status_to_issue_status("RESOLVED")
97
+ assert result == IssueStatus.Closed, "RESOLVED should map to Closed with compliance settings"
98
+
99
+ def test_match_wiz_status_to_label(self, wiz_integration):
100
+ """Test the _match_wiz_status_to_label method."""
101
+ # Test open status mappings
102
+ assert wiz_integration._match_wiz_status_to_label("open", "Open") == IssueStatus.Open
103
+ assert wiz_integration._match_wiz_status_to_label("in_progress", "In Progress") == IssueStatus.Open
104
+ assert wiz_integration._match_wiz_status_to_label("in_progress", "Active") == IssueStatus.Open
105
+
106
+ # Test closed status mappings
107
+ assert wiz_integration._match_wiz_status_to_label("resolved", "Closed") == IssueStatus.Closed
108
+ assert wiz_integration._match_wiz_status_to_label("rejected", "Resolved") == IssueStatus.Closed
109
+
110
+ # Test non-matching combinations
111
+ assert wiz_integration._match_wiz_status_to_label("open", "Closed") is None
112
+ assert wiz_integration._match_wiz_status_to_label("resolved", "Open") is None
113
+
114
+ def test_wiz_issue_status_mapping(self, wiz_issue_integration):
115
+ """Test that WizIssue class uses the same status mapping."""
116
+ test_cases = [
117
+ ("OPEN", IssueStatus.Open),
118
+ ("IN_PROGRESS", IssueStatus.Open),
119
+ ("RESOLVED", IssueStatus.Closed),
120
+ ("REJECTED", IssueStatus.Closed),
121
+ ]
122
+
123
+ for wiz_status, expected in test_cases:
124
+ result = wiz_issue_integration.map_status_to_issue_status(wiz_status)
125
+ assert result == expected, f"WizIssue: Status '{wiz_status}' should map to {expected}, got {result}"
126
+
127
+ @pytest.mark.parametrize(
128
+ "status,expected",
129
+ [
130
+ ("OPEN", IssueStatus.Open),
131
+ ("Open", IssueStatus.Open),
132
+ ("open", IssueStatus.Open),
133
+ ("IN_PROGRESS", IssueStatus.Open),
134
+ ("In_Progress", IssueStatus.Open),
135
+ ("in_progress", IssueStatus.Open),
136
+ ("RESOLVED", IssueStatus.Closed),
137
+ ("Resolved", IssueStatus.Closed),
138
+ ("resolved", IssueStatus.Closed),
139
+ ("REJECTED", IssueStatus.Closed),
140
+ ("Rejected", IssueStatus.Closed),
141
+ ("rejected", IssueStatus.Closed),
142
+ ("UNKNOWN_STATUS", IssueStatus.Open),
143
+ ("", IssueStatus.Open),
144
+ ],
145
+ )
146
+ def test_comprehensive_status_mapping(self, wiz_integration, status, expected):
147
+ """Comprehensive parameterized test for all status variations."""
148
+ result = wiz_integration.map_status_to_issue_status(status)
149
+ assert result == expected, f"Status '{status}' should map to {expected}, got {result}"