diff --git a/lms/djangoapps/courseware/tabs.py b/lms/djangoapps/courseware/tabs.py index 7a77898cdd..8931f82724 100644 --- a/lms/djangoapps/courseware/tabs.py +++ b/lms/djangoapps/courseware/tabs.py @@ -91,6 +91,13 @@ def _discussion(tab, user, course, active_page): return [] +def _external_discussion(tab, user, course, active_page): + """ + This returns a tab that links to an external discussion service + """ + return [CourseTab('Discussion', tab['link'], active_page == 'discussion')] + + def _external_link(tab, user, course, active_page): # external links are never active return [CourseTab(tab['name'], tab['link'], False)] @@ -150,6 +157,12 @@ def _staff_grading(tab, user, course, active_page): return [] +def _syllabus(tab, user, course, active_page): + """Display the syllabus tab""" + link = reverse('syllabus', args=[course.id]) + return [CourseTab('Syllabus', link, active_page == 'syllabus')] + + def _peer_grading(tab, user, course, active_page): if user.is_authenticated(): @@ -216,6 +229,7 @@ VALID_TAB_TYPES = { 'course_info': TabImpl(need_name, _course_info), 'wiki': TabImpl(need_name, _wiki), 'discussion': TabImpl(need_name, _discussion), + 'external_discussion': TabImpl(key_checker(['link']), _external_discussion), 'external_link': TabImpl(key_checker(['name', 'link']), _external_link), 'textbooks': TabImpl(null_validator, _textbooks), 'pdf_textbooks': TabImpl(null_validator, _pdf_textbooks), @@ -225,7 +239,8 @@ VALID_TAB_TYPES = { 'peer_grading': TabImpl(null_validator, _peer_grading), 'staff_grading': TabImpl(null_validator, _staff_grading), 'open_ended': TabImpl(null_validator, _combined_open_ended_grading), - 'notes': TabImpl(null_validator, _notes_tab) + 'notes': TabImpl(null_validator, _notes_tab), + 'syllabus': TabImpl(null_validator, _syllabus) } diff --git a/lms/djangoapps/user_api/tests/test_views.py b/lms/djangoapps/user_api/tests/test_views.py index 075c1f0d9f..451b167050 100644 --- a/lms/djangoapps/user_api/tests/test_views.py +++ b/lms/djangoapps/user_api/tests/test_views.py @@ -1,3 +1,5 @@ +import base64 + from django.contrib.auth.models import User from django.test import TestCase from django.test.utils import override_settings @@ -31,6 +33,9 @@ class UserApiTestCase(TestCase): UserPreferenceFactory.create(user=self.users[1], key="key0") ] + def basic_auth(self, username, password): + return {'HTTP_AUTHORIZATION': 'Basic ' + base64.b64encode('%s:%s' % (username, password))} + def request_with_auth(self, method, *args, **kwargs): """Issue a get request to the given URI with the API key header""" return getattr(self.client, method)(*args, HTTP_X_EDX_API_KEY=TEST_API_KEY, **kwargs) @@ -127,6 +132,15 @@ class UserViewSetTest(UserApiTestCase): def test_debug_auth(self): self.assertHttpOK(self.client.get(self.LIST_URI)) + @override_settings(DEBUG=False) + @override_settings(EDX_API_KEY=TEST_API_KEY) + def test_basic_auth(self): + # ensure that having basic auth headers in the mix does not break anything + self.assertHttpOK( + self.request_with_auth("get", self.LIST_URI, **self.basic_auth('someuser', 'somepass'))) + self.assertHttpForbidden( + self.client.get(self.LIST_URI, **self.basic_auth('someuser', 'somepass'))) + def test_get_list_empty(self): User.objects.all().delete() result = self.get_json(self.LIST_URI) diff --git a/lms/djangoapps/user_api/views.py b/lms/djangoapps/user_api/views.py index d4f19be099..c64a5a4d23 100644 --- a/lms/djangoapps/user_api/views.py +++ b/lms/djangoapps/user_api/views.py @@ -1,5 +1,6 @@ from django.conf import settings from django.contrib.auth.models import User +from rest_framework import authentication from rest_framework import filters from rest_framework import permissions from rest_framework import viewsets @@ -25,6 +26,7 @@ class ApiKeyHeaderPermission(permissions.BasePermission): class UserViewSet(viewsets.ReadOnlyModelViewSet): + authentication_classes = (authentication.SessionAuthentication,) permission_classes = (ApiKeyHeaderPermission,) queryset = User.objects.all() serializer_class = UserSerializer @@ -33,6 +35,7 @@ class UserViewSet(viewsets.ReadOnlyModelViewSet): class UserPreferenceViewSet(viewsets.ReadOnlyModelViewSet): + authentication_classes = (authentication.SessionAuthentication,) permission_classes = (ApiKeyHeaderPermission,) queryset = UserPreference.objects.all() filter_backends = (filters.DjangoFilterBackend,) diff --git a/lms/envs/aws.py b/lms/envs/aws.py index fa490a244f..e039219be8 100644 --- a/lms/envs/aws.py +++ b/lms/envs/aws.py @@ -182,9 +182,6 @@ COURSES_WITH_UNSAFE_CODE = ENV_TOKENS.get("COURSES_WITH_UNSAFE_CODE", []) MITX_FEATURES['AUTOMATIC_AUTH_FOR_LOAD_TESTING'] = ENV_TOKENS.get('AUTOMATIC_AUTH_FOR_LOAD_TESTING') MITX_FEATURES['MAX_AUTO_AUTH_USERS'] = ENV_TOKENS.get('MAX_AUTO_AUTH_USERS') -# discussion home panel must be explicitly enabled -MITX_FEATURES['ENABLE_DISCUSSION_HOME_PANEL'] = ENV_TOKENS.get('ENABLE_DISCUSSION_HOME_PANEL', False) - ############################## SECURE AUTH ITEMS ############### # Secret things: passwords, access keys, etc. diff --git a/lms/envs/common.py b/lms/envs/common.py index aa17d3f783..95b2af422e 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -73,7 +73,7 @@ MITX_FEATURES = { 'ENABLE_DISCUSSION_SERVICE': True, # discussion home panel, which includes a subscription on/off setting for discussion digest emails. # this should remain off in production until digest notifications are online. - 'ENABLE_DISCUSSION_HOME_PANEL': True, + 'ENABLE_DISCUSSION_HOME_PANEL': False, 'ENABLE_PSYCHOMETRICS': False, # real-time psychometrics (eg item response theory analysis in instructor dashboard) @@ -320,8 +320,6 @@ CODE_JAIL = { 'limits': { # How many CPU seconds can jailed code use? 'CPU': 1, - # How large a file can jailed code write? - 'FSIZE': 50000, }, } diff --git a/requirements/edx/github.txt b/requirements/edx/github.txt index 97bc325d35..0d77dac179 100644 --- a/requirements/edx/github.txt +++ b/requirements/edx/github.txt @@ -9,5 +9,5 @@ # Our libraries: -e git+https://github.com/edx/XBlock.git@b697bebd45deebd0f868613fab6722a0460ca0c1#egg=XBlock --e git+https://github.com/edx/codejail.git@c08967fb44d1bcdb259d3ec58812e3ac592539c2#egg=codejail +-e git+https://github.com/edx/codejail.git@0a1b468#egg=codejail -e git+https://github.com/edx/diff-cover.git@v0.2.0#egg=diff_cover