diff --git a/moto/securityhub/models.py b/moto/securityhub/models.py index 8f4531783dfd..7262a9e39bfd 100644 --- a/moto/securityhub/models.py +++ b/moto/securityhub/models.py @@ -71,10 +71,11 @@ def get_findings( if max_results is not None: try: max_results = int(max_results) - if max_results < 1: + if max_results < 1 or max_results > 100: + print("max_results", max_results) raise InvalidInputException( op="GetFindings", - msg="MaxResults must be a number greater than 0", + msg="MaxResults must be a number between 1 and 100", ) except ValueError: raise InvalidInputException( @@ -119,29 +120,6 @@ def batch_import_findings( for finding_data in findings: try: - # # Validate required fields - # required_fields = [ - # "AwsAccountId", - # "CreatedAt", - # "UpdatedAt", - # "Description", - # "GeneratorId", - # "Id", - # "ProductArn", - # "Severity", - # "Title", - # "Types", - # ] - - # missing_fields = [ - # field for field in required_fields if field not in finding_data - # ] - # if missing_fields: - # raise InvalidInputException( - # op="BatchImportFindings", - # msg=f"Finding must contain the following required fields: {', '.join(missing_fields)}", - # ) - if ( not isinstance(finding_data["Resources"], list) or len(finding_data["Resources"]) == 0 diff --git a/moto/securityhub/responses.py b/moto/securityhub/responses.py index 75bfa8e7be90..a06e0d42b492 100644 --- a/moto/securityhub/responses.py +++ b/moto/securityhub/responses.py @@ -16,22 +16,15 @@ def securityhub_backend(self) -> SecurityHubBackend: return securityhub_backends[self.current_account][self.region] def get_findings(self) -> str: - params = self._get_params() + raw_params = self._get_params() - # # Don't try to parse JSON if we already have a dict with the right keys - # if "SortCriteria" in params: - # sort_criteria = params["SortCriteria"] - # else: - # # Try to parse JSON only if needed - # try: - # json_params = json.loads(list(params.keys())[0]) - # sort_criteria = json_params.get("SortCriteria") - # except (json.JSONDecodeError, IndexError): - # sort_criteria = None - sort_criteria = params.get("SortCriteria") - filters = params.get("Filters") - next_token = params.get("NextToken") - max_results = params.get("MaxResults") + # Parse the JSON string that's being used as a key + params = json.loads(next(iter(raw_params.keys()), "{}")) + + sort_criteria = params.get("SortCriteria", []) + filters = params.get("Filters", {}) + next_token = params.get("NextToken", None) + max_results = params.get("MaxResults", 100) result = self.securityhub_backend.get_findings( filters=filters, diff --git a/tests/test_securityhub/test_securityhub.py b/tests/test_securityhub/test_securityhub.py index e03f8c61f0fd..d0a8769822a1 100644 --- a/tests/test_securityhub/test_securityhub.py +++ b/tests/test_securityhub/test_securityhub.py @@ -1,6 +1,8 @@ """Unit tests for securityhub-supported APIs.""" import boto3 +import pytest +from botocore.exceptions import ClientError from moto import mock_aws from moto.core import DEFAULT_ACCOUNT_ID @@ -77,53 +79,15 @@ def test_batch_import_findings(): assert len(response["FailedFindings"]) == 0 -# @mock_aws -# def test_get_findings_invalid_parameters(): -# """Test getting findings with invalid parameters.""" -# client = boto3.client("securityhub", region_name="us-east-1") - -# # Test invalid MaxResults -# with pytest.raises(ClientError) as exc: -# client.get_findings(MaxResults=0) -# err = exc.value.response["Error"] -# assert err["Code"] == "InvalidInputException" -# assert "MaxResults must be a number greater than 0" in err["Message"] - -# @mock_aws -# def test_batch_import_findings_validation(): -# """Test batch import findings with invalid input.""" -# client = boto3.client("securityhub", region_name="us-east-1") - -# # Test missing required fields -# invalid_finding = { -# "Id": "test-finding-001", -# # Missing other required fields -# } - -# response = client.batch_import_findings(Findings=[invalid_finding]) -# assert response["FailedCount"] == 1 -# assert response["SuccessCount"] == 0 -# assert len(response["FailedFindings"]) == 1 -# assert "required fields" in response["FailedFindings"][0]["ErrorMessage"] - -# # Test empty resources array -# invalid_finding = { -# "AwsAccountId": DEFAULT_ACCOUNT_ID, -# "CreatedAt": "2024-01-01T00:00:00.000Z", -# "UpdatedAt": "2024-01-01T00:00:00.000Z", -# "Description": "Test finding", -# "GeneratorId": "test-generator", -# "Id": "test-finding-001", -# "ProductArn": f"arn:aws:securityhub:{client.meta.region_name}:{DEFAULT_ACCOUNT_ID}:product/{DEFAULT_ACCOUNT_ID}/default", -# "Resources": [], # Empty resources array -# "SchemaVersion": "2018-10-08", -# "Severity": {"Label": "HIGH"}, -# "Title": "Test Finding", -# "Types": ["Software and Configuration Checks"], -# } - -# response = client.batch_import_findings(Findings=[invalid_finding]) -# assert response["FailedCount"] == 1 -# assert response["SuccessCount"] == 0 -# assert len(response["FailedFindings"]) == 1 -# assert "must contain at least one resource" in response["FailedFindings"][0]["ErrorMessage"] +@mock_aws +def test_get_findings_invalid_parameters(): + """Test getting findings with invalid parameters.""" + client = boto3.client("securityhub", region_name="us-east-1") + + # Test invalid MaxResults (must be between 1 and 100) + with pytest.raises(ClientError) as exc: + client.get_findings(MaxResults=101) + + err = exc.value.response["Error"] + assert err["Code"] == "InvalidInputException" + assert "MaxResults must be a number between 1 and 100" in err["Message"]