Commit babd972c by Matt Drayer Committed by Jonathan Piacenti

mattdrayer/api-course-exists-check: Refactored course lookup logic

parent 7cab70b6
...@@ -474,7 +474,7 @@ class CoursesApiTests(TestCase): ...@@ -474,7 +474,7 @@ class CoursesApiTests(TestCase):
def test_courses_groups_list_get(self): def test_courses_groups_list_get(self):
test_uri = '{}/{}/groups'.format(self.base_courses_uri, self.test_course_id) test_uri = '{}/{}/groups'.format(self.base_courses_uri, self.test_course_id)
course_fail_uri = '{}/{}/groups'.format(self.base_courses_uri, '/ed/Open_DemoX/edx_demo_course') course_fail_uri = '{}/{}/groups'.format(self.base_courses_uri, 'ed/Open_DemoX/edx_demo_course')
for i in xrange(2): for i in xrange(2):
data_dict = { data_dict = {
'name': 'Alpha Group {}'.format(i), 'type': 'Programming', 'name': 'Alpha Group {}'.format(i), 'type': 'Programming',
...@@ -1311,7 +1311,6 @@ class CoursesApiTests(TestCase): ...@@ -1311,7 +1311,6 @@ class CoursesApiTests(TestCase):
data = {'group_id': group_id} data = {'group_id': group_id}
response = self.do_post(test_uri, data) response = self.do_post(test_uri, data)
self.assertEqual(response.status_code, 201) self.assertEqual(response.status_code, 201)
# Create another group and add it to course module # Create another group and add it to course module
data = {'name': 'Beta Group', 'type': 'project'} data = {'name': 'Beta Group', 'type': 'project'}
response = self.do_post(self.base_groups_uri, data) response = self.do_post(self.base_groups_uri, data)
...@@ -1320,7 +1319,6 @@ class CoursesApiTests(TestCase): ...@@ -1320,7 +1319,6 @@ class CoursesApiTests(TestCase):
data = {'group_id': another_group_id} data = {'group_id': another_group_id}
response = self.do_post(test_uri, data) response = self.do_post(test_uri, data)
self.assertEqual(response.status_code, 201) self.assertEqual(response.status_code, 201)
# create a 5 new users # create a 5 new users
for i in xrange(1, 6): for i in xrange(1, 6):
data = { data = {
...@@ -1344,12 +1342,10 @@ class CoursesApiTests(TestCase): ...@@ -1344,12 +1342,10 @@ class CoursesApiTests(TestCase):
data = {'user_id': created_user_id} data = {'user_id': created_user_id}
response = self.do_post(test_group_users_uri, data) response = self.do_post(test_group_users_uri, data)
self.assertEqual(response.status_code, 201) self.assertEqual(response.status_code, 201)
#enroll one user in Alpha Group and one in Beta Group created user #enroll one user in Alpha Group and one in Beta Group created user
if i >= 2: if i >= 2:
response = self.do_post(test_course_users_uri, data) response = self.do_post(test_course_users_uri, data)
self.assertEqual(response.status_code, 201) self.assertEqual(response.status_code, 201)
response = self.do_get('{}?enrolled={}'.format(test_uri_users, 'True')) response = self.do_get('{}?enrolled={}'.format(test_uri_users, 'True'))
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data), 2) self.assertEqual(len(response.data), 2)
......
...@@ -27,7 +27,7 @@ from student.roles import CourseRole, CourseAccessRole, CourseInstructorRole, Co ...@@ -27,7 +27,7 @@ from student.roles import CourseRole, CourseAccessRole, CourseInstructorRole, Co
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from api_manager.courseware_access import get_course, get_course_child, get_course_leaf_nodes from api_manager.courseware_access import get_course, get_course_child, get_course_leaf_nodes, get_course_key, course_exists
from api_manager.models import CourseGroupRelationship, CourseContentGroupRelationship, GroupProfile, \ from api_manager.models import CourseGroupRelationship, CourseContentGroupRelationship, GroupProfile, \
CourseModuleCompletion CourseModuleCompletion
from api_manager.permissions import SecureAPIView, SecureListAPIView from api_manager.permissions import SecureAPIView, SecureListAPIView
...@@ -387,7 +387,7 @@ class CourseContentList(SecureAPIView): ...@@ -387,7 +387,7 @@ class CourseContentList(SecureAPIView):
response_data = [] response_data = []
content_type = request.QUERY_PARAMS.get('type', None) content_type = request.QUERY_PARAMS.get('type', None)
if course_id != content_id: if course_id != content_id:
content_descriptor, content_key, content = get_course_child(request, request.user, course_key, content_id) # pylint: disable=W0612 content_descriptor, content_key, content = get_course_child(request, request.user, course_key, content_id, load_content=True) # pylint: disable=W0612
else: else:
content = course_descriptor content = course_descriptor
if content: if content:
...@@ -460,7 +460,7 @@ class CourseContentDetail(SecureAPIView): ...@@ -460,7 +460,7 @@ class CourseContentDetail(SecureAPIView):
response_data['uri'] = base_uri response_data['uri'] = base_uri
if course_id != content_id: if course_id != content_id:
element_name = 'children' element_name = 'children'
content_descriptor, content_key, content = get_course_child(request, request.user, course_key, content_id) # pylint: disable=W0612 content_descriptor, content_key, content = get_course_child(request, request.user, course_key, content_id, load_content=True) # pylint: disable=W0612
else: else:
element_name = 'content' element_name = 'content'
protocol = 'http' protocol = 'http'
...@@ -666,9 +666,9 @@ class CoursesGroupsList(SecureAPIView): ...@@ -666,9 +666,9 @@ class CoursesGroupsList(SecureAPIView):
response_data = {} response_data = {}
group_id = request.DATA['group_id'] group_id = request.DATA['group_id']
base_uri = generate_base_uri(request) base_uri = generate_base_uri(request)
course_descriptor, course_key, course_content = get_course(request, request.user, course_id) # pylint: disable=W0612 if not course_exists(request, request.user, course_id):
if not course_descriptor:
return Response({}, status=status.HTTP_404_NOT_FOUND) return Response({}, status=status.HTTP_404_NOT_FOUND)
course_key = get_course_key(course_id)
try: try:
existing_group = Group.objects.get(id=group_id) existing_group = Group.objects.get(id=group_id)
except ObjectDoesNotExist: except ObjectDoesNotExist:
...@@ -695,12 +695,11 @@ class CoursesGroupsList(SecureAPIView): ...@@ -695,12 +695,11 @@ class CoursesGroupsList(SecureAPIView):
""" """
GET /api/courses/{course_id}/groups?type=workgroup GET /api/courses/{course_id}/groups?type=workgroup
""" """
course_descriptor, course_key, course_content = get_course(request, request.user, course_id) # pylint: disable=W0612 if not course_exists(request, request.user, course_id):
if not course_descriptor:
return Response({}, status=status.HTTP_404_NOT_FOUND) return Response({}, status=status.HTTP_404_NOT_FOUND)
group_type = request.QUERY_PARAMS.get('type', None) group_type = request.QUERY_PARAMS.get('type', None)
course_key = get_course_key(course_id)
course_groups = CourseGroupRelationship.objects.filter(course_id=course_key) course_groups = CourseGroupRelationship.objects.filter(course_id=course_key)
if group_type: if group_type:
course_groups = course_groups.filter(group__groupprofile__group_type=group_type) course_groups = course_groups.filter(group__groupprofile__group_type=group_type)
response_data = [] response_data = []
...@@ -727,14 +726,14 @@ class CoursesGroupsDetail(SecureAPIView): ...@@ -727,14 +726,14 @@ class CoursesGroupsDetail(SecureAPIView):
""" """
GET /api/courses/{course_id}/groups/{group_id} GET /api/courses/{course_id}/groups/{group_id}
""" """
course_descriptor, course_key, course_content = get_course(request, request.user, course_id) # pylint: disable=W0612 if not course_exists(request, request.user, course_id):
if not course_descriptor:
return Response({}, status=status.HTTP_404_NOT_FOUND) return Response({}, status=status.HTTP_404_NOT_FOUND)
try: try:
existing_group = Group.objects.get(id=group_id) existing_group = Group.objects.get(id=group_id)
except ObjectDoesNotExist: except ObjectDoesNotExist:
return Response({}, status=status.HTTP_404_NOT_FOUND) return Response({}, status=status.HTTP_404_NOT_FOUND)
try: try:
course_key = get_course_key(course_id)
CourseGroupRelationship.objects.get(course_id=course_key, group=existing_group) CourseGroupRelationship.objects.get(course_id=course_key, group=existing_group)
except ObjectDoesNotExist: except ObjectDoesNotExist:
return Response({}, status=status.HTTP_404_NOT_FOUND) return Response({}, status=status.HTTP_404_NOT_FOUND)
...@@ -749,11 +748,11 @@ class CoursesGroupsDetail(SecureAPIView): ...@@ -749,11 +748,11 @@ class CoursesGroupsDetail(SecureAPIView):
""" """
DELETE /api/courses/{course_id}/groups/{group_id} DELETE /api/courses/{course_id}/groups/{group_id}
""" """
course_descriptor, course_key, course_content = get_course(request, request.user, course_id) # pylint: disable=W0612 if not course_exists(request, request.user, course_id):
if not course_descriptor:
return Response({}, status=status.HTTP_204_NO_CONTENT) return Response({}, status=status.HTTP_204_NO_CONTENT)
try: try:
existing_group = Group.objects.get(id=group_id) existing_group = Group.objects.get(id=group_id)
course_key = get_course_key(course_id)
CourseGroupRelationship.objects.get(course_id=course_key, group=existing_group).delete() CourseGroupRelationship.objects.get(course_id=course_key, group=existing_group).delete()
except ObjectDoesNotExist: except ObjectDoesNotExist:
pass pass
...@@ -994,9 +993,9 @@ class CoursesUsersList(SecureAPIView): ...@@ -994,9 +993,9 @@ class CoursesUsersList(SecureAPIView):
""" """
POST /api/courses/{course_id}/users POST /api/courses/{course_id}/users
""" """
course_descriptor, course_key, course_content = get_course(request, request.user, course_id) # pylint: disable=W0612 if not course_exists(request, request.user, course_id):
if not course_descriptor:
return Response({}, status=status.HTTP_404_NOT_FOUND) return Response({}, status=status.HTTP_404_NOT_FOUND)
course_key = get_course_key(course_id)
if 'user_id' in request.DATA: if 'user_id' in request.DATA:
user_id = request.DATA['user_id'] user_id = request.DATA['user_id']
try: try:
...@@ -1034,9 +1033,9 @@ class CoursesUsersList(SecureAPIView): ...@@ -1034,9 +1033,9 @@ class CoursesUsersList(SecureAPIView):
response_data = OrderedDict() response_data = OrderedDict()
base_uri = generate_base_uri(request) base_uri = generate_base_uri(request)
response_data['uri'] = base_uri response_data['uri'] = base_uri
course_descriptor, course_key, course_content = get_course(request, request.user, course_id) # pylint: disable=W0612 if not course_exists(request, request.user, course_id):
if not course_descriptor:
return Response({}, status=status.HTTP_404_NOT_FOUND) return Response({}, status=status.HTTP_404_NOT_FOUND)
course_key = get_course_key(course_id)
# Get a list of all enrolled students # Get a list of all enrolled students
users = CourseEnrollment.users_enrolled_in(course_key) users = CourseEnrollment.users_enrolled_in(course_key)
upper_bound = getattr(settings, 'API_LOOKUP_UPPER_BOUND', 100) upper_bound = getattr(settings, 'API_LOOKUP_UPPER_BOUND', 100)
...@@ -1106,7 +1105,7 @@ class CoursesUsersDetail(SecureAPIView): ...@@ -1106,7 +1105,7 @@ class CoursesUsersDetail(SecureAPIView):
user = User.objects.get(id=user_id, is_active=True) user = User.objects.get(id=user_id, is_active=True)
except ObjectDoesNotExist: except ObjectDoesNotExist:
return Response(response_data, status=status.HTTP_404_NOT_FOUND) return Response(response_data, status=status.HTTP_404_NOT_FOUND)
course_descriptor, course_key, course_content = get_course(request, user, course_id) course_descriptor, course_key, course_content = get_course(request, user, course_id, load_content=True)
if not course_descriptor: if not course_descriptor:
return Response(response_data, status=status.HTTP_404_NOT_FOUND) return Response(response_data, status=status.HTTP_404_NOT_FOUND)
if CourseEnrollment.is_enrolled(user, course_key): if CourseEnrollment.is_enrolled(user, course_key):
...@@ -1124,9 +1123,9 @@ class CoursesUsersDetail(SecureAPIView): ...@@ -1124,9 +1123,9 @@ class CoursesUsersDetail(SecureAPIView):
user = User.objects.get(id=user_id, is_active=True) user = User.objects.get(id=user_id, is_active=True)
except ObjectDoesNotExist: except ObjectDoesNotExist:
return Response({}, status=status.HTTP_204_NO_CONTENT) return Response({}, status=status.HTTP_204_NO_CONTENT)
course_descriptor, course_key, course_content = get_course(request, user, course_id) # pylint: disable=W0612 if not course_exists(request, request.user, course_id):
if not course_descriptor:
return Response({}, status=status.HTTP_404_NOT_FOUND) return Response({}, status=status.HTTP_404_NOT_FOUND)
course_key = get_course_key(course_id)
CourseEnrollment.unenroll(user, course_key) CourseEnrollment.unenroll(user, course_key)
response_data = {} response_data = {}
base_uri = generate_base_uri(request) base_uri = generate_base_uri(request)
...@@ -1157,11 +1156,11 @@ class CourseContentGroupsList(SecureAPIView): ...@@ -1157,11 +1156,11 @@ class CourseContentGroupsList(SecureAPIView):
""" """
POST /api/courses/{course_id}/content/{content_id}/groups POST /api/courses/{course_id}/content/{content_id}/groups
""" """
course_descriptor, course_key, course_content = get_course(request, request.user, course_id) # pylint: disable=W0612 if not course_exists(request, request.user, course_id):
if not course_descriptor:
return Response({}, status=status.HTTP_404_NOT_FOUND) return Response({}, status=status.HTTP_404_NOT_FOUND)
course_key = get_course_key(course_id)
content_descriptor, content_key, existing_content = get_course_child(request, request.user, course_key, content_id) # pylint: disable=W0612 content_descriptor, content_key, existing_content = get_course_child(request, request.user, course_key, content_id) # pylint: disable=W0612
if not existing_content: if not content_descriptor:
return Response({}, status=status.HTTP_404_NOT_FOUND) return Response({}, status=status.HTTP_404_NOT_FOUND)
group_id = request.DATA.get('group_id') group_id = request.DATA.get('group_id')
if group_id is None: if group_id is None:
...@@ -1174,12 +1173,12 @@ class CourseContentGroupsList(SecureAPIView): ...@@ -1174,12 +1173,12 @@ class CourseContentGroupsList(SecureAPIView):
base_uri = generate_base_uri(request) base_uri = generate_base_uri(request)
response_data['uri'] = '{}/{}'.format(base_uri, existing_profile.group_id) response_data['uri'] = '{}/{}'.format(base_uri, existing_profile.group_id)
response_data['course_id'] = unicode(course_key) response_data['course_id'] = unicode(course_key)
response_data['content_id'] = unicode(existing_content.scope_ids.usage_id) response_data['content_id'] = unicode(content_key)
response_data['group_id'] = str(existing_profile.group_id) response_data['group_id'] = str(existing_profile.group_id)
try: try:
CourseContentGroupRelationship.objects.get( CourseContentGroupRelationship.objects.get(
course_id=course_key, course_id=course_key,
content_id=existing_content.location, content_id=content_key,
group_profile=existing_profile group_profile=existing_profile
) )
response_data['message'] = "Relationship already exists." response_data['message'] = "Relationship already exists."
...@@ -1187,7 +1186,7 @@ class CourseContentGroupsList(SecureAPIView): ...@@ -1187,7 +1186,7 @@ class CourseContentGroupsList(SecureAPIView):
except ObjectDoesNotExist: except ObjectDoesNotExist:
CourseContentGroupRelationship.objects.create( CourseContentGroupRelationship.objects.create(
course_id=course_key, course_id=course_key,
content_id=existing_content.location, content_id=content_key,
group_profile=existing_profile group_profile=existing_profile
) )
return Response(response_data, status=status.HTTP_201_CREATED) return Response(response_data, status=status.HTTP_201_CREATED)
...@@ -1198,15 +1197,15 @@ class CourseContentGroupsList(SecureAPIView): ...@@ -1198,15 +1197,15 @@ class CourseContentGroupsList(SecureAPIView):
""" """
response_data = [] response_data = []
group_type = request.QUERY_PARAMS.get('type') group_type = request.QUERY_PARAMS.get('type')
course_descriptor, course_key, course_content = get_course(request, request.user, course_id) # pylint: disable=W0612 if not course_exists(request, request.user, course_id):
if not course_descriptor:
return Response({}, status=status.HTTP_404_NOT_FOUND) return Response({}, status=status.HTTP_404_NOT_FOUND)
course_key = get_course_key(course_id)
content_descriptor, content_key, existing_content = get_course_child(request, request.user, course_key, content_id) # pylint: disable=W0612 content_descriptor, content_key, existing_content = get_course_child(request, request.user, course_key, content_id) # pylint: disable=W0612
if not existing_content: if not content_descriptor:
return Response({}, status=status.HTTP_404_NOT_FOUND) return Response({}, status=status.HTTP_404_NOT_FOUND)
relationships = CourseContentGroupRelationship.objects.filter( relationships = CourseContentGroupRelationship.objects.filter(
course_id=course_key, course_id=course_key,
content_id=existing_content.location, content_id=content_key,
).select_related("groupprofile") ).select_related("groupprofile")
if group_type: if group_type:
relationships = relationships.filter(group_profile__group_type=group_type) relationships = relationships.filter(group_profile__group_type=group_type)
...@@ -1230,16 +1229,16 @@ class CourseContentGroupsDetail(SecureAPIView): ...@@ -1230,16 +1229,16 @@ class CourseContentGroupsDetail(SecureAPIView):
""" """
GET /api/courses/{course_id}/content/{content_id}/groups/{group_id} GET /api/courses/{course_id}/content/{content_id}/groups/{group_id}
""" """
course_descriptor, course_key, course_content = get_course(request, request.user, course_id) # pylint: disable=W0612 if not course_exists(request, request.user, course_id):
if not course_descriptor:
return Response({}, status=status.HTTP_404_NOT_FOUND) return Response({}, status=status.HTTP_404_NOT_FOUND)
course_key = get_course_key(course_id)
content_descriptor, content_key, existing_content = get_course_child(request, request.user, course_key, content_id) # pylint: disable=W0612 content_descriptor, content_key, existing_content = get_course_child(request, request.user, course_key, content_id) # pylint: disable=W0612
if not existing_content: if not content_descriptor:
return Response({}, status=status.HTTP_404_NOT_FOUND) return Response({}, status=status.HTTP_404_NOT_FOUND)
try: try:
CourseContentGroupRelationship.objects.get( CourseContentGroupRelationship.objects.get(
course_id=course_key, course_id=course_key,
content_id=existing_content.location, content_id=content_key,
group_profile__group_id=group_id group_profile__group_id=group_id
) )
except ObjectDoesNotExist: except ObjectDoesNotExist:
...@@ -1271,17 +1270,17 @@ class CourseContentUsersList(SecureAPIView): ...@@ -1271,17 +1270,17 @@ class CourseContentUsersList(SecureAPIView):
""" """
GET /api/courses/{course_id}/content/{content_id}/users GET /api/courses/{course_id}/content/{content_id}/users
""" """
course_descriptor, course_key, course_content = get_course(request, request.user, course_id) # pylint: disable=W0612 if not course_exists(request, request.user, course_id):
if not course_descriptor:
return Response({}, status=status.HTTP_404_NOT_FOUND) return Response({}, status=status.HTTP_404_NOT_FOUND)
course_key = get_course_key(course_id)
content_descriptor, content_key, existing_content = get_course_child(request, request.user, course_key, content_id) # pylint: disable=W0612 content_descriptor, content_key, existing_content = get_course_child(request, request.user, course_key, content_id) # pylint: disable=W0612
if not existing_content: if not content_descriptor:
return Response({}, status=status.HTTP_404_NOT_FOUND) return Response({}, status=status.HTTP_404_NOT_FOUND)
enrolled = self.request.QUERY_PARAMS.get('enrolled', 'True') enrolled = self.request.QUERY_PARAMS.get('enrolled', 'True')
group_type = self.request.QUERY_PARAMS.get('type', None) group_type = self.request.QUERY_PARAMS.get('type', None)
group_id = self.request.QUERY_PARAMS.get('group_id', None) group_id = self.request.QUERY_PARAMS.get('group_id', None)
relationships = CourseContentGroupRelationship.objects.filter( relationships = CourseContentGroupRelationship.objects.filter(
course_id=course_key, content_id=existing_content.location).select_related("groupprofile") course_id=course_key, content_id=content_key).select_related("groupprofile")
if group_id: if group_id:
relationships = relationships.filter(group_profile__group__id=group_id) relationships = relationships.filter(group_profile__group__id=group_id)
...@@ -1351,9 +1350,9 @@ class CourseModuleCompletionList(SecureListAPIView): ...@@ -1351,9 +1350,9 @@ class CourseModuleCompletionList(SecureListAPIView):
content_id = self.request.QUERY_PARAMS.get('content_id', None) content_id = self.request.QUERY_PARAMS.get('content_id', None)
stage = self.request.QUERY_PARAMS.get('stage', None) stage = self.request.QUERY_PARAMS.get('stage', None)
course_id = self.kwargs['course_id'] course_id = self.kwargs['course_id']
course_descriptor, course_key, course_content = get_course(self.request, self.request.user, course_id) # pylint: disable=W0612 if not course_exists(self.request, self.request.user, course_id):
if not course_descriptor:
raise Http404 raise Http404
course_key = get_course_key(course_id)
queryset = CourseModuleCompletion.objects.filter(course_id=course_key) queryset = CourseModuleCompletion.objects.filter(course_id=course_key)
upper_bound = getattr(settings, 'API_LOOKUP_UPPER_BOUND', 100) upper_bound = getattr(settings, 'API_LOOKUP_UPPER_BOUND', 100)
if user_ids: if user_ids:
...@@ -1362,9 +1361,9 @@ class CourseModuleCompletionList(SecureListAPIView): ...@@ -1362,9 +1361,9 @@ class CourseModuleCompletionList(SecureListAPIView):
if content_id: if content_id:
content_descriptor, content_key, existing_content = get_course_child(self.request, self.request.user, course_key, content_id) # pylint: disable=W0612 content_descriptor, content_key, existing_content = get_course_child(self.request, self.request.user, course_key, content_id) # pylint: disable=W0612
if not existing_content: if not content_descriptor:
raise Http404 raise Http404
queryset = queryset.filter(content_id=existing_content.location) queryset = queryset.filter(content_id=content_key)
if stage: if stage:
queryset = queryset.filter(stage=stage) queryset = queryset.filter(stage=stage)
...@@ -1382,16 +1381,16 @@ class CourseModuleCompletionList(SecureListAPIView): ...@@ -1382,16 +1381,16 @@ class CourseModuleCompletionList(SecureListAPIView):
return Response({'message': _('content_id is missing')}, status.HTTP_400_BAD_REQUEST) return Response({'message': _('content_id is missing')}, status.HTTP_400_BAD_REQUEST)
if not user_id: if not user_id:
return Response({'message': _('user_id is missing')}, status.HTTP_400_BAD_REQUEST) return Response({'message': _('user_id is missing')}, status.HTTP_400_BAD_REQUEST)
course_descriptor, course_key, course_content = get_course(request, request.user, course_id) # pylint: disable=W0612 if not course_exists(request, request.user, course_id):
if not course_descriptor:
return Response({}, status=status.HTTP_404_NOT_FOUND) return Response({}, status=status.HTTP_404_NOT_FOUND)
course_key = get_course_key(course_id)
content_descriptor, content_key, existing_content = get_course_child(request, request.user, course_key, content_id) # pylint: disable=W0612 content_descriptor, content_key, existing_content = get_course_child(request, request.user, course_key, content_id) # pylint: disable=W0612
if not existing_content: if not content_descriptor:
return Response({'message': _('content_id is invalid')}, status.HTTP_400_BAD_REQUEST) return Response({'message': _('content_id is invalid')}, status.HTTP_400_BAD_REQUEST)
completion, created = CourseModuleCompletion.objects.get_or_create(user_id=user_id, completion, created = CourseModuleCompletion.objects.get_or_create(user_id=user_id,
course_id=course_key, course_id=course_key,
content_id=existing_content.location, content_id=content_key,
stage=stage) stage=stage)
serializer = CourseModuleCompletionSerializer(completion) serializer = CourseModuleCompletionSerializer(completion)
if created: if created:
...@@ -1413,9 +1412,9 @@ class CoursesGradesList(SecureListAPIView): ...@@ -1413,9 +1412,9 @@ class CoursesGradesList(SecureListAPIView):
""" """
GET /api/courses/{course_id}/grades?user_ids=1,2&content_ids=i4x://1/2/3,i4x://a/b/c GET /api/courses/{course_id}/grades?user_ids=1,2&content_ids=i4x://1/2/3,i4x://a/b/c
""" """
course_descriptor, course_key, course_content = get_course(request, request.user, course_id) # pylint: disable=W0612 if not course_exists(request, request.user, course_id):
if not course_descriptor:
return Response({}, status=status.HTTP_404_NOT_FOUND) return Response({}, status=status.HTTP_404_NOT_FOUND)
course_key = get_course_key(course_id)
queryset = StudentModule.objects.filter( queryset = StudentModule.objects.filter(
course_id__exact=course_key, course_id__exact=course_key,
grade__isnull=False, grade__isnull=False,
...@@ -1432,9 +1431,9 @@ class CoursesGradesList(SecureListAPIView): ...@@ -1432,9 +1431,9 @@ class CoursesGradesList(SecureListAPIView):
content_id = self.request.QUERY_PARAMS.get('content_id', None) content_id = self.request.QUERY_PARAMS.get('content_id', None)
if content_id: if content_id:
content_descriptor, content_key, existing_content = get_course_child(request, request.user, course_key, content_id) # pylint: disable=W0612 content_descriptor, content_key, existing_content = get_course_child(request, request.user, course_key, content_id) # pylint: disable=W0612
if not existing_content: if not content_descriptor:
return Response({}, status=status.HTTP_400_BAD_REQUEST) return Response({}, status=status.HTTP_400_BAD_REQUEST)
queryset = queryset.filter(module_state_key=existing_content.location) queryset = queryset.filter(module_state_key=content_key)
queryset_grade_avg = queryset.aggregate(Avg('grade')) queryset_grade_avg = queryset.aggregate(Avg('grade'))
queryset_grade_sum = queryset.aggregate(Sum('grade')) queryset_grade_sum = queryset.aggregate(Sum('grade'))
...@@ -1478,7 +1477,7 @@ class CoursesProjectList(SecureListAPIView): ...@@ -1478,7 +1477,7 @@ class CoursesProjectList(SecureListAPIView):
def get_queryset(self): def get_queryset(self):
course_id = self.kwargs['course_id'] course_id = self.kwargs['course_id']
course_descriptor, course_key, course_content = get_course(self.request, self.request.user, course_id) # pylint: disable=W0612 course_key = get_course_key(course_id)
return Project.objects.filter(course_id=course_key) return Project.objects.filter(course_id=course_key)
...@@ -1495,9 +1494,9 @@ class CourseMetrics(SecureAPIView): ...@@ -1495,9 +1494,9 @@ class CourseMetrics(SecureAPIView):
""" """
GET /api/courses/{course_id}/metrics/ GET /api/courses/{course_id}/metrics/
""" """
course_descriptor, course_key, course_content = get_course(request, request.user, course_id) # pylint: disable=W0612 if not course_exists(request, request.user, course_id):
if not course_descriptor:
return Response({}, status=status.HTTP_404_NOT_FOUND) return Response({}, status=status.HTTP_404_NOT_FOUND)
course_key = get_course_key(course_id)
users_enrolled = CourseEnrollment.num_enrolled_in(course_key) users_enrolled = CourseEnrollment.num_enrolled_in(course_key)
data = { data = {
'users_enrolled': users_enrolled 'users_enrolled': users_enrolled
...@@ -1530,10 +1529,9 @@ class CoursesLeadersList(SecureListAPIView): ...@@ -1530,10 +1529,9 @@ class CoursesLeadersList(SecureListAPIView):
count = self.request.QUERY_PARAMS.get('count', 3) count = self.request.QUERY_PARAMS.get('count', 3)
data = {} data = {}
course_avg = 0 course_avg = 0
course_descriptor, course_key, course_content = get_course(request, request.user, course_id) # pylint: disable=W0612 if not course_exists(request, request.user, course_id):
if not course_descriptor:
return Response({}, status=status.HTTP_404_NOT_FOUND) return Response({}, status=status.HTTP_404_NOT_FOUND)
course_key = get_course_key(course_id)
exclude_users = _get_aggregate_exclusion_user_ids(course_key) exclude_users = _get_aggregate_exclusion_user_ids(course_key)
queryset = StudentModule.objects.filter( queryset = StudentModule.objects.filter(
course_id__exact=course_key, course_id__exact=course_key,
...@@ -1545,9 +1543,9 @@ class CoursesLeadersList(SecureListAPIView): ...@@ -1545,9 +1543,9 @@ class CoursesLeadersList(SecureListAPIView):
if content_id: if content_id:
content_descriptor, content_key, existing_content = get_course_child(request, request.user, course_key, content_id) # pylint: disable=W0612 content_descriptor, content_key, existing_content = get_course_child(request, request.user, course_key, content_id) # pylint: disable=W0612
if not existing_content: if not content_descriptor:
return Response({}, status=status.HTTP_400_BAD_REQUEST) return Response({}, status=status.HTTP_400_BAD_REQUEST)
queryset = queryset.filter(module_state_key=existing_content.location) queryset = queryset.filter(module_state_key=content_key)
if user_id: if user_id:
user_points = StudentModule.objects.filter(course_id__exact=course_key, user_points = StudentModule.objects.filter(course_id__exact=course_key,
...@@ -1600,10 +1598,9 @@ class CoursesCompletionsLeadersList(SecureAPIView): ...@@ -1600,10 +1598,9 @@ class CoursesCompletionsLeadersList(SecureAPIView):
count = self.request.QUERY_PARAMS.get('count', 3) count = self.request.QUERY_PARAMS.get('count', 3)
data = {} data = {}
course_avg = 0 course_avg = 0
course_descriptor, course_key, course_content = get_course(request, request.user, course_id) # pylint: disable=W0612 if not course_exists(request, request.user, course_id):
if not course_descriptor:
return Response({}, status=status.HTTP_404_NOT_FOUND) return Response({}, status=status.HTTP_404_NOT_FOUND)
course_key = get_course_key(course_id)
total_possible_completions = len(get_course_leaf_nodes(course_key, total_possible_completions = len(get_course_leaf_nodes(course_key,
['discussion-course', 'group-project'])) ['discussion-course', 'group-project']))
exclude_users = _get_aggregate_exclusion_user_ids(course_key) exclude_users = _get_aggregate_exclusion_user_ids(course_key)
...@@ -1647,8 +1644,7 @@ class CoursesWorkgroupsList(SecureListAPIView): ...@@ -1647,8 +1644,7 @@ class CoursesWorkgroupsList(SecureListAPIView):
def get_queryset(self): def get_queryset(self):
course_id = self.kwargs['course_id'] course_id = self.kwargs['course_id']
course_descriptor, course_key, course_content = get_course(self.request, self.request.user, course_id) # pylint: disable=W0612 if not course_exists(self.request, self.request.user, course_id):
if not course_descriptor:
raise Http404 raise Http404
queryset = Workgroup.objects.filter(project__course_id=course_id) queryset = Workgroup.objects.filter(project__course_id=course_id)
...@@ -1712,10 +1708,9 @@ class CoursesCitiesMetrics(SecureListAPIView): ...@@ -1712,10 +1708,9 @@ class CoursesCitiesMetrics(SecureListAPIView):
course_id = self.kwargs['course_id'] course_id = self.kwargs['course_id']
city = self.request.QUERY_PARAMS.get('city', None) city = self.request.QUERY_PARAMS.get('city', None)
upper_bound = getattr(settings, 'API_LOOKUP_UPPER_BOUND', 100) upper_bound = getattr(settings, 'API_LOOKUP_UPPER_BOUND', 100)
course_descriptor, course_key, course_content = get_course(self.request, self.request.user, course_id) # pylint: disable=W0612 if not course_exists(self.request, self.request.user, course_id):
if not course_descriptor:
raise Http404 raise Http404
course_key = get_course_key(course_id)
exclude_users = _get_aggregate_exclusion_user_ids(course_key) exclude_users = _get_aggregate_exclusion_user_ids(course_key)
queryset = CourseEnrollment.users_enrolled_in(course_key).exclude(id__in=exclude_users) queryset = CourseEnrollment.users_enrolled_in(course_key).exclude(id__in=exclude_users)
if city: if city:
...@@ -1745,12 +1740,11 @@ class CoursesRolesList(SecureAPIView): ...@@ -1745,12 +1740,11 @@ class CoursesRolesList(SecureAPIView):
GET /api/courses/{course_id}/roles/ GET /api/courses/{course_id}/roles/
""" """
course_id = self.kwargs['course_id'] course_id = self.kwargs['course_id']
course_descriptor, course_key, course_content = get_course(self.request, self.request.user, course_id) # pylint: disable=W0612 if not course_exists(request, request.user, course_id):
if not course_descriptor:
raise Http404 raise Http404
response_data = [] response_data = []
course_key = get_course_key(course_id)
instructors = CourseInstructorRole(course_key).users_with_role() instructors = CourseInstructorRole(course_key).users_with_role()
for instructor in instructors: for instructor in instructors:
response_data.append({'id': instructor.id, 'role': 'instructor'}) response_data.append({'id': instructor.id, 'role': 'instructor'})
......
...@@ -10,64 +10,32 @@ from xmodule.modulestore.django import modulestore ...@@ -10,64 +10,32 @@ from xmodule.modulestore.django import modulestore
from xmodule.modulestore.exceptions import ItemNotFoundError from xmodule.modulestore.exceptions import ItemNotFoundError
def get_course(request, user, course_id, depth=0): def get_course(request, user, course_id, depth=0, load_content=False):
""" """
Utility method to obtain course components Utility method to obtain course components
""" """
course_descriptor = None course_descriptor = None
course_key = None
course_content = None course_content = None
try: course_key = get_course_key(course_id)
course_key = CourseKey.from_string(course_id)
except InvalidKeyError:
try:
course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
except InvalidKeyError:
pass
if course_key: if course_key:
try: course_descriptor = get_course_descriptor(course_key, depth)
course_descriptor = courses.get_course(course_key, depth) if course_descriptor and load_content:
except ValueError: course_content = get_course_content(request, user, course_key, course_descriptor)
pass
if course_descriptor:
field_data_cache = FieldDataCache([course_descriptor], course_key, user)
course_content = module_render.get_module_for_descriptor(
user,
request,
course_descriptor,
field_data_cache,
course_key)
return course_descriptor, course_key, course_content return course_descriptor, course_key, course_content
def get_course_child(request, user, course_key, content_id): def get_course_child(request, user, course_key, content_id, load_content=False):
""" """
Return a course xmodule/xblock to the caller Return a course xmodule/xblock to the caller
""" """
content_descriptor = None child_descriptor = None
content_key = None child_content = None
content = None child_key = get_course_child_key(content_id)
try: if child_key:
content_key = UsageKey.from_string(content_id) child_descriptor = get_course_child_descriptor(child_key)
except InvalidKeyError: if child_descriptor and load_content:
try: child_content = get_course_child_content(request, user, course_key, child_descriptor)
content_key = Location.from_deprecated_string(content_id) return child_descriptor, child_key, child_content
except (InvalidLocationError, InvalidKeyError):
pass
if content_key:
try:
content_descriptor = modulestore().get_item(content_key)
except ItemNotFoundError:
pass
if content_descriptor:
field_data_cache = FieldDataCache([content_descriptor], course_key, user)
content = module_render.get_module_for_descriptor(
user,
request,
content_descriptor,
field_data_cache,
course_key)
return content_descriptor, content_key, content
def get_course_total_score(course_summary): def get_course_total_score(course_summary):
...@@ -92,3 +60,72 @@ def get_course_leaf_nodes(course_key, detached_categories): ...@@ -92,3 +60,72 @@ def get_course_leaf_nodes(course_key, detached_categories):
nodes.extend([unit.location for unit in vertical.get_children() nodes.extend([unit.location for unit in vertical.get_children()
if getattr(unit, 'category') not in detached_categories]) if getattr(unit, 'category') not in detached_categories])
return nodes return nodes
def get_course_key(course_id):
try:
course_key = CourseKey.from_string(course_id)
except InvalidKeyError:
try:
course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
except InvalidKeyError:
course_key = None
return course_key
def get_course_descriptor(course_key, depth):
try:
course_descriptor = courses.get_course(course_key, depth)
except ValueError:
course_descriptor = None
return course_descriptor
def get_course_content(request, user, course_key, course_descriptor):
field_data_cache = FieldDataCache([course_descriptor], course_key, user)
course_content = module_render.get_module_for_descriptor(
user,
request,
course_descriptor,
field_data_cache,
course_key)
return course_content
def course_exists(request, user, course_id):
course_key = get_course_key(course_id)
if not course_key:
return False
if not modulestore().has_course(course_key):
return False
return True
def get_course_child_key(content_id):
try:
content_key = UsageKey.from_string(content_id)
except InvalidKeyError:
try:
content_key = Location.from_deprecated_string(content_id)
except (InvalidLocationError, InvalidKeyError):
content_key = None
return content_key
def get_course_child_descriptor(child_key):
try:
content_descriptor = modulestore().get_item(child_key)
except ItemNotFoundError:
content_descriptor = None
return content_descriptor
def get_course_child_content(request, user, course_key, child_descriptor):
field_data_cache = FieldDataCache([child_descriptor], course_key, user)
child_content = module_render.get_module_for_descriptor(
user,
request,
child_descriptor,
field_data_cache,
course_key)
return child_content
...@@ -22,7 +22,7 @@ from capa.tests.response_xml_factory import StringResponseXMLFactory ...@@ -22,7 +22,7 @@ from capa.tests.response_xml_factory import StringResponseXMLFactory
from courseware.tests.factories import StudentModuleFactory from courseware.tests.factories import StudentModuleFactory
from django_comment_common.models import Role, FORUM_ROLE_MODERATOR from django_comment_common.models import Role, FORUM_ROLE_MODERATOR
from instructor.access import allow_access from instructor.access import allow_access
from projects.models import Project from projects.models import Project, Workgroup
from student.tests.factories import UserFactory from student.tests.factories import UserFactory
from student.models import anonymous_id_for_user from student.models import anonymous_id_for_user
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
...@@ -60,6 +60,7 @@ class UsersApiTests(ModuleStoreTestCase): ...@@ -60,6 +60,7 @@ class UsersApiTests(ModuleStoreTestCase):
self.groups_base_uri = '/api/server/groups' self.groups_base_uri = '/api/server/groups'
self.org_base_uri = '/api/server/organizations/' self.org_base_uri = '/api/server/organizations/'
self.workgroups_base_uri = '/api/server/workgroups/' self.workgroups_base_uri = '/api/server/workgroups/'
self.projects_base_uri = '/api/server/projects/'
self.users_base_uri = '/api/server/users' self.users_base_uri = '/api/server/users'
self.sessions_base_uri = '/api/server/sessions' self.sessions_base_uri = '/api/server/sessions'
self.test_bogus_course_id = 'foo/bar/baz' self.test_bogus_course_id = 'foo/bar/baz'
...@@ -1251,47 +1252,46 @@ class UsersApiTests(ModuleStoreTestCase): ...@@ -1251,47 +1252,46 @@ class UsersApiTests(ModuleStoreTestCase):
def test_user_workgroups_list(self): def test_user_workgroups_list(self):
test_workgroups_uri = self.workgroups_base_uri test_workgroups_uri = self.workgroups_base_uri
user_id = self.user.id project_1 = Project.objects.create(
# create anonymous user course_id=unicode(self.course.id),
anonymous_id = anonymous_id_for_user(self.user, self.course.id) content_id=unicode(self.course_content.scope_ids.usage_id),
for i in xrange(1, 12): )
course = CourseFactory.create( p1_workgroup_1 = Workgroup.objects.create(
display_name="TEST COURSE {}".format(i), name = 'Workgroup 1',
) project = project_1
)
course_content = ItemFactory.create(
category="videosequence",
parent_location=course.location,
data=self.test_course_data,
display_name="View_Sequence"
)
test_project = Project.objects.create( project_2 = Project.objects.create(
course_id=unicode(course.id), course_id=unicode(self.course2.id),
content_id=unicode(course_content.scope_ids.usage_id) content_id=unicode(self.course2_content.scope_ids.usage_id),
) )
data = { p2_workgroup_1 = Workgroup.objects.create(
'name': 'Workgroup ' + str(i), name = 'Workgroup 2',
'project': test_project.id project = project_2
} )
response = self.do_post(test_workgroups_uri, data) for i in xrange(1,12):
self.assertEqual(response.status_code, 201) test_user = UserFactory()
test_uri = '{}{}/'.format(test_workgroups_uri, str(response.data['id'])) users_uri = '{}{}/users/'.format(self.workgroups_base_uri, 1)
users_uri = '{}users/'.format(test_uri) data = {"id": test_user.id}
data = {"id": user_id}
response = self.do_post(users_uri, data) response = self.do_post(users_uri, data)
self.assertEqual(response.status_code, 201) self.assertEqual(response.status_code, 201)
if test_user.id > 6:
users_uri = '{}{}/users/'.format(self.workgroups_base_uri, 2)
data = {"id": test_user.id}
response = self.do_post(users_uri, data)
self.assertEqual(response.status_code, 201)
# test with anonymous user id # test with anonymous user id
test_uri = '{}/{}/workgroups/?page_size=10'.format(self.users_base_uri, anonymous_id) anonymous_id = anonymous_id_for_user(test_user, self.course.id)
test_uri = '{}/{}/workgroups/?page_size=1'.format(self.users_base_uri, anonymous_id)
response = self.do_get(test_uri) response = self.do_get(test_uri)
self.assertEqual(response.data['count'], 11) self.assertEqual(response.data['count'], 2)
self.assertEqual(len(response.data['results']), 10) self.assertEqual(len(response.data['results']), 1)
self.assertEqual(response.data['num_pages'], 2) self.assertEqual(response.data['num_pages'], 2)
# test with course_id filter and integer user id # test with course_id filter and integer user id
course_id = {'course_id': unicode(course.id)} course_id = {'course_id': unicode(self.course.id)}
response = self.do_get('{}/{}/workgroups/?{}'.format(self.users_base_uri, user_id, urlencode(course_id))) response = self.do_get('{}/{}/workgroups/?{}'.format(self.users_base_uri, test_user.id, urlencode(course_id)))
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertEqual(response.data['count'], 1) self.assertEqual(response.data['count'], 1)
self.assertEqual(len(response.data['results']), 1) self.assertEqual(len(response.data['results']), 1)
......
...@@ -34,7 +34,7 @@ from util.password_policy_validators import ( ...@@ -34,7 +34,7 @@ from util.password_policy_validators import (
) )
from api_manager.courses.serializers import CourseModuleCompletionSerializer from api_manager.courses.serializers import CourseModuleCompletionSerializer
from api_manager.courseware_access import get_course, get_course_child, get_course_total_score from api_manager.courseware_access import get_course, get_course_child, get_course_total_score, get_course_key, course_exists
from api_manager.permissions import SecureAPIView, SecureListAPIView, IdsInFilterBackend, HasOrgsFilterBackend from api_manager.permissions import SecureAPIView, SecureListAPIView, IdsInFilterBackend, HasOrgsFilterBackend
from api_manager.models import GroupProfile, APIUser as User from api_manager.models import GroupProfile, APIUser as User
from api_manager.organizations.serializers import OrganizationSerializer from api_manager.organizations.serializers import OrganizationSerializer
...@@ -90,10 +90,9 @@ def _save_content_position(request, user, course_key, position): ...@@ -90,10 +90,9 @@ def _save_content_position(request, user, course_key, position):
parent_content_id = position['parent_content_id'] parent_content_id = position['parent_content_id']
child_content_id = position['child_content_id'] child_content_id = position['child_content_id']
if unicode(course_key) == parent_content_id: if unicode(course_key) == parent_content_id:
parent_descriptor, parent_key, parent_content = get_course(request, user, parent_content_id) # pylint: disable=W0612 parent_descriptor, parent_key, parent_content = get_course(request, user, parent_content_id, load_content=True) # pylint: disable=W0612
else: else:
parent_descriptor, parent_key, parent_content = get_course_child(request, user, course_key, parent_content_id) # pylint: disable=W0612 parent_descriptor, parent_key, parent_content = get_course_child(request, user, course_key, parent_content_id, load_content=True) # pylint: disable=W0612
if not parent_descriptor: if not parent_descriptor:
return None return None
...@@ -126,8 +125,7 @@ def _save_child_position(parent_descriptor, target_child_location): ...@@ -126,8 +125,7 @@ def _save_child_position(parent_descriptor, target_child_location):
# Only save if position changed # Only save if position changed
if position != parent_descriptor.position: if position != parent_descriptor.position:
parent_descriptor.position = position parent_descriptor.position = position
# Save this new position to the underlying KeyValueStore parent_descriptor.save()
parent_descriptor.save()
def _manage_role(course_descriptor, user, role, action): def _manage_role(course_descriptor, user, role, action):
...@@ -807,13 +805,13 @@ class UsersCoursesDetail(SecureAPIView): ...@@ -807,13 +805,13 @@ class UsersCoursesDetail(SecureAPIView):
user = User.objects.get(id=user_id, is_active=True) user = User.objects.get(id=user_id, is_active=True)
except ObjectDoesNotExist: except ObjectDoesNotExist:
return Response({}, status=status.HTTP_404_NOT_FOUND) return Response({}, status=status.HTTP_404_NOT_FOUND)
course_descriptor, course_key, course_content = get_course(request, user, course_id) # pylint: disable=W0612 if not course_exists(request, user, course_id):
if not course_descriptor:
return Response({}, status=status.HTTP_404_NOT_FOUND) return Response({}, status=status.HTTP_404_NOT_FOUND)
response_data['user_id'] = user.id response_data['user_id'] = user.id
response_data['course_id'] = course_id response_data['course_id'] = course_id
if request.DATA['positions']: if request.DATA['positions']:
course_key = get_course_key(course_id)
response_data['positions'] = [] response_data['positions'] = []
for position in request.DATA['positions']: for position in request.DATA['positions']:
content_position = _save_content_position( content_position = _save_content_position(
...@@ -865,7 +863,7 @@ class UsersCoursesDetail(SecureAPIView): ...@@ -865,7 +863,7 @@ class UsersCoursesDetail(SecureAPIView):
response_data['position_tree'][current_child_loc.category] = {} response_data['position_tree'][current_child_loc.category] = {}
response_data['position_tree'][current_child_loc.category]['id'] = unicode(current_child_loc) response_data['position_tree'][current_child_loc.category]['id'] = unicode(current_child_loc)
_,_,parent_module = get_course_child(request, user, course_key, unicode(current_child_loc)) _,_,parent_module = get_course_child(request, user, course_key, unicode(current_child_loc), load_content=True)
else: else:
parent_module = None parent_module = None
...@@ -879,9 +877,9 @@ class UsersCoursesDetail(SecureAPIView): ...@@ -879,9 +877,9 @@ class UsersCoursesDetail(SecureAPIView):
user = User.objects.get(id=user_id, is_active=True) user = User.objects.get(id=user_id, is_active=True)
except ObjectDoesNotExist: except ObjectDoesNotExist:
return Response({}, status=status.HTTP_204_NO_CONTENT) return Response({}, status=status.HTTP_204_NO_CONTENT)
course_descriptor, course_key, course_content = get_course(request, user, course_id) # pylint: disable=W0612 if not course_exists(request, user, course_id):
if not course_descriptor:
return Response({}, status=status.HTTP_204_NO_CONTENT) return Response({}, status=status.HTTP_204_NO_CONTENT)
course_key = get_course_key(course_id)
CourseEnrollment.unenroll(user, course_key) CourseEnrollment.unenroll(user, course_key)
return Response({}, status=status.HTTP_204_NO_CONTENT) return Response({}, status=status.HTTP_204_NO_CONTENT)
...@@ -1234,9 +1232,9 @@ class UsersRolesList(SecureListAPIView): ...@@ -1234,9 +1232,9 @@ class UsersRolesList(SecureListAPIView):
course_id = self.request.QUERY_PARAMS.get('course_id', None) course_id = self.request.QUERY_PARAMS.get('course_id', None)
if course_id: if course_id:
course_descriptor, course_key, course_content = get_course(self.request, user, course_id) # pylint: disable=W0612 if not course_exists(self.request, user, course_id):
if not course_descriptor:
raise Http404 raise Http404
course_key = get_course_key(course_id)
queryset = queryset.filter(course_id=course_key) queryset = queryset.filter(course_id=course_key)
role = self.request.QUERY_PARAMS.get('role', None) role = self.request.QUERY_PARAMS.get('role', None)
......
...@@ -30,7 +30,7 @@ from .serializers import ProjectSerializer, WorkgroupSerializer, WorkgroupSubmis ...@@ -30,7 +30,7 @@ from .serializers import ProjectSerializer, WorkgroupSerializer, WorkgroupSubmis
from .serializers import WorkgroupReviewSerializer, WorkgroupSubmissionReviewSerializer, WorkgroupPeerReviewSerializer from .serializers import WorkgroupReviewSerializer, WorkgroupSubmissionReviewSerializer, WorkgroupPeerReviewSerializer
def _get_course(request, user, course_id, depth=0): def _get_course(request, user, course_id, depth=0, load_content=False):
""" """
Utility method to obtain course components Utility method to obtain course components
""" """
...@@ -49,7 +49,7 @@ def _get_course(request, user, course_id, depth=0): ...@@ -49,7 +49,7 @@ def _get_course(request, user, course_id, depth=0):
course_descriptor = get_course(course_key, depth=depth) course_descriptor = get_course(course_key, depth=depth)
except ValueError: except ValueError:
pass pass
if course_descriptor: if course_descriptor and load_content:
field_data_cache = FieldDataCache([course_descriptor], course_key, user) field_data_cache = FieldDataCache([course_descriptor], course_key, user)
course_content = module_render.get_module( course_content = module_render.get_module(
user, user,
...@@ -60,7 +60,7 @@ def _get_course(request, user, course_id, depth=0): ...@@ -60,7 +60,7 @@ def _get_course(request, user, course_id, depth=0):
return course_descriptor, course_key, course_content return course_descriptor, course_key, course_content
def _get_course_child(request, user, course_key, content_id): def _get_course_child(request, user, course_key, content_id, load_content=False):
""" """
Return a course xmodule/xblock to the caller Return a course xmodule/xblock to the caller
""" """
...@@ -77,7 +77,7 @@ def _get_course_child(request, user, course_key, content_id): ...@@ -77,7 +77,7 @@ def _get_course_child(request, user, course_key, content_id):
if content_key: if content_key:
store = modulestore() store = modulestore()
content_descriptor = store.get_item(content_key) content_descriptor = store.get_item(content_key)
if content_descriptor: if content_descriptor and load_content:
field_data_cache = FieldDataCache([content_descriptor], course_key, user) field_data_cache = FieldDataCache([content_descriptor], course_key, user)
content = module_render.get_module( content = module_render.get_module(
user, user,
......
...@@ -500,3 +500,11 @@ PROFILE_IMAGE_MIN_BYTES = 100 ...@@ -500,3 +500,11 @@ PROFILE_IMAGE_MIN_BYTES = 100
FEATURES['ENABLE_LTI_PROVIDER'] = True FEATURES['ENABLE_LTI_PROVIDER'] = True
INSTALLED_APPS += ('lti_provider',) INSTALLED_APPS += ('lti_provider',)
AUTHENTICATION_BACKENDS += ('lti_provider.users.LtiBackend',) AUTHENTICATION_BACKENDS += ('lti_provider.users.LtiBackend',)
########################## SECURITY #######################
FEATURES['ENFORCE_PASSWORD_POLICY'] = False
FEATURES['ENABLE_MAX_FAILED_LOGIN_ATTEMPTS'] = False
FEATURES['SQUELCH_PII_IN_LOGS'] = False
FEATURES['PREVENT_CONCURRENT_LOGINS'] = False
FEATURES['ADVANCED_SECURITY'] = False
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