diff --git a/stix2/test/v21/test_location.py b/stix2/test/v21/test_location.py index 5a4e17a..c734334 100644 --- a/stix2/test/v21/test_location.py +++ b/stix2/test/v21/test_location.py @@ -50,7 +50,6 @@ def test_location_with_some_required_properties(): now = dt.datetime(2016, 4, 6, 20, 3, 0, tzinfo=pytz.utc) loc = stix2.v21.Location( - type="location", id=LOCATION_ID, created=now, modified=now, @@ -263,3 +262,100 @@ def test_location_lat_or_lon_dependency_missing(data, msg): stix2.parse(data) assert msg in str(excinfo.value) + + +def test_google_map_url_long_lat_provided(): + expected_url = "https://www.google.com/maps/search/?api=1&query=41.862401%2C-87.616001" + + loc = stix2.v21.Location( + latitude=41.862401, + longitude=-87.616001, + ) + + loc_url = loc.to_maps_url() + assert loc_url == expected_url + + +def test_google_map_url_multiple_props_no_long_lat_provided(): + expected_url = "https://www.google.com/maps/search/?api=1&query=1410+Museum+Campus+Drive%2C+Chicago%2C+IL+60605%2CUnited+States+of+America%2CNorth+America" + now = dt.datetime(2019, 2, 7, 12, 34, 56, tzinfo=pytz.utc) + + loc = stix2.v21.Location( + type="location", + id=LOCATION_ID, + created=now, + modified=now, + region="North America", + country="United States of America", + street_address="1410 Museum Campus Drive, Chicago, IL 60605", + ) + + loc_url = loc.to_maps_url() + assert loc_url == expected_url + + +def test_google_map_url_multiple_props_and_long_lat_provided(): + expected_url = "https://www.google.com/maps/search/?api=1&query=41.862401%2C-87.616001" + + loc = stix2.v21.Location( + region="North America", + country="United States of America", + street_address="1410 Museum Campus Drive, Chicago, IL 60605", + latitude=41.862401, + longitude=-87.616001, + ) + + loc_url = loc.to_maps_url() + assert loc_url == expected_url + + +def test_map_url_invalid_map_engine_provided(): + loc = stix2.v21.Location( + latitude=41.862401, + longitude=-87.616001, + ) + + with pytest.raises(ValueError) as excinfo: + loc.to_maps_url("Fake Maps") + + assert "is not a valid or currently-supported map engine" in str(excinfo.value) + + +def test_bing_map_url_long_lat_provided(): + expected_url = "https://bing.com/maps/default.aspx?where1=41.862401%2C-87.616001&lvl=16" + + loc = stix2.v21.Location( + latitude=41.862401, + longitude=-87.616001, + ) + + loc_url = loc.to_maps_url("Bing Maps") + assert loc_url == expected_url + + +def test_bing_map_url_multiple_props_no_long_lat_provided(): + expected_url = "https://bing.com/maps/default.aspx?where1=1410+Museum+Campus+Drive%2C+Chicago%2C+IL+60605%2CUnited+States+of+America%2CNorth+America&lvl=16" + + loc = stix2.v21.Location( + region="North America", + country="United States of America", + street_address="1410 Museum Campus Drive, Chicago, IL 60605", + ) + + loc_url = loc.to_maps_url("Bing Maps") + assert loc_url == expected_url + + +def test_bing_map_url_multiple_props_and_long_lat_provided(): + expected_url = "https://bing.com/maps/default.aspx?where1=41.862401%2C-87.616001&lvl=16" + + loc = stix2.v21.Location( + region="North America", + country="United States of America", + street_address="1410 Museum Campus Drive, Chicago, IL 60605", + latitude=41.862401, + longitude=-87.616001, + ) + + loc_url = loc.to_maps_url("Bing Maps") + assert loc_url == expected_url diff --git a/stix2/v21/sdo.py b/stix2/v21/sdo.py index 37699a6..cff8ba6 100644 --- a/stix2/v21/sdo.py +++ b/stix2/v21/sdo.py @@ -3,6 +3,8 @@ from collections import OrderedDict import itertools +from six.moves.urllib.parse import quote_plus + from ..core import STIXDomainObject from ..custom import _custom_object_builder from ..properties import ( @@ -263,6 +265,45 @@ class Location(STIXDomainObject): self._check_properties_dependency(['latitude'], ['longitude']) self._check_properties_dependency(['longitude'], ['latitude']) + def to_maps_url(self, map_engine="Google Maps"): + params = [] + + latitude = self.get('latitude', None) + longitude = self.get('longitude', None) + if latitude is not None and longitude is not None: + params.extend([str(latitude), str(longitude)]) + else: + properties = ['street_address', 'city', 'country', 'region', 'administrative_area', 'postal_code'] + params = [self.get(prop) for prop in properties if self.get(prop) is not None] + + return self._to_maps_url_dispatcher(map_engine, params) + + def _to_maps_url_dispatcher(self, map_engine, params): + if map_engine == "Google Maps": + return self._to_google_maps_url(params) + elif map_engine == "Bing Maps": + return self._to_bing_maps_url(params) + else: + raise ValueError(map_engine + " is not a valid or currently-supported map engine") + + def _to_google_maps_url(self, params): + url_base = "https://www.google.com/maps/search/?api=1&query=" + url_ending = params[0] + for i in range(1, len(params)): + url_ending = url_ending + "," + params[i] + + final_url = url_base + quote_plus(url_ending) + return final_url + + def _to_bing_maps_url(self, params): + url_base = "https://bing.com/maps/default.aspx?where1=" + url_ending = params[0] + for i in range(1, len(params)): + url_ending = url_ending + "," + params[i] + + final_url = url_base + quote_plus(url_ending) + "&lvl=16" # level 16 zoom so long/lat searches shown more clearly + return final_url + class Malware(STIXDomainObject): # TODO: Add link