Implement IP filtering in embargo middleware.
Add history table for course access rule changes. Provide test utility for simulating restricted access. Provide `redirect_if_blocked` method for integration with other parts of the system (will be used for blocking enrollment). Add info-level logging explaining when and why users are blocked.
This commit is contained in:
82
common/djangoapps/embargo/test_utils.py
Normal file
82
common/djangoapps/embargo/test_utils.py
Normal file
@@ -0,0 +1,82 @@
|
||||
"""Utilities for writing unit tests that involve course embargos. """
|
||||
import contextlib
|
||||
import mock
|
||||
|
||||
import pygeoip
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.core.cache import cache
|
||||
from embargo.models import Country, CountryAccessRule, RestrictedCourse
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def restrict_course(course_key, access_point="enrollment"):
|
||||
"""Simulate that a course is restricted.
|
||||
|
||||
This does two things:
|
||||
1) Configures country access rules so that the course is restricted.
|
||||
2) Mocks the GeoIP call so the user appears to be coming
|
||||
from a country that's blocked from the course.
|
||||
|
||||
This is useful for tests that need to verify
|
||||
that restricted users won't be able to access
|
||||
particular views.
|
||||
|
||||
Arguments:
|
||||
course_key (CourseKey): The location of the course to block.
|
||||
|
||||
Keyword Arguments:
|
||||
access_point (str): Either "courseware" or "enrollment"
|
||||
|
||||
Yields:
|
||||
str: A URL to the page in the embargo app that explains
|
||||
why the user was blocked.
|
||||
|
||||
Example Usage:
|
||||
>>> with restrict_course(course_key) as redirect_url:
|
||||
>>> # The client will appear to be coming from
|
||||
>>> # an IP address that is blocked.
|
||||
>>> resp = self.client.get(url)
|
||||
>>> self.assertRedirects(resp, redirect_url)
|
||||
|
||||
"""
|
||||
# Clear the cache to ensure that previous tests don't interfere
|
||||
# with this test.
|
||||
cache.clear()
|
||||
|
||||
with mock.patch.object(pygeoip.GeoIP, 'country_code_by_addr') as mock_ip:
|
||||
|
||||
# Remove all existing rules for the course
|
||||
CountryAccessRule.objects.all().delete()
|
||||
|
||||
# Create the country object
|
||||
# Ordinarily, we'd create models for every country,
|
||||
# but that would slow down the test suite.
|
||||
country, __ = Country.objects.get_or_create(country='IR')
|
||||
|
||||
# Create a model for the restricted course
|
||||
restricted_course, __ = RestrictedCourse.objects.get_or_create(course_key=course_key)
|
||||
restricted_course.enroll_msg_key = 'default'
|
||||
restricted_course.access_msg_key = 'default'
|
||||
restricted_course.save()
|
||||
|
||||
# Ensure that there is a blacklist rule for the country
|
||||
CountryAccessRule.objects.get_or_create(
|
||||
restricted_course=restricted_course,
|
||||
country=country,
|
||||
rule_type='blacklist'
|
||||
)
|
||||
|
||||
# Simulate that the user is coming from the blacklisted country
|
||||
mock_ip.return_value = 'IR'
|
||||
|
||||
# Yield the redirect url so the tests don't need to know
|
||||
# the embargo messaging URL structure.
|
||||
redirect_url = reverse(
|
||||
'embargo_blocked_message',
|
||||
kwargs={
|
||||
'access_point': access_point,
|
||||
'message_key': 'default'
|
||||
}
|
||||
)
|
||||
yield redirect_url
|
||||
Reference in New Issue
Block a user