Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion lms/djangoapps/dashboard/sysadmin.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@
from django.http import HttpResponse
from django.utils.html import escape
from django.contrib.admin.views.decorators import staff_member_required
from django.contrib.auth.decorators import login_required
from django.http import Http404

from mitxmako.shortcuts import render_to_response
from xmodule.modulestore.django import modulestore
from xmodule.contentstore.django import contentstore
from xmodule.modulestore.store_utilities import delete_course
from courseware.access import has_access
import mongoengine

import track.views
Expand Down Expand Up @@ -526,7 +528,7 @@ def sysadmin_dashboard(request):

# -----------------------------------------------------------------------------

@staff_member_required
@login_required
def view_git_logs(request, course_id=None):
"""Shows logs of imports that happened as a result of a git import"""
# pylint: disable-msg=W0613
Expand Down Expand Up @@ -559,8 +561,18 @@ def view_git_logs(request, course_id=None):
'MONGODB_LOG settings. error: {0}').format(str(ex)))

if course_id is None:

# Require staff if not going to specific course
if not request.user.is_staff:
raise Http404
cilset = CourseImportLog.objects.all().order_by('-created')
else:
course = get_course_by_id(course_id)
# Allow only course team, instructors, and staff
if not (request.user.is_staff or
has_access(request.user, course, 'instructor') or
has_access(request.user, course, 'staff')):
raise Http404
log.debug('course_id={0}'.format(course_id))
cilset = CourseImportLog.objects.filter(
course_id=course_id).order_by('-created')
Expand Down
49 changes: 43 additions & 6 deletions lms/djangoapps/dashboard/tests/test_sysadmin.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
from dashboard.sysadmin import create_user
from external_auth.models import ExternalAuthMap
from django.contrib.auth.hashers import check_password
from django.contrib.auth.models import Group
from xmodule.modulestore.django import modulestore
from courseware.tests.tests import TEST_DATA_MONGO_MODULESTORE
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from django.utils.html import escape
from courseware.access import get_access_group_name, has_access
from dashboard.sysadmin import CourseImportLog
import mongoengine

Expand Down Expand Up @@ -86,9 +88,6 @@ def test_staff_access(self):
response = self.client.get(reverse('sysadmin'))
self.assertEqual('/sysadmin', response.context['next'])

response = self.client.get(reverse('gitlogs'))
self.assertEqual('/gitlogs', response.context['next'])

logged_in = self.client.login(username=self.user.username,
password='foo')
self.assertTrue(logged_in)
Expand All @@ -97,7 +96,7 @@ def test_staff_access(self):
self.assertEqual('/sysadmin', response.context['next'])

response = self.client.get(reverse('gitlogs'))
self.assertEqual('/gitlogs', response.context['next'])
self.assertEqual(response.status_code, 404)

self.user.is_staff = True
self.user.save()
Expand Down Expand Up @@ -344,8 +343,7 @@ def test_gitlogs(self):

self._add_edx4edx()
response = self.client.get(reverse('gitlogs'))
print(response.content)
print(CourseImportLog.objects.all())

# Check that our earlier import has a log with a link to details
self.assertIn('/gitlogs/MITx/edx4edx/edx4edx', response.content)

Expand All @@ -356,6 +354,45 @@ def test_gitlogs(self):

self._rm_edx4edx()

def test_gitlog_courseteam_access(self):
"""Ensure course team users are allowed to access only their own course"""

try:
os.mkdir(getattr(settings, 'GIT_REPO_DIR'))
except OSError:
pass

self._setstaff_login()
self._add_edx4edx()
self.user.is_staff = False
self.user.save()
logged_in = self.client.login(username=self.user.username,
password='foo')
response = self.client.get(reverse('gitlogs'))

# Make sure our non privileged user doesn't have access to all logs
self.assertEqual(response.status_code, 404)

# Add user as staff in course team
def_ms = modulestore()
course = def_ms.get_course('MITx/edx4edx/edx4edx')

staff_groupname = get_access_group_name(course, 'staff')
group, _ = Group.objects.get_or_create(name=staff_groupname)
self.user.groups.add(group)

self.assertTrue(has_access(self.user, course, 'staff'))
logged_in = self.client.login(username=self.user.username,
password='foo')
self.assertTrue(logged_in)

response = self.client.get(
reverse('gitlogs_detail', kwargs={'course_id': 'MITx/edx4edx/edx4edx'}))
print(response.content)
self.assertIn('======> IMPORTING course to location', response.content)

self._rm_edx4edx()

@override_settings(GIT_ADD_COURSE_SCRIPT='')
def test_no_script_set(self):
""" Test if settings are right on mongo store import"""
Expand Down
16 changes: 15 additions & 1 deletion scripts/git_add_course.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,18 @@ def add_repo(repo, rdir_in):
# Get XML logging logger and capture debug to parse results
output = StringIO.StringIO()
import_logger = logging.getLogger('xmodule.modulestore.xml_importer')
git_logger = logging.getLogger('git_add_script')
xml_logger = logging.getLogger('xmodule.modulestore.xml')
xml_seq_logger = logging.getLogger('xmodule.seq_module')

import_log_handler = logging.StreamHandler(output)
import_log_handler.setLevel(logging.DEBUG)
import_logger.addHandler(import_log_handler)

for logger in [import_logger, git_logger, xml_logger, xml_seq_logger, ]:
logger.old_level = logger.level
logger.setLevel(logging.DEBUG)
logger.addHandler(import_log_handler)

try:
management.call_command('import', GIT_REPO_DIR, rdir,
nostatic=not GIT_IMPORT_STATIC)
Expand All @@ -132,6 +141,11 @@ def add_repo(repo, rdir_in):

ret_import = output.getvalue()

# Remove handler hijacks
for logger in [import_logger, git_logger, xml_logger, xml_seq_logger, ]:
logger.setLevel(logger.old_level)
logger.removeHandler(import_log_handler)

course_id = 'unknown'
location = 'unknown'

Expand Down