def test_parse_email_address(data): odata = stix2.parse_observable(data, {"0": "user-account"}, version='2.0') assert odata.type == "email-addr" odata_str = re.compile('"belongs_to_ref": "0"', re.DOTALL).sub('"belongs_to_ref": "3"', data) with pytest.raises(stix2.exceptions.InvalidObjRefError): stix2.parse_observable(odata_str, {"0": "user-account"}, version='2.0')
def test_parse_observable_with_unregistered_custom_extension(data): with pytest.raises(ValueError) as excinfo: stix2.parse_observable(data, version='2.0') assert "Can't parse unknown extension type" in str(excinfo.value) parsed_ob = stix2.parse_observable(data, allow_custom=True, version='2.0') assert parsed_ob['extensions']['x-foobar-ext']['property1'] == 'foo' assert not isinstance(parsed_ob['extensions']['x-foobar-ext'], stix2.base._STIXBase)
def test_parse_invalid_custom_observable_object(): nt_string = """{ "property1": "something" }""" with pytest.raises(stix2.exceptions.ParseError) as excinfo: stix2.parse_observable(nt_string, version='2.0') assert "Can't parse observable with no 'type' property" in str(excinfo.value)
def test_parse_unregistered_custom_observable_object_with_no_type(): nt_string = """{ "property1": "something" }""" with pytest.raises(stix2.exceptions.ParseError) as excinfo: stix2.parse_observable(nt_string, allow_custom=True, version='2.0') assert "Can't parse observable with no 'type' property" in str(excinfo.value)
def test_parse_unregistered_custom_observable_object(): nt_string = """{ "type": "x-foobar-observable", "property1": "something" }""" with pytest.raises(stix2.exceptions.ParseError) as excinfo: stix2.parse_observable(nt_string) assert "Can't parse unknown observable type" in str(excinfo.value)
def test_parse_email_message_not_multipart(data): valid_refs = { "0": "email-addr", "1": "email-addr", } with pytest.raises(stix2.exceptions.DependentPropertiesError) as excinfo: stix2.parse_observable(data, valid_refs, version='2.0') assert excinfo.value.cls == stix2.v20.EmailMessage assert excinfo.value.dependencies == [("is_multipart", "body")]
def test_generation_min_props(generator_min_props, spec_name): obj_dict = generator_min_props.generate(spec_name) # Distinguish between a STIX object spec and a "helper" spec used # by STIX object specs. Only makes sense to stix2.parse() the former. if spec_name[0].isupper(): try: stix2.parse(obj_dict, version="2.1") except stix2.exceptions.ParseError: # Maybe we can use this to mean this was an SCO? # Try a re-parse as an SCO. Need a better way to make the # distinction... stix2.parse_observable(obj_dict, version="2.1")
def test_parse_unregistered_custom_observable_object(): nt_string = """{ "type": "x-foobar-observable", "property1": "something" }""" with pytest.raises(stix2.exceptions.CustomContentError) as excinfo: stix2.parse_observable(nt_string) assert "Can't parse unknown observable type" in str(excinfo.value) parsed_custom = stix2.parse_observable(nt_string, allow_custom=True) assert parsed_custom['property1'] == 'something' with pytest.raises(AttributeError) as excinfo: assert parsed_custom.property1 == 'something' assert not isinstance(parsed_custom, stix2.core._STIXBase)
def test_parse_email_message_with_at_least_one_error(data): valid_refs = { "0": "email-message", "1": "email-addr", "2": "email-addr", "3": "email-addr", "4": "artifact", "5": "file", } with pytest.raises(InvalidValueError) as excinfo: stix2.parse_observable(data, valid_refs, version='2.0') assert excinfo.value.cls == stix2.v20.EmailMessage assert "At least one of the" in str(excinfo.value) assert "must be populated" in str(excinfo.value)
def test_parse_observable_with_unregistered_custom_extension(): input_str = """{ "type": "domain-name", "value": "example.com", "extensions": { "x-foobar-ext": { "property1": "foo", "property2": 12 } } }""" with pytest.raises(ValueError) as excinfo: stix2.parse_observable(input_str) assert "Can't parse Unknown extension type" in str(excinfo.value)
def test_parse_basic_tcp_traffic(data): odata = stix2.parse_observable(data, {"0": "ipv4-addr", "1": "ipv4-addr"}) assert odata.type == "network-traffic" assert odata.src_ref == "0" assert odata.dst_ref == "1" assert odata.protocols == ["tcp"]
def test_parse_email_message_with_at_least_one_error(data): valid_refs = { "0": "email-message", "1": "email-addr", "2": "email-addr", "3": "email-addr", "4": "artifact", "5": "file", } with pytest.raises(stix2.exceptions.AtLeastOnePropertyError) as excinfo: stix2.parse_observable(data, valid_refs) assert excinfo.value.cls == stix2.EmailMIMEComponent assert excinfo.value.properties == ["body", "body_raw_ref"] assert "At least one of the" in str(excinfo.value) assert "must be populated" in str(excinfo.value)
def test_parse_custom_observable_object(): nt_string = """{ "type": "x-new-observable", "property1": "something" }""" nt = stix2.parse_observable(nt_string, []) assert nt.property1 == 'something'
def test_parse_custom_observable_object(): nt_string = """{ "type": "x-new-observable", "property1": "something" }""" nt = stix2.parse_observable(nt_string, [], version='2.0') assert isinstance(nt, stix2.base._STIXBase) assert nt.property1 == 'something'
def test_generation_random_props(generator_random_props, spec_name, num_trials): for _ in range(num_trials): obj_dict = generator_random_props.generate(spec_name) # Ensure json-serializability json.dumps(obj_dict, ensure_ascii=False) # Distinguish between a STIX object spec and a "helper" spec used # by STIX object specs. Only makes sense to stix2.parse() the former. if spec_name[0].isupper(): try: stix2.parse(obj_dict, version="2.1") except stix2.exceptions.ParseError: # Maybe we can use this to mean this was an SCO? # Try a re-parse as an SCO. Need a better way to make the # distinction... stix2.parse_observable(obj_dict, version="2.1")
def test_parse_observable_with_unregistered_custom_extension(): input_str = """{ "type": "domain-name", "value": "example.com", "extensions": { "x-foobar-ext": { "property1": "foo", "property2": 12 } } }""" with pytest.raises(ValueError) as excinfo: stix2.parse_observable(input_str) assert "Can't parse unknown extension type" in str(excinfo.value) parsed_ob = stix2.parse_observable(input_str, allow_custom=True) assert parsed_ob['extensions']['x-foobar-ext']['property1'] == 'foo' assert not isinstance(parsed_ob['extensions']['x-foobar-ext'], stix2.core._STIXBase)
def test_parse_email_message(data): valid_refs = { "0": "email-message", "1": "email-addr", "2": "email-addr", "3": "email-addr", "4": "artifact", "5": "file", } odata = stix2.parse_observable(data, valid_refs, version='2.0') assert odata.type == "email-message" assert odata.body_multipart[0].content_disposition == "inline"
def test_parse_observable_with_custom_extension(): input_str = """{ "type": "domain-name", "value": "example.com", "extensions": { "x-new-ext": { "property1": "foo", "property2": 12 } } }""" parsed = stix2.parse_observable(input_str, version='2.0') assert parsed.extensions['x-new-ext'].property2 == 12
def _stix_parse(self, stix_dict): """Parses a dictionary into an actual STIX2 object. Args: stix_dict: The STIX dictionary to use to create the STIX obejct. Raises: ValidationError: If the dictionary does not comply with the STIX2 standard. """ if 'type' not in stix_dict: stix_dict['type'] = self.type try: self._stix_object = parse_observable(stix_dict) except (exceptions.MissingPropertiesError, exceptions.ParseError, exceptions.ExtraPropertiesError) as err: raise ValidationError(str(err))
def test_parse_basic_tcp_traffic_with_error(data): with pytest.raises(stix2.exceptions.AtLeastOnePropertyError) as excinfo: stix2.parse_observable(data, {"4": "network-traffic"}, version='2.0') assert excinfo.value.cls == stix2.v20.NetworkTraffic assert excinfo.value.properties == ["dst_ref", "src_ref"]