def test_in_string():
    f = Filters({'fld': ('fld', '~', 'malicious')}, True)
    assert f.match_payload_value(
        'fld',
        'this id a long description which contains malicious as the trigger word'
    )
    assert not f.match_payload_value(
        'fld',
        'this id a long description which does not contain the trigger word')
def test_or():
    # or logic
    f = Filters(
        {
            'fld': ('fld', 'in', 'here is a string'),
            'org': ('org', '=', 'abc')
        }, False)
    assert not f.match_payload_value('fld', 'isnt')
    assert f.match_payload_value('fld', 'is')
    assert f.match_payload_value('org', 'def')
def test_in():
    f = Filters({'fld': ('fld', 'in', ["aa", "bb", "cc"])}, True)
    assert f.match_payload_value('fld', 'aa')
    assert f.match_payload_value('fld', 'bb')
    assert not f.match_payload_value('fld', 'a')

    f = Filters({'fld': ('fld', 'in', ["aa", "bb", "cc"])}, True)
    assert not f.match_payload_value('fld', 'd')

    f = Filters({'fld': ('fld', 'in', ["aa", "bb", "cc"])}, True)
    assert not f.match_payload_value('fld', None)
def test_bool():
    f = Filters({'bool': ('bool', '==', True)}, True)
    assert f.match_payload_value('bool', True)

    f = Filters({'bool': ('bool', '==', True)}, False)
    assert not f.match_payload_value('bool', False)
    assert not f.match_payload_value('bool', '12abc')
    assert not f.match_payload_value('bool', 123)
    assert not f.match_payload_value('bool', None)
def test_string():
    f = Filters({'org': ('org', '==', '12abc')}, True)
    assert f.match_payload_value('org', '12abc')

    f = Filters({'org': ('org', '==', '12abc')}, False)
    assert not f.match_payload_value('org', 123)
    assert not f.match_payload_value('org', None)
    assert not f.match_payload_value('org', True)
def test_number():
    f = Filters({'org_id': ('org_id', '==', 123)}, True)
    assert f.match_payload_value('org_id', 123)
    assert not f.match_payload_value('org_id', 456)
    assert not f.match_payload_value('org_id', '123')
    assert not f.match_payload_value('org_id', None)
    assert not f.match_payload_value('org_id', True)
def test_unicode():
    f = Filters({'org': ('org', '==', u"ƀ Ɓ Ƃ ƃ Ƅ ƅ Ɔ Ƈ ƈ")}, True)
    assert f.match_payload_value('org', u'ƀ Ɓ Ƃ ƃ Ƅ ƅ Ɔ Ƈ ƈ')
    assert not f.match_payload_value('org', 123)
    assert not f.match_payload_value('org', '123')
    assert not f.match_payload_value('org', None)
    assert not f.match_payload_value('org', True)
def test_and():
    # and logic
    f = Filters(
        {
            'fld': ('fld', 'in', 'here is a string'),
            'org': ('org', '=', 'abc')
        }, True)
    assert f.match_payload_value('fld', 'here')
    assert f.match_payload_value('fld', 'string')
    assert not f.match_payload_value('fld', 'isnt')
    assert not f.match_payload_value('org', 'abc')
    def send_data(self, context, payload):
        """
        synchronize a object between Resilient instances. Steps performed are:
        1) Convert id references to values
        2) Match incident filter criteria
        3) cleanup loads, removing fields identified
        4) Perform synchronization, create or update
        :param context:
        :param payload:
        :return: None
        """
        type_name = context.type_info.get_pretty_type_name()

        orig_type_id = payload.get('id', None)
        if context.is_deleted:
            type_id = self.resilient_target.delete_type(
                self.resilient_source.rest_client.org_id,
                context.inc_id,
                type_name,
                payload,
                orig_type_id,
                delete=self.delete_incidents)

            return

        # set up the criteria to accept incident synchronizing, if any
        matching_criteria = Filters(self.match_list, self.match_operator_and)

        # check for attachments and artifacts with attachments
        if type_name == "attachment" or (type_name == "artifact"
                                         and payload.get("attachment", None)):
            cleaned_payload = self.clean_payload(context.inc_id, type_name,
                                                 payload)

            self.resilient_target.upload_attachment(
                self.resilient_source.rest_client,
                self.resilient_source.rest_client.org_id, context.inc_id,
                type_name, cleaned_payload, orig_type_id)
            return

        src_field_names = self.build_field_names(context,
                                                 self._is_datatable(payload))
        # get target org field names
        target_field_names = self.resilient_target.get_type_info(type_name)

        # convert selection lists and multi-selection lists to values, not id's
        try:
            # make sure datatables exist in new org
            if self._is_datatable(payload) and not target_field_names:
                LOG.warning(
                    u"Discarding datatable not found in target org: %s",
                    type_name)
                return

            if self._is_datatable(payload):
                new_payload = self.convert_datatable_values(
                    src_field_names, payload)
                discard_list = None
            else:
                # get the fields for the target resilient
                new_payload, discard_list = self.convert_values(
                    matching_criteria, type_name, src_field_names,
                    target_field_names, None, payload)

            # remove fields unrelated to creating/upgrading an object
            cleaned_payload = self.clean_payload(context.inc_id, type_name,
                                                 new_payload)

            # perform the creation or update in the new resilient org
            new_id, opr_type, create_list = self.resilient_target.create_update_type(
                self.resilient_source.rest_client.org_id, context.inc_id,
                type_name, cleaned_payload, orig_type_id)

            # create a note for the downstream incident when created
            if new_id and opr_type == "created" and type_name == "incident":
                note = u"Incident created from \nHost:{}\nOrg {}\nIncident {}".format(
                    self.resilient_source.get_source_host(),
                    self.resilient_source.rest_client.org_id, context.inc_id)
                if discard_list:
                    note = u"{}\n\nDiscarded fields: \n{}".format(
                        note, "\n".join(discard_list))

                payload = {"text": {"format": "text", "content": note}}
                sync_inc_id, new_type_id = self.resilient_target._create_type(
                    new_id, None, "note", payload)
                if sync_inc_id:
                    create_list.append("{}:{}".format('note', new_type_id))

            new_id and LOG.debug("%s:%s %s, additional updates: %s", type_name,
                                 new_id, opr_type, create_list)
        except MatchError as err:
            LOG.info("%s on Incident %s", err, context.inc_id)

            # create a sync entry so we know we skipped this incident
            self.resilient_target.dbsync.create_sync_row(
                self.resilient_source.rest_client.org_id, context.inc_id,
                type_name, orig_type_id, None, None, "filtered")
