From dc91c9cbf4f343a0d8483b404dd60b2e4b142cea Mon Sep 17 00:00:00 2001 From: "Desai, Kartikey H" Date: Wed, 6 Feb 2019 16:16:50 -0500 Subject: [PATCH 1/4] Initial fix for issue 86. Fixes #86 --- stix2/v21/sdo.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/stix2/v21/sdo.py b/stix2/v21/sdo.py index 37699a6..887fd0b 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,30 @@ 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 = [] + if self.get('latitude') is not None and self.get('longitude') is not None: + latitude = self.get('latitude') + longitude = self.get('longitude') + params.extend([str(latitude), str(longitude)]) + else: + properties = ['street_address', 'city', 'region', 'administrative_area', 'country', 'postal_code'] + params = [self.get(prop) for prop in properties if self.get(prop) is not None] + + return self._to_maps_url_creator(map_engine, params) + + def _to_maps_url_creator(self, map_engine, params): + if map_engine == "Google Maps": + 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 + else: + return "Other map engines are not currently supported." + class Malware(STIXDomainObject): # TODO: Add link From 8be704a5b991724c14349e6e461a6f19aa790aff Mon Sep 17 00:00:00 2001 From: "Desai, Kartikey H" Date: Thu, 7 Feb 2019 10:31:51 -0500 Subject: [PATCH 2/4] Update to_map_url and add tests. Fixes #86 --- stix2/test/v21/test_location.py | 73 +++++++++++++++++++++++++++++++++ stix2/v21/sdo.py | 11 ++--- 2 files changed, 79 insertions(+), 5 deletions(-) diff --git a/stix2/test/v21/test_location.py b/stix2/test/v21/test_location.py index 5a4e17a..9244b1d 100644 --- a/stix2/test/v21/test_location.py +++ b/stix2/test/v21/test_location.py @@ -263,3 +263,76 @@ def test_location_lat_or_lon_dependency_missing(data, msg): stix2.parse(data) assert msg in str(excinfo.value) + + +def test_map_url_long_lat_provided(): + EXPECTED_URL = "https://www.google.com/maps/search/?api=1&query=41.862401%2C-87.616001" + 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, + latitude=41.862401, + longitude=-87.616001, + ) + + loc_url = loc.to_maps_url() + assert loc_url == EXPECTED_URL + + +def test_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_map_url_multiple_props_and_long_lat_provided(): + EXPECTED_URL = "https://www.google.com/maps/search/?api=1&query=41.862401%2C-87.616001" + 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", + 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(): + 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, + 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) diff --git a/stix2/v21/sdo.py b/stix2/v21/sdo.py index 887fd0b..6fbb6f5 100644 --- a/stix2/v21/sdo.py +++ b/stix2/v21/sdo.py @@ -267,12 +267,13 @@ class Location(STIXDomainObject): def to_maps_url(self, map_engine="Google Maps"): params = [] - if self.get('latitude') is not None and self.get('longitude') is not None: - latitude = self.get('latitude') - longitude = self.get('longitude') + + 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', 'region', 'administrative_area', 'country', 'postal_code'] + 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_creator(map_engine, params) @@ -287,7 +288,7 @@ class Location(STIXDomainObject): final_url = url_base + quote_plus(url_ending) return final_url else: - return "Other map engines are not currently supported." + raise ValueError(map_engine + " is not a valid or currently-supported map engine") class Malware(STIXDomainObject): From edfe0ba51adbc4b5ecd581752cd35a8c7539da93 Mon Sep 17 00:00:00 2001 From: "Desai, Kartikey H" Date: Fri, 8 Feb 2019 09:37:27 -0500 Subject: [PATCH 3/4] Add support for Bing Maps and corresponding tests. Fixes #86 --- stix2/test/v21/test_location.py | 61 +++++++++++++++++++++++++++++++-- stix2/v21/sdo.py | 32 ++++++++++++----- 2 files changed, 81 insertions(+), 12 deletions(-) diff --git a/stix2/test/v21/test_location.py b/stix2/test/v21/test_location.py index 9244b1d..c8bf0fc 100644 --- a/stix2/test/v21/test_location.py +++ b/stix2/test/v21/test_location.py @@ -265,7 +265,7 @@ def test_location_lat_or_lon_dependency_missing(data, msg): assert msg in str(excinfo.value) -def test_map_url_long_lat_provided(): +def test_google_map_url_long_lat_provided(): EXPECTED_URL = "https://www.google.com/maps/search/?api=1&query=41.862401%2C-87.616001" now = dt.datetime(2019, 2, 7, 12, 34, 56, tzinfo=pytz.utc) @@ -282,7 +282,7 @@ def test_map_url_long_lat_provided(): assert loc_url == EXPECTED_URL -def test_map_url_multiple_props_no_long_lat_provided(): +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) @@ -300,7 +300,7 @@ def test_map_url_multiple_props_no_long_lat_provided(): assert loc_url == EXPECTED_URL -def test_map_url_multiple_props_and_long_lat_provided(): +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" now = dt.datetime(2019, 2, 7, 12, 34, 56, tzinfo=pytz.utc) @@ -336,3 +336,58 @@ def test_map_url_invalid_map_engine_provided(): 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" + 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, + 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" + 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("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" + 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", + 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 6fbb6f5..cff8ba6 100644 --- a/stix2/v21/sdo.py +++ b/stix2/v21/sdo.py @@ -276,20 +276,34 @@ class Location(STIXDomainObject): 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_creator(map_engine, params) + return self._to_maps_url_dispatcher(map_engine, params) - def _to_maps_url_creator(self, map_engine, params): + def _to_maps_url_dispatcher(self, map_engine, params): if map_engine == "Google Maps": - 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 + 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 From e976f0a9260d2be48b8cceeba96dbff4db5923d6 Mon Sep 17 00:00:00 2001 From: Chris Lenk Date: Fri, 8 Feb 2019 14:17:19 -0500 Subject: [PATCH 4/4] Trim location tests We can rely on defaults for some properties we aren't testing. --- stix2/test/v21/test_location.py | 56 +++++++-------------------------- 1 file changed, 12 insertions(+), 44 deletions(-) diff --git a/stix2/test/v21/test_location.py b/stix2/test/v21/test_location.py index c8bf0fc..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, @@ -266,24 +265,19 @@ def test_location_lat_or_lon_dependency_missing(data, msg): def test_google_map_url_long_lat_provided(): - EXPECTED_URL = "https://www.google.com/maps/search/?api=1&query=41.862401%2C-87.616001" - now = dt.datetime(2019, 2, 7, 12, 34, 56, tzinfo=pytz.utc) + expected_url = "https://www.google.com/maps/search/?api=1&query=41.862401%2C-87.616001" loc = stix2.v21.Location( - type="location", - id=LOCATION_ID, - created=now, - modified=now, latitude=41.862401, longitude=-87.616001, ) loc_url = loc.to_maps_url() - assert loc_url == EXPECTED_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" + 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( @@ -297,18 +291,13 @@ def test_google_map_url_multiple_props_no_long_lat_provided(): ) loc_url = loc.to_maps_url() - assert loc_url == EXPECTED_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" - now = dt.datetime(2019, 2, 7, 12, 34, 56, tzinfo=pytz.utc) + expected_url = "https://www.google.com/maps/search/?api=1&query=41.862401%2C-87.616001" 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", @@ -317,17 +306,11 @@ def test_google_map_url_multiple_props_and_long_lat_provided(): ) loc_url = loc.to_maps_url() - assert loc_url == EXPECTED_URL + assert loc_url == expected_url def test_map_url_invalid_map_engine_provided(): - 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, latitude=41.862401, longitude=-87.616001, ) @@ -339,49 +322,34 @@ def test_map_url_invalid_map_engine_provided(): def test_bing_map_url_long_lat_provided(): - EXPECTED_URL = "https://bing.com/maps/default.aspx?where1=41.862401%2C-87.616001&lvl=16" - now = dt.datetime(2019, 2, 7, 12, 34, 56, tzinfo=pytz.utc) + expected_url = "https://bing.com/maps/default.aspx?where1=41.862401%2C-87.616001&lvl=16" loc = stix2.v21.Location( - type="location", - id=LOCATION_ID, - created=now, - modified=now, latitude=41.862401, longitude=-87.616001, ) loc_url = loc.to_maps_url("Bing Maps") - assert loc_url == EXPECTED_URL + 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" - now = dt.datetime(2019, 2, 7, 12, 34, 56, tzinfo=pytz.utc) + 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( - 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("Bing Maps") - assert loc_url == EXPECTED_URL + 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" - now = dt.datetime(2019, 2, 7, 12, 34, 56, tzinfo=pytz.utc) + expected_url = "https://bing.com/maps/default.aspx?where1=41.862401%2C-87.616001&lvl=16" 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", @@ -390,4 +358,4 @@ def test_bing_map_url_multiple_props_and_long_lat_provided(): ) loc_url = loc.to_maps_url("Bing Maps") - assert loc_url == EXPECTED_URL + assert loc_url == expected_url