Fix: Find the submission history using learner's email address along with username (#25642)
Co-authored-by: asadiqbal <aiqbal@edx.org> Co-authored-by: asadiqbal08 <asad.iqbal@arbisoft.com>
This commit is contained in:
@@ -612,7 +612,7 @@ class ViewsTestCase(BaseViewsTestCase):
|
||||
|
||||
url = reverse('submission_history', kwargs={
|
||||
'course_id': str(self.course_key),
|
||||
'student_username': 'dummy',
|
||||
'learner_identifier': 'dummy',
|
||||
'location': str(self.problem.location),
|
||||
})
|
||||
response = self.client.get(url)
|
||||
@@ -628,7 +628,7 @@ class ViewsTestCase(BaseViewsTestCase):
|
||||
# try it with an existing user and a malicious location
|
||||
url = reverse('submission_history', kwargs={
|
||||
'course_id': str(self.course_key),
|
||||
'student_username': 'dummy',
|
||||
'learner_identifier': 'dummy',
|
||||
'location': '<script>alert("hello");</script>'
|
||||
})
|
||||
response = self.client.get(url)
|
||||
@@ -637,7 +637,7 @@ class ViewsTestCase(BaseViewsTestCase):
|
||||
# try it with a malicious user and a non-existent location
|
||||
url = reverse('submission_history', kwargs={
|
||||
'course_id': str(self.course_key),
|
||||
'student_username': '<script>alert("hello");</script>',
|
||||
'learner_identifier': '<script>alert("hello");</script>',
|
||||
'location': 'dummy'
|
||||
})
|
||||
response = self.client.get(url)
|
||||
@@ -670,7 +670,7 @@ class ViewsTestCase(BaseViewsTestCase):
|
||||
|
||||
url = reverse('submission_history', kwargs={
|
||||
'course_id': str(self.course_key),
|
||||
'student_username': admin.username,
|
||||
'learner_identifier': admin.email,
|
||||
'location': str(usage_key),
|
||||
})
|
||||
response = self.client.get(url)
|
||||
@@ -711,7 +711,7 @@ class ViewsTestCase(BaseViewsTestCase):
|
||||
)
|
||||
url = reverse('submission_history', kwargs={
|
||||
'course_id': str(course_key),
|
||||
'student_username': admin.username,
|
||||
'learner_identifier': admin.username,
|
||||
'location': str(usage_key),
|
||||
})
|
||||
response = client.get(url)
|
||||
|
||||
@@ -1340,12 +1340,15 @@ def _course_home_redirect_enabled():
|
||||
|
||||
@login_required
|
||||
@ensure_valid_course_key
|
||||
def submission_history(request, course_id, student_username, location):
|
||||
def submission_history(request, course_id, learner_identifier, location):
|
||||
"""Render an HTML fragment (meant for inclusion elsewhere) that renders a
|
||||
history of all state changes made by this user for this problem location.
|
||||
Right now this only works for problems because that's all
|
||||
StudentModuleHistory records.
|
||||
"""
|
||||
found_user_name = get_learner_username(learner_identifier)
|
||||
if not found_user_name:
|
||||
return HttpResponse(escape(_('User does not exist.')))
|
||||
|
||||
course_key = CourseKey.from_string(course_id)
|
||||
|
||||
@@ -1359,15 +1362,15 @@ def submission_history(request, course_id, student_username, location):
|
||||
|
||||
# Permission Denied if they don't have staff access and are trying to see
|
||||
# somebody else's submission history.
|
||||
if (student_username != request.user.username) and (not staff_access):
|
||||
if (found_user_name != request.user.username) and (not staff_access):
|
||||
raise PermissionDenied
|
||||
|
||||
user_state_client = DjangoXBlockUserStateClient()
|
||||
try:
|
||||
history_entries = list(user_state_client.get_history(student_username, usage_key))
|
||||
history_entries = list(user_state_client.get_history(found_user_name, usage_key))
|
||||
except DjangoXBlockUserStateClient.DoesNotExist:
|
||||
return HttpResponse(escape(_('User {username} has never accessed problem {location}').format(
|
||||
username=student_username,
|
||||
return HttpResponse(escape(_(u'User {username} has never accessed problem {location}').format(
|
||||
username=found_user_name,
|
||||
location=location
|
||||
)))
|
||||
|
||||
@@ -1375,7 +1378,7 @@ def submission_history(request, course_id, student_username, location):
|
||||
# the scores instead, it will have to do.
|
||||
csm = StudentModule.objects.filter(
|
||||
module_state_key=usage_key,
|
||||
student__username=student_username,
|
||||
student__username=found_user_name,
|
||||
course_id=course_key)
|
||||
|
||||
scores = BaseStudentModuleHistory.get_history(csm)
|
||||
@@ -1387,7 +1390,7 @@ def submission_history(request, course_id, student_username, location):
|
||||
"%d scores were found, and %d history entries were found. "
|
||||
"Matching scores to history entries by date for display.",
|
||||
course_id,
|
||||
student_username,
|
||||
found_user_name,
|
||||
location,
|
||||
len(scores),
|
||||
len(history_entries),
|
||||
@@ -1404,7 +1407,7 @@ def submission_history(request, course_id, student_username, location):
|
||||
context = {
|
||||
'history_entries': history_entries,
|
||||
'scores': scores,
|
||||
'username': student_username,
|
||||
'username': found_user_name,
|
||||
'location': location,
|
||||
'course_id': str(course_key)
|
||||
}
|
||||
@@ -2094,3 +2097,10 @@ def get_financial_aid_courses(user):
|
||||
)
|
||||
|
||||
return financial_aid_courses
|
||||
|
||||
|
||||
def get_learner_username(learner_identifier):
|
||||
""" Return the username """
|
||||
learner = User.objects.filter(Q(username=learner_identifier) | Q(email=learner_identifier)).first()
|
||||
if learner:
|
||||
return learner.username
|
||||
|
||||
@@ -25,11 +25,11 @@ function setup_debug(element_id, edit_link, staff_context){
|
||||
|
||||
$('#' + element_id + '_history_form').submit(
|
||||
function () {
|
||||
var username = $("#" + element_id + "_history_student_username").val();
|
||||
var username_or_email = $("#" + element_id + "_history_student_username").val();
|
||||
var location = $("#" + element_id + "_history_location").val();
|
||||
// xss-lint: disable=mako-invalid-js-filter
|
||||
$("#" + element_id + "_history_text").load('/courses/' + "${six.text_type(getattr(course,'id','')) | u}" +
|
||||
"/submission_history/" + username + "/" + location);
|
||||
"/submission_history/" + username_or_email + "/" + location);
|
||||
return false;
|
||||
}
|
||||
);
|
||||
|
||||
@@ -128,8 +128,8 @@ ${block_content | n, decode.utf8}
|
||||
<h2>${_("Submission History Viewer")}</h2>
|
||||
</header>
|
||||
<form id="${element_id}_history_form">
|
||||
<label for="${element_id}_history_student_username">${_("User:")}</label>
|
||||
<input tabindex="0" id="${element_id}_history_student_username" type="text" placeholder=""/>
|
||||
<label for="${element_id}_history_student_username">${_("Learner's {platform_name} email address or username:").format(platform_name=settings.PLATFORM_NAME)}</label>
|
||||
<input tabindex="0" id="${element_id}_history_student_username" type="text" placeholder="${_('Enter the learner email address or username')}"/>
|
||||
<input type="hidden" id="${element_id}_history_location" value="${location}"/>
|
||||
<div class="submit">
|
||||
<button name="submit" type="submit">${_("View History")}</button>
|
||||
|
||||
@@ -779,7 +779,7 @@ urlpatterns += [
|
||||
if settings.FEATURES.get('ENABLE_STUDENT_HISTORY_VIEW'):
|
||||
urlpatterns += [
|
||||
url(
|
||||
r'^courses/{}/submission_history/(?P<student_username>[^/]*)/(?P<location>.*?)$'.format(
|
||||
r'^courses/{}/submission_history/(?P<learner_identifier>[^/]*)/(?P<location>.*?)$'.format(
|
||||
settings.COURSE_ID_PATTERN
|
||||
),
|
||||
courseware_views.submission_history,
|
||||
|
||||
Reference in New Issue
Block a user