def test_new_version_new_rules_same_objects(self, mock_table: mock.MagicMock):
        """A previously analyzed binary matches a new YARA rule - create DB entry and alert."""
        match_table = analyzer_aws_lib.DynamoMatchTable(MOCK_DYNAMO_TABLE_NAME)
        match_table._table.query = lambda **kwargs: {
            'Items': [
                {
                    'AnalyzerVersion': 1,
                    'MatchedRules': {'file.yara:rule_name'},
                    'S3Objects': {'S3:test-bucket:test-key'}
                }
            ]
        }
        self._binary.yara_matches.append(
            yara_mocks.YaraMatchMock('new_file.yara', 'different_rule_name'))

        needs_alert = match_table.save_matches(self._binary, 2)

        self.assertTrue(needs_alert)
        mock_table.assert_has_calls([
            mock.call.Table().put_item(Item={
                'SHA256': 'Computed_SHA',
                'AnalyzerVersion': 2,
                'MatchedRules': {'new_file.yara:different_rule_name', 'file.yara:rule_name'},
                'MD5': 'Computed_MD5',
                'S3LastModified': 'time:right_now',
                'S3Metadata': {'test-filename': 'test.txt'},
                'S3Objects': {'S3:test-bucket:test-key'}})
        ])
 def setUp(self):
     """Before each test, setup a BinaryInfo."""
     self._binary = binary_info.BinaryInfo('test-bucket', 'test-key', None)
     self._binary.s3_last_modified = 'time:right_now'
     self._binary.s3_metadata = {'test-filename': 'test.txt'}
     self._binary.computed_md5 = 'Computed_MD5'
     self._binary.computed_sha = 'Computed_SHA'
     self._binary.yara_matches = [yara_mocks.YaraMatchMock('file.yara', 'rule_name')]
    def test_old_version(self):
        """Analyze with an older version of the Lambda function - update DB but do not alert."""
        self._add_item()
        self._binary.yara_matches.append(
            yara_mocks.YaraMatchMock('new_file.yara', 'better_rule_name'))
        needs_alert = self._match_table.save_matches(self._binary, 0)

        self.assertFalse(needs_alert)  # Don't alert even if there was a change
        self.assertEqual([(self._binary.computed_sha, '0'),
                          (self._binary.computed_sha, '1')],
                         sorted(self._mock_dynamo_table.items))
    def test_new_version_new_rules_same_objects(self):
        """A previously analyzed binary matches a new YARA rule - create DB entry and alert."""
        self._add_item()
        self._binary.yara_matches.append(
            yara_mocks.YaraMatchMock('new_file.yara', 'better_rule_name'))
        needs_alert = self._match_table.save_matches(self._binary, 2)

        self.assertTrue(needs_alert)
        stored_item = self._mock_dynamo_table.items[(self._binary.computed_sha,
                                                     '2')]
        self.assertTrue(
            'new_file.yara' in str(stored_item.key_value_dict.values()))
    def setUp(self):
        """Before each test, create the mock environment."""
        # Create a mock Dynamo table.
        self._mock_dynamo_client = boto3_mocks.MockDynamoDBClient(
            MOCK_DYNAMO_TABLE_NAME, HASH_KEY, RANGE_KEY)
        self._mock_dynamo_table = self._mock_dynamo_client.tables[
            MOCK_DYNAMO_TABLE_NAME]

        # Setup mocks.
        boto3.client = mock.MagicMock(return_value=self._mock_dynamo_client)

        self._binary = binary_info.BinaryInfo('Bucket', 'Key', None)
        self._binary.reported_md5 = 'Original_MD5'
        self._binary.observed_path = '/bin/path/run.exe'
        self._binary.yara_matches = [
            yara_mocks.YaraMatchMock('file.yara', 'rule_name')
        ]
        self._binary.computed_sha = 'Computed_SHA'
        self._binary.computed_md5 = 'Computed_MD5'

        self._match_table = analyzer_aws_lib.DynamoMatchTable(
            MOCK_DYNAMO_TABLE_NAME)
    def test_old_version(self, mock_logger: mock.MagicMock, mock_table: mock.MagicMock):
        """Analyze with an older version of the Lambda function - update DB but do not alert."""
        match_table = analyzer_aws_lib.DynamoMatchTable(MOCK_DYNAMO_TABLE_NAME)
        match_table._table.query = lambda **kwargs: {
            'Items': [
                {
                    'AnalyzerVersion': 1,
                    'MatchedRules': {'file.yara:rule_name'},
                    'S3Objects': {'S3:test-bucket:test-key'}
                }
            ]
        }
        self._binary.yara_matches.append(
            yara_mocks.YaraMatchMock('new_file.yara', 'different_rule_name'))
        needs_alert = match_table.save_matches(self._binary, 0)

        self.assertFalse(needs_alert)  # Don't alert even if there was a change
        mock_logger.assert_has_calls([
            mock.call.warning(
                'Current Lambda version %d is < version %d from previous analysis', 0, 1
            )
        ])
        mock_table.assert_has_calls([mock.call.Table().put_item(Item=mock.ANY)])