diff --git a/course/exam.py b/course/exam.py index a0f4027f0bba01a0e15247d78ba6c4fbe1cb7bb0..eaef4f3ed0704276edcfafa27d10ba6392d2cb58 100644 --- a/course/exam.py +++ b/course/exam.py @@ -527,8 +527,8 @@ def check_in_for_exam(request): def is_from_exams_only_facility(request): - from django.conf import settings - for name, props in six.iteritems(settings.RELATE_FACILITIES): + from course.utils import get_facilities_config + for name, props in six.iteritems(get_facilities_config(request)): if not props.get("exams_only", False): continue diff --git a/course/utils.py b/course/utils.py index 4a9fa0032162087e3fc4ce3d4e05d0944ac7bbf0..6041dcc1d8bc5d6f79728bbedc56cd17b8e90870 100644 --- a/course/utils.py +++ b/course/utils.py @@ -720,6 +720,22 @@ def get_codemirror_widget(language_mode, interaction_mode, # {{{ facility processing +def get_facilities_config(request=None): + from django.conf import settings + facilities = settings.RELATE_FACILITIES + + if callable(facilities): + from course.views import get_now_or_fake_time + now_datetime = get_now_or_fake_time(request) + + result = facilities(now_datetime) + if not isinstance(result, dict): + raise RuntimeError("RELATE_FACILITIES must return a dictionary") + return result + else: + return facilities + + class FacilityFindingMiddleware(object): def process_request(self, request): pretend_facilities = request.session.get("relate_pretend_facilities") @@ -733,8 +749,7 @@ class FacilityFindingMiddleware(object): facilities = set() - from django.conf import settings - for name, props in six.iteritems(settings.RELATE_FACILITIES): + for name, props in six.iteritems(get_facilities_config(request)): ip_ranges = props.get("ip_ranges", []) for ir in ip_ranges: if remote_address in ipaddress.ip_network(six.text_type(ir)): diff --git a/course/validation.py b/course/validation.py index 6179254de6eaaece181c8151d521471acc9f1663..e118f58b5e55d6662d684e86ca3abd53a84eff3d 100644 --- a/course/validation.py +++ b/course/validation.py @@ -83,8 +83,8 @@ def validate_role(location, role): def validate_facility(vctx, location, facility): - from django.conf import settings - facilities = getattr(settings, "RELATE_FACILITIES", None) + from course.utils import get_facilities_config + facilities = get_facilities_config() if facilities is None: return diff --git a/course/views.py b/course/views.py index 663e8f145e979e4f1ee34aa7992383cf8cf089e8..6a5b897f0606619743ba9f353d49b18f59892edf 100644 --- a/course/views.py +++ b/course/views.py @@ -342,7 +342,7 @@ class FakeTimeForm(StyledForm): def get_fake_time(request): - if "relate_fake_time" in request.session: + if request is not None and "relate_fake_time" in request.session: import datetime from django.conf import settings @@ -415,14 +415,13 @@ def fake_time_context_processor(request): class FakeFacilityForm(StyledForm): def __init__(self, *args, **kwargs): - from django.conf import settings - super(FakeFacilityForm, self).__init__(*args, **kwargs) + from course.utils import get_facilities_config self.fields["facilities"] = forms.MultipleChoiceField( choices=( (name, name) - for name in settings.RELATE_FACILITIES), + for name in get_facilities_config()), widget=forms.CheckboxSelectMultiple, required=False, label=_("Facilities"), diff --git a/local_settings.py.example b/local_settings.py.example index ccb43643a90cecdf2900304be19ac82bddd12486..00aac3291e19f861fafff4a1c3fd2f5839917b70 100644 --- a/local_settings.py.example +++ b/local_settings.py.example @@ -196,6 +196,30 @@ RELATE_SITE_ANNOUNCEMENT = None # {{{ exams and testing +# This may also be a callable that receives a local-timezone datetime and returns +# an equivalent dictionary. +# +# def RELATE_FACILITIES(now_datetime): +# from relate.utils import localize_datetime +# from datetime import datetime +# +# if (now_datetime >= localize_datetime(datetime(2016, 5, 5, 0, 0)) +# and now_datetime < localize_datetime(datetime(2016, 5, 6, 0, 0))): +# ip_ranges = [ +# "127.0.0.1/32", +# "192.168.77.0/24", +# ] +# else: +# ip_ranges = [] +# +# return { +# "test_center": { +# "ip_ranges": ip_ranges, +# "exams_only": True, +# }, +# } + + RELATE_FACILITIES = { "test_center": { "ip_ranges": [