From b3d614eac928a9eea277d2a3408a08bbd64b6604 Mon Sep 17 00:00:00 2001 From: davidt99 Date: Mon, 6 Jul 2026 14:16:30 +0300 Subject: [PATCH] feat: add PasswordProtectedArchiveError for password-protected archive submissions Co-Authored-By: Claude Opus 4.8 (1M context) --- CHANGES | 4 ++++ intezer_sdk/__init__.py | 2 +- intezer_sdk/_api.py | 3 +++ intezer_sdk/errors.py | 7 +++++++ tests/unit/test_file_analysis.py | 28 ++++++++++++++++++++++++++++ 5 files changed, 43 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 191e86b..6d31182 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +1.27.5 +------- +- Add PasswordProtectedArchiveError raised when a submitted archive is password protected + 1.27.4 ------- - Add alert_update_time field to alert and remove case_association_time diff --git a/intezer_sdk/__init__.py b/intezer_sdk/__init__.py index f9b76ba..cbe92da 100644 --- a/intezer_sdk/__init__.py +++ b/intezer_sdk/__init__.py @@ -1 +1 @@ -__version__ = '1.27.4' +__version__ = '1.27.5' diff --git a/intezer_sdk/_api.py b/intezer_sdk/_api.py index 5c2b9cd..d620e6d 100644 --- a/intezer_sdk/_api.py +++ b/intezer_sdk/_api.py @@ -970,6 +970,9 @@ def _assert_analysis_response_status_code(response: Response): if error == 'Invalid url': raise errors.InvalidUrlError(response) + if error == 'Archive is password protected': + raise errors.PasswordProtectedArchiveError(response) + raise errors.ServerError(f'Server returned bad request error: {error}, details: {details}', response) case HTTPStatus.CREATED: pass diff --git a/intezer_sdk/errors.py b/intezer_sdk/errors.py index 9744eef..a1a5737 100644 --- a/intezer_sdk/errors.py +++ b/intezer_sdk/errors.py @@ -188,6 +188,13 @@ def __init__(self, response: requests.Response): super().__init__('Invalid url', response) +class PasswordProtectedArchiveError(ServerError): + """Raised when the submitted archive is password protected and cannot be extracted.""" + + def __init__(self, response: requests.Response): + super().__init__('Archive is password protected', response) + + class AnalysisSkippedByRuleError(ServerError): def __init__(self, response: requests.Response): super().__init__('Analysis skipped by rule', response) diff --git a/tests/unit/test_file_analysis.py b/tests/unit/test_file_analysis.py index db03a59..b2ad2d8 100644 --- a/tests/unit/test_file_analysis.py +++ b/tests/unit/test_file_analysis.py @@ -552,6 +552,34 @@ def test_send_analysis_by_sha256_that_is_too_large_raise_error(self): with self.assertRaises(errors.FileTooLargeError): analysis.send() + def test_send_analysis_of_password_protected_archive_raise_error(self): + # Arrange + with responses.RequestsMock() as mock: + mock.add('POST', + url=f'{self.full_url}/analyze', + status=HTTPStatus.BAD_REQUEST, + json={'error': 'Archive is password protected'}) + analysis = FileAnalysis(file_path='a') + + with patch(self.patch_prop, mock_open_bytes()): + # Act + Assert + with self.assertRaises(errors.PasswordProtectedArchiveError): + analysis.send() + + def test_password_protected_archive_error_is_a_server_error(self): + # Arrange + with responses.RequestsMock() as mock: + mock.add('POST', + url=f'{self.full_url}/analyze', + status=HTTPStatus.BAD_REQUEST, + json={'error': 'Archive is password protected'}) + analysis = FileAnalysis(file_path='a') + + with patch(self.patch_prop, mock_open_bytes()): + # Act + Assert + with self.assertRaises(errors.ServerError): + analysis.send() + def test_send_analysis_by_sha256_with_expired_jwt_token_gets_new_token(self): # Arrange analysis = FileAnalysis(file_hash='a' * 64)