def test_none_or():
    # no filter
    f = Filters(None, False)
    assert f.match_payload_value('fld_not_found', 'is')
    assert f.match_payload_value('fld_not_found', 'isnt')
def test_not_in_string():
    f = Filters({'fld': ('fld', 'not in', 'here is a string')}, True)
    assert f.match_payload_value('fld', 'not')
    assert not f.match_payload_value('fld', 'here')
def test_is_not_none():
    f = Filters({'fld': ('fld', 'is not', None)}, True)
    assert f.match_payload_value('fld', 123)
    assert f.match_payload_value('fld', True)
    assert f.match_payload_value('fld', 'abc')
    assert not f.match_payload_value('fld', None)
def test_none_none():
    f = Filters(None, None)
    assert f.match_payload_value('fld_not_found', 'is')
def test_empty_string():
    f = Filters([], False)
    assert f.match_payload_value('fld_not_found', 'is')

    f = Filters([], True)
    assert f.match_payload_value('fld_not_found', 'is')
def test_int_ge():
    f = Filters({'int': ('int', '>=', 10)}, True)
    assert f.match_payload_value('int', 11)
    assert f.match_payload_value('int', 10)
    assert not f.match_payload_value('int', 5)
def test_none():
    f = Filters(None, True)
    assert f.match_payload_value('org_id', 123)
    assert f.match_payload_value('org_id', '123')
    assert f.match_payload_value('org_id', None)
    assert f.match_payload_value('org_id', True)
def test_string_to_list():
    f = Filters({'fld': ('fld', 'in', ['Phishing', 'Malicious'])}, True)
    assert f.match_payload_value('fld', 'Phishing')
    assert not f.match_payload_value('fld', 'hish')
def test_parse_field_matches():
    filter_dict, and_operator = parse_matching_criteria("fld == abc", "any")
    assert filter_dict == {"fld": ("fld", "==", "abc")}
    assert not and_operator
    f = Filters(filter_dict, and_operator)
    assert f.match_payload_value('fld', 'abc')

    filter_dict, and_operator = parse_matching_criteria("fld > 10 ", "all")
    assert filter_dict == {"fld": ("fld", ">", 10)}
    assert and_operator
    f = Filters(filter_dict, and_operator)
    assert f.match_payload_value('fld', 11)

    filter_dict, and_operator = parse_matching_criteria("fld = True", "all")
    assert filter_dict == {"fld": ("fld", "==", True)}
    f = Filters(filter_dict, and_operator)
    assert f.match_payload_value('fld', True)

    filter_dict, and_operator = parse_matching_criteria("fld ~ list", "all")
    assert filter_dict == {"fld": ("fld", "~", "list")}
    f = Filters(filter_dict, and_operator)
    assert f.match_payload_value('fld', 'something is in this list')

    filter_dict, and_operator = parse_matching_criteria(
        "fld not in something is a list", "all")
    assert filter_dict == {"fld": ("fld", "not in", "something is a list")}
    f = Filters(filter_dict, and_operator)
    assert f.match_payload_value('fld', 'nothing')

    filter_dict, and_operator = parse_matching_criteria(
        "fld in ['Phishing', 'Malware']", "all")
    assert filter_dict == {"fld": ("fld", " in ", ['Phishing', 'Malware'])}
    f = Filters(filter_dict, and_operator)
    assert f.match_payload_value('fld', 'Phishing')