Commit c285bda6 by Sarina Canelake

Merge pull request #4625 from fmyzjs/ipv6

Support ipv6 in geoinfo and Embargo
parents 244554f7 13846e07
......@@ -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')
......@@ -94,6 +96,32 @@ class EmbargoMiddlewareTests(TestCase):
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
IPFilter(
......
......@@ -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'))
......@@ -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"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment