[FIX] core: cannot read country geoip on city db
Start odoo-bin shell with `--geoip_country_db='/i/dont/exist'` and type
the following code:
from odoo.http import GeoIP
GeoIP('8.8.8.8').country_code
TypeError: The country method cannot be used with the GeoLite2-City
database
There are two "things" here: the raw country and city entries in the
databases and the rich python country and city objects returned when an
entry was found and parsed.
Then there are two "readers", a reader capable of reading and parsing
entries from the city database and **another** reader for the country.
The two readers are **only** compatible with their specific database:
the city reader cannot read or parse information from the country
database and vis-versa. That's the bug reported by the TypeError that
this commit fixes.
But, the two python instances created from parsing the entries of
respecting databases with respecting parsers **do** share a same API:
the city record class inherits from the country record class.
# Valid
city_db = geoip2.database.Reader(config['geoip_city_db'])
city_record = city_db.city('8.8.8.8')
city_record.country.name # works, a city record also
# holds country attributes
# Invalid
city_db = geoip2.database.Reader(config['geoip_city_db'])
country_record = city_db.country('8.8.8.8') # TypeError
closes odoo/odoo#109095
Signed-off-by: Julien Castiaux <juc@odoo.com>
This commit is contained in:
@@ -16,11 +16,12 @@ class TestHttpBase(HttpCase):
|
||||
geoip_resolver = MemoryGeoipResolver()
|
||||
session_store = MemorySessionStore(session_class=Session)
|
||||
|
||||
lazy_property.reset_all(odoo.http.root)
|
||||
cls.addClassCleanup(lazy_property.reset_all, odoo.http.root)
|
||||
cls.classPatch(odoo.conf, 'server_wide_modules', ['base', 'web', 'test_http'])
|
||||
cls.classPatch(odoo.http.root, 'session_store', session_store)
|
||||
cls.classPatch(odoo.http.root, 'geoip_city_db', geoip_resolver)
|
||||
cls.classPatch(odoo.http.root, 'geoip_country_db', geoip_resolver)
|
||||
cls.classPatch(odoo.http.Application, 'session_store', session_store)
|
||||
cls.classPatch(odoo.http.Application, 'geoip_city_db', geoip_resolver)
|
||||
cls.classPatch(odoo.http.Application, 'geoip_country_db', geoip_resolver)
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
+6
-5
@@ -1045,6 +1045,8 @@ class GeoIP(collections.abc.Mapping):
|
||||
def _city_record(self):
|
||||
try:
|
||||
return root.geoip_city_db.city(self.ip)
|
||||
except (OSError, maxminddb.InvalidDatabaseError):
|
||||
return GEOIP_EMPTY_CITY
|
||||
except geoip2.errors.AddressNotFoundError:
|
||||
return GEOIP_EMPTY_CITY
|
||||
|
||||
@@ -1056,6 +1058,8 @@ class GeoIP(collections.abc.Mapping):
|
||||
return self._city_record
|
||||
try:
|
||||
return root.geoip_country_db.country(self.ip)
|
||||
except (OSError, maxminddb.InvalidDatabaseError):
|
||||
return self._city_record
|
||||
except geoip2.errors.AddressNotFoundError:
|
||||
return GEOIP_EMPTY_COUNTRY
|
||||
|
||||
@@ -2020,10 +2024,7 @@ class Application:
|
||||
"Couldn't load Geoip City file at %s. IP Resolver disabled.",
|
||||
config['geoip_city_db'], exc_info=True
|
||||
)
|
||||
return type('FakeReader', (), {
|
||||
'city': lambda self, ip: GEOIP_EMPTY_CITY,
|
||||
'country': lambda self, ip: GEOIP_EMPTY_COUNTRY
|
||||
})()
|
||||
raise
|
||||
|
||||
@lazy_property
|
||||
def geoip_country_db(self):
|
||||
@@ -2031,7 +2032,7 @@ class Application:
|
||||
return geoip2.database.Reader(config['geoip_country_db'])
|
||||
except (OSError, maxminddb.InvalidDatabaseError) as exc:
|
||||
_logger.debug("Couldn't load Geoip Country file (%s). Fallbacks on Geoip City.", exc,)
|
||||
return self.geoip_city_db
|
||||
raise
|
||||
|
||||
def set_csp(self, response):
|
||||
headers = response.headers
|
||||
|
||||
Reference in New Issue
Block a user