Skip to content
Snippets Groups Projects
Commit 13846e07 authored by Jason Zhu's avatar Jason Zhu
Browse files

Support ipv6 in geoinfo and Embargo

parent 76516f52
No related merge requests found
......@@ -169,3 +169,4 @@ Clinton Blackburn <cblackburn@edx.org>
Dennis Jen <djen@edx.org>
Filippo Valsorda <hi@filippo.io>
Ivica Ceraj <ceraj@mit.edu>
Jason Zhu <fmyzjs@gmail.com>
\ No newline at end of file
......@@ -129,7 +129,7 @@ sys.path.append(COMMON_ROOT / 'lib')
# For geolocation ip database
GEOIP_PATH = REPO_ROOT / "common/static/data/geoip/GeoIP.dat"
GEOIPV6_PATH = REPO_ROOT / "common/static/data/geoip/GeoIPv6.dat"
############################# WEB CONFIGURATION #############################
# This is where we stick our compiled template files.
......
......@@ -86,13 +86,17 @@ class EmbargoMiddleware(object):
(ip_addr, course_id)
else:
msg = "Embargo: Restricting IP address %s because IP is blacklisted." % ip_addr
log.info(msg)
return response
# ipv6 support
if ip_addr.find(':') >= 0:
country_code_from_ip = pygeoip.GeoIP(settings.GEOIPV6_PATH).country_code_by_addr(ip_addr)
else:
country_code_from_ip = pygeoip.GeoIP(settings.GEOIP_PATH).country_code_by_addr(ip_addr)
country_code_from_ip = pygeoip.GeoIP(settings.GEOIP_PATH).country_code_by_addr(ip_addr)
is_embargoed = country_code_from_ip in EmbargoedState.current().embargoed_countries_list
# Fail if country is embargoed and the ip address isn't explicitly whitelisted
# Fail if country is embargoed and the ip address isn't explicitly
# whitelisted
if is_embargoed and ip_addr not in IPFilter.current().whitelist_ips:
if course_is_embargoed:
msg = "Embargo: Restricting IP address %s to course %s because IP is from country %s." % \
......
......@@ -64,6 +64,8 @@ class EmbargoMiddlewareTests(TestCase):
'3.0.0.0': 'SY',
'4.0.0.0': 'SD',
'5.0.0.0': 'AQ', # Antartica
'2001:250::': 'CN',
'2001:1340::': 'CU',
}
return ip_dict.get(ip_addr, 'US')
......@@ -93,6 +95,32 @@ class EmbargoMiddlewareTests(TestCase):
response = self.client.get(self.regular_page, HTTP_X_FORWARDED_FOR='5.0.0.0', REMOTE_ADDR='5.0.0.0')
self.assertEqual(response.status_code, 200)
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_countries_ipv6(self):
# Accessing an embargoed page from a blocked IP should cause a redirect
response = self.client.get(self.embargoed_page, HTTP_X_FORWARDED_FOR='2001:1340::', REMOTE_ADDR='2001:1340::')
self.assertEqual(response.status_code, 302)
# Following the redirect should give us the embargo page
response = self.client.get(
self.embargoed_page,
HTTP_X_FORWARDED_FOR='2001:1340::',
REMOTE_ADDR='2001:1340::',
follow=True
)
self.assertIn(self.embargo_text, response.content)
# Accessing a regular page from a blocked IP should succeed
response = self.client.get(self.regular_page, HTTP_X_FORWARDED_FOR='2001:1340::', REMOTE_ADDR='2001:1340::')
self.assertEqual(response.status_code, 200)
# Accessing an embargoed page from a non-embargoed IP should succeed
response = self.client.get(self.embargoed_page, HTTP_X_FORWARDED_FOR='2001:250::', REMOTE_ADDR='2001:250::')
self.assertEqual(response.status_code, 200)
# Accessing a regular page from a non-embargoed IP should succeed
response = self.client.get(self.regular_page, HTTP_X_FORWARDED_FOR='2001:250::', REMOTE_ADDR='2001:250::')
self.assertEqual(response.status_code, 200)
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_ip_exceptions(self):
# Explicitly whitelist/blacklist some IPs
......
......@@ -36,7 +36,10 @@ class CountryMiddleware(object):
del request.session['ip_address']
del request.session['country_code']
elif new_ip_address != old_ip_address:
country_code = pygeoip.GeoIP(settings.GEOIP_PATH).country_code_by_addr(new_ip_address)
if new_ip_address.find(':') >= 0:
country_code = pygeoip.GeoIP(settings.GEOIPV6_PATH).country_code_by_addr(new_ip_address)
else:
country_code = pygeoip.GeoIP(settings.GEOIP_PATH).country_code_by_addr(new_ip_address)
request.session['country_code'] = country_code
request.session['ip_address'] = new_ip_address
log.debug('Country code for IP: %s is set to %s', new_ip_address, country_code)
......@@ -41,6 +41,7 @@ class CountryMiddlewareTests(TestCase):
'117.79.83.1': 'CN',
'117.79.83.100': 'CN',
'4.0.0.0': 'SD',
'2001:da8:20f:1502:edcf:550b:4a9c:207d': 'CN',
}
return ip_dict.get(ip_addr, 'US')
......@@ -106,3 +107,19 @@ class CountryMiddlewareTests(TestCase):
# No country code exists after request processing.
self.assertNotIn('country_code', request.session)
self.assertNotIn('ip_address', request.session)
def test_ip_address_is_ipv6(self):
request = self.request_factory.get(
'/somewhere',
HTTP_X_FORWARDED_FOR='2001:da8:20f:1502:edcf:550b:4a9c:207d'
)
request.user = self.authenticated_user
self.session_middleware.process_request(request)
# No country code exists before request.
self.assertNotIn('country_code', request.session)
self.assertNotIn('ip_address', request.session)
self.country_middleware.process_request(request)
# Country code added to session.
self.assertEqual('CN', request.session.get('country_code'))
self.assertEqual(
'2001:da8:20f:1502:edcf:550b:4a9c:207d', request.session.get('ip_address'))
File added
......@@ -307,7 +307,7 @@ NODE_PATH = ':'.join(node_paths)
# For geolocation ip database
GEOIP_PATH = REPO_ROOT / "common/static/data/geoip/GeoIP.dat"
GEOIPV6_PATH = REPO_ROOT / "common/static/data/geoip/GeoIPv6.dat"
# Where to look for a status message
STATUS_MESSAGE_PATH = ENV_ROOT / "status_message.json"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment