diff --git a/server/extension/cdb_dataservices_server--0.24.1--0.24.2.sql b/server/extension/cdb_dataservices_server--0.24.1--0.24.2.sql new file mode 100644 index 0000000..47ffa98 --- /dev/null +++ b/server/extension/cdb_dataservices_server--0.24.1--0.24.2.sql @@ -0,0 +1,5 @@ +--DO NOT MODIFY THIS FILE, IT IS GENERATED AUTOMATICALLY FROM SOURCES +-- Complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "ALTER EXTENSION cdb_dataservices_server UPDATE TO '0.24.2'" to load this file. \quit + +-- HERE goes your code to upgrade/downgrade diff --git a/server/extension/cdb_dataservices_server--0.24.2--0.24.1.sql b/server/extension/cdb_dataservices_server--0.24.2--0.24.1.sql new file mode 100644 index 0000000..8e9d84c --- /dev/null +++ b/server/extension/cdb_dataservices_server--0.24.2--0.24.1.sql @@ -0,0 +1,5 @@ +--DO NOT MODIFY THIS FILE, IT IS GENERATED AUTOMATICALLY FROM SOURCES +-- Complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "ALTER EXTENSION cdb_dataservices_server UPDATE TO '0.24.1'" to load this file. \quit + +-- HERE goes your code to upgrade/downgrade diff --git a/server/extension/cdb_dataservices_server.control b/server/extension/cdb_dataservices_server.control index 487ed63..1512a6d 100644 --- a/server/extension/cdb_dataservices_server.control +++ b/server/extension/cdb_dataservices_server.control @@ -1,5 +1,5 @@ comment = 'CartoDB dataservices server extension' -default_version = '0.24.1' +default_version = '0.24.2' requires = 'plpythonu, plproxy, postgis, cdb_geocoder' superuser = true schema = cdb_dataservices_server diff --git a/server/extension/cdb_dataservices_server--0.24.0--0.24.1.sql b/server/extension/old_versions/cdb_dataservices_server--0.24.0--0.24.1.sql similarity index 100% rename from server/extension/cdb_dataservices_server--0.24.0--0.24.1.sql rename to server/extension/old_versions/cdb_dataservices_server--0.24.0--0.24.1.sql diff --git a/server/extension/cdb_dataservices_server--0.24.1--0.24.0.sql b/server/extension/old_versions/cdb_dataservices_server--0.24.1--0.24.0.sql similarity index 100% rename from server/extension/cdb_dataservices_server--0.24.1--0.24.0.sql rename to server/extension/old_versions/cdb_dataservices_server--0.24.1--0.24.0.sql diff --git a/server/extension/cdb_dataservices_server--0.24.1.sql b/server/extension/old_versions/cdb_dataservices_server--0.24.1.sql similarity index 100% rename from server/extension/cdb_dataservices_server--0.24.1.sql rename to server/extension/old_versions/cdb_dataservices_server--0.24.1.sql diff --git a/server/extension/sql/50_namedplaces.sql b/server/extension/sql/50_namedplaces.sql index 338591d..ca9196e 100644 --- a/server/extension/sql/50_namedplaces.sql +++ b/server/extension/sql/50_namedplaces.sql @@ -1,10 +1,11 @@ ---- cdb_geocode_namedplace_point(city_name text) CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_geocode_namedplace_point(username text, orgname text, city_name text) RETURNS Geometry AS $$ + import spiexceptions try: mapzen_plan = plpy.prepare("SELECT cdb_dataservices_server._cdb_mapzen_geocode_namedplace($1, $2, $3) as point;", ["text", "text", "text"]) return plpy.execute(mapzen_plan, [username, orgname, city_name])[0]['point'] - except BaseException as e: + except spiexceptions.ExternalRoutineException as e: internal_plan = plpy.prepare("SELECT cdb_dataservices_server._cdb_internal_geocode_namedplace($1, $2, $3) as point;", ["text", "text", "text"]) return plpy.execute(internal_plan, [username, orgname, city_name])[0]['point'] $$ LANGUAGE plpythonu; @@ -12,10 +13,11 @@ $$ LANGUAGE plpythonu; ---- cdb_geocode_namedplace_point(city_name text, country_name text) CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_geocode_namedplace_point(username text, orgname text, city_name text, country_name text) RETURNS Geometry AS $$ + import spiexceptions try: mapzen_plan = plpy.prepare("SELECT cdb_dataservices_server._cdb_mapzen_geocode_namedplace($1, $2, $3, NULL, $4) as point;", ["text", "text", "text", "text"]) return plpy.execute(mapzen_plan, [username, orgname, city_name, country_name])[0]['point'] - except BaseException as e: + except spiexceptions.ExternalRoutineException as e: internal_plan = plpy.prepare("SELECT cdb_dataservices_server._cdb_internal_geocode_namedplace($1, $2, $3, NULL, $4) as point;", ["text", "text", "text", "text"]) return plpy.execute(internal_plan, [username, orgname, city_name, country_name])[0]['point'] $$ LANGUAGE plpythonu; @@ -23,10 +25,11 @@ $$ LANGUAGE plpythonu; ---- cdb_geocode_namedplace_point(city_name text, admin1_name text, country_name text) CREATE OR REPLACE FUNCTION cdb_dataservices_server.cdb_geocode_namedplace_point(username text, orgname text, city_name text, admin1_name text, country_name text) RETURNS Geometry AS $$ + import spiexceptions try: mapzen_plan = plpy.prepare("SELECT cdb_dataservices_server._cdb_mapzen_geocode_namedplace($1, $2, $3, $4, $5) as point;", ["text", "text", "text", "text", "text"]) return plpy.execute(mapzen_plan, [username, orgname, city_name, admin1_name, country_name])[0]['point'] - except BaseException as e: + except spiexceptions.ExternalRoutineException as e: internal_plan = plpy.prepare("SELECT cdb_dataservices_server._cdb_internal_geocode_namedplace($1, $2, $3, $4, $5) as point;", ["text", "text", "text", "text", "text"]) return plpy.execute(internal_plan, [username, orgname, city_name, admin1_name, country_name])[0]['point'] $$ LANGUAGE plpythonu; diff --git a/server/lib/python/cartodb_services/cartodb_services/google/exceptions.py b/server/lib/python/cartodb_services/cartodb_services/google/exceptions.py index f4a3015..4a0e15e 100644 --- a/server/lib/python/cartodb_services/cartodb_services/google/exceptions.py +++ b/server/lib/python/cartodb_services/cartodb_services/google/exceptions.py @@ -2,6 +2,8 @@ # -*- coding: utf-8 -*- import json +class InvalidGoogleCredentials(Exception): + pass class BadGeocodingParams(Exception): def __init__(self, value): diff --git a/server/lib/python/cartodb_services/cartodb_services/google/geocoder.py b/server/lib/python/cartodb_services/cartodb_services/google/geocoder.py index 2a836f3..a8458a4 100644 --- a/server/lib/python/cartodb_services/cartodb_services/google/geocoder.py +++ b/server/lib/python/cartodb_services/cartodb_services/google/geocoder.py @@ -1,15 +1,18 @@ #!/usr/local/bin/python # -*- coding: utf-8 -*- +import base64 import googlemaps -from exceptions import MalformedResult +from exceptions import MalformedResult, InvalidGoogleCredentials class GoogleMapsGeocoder: """A Google Maps Geocoder wrapper for python""" def __init__(self, client_id, client_secret, logger): + if not self._valid_credentials(client_secret): + raise InvalidGoogleCredentials('Invalid google secret key') self.client_id = self._clean_client_id(client_id) self.client_secret = client_secret self.geocoder = googlemaps.Client( @@ -36,7 +39,7 @@ class GoogleMapsGeocoder: return [longitude, latitude] def _build_optional_parameters(self, city=None, state=None, - country=None): + country=None): optional_params = {} if city: optional_params['locality'] = city @@ -49,3 +52,13 @@ class GoogleMapsGeocoder: def _clean_client_id(self, client_id): # Consistency with how the client_id is saved in metadata return client_id.replace('client=', '') + + def _valid_credentials(self, private_key): + try: + # Only fails if the string dont have a correct padding for b64 + # but this way we could provide a more clear error than + # TypeError: Incorrect padding + base64.b64decode(private_key) + return True + except TypeError: + return False diff --git a/server/lib/python/cartodb_services/cartodb_services/metrics/config.py b/server/lib/python/cartodb_services/cartodb_services/metrics/config.py index ee849c3..6ad260f 100644 --- a/server/lib/python/cartodb_services/cartodb_services/metrics/config.py +++ b/server/lib/python/cartodb_services/cartodb_services/metrics/config.py @@ -359,10 +359,10 @@ class GeocoderConfig(ServiceConfig): if self._geocoder_provider == self.NOKIA_GEOCODER: if not set(self.NOKIA_GEOCODER_REDIS_MANDATORY_KEYS).issubset(set(filtered_config.keys())) or \ not self.heremaps_app_id or not self.heremaps_app_code: - raise ConfigException("""Some mandatory parameter/s for Nokia geocoder are missing. Check it please""") + raise ConfigException("""Heremaps app id or app code is not set up""") elif self._geocoder_provider == self.GOOGLE_GEOCODER: if self.GOOGLE_GEOCODER_API_KEY not in filtered_config.keys(): - raise ConfigException("""Google geocoder need the mandatory parameter 'google_maps_private_key'""") + raise ConfigException("""Google geocoder private key is not set up""") elif self._geocoder_provider == self.MAPZEN_GEOCODER: if not self.mapzen_api_key: raise ConfigException("""Mapzen config is not set up""") diff --git a/server/lib/python/cartodb_services/setup.py b/server/lib/python/cartodb_services/setup.py index 681e064..1517adb 100644 --- a/server/lib/python/cartodb_services/setup.py +++ b/server/lib/python/cartodb_services/setup.py @@ -10,7 +10,7 @@ from setuptools import setup, find_packages setup( name='cartodb_services', - version='0.15.0', + version='0.15.1', description='CartoDB Services API Python Library', diff --git a/server/lib/python/cartodb_services/test/test_googlegeocoder.py b/server/lib/python/cartodb_services/test/test_googlegeocoder.py index 5593560..f700ec3 100644 --- a/server/lib/python/cartodb_services/test/test_googlegeocoder.py +++ b/server/lib/python/cartodb_services/test/test_googlegeocoder.py @@ -6,9 +6,7 @@ import requests_mock from mock import Mock from cartodb_services.google import GoogleMapsGeocoder -from cartodb_services.google.exceptions import BadGeocodingParams -from cartodb_services.google.exceptions import NoGeocodingParams -from cartodb_services.google.exceptions import MalformedResult +from cartodb_services.google.exceptions import MalformedResult, InvalidGoogleCredentials requests_mock.Mocker.TEST_PREFIX = 'test_' @@ -92,7 +90,8 @@ class GoogleGeocoderTestCase(unittest.TestCase): def setUp(self): logger = Mock() self.geocoder = GoogleMapsGeocoder('dummy_client_id', - 'MgxyOFxjZXIyOGO52jJlMzEzY1Oqy4hsO49E', logger) + 'MgxyOFxjZXIyOGO52jJlMzEzY1Oqy4hsO49E', + logger) def test_geocode_address_with_valid_params(self, req_mock): req_mock.register_uri('GET', self.GOOGLE_MAPS_GEOCODER_URL, @@ -119,3 +118,9 @@ class GoogleGeocoderTestCase(unittest.TestCase): searchtext='Calle Eloy Gonzalo 27', city='Madrid', country='EspaƱa') + + def test_invalid_credentials(self, req_mock): + with self.assertRaises(InvalidGoogleCredentials): + GoogleMapsGeocoder('dummy_client_id', + 'lalala', + None)