diff --git a/common/lib/capa/capa/responsetypes.py b/common/lib/capa/capa/responsetypes.py index 032970e324..fb7a69a2f2 100644 --- a/common/lib/capa/capa/responsetypes.py +++ b/common/lib/capa/capa/responsetypes.py @@ -1123,10 +1123,11 @@ class CodeResponse(LoncapaResponse): # Prepare xqueue request #------------------------------------------------------------ qinterface = self.system.xqueue['interface'] + anonymous_student_id = self.system.anonymous_student_id # Generate header queuekey = xqueue_interface.make_hashkey(str(self.system.seed) + str(time.time()) + - str(self.system.xqueue['student_identifier']) + + anonymous_student_id + self.answer_id) xheader = xqueue_interface.make_xheader(lms_callback_url=self.system.xqueue['callback_url'], lms_key=queuekey, @@ -1134,15 +1135,14 @@ class CodeResponse(LoncapaResponse): # Generate body if is_list_of_files(submission): - self.context.update({'submission': queuekey}) # For tracking. TODO: May want to record something else here + self.context.update({'submission': ''}) # TODO: Get S3 pointer from the Queue else: self.context.update({'submission': submission}) contents = self.payload.copy() # Anonymized student identifier to the external grader - student_identifier_hash = xqueue_interface.make_hashkey(self.system.xqueue['student_identifier']) - student_info = {'student_identifier_hash': student_identifier_hash} + student_info = {'anonymous_student_id': anonymous_student_id} contents.update({'student_info': json.dumps(student_info)}) # Submit request. When successful, 'msg' is the prior length of the queue diff --git a/common/lib/xmodule/xmodule/tests/__init__.py b/common/lib/xmodule/xmodule/tests/__init__.py index 01462d16ac..0d10184501 100644 --- a/common/lib/xmodule/xmodule/tests/__init__.py +++ b/common/lib/xmodule/xmodule/tests/__init__.py @@ -35,8 +35,9 @@ i4xs = ModuleSystem( user=Mock(), filestore=fs.osfs.OSFS(os.path.dirname(os.path.realpath(__file__))+"/test_files"), debug=True, - xqueue={'interface':None, 'callback_url':'/', 'default_queuename': 'testqueue', 'student_identifier': 0}, - node_path=os.environ.get("NODE_PATH", "/usr/local/lib/node_modules") + xqueue={'interface':None, 'callback_url':'/', 'default_queuename': 'testqueue'}, + node_path=os.environ.get("NODE_PATH", "/usr/local/lib/node_modules"), + anonymous_student_id = 'student' ) diff --git a/common/lib/xmodule/xmodule/x_module.py b/common/lib/xmodule/xmodule/x_module.py index c581911c03..0dc16bd976 100644 --- a/common/lib/xmodule/xmodule/x_module.py +++ b/common/lib/xmodule/xmodule/x_module.py @@ -717,7 +717,8 @@ class ModuleSystem(object): filestore=None, debug=False, xqueue=None, - node_path=""): + node_path="", + anonymous_student_id=''): ''' Create a closure around the system environment. @@ -742,11 +743,16 @@ class ModuleSystem(object): at settings.DATA_DIR. xqueue - Dict containing XqueueInterface object, as well as parameters - for the specific StudentModule + for the specific StudentModule: + xqueue = {'interface': XQueueInterface object, + 'callback_url': Callback into the LMS, + 'queue_name': Target queuename in Xqueue} replace_urls - TEMPORARY - A function like static_replace.replace_urls that capa_module can use to fix up the static urls in ajax results. + + anonymous_student_id - Used for tracking modules with student id ''' self.ajax_url = ajax_url self.xqueue = xqueue @@ -758,6 +764,7 @@ class ModuleSystem(object): self.seed = user.id if user is not None else 0 self.replace_urls = replace_urls self.node_path = node_path + self.anonymous_student_id = anonymous_student_id def get(self, attr): ''' provide uniform access to attributes (like etree).''' diff --git a/lms/djangoapps/courseware/module_render.py b/lms/djangoapps/courseware/module_render.py index 467b147d0f..b278d2615b 100644 --- a/lms/djangoapps/courseware/module_render.py +++ b/lms/djangoapps/courseware/module_render.py @@ -1,3 +1,4 @@ +import hashlib import json import logging import sys @@ -173,6 +174,11 @@ def _get_module(user, request, location, student_module_cache, course_id, positi if not has_access(user, descriptor, 'load'): return None + # Anonymized student identifier + h = hashlib.md5() # TODO: Seed with LMS secret key + h.update(str(user.id)) + anonymous_student_id = h.hexdigest() + #TODO Only check the cache if this module can possibly have state instance_module = None shared_module = None @@ -218,7 +224,6 @@ def _get_module(user, request, location, student_module_cache, course_id, positi xqueue = {'interface': xqueue_interface, 'callback_url': xqueue_callback_url, 'default_queuename': xqueue_default_queuename.replace(' ', '_'), - 'student_identifier': user.id, } def inner_get_module(location): @@ -243,7 +248,8 @@ def _get_module(user, request, location, student_module_cache, course_id, positi # a module is coming through get_html and is therefore covered # by the replace_static_urls code below replace_urls=replace_urls, - node_path=settings.NODE_PATH + node_path=settings.NODE_PATH, + anonymous_student_id=anonymous_student_id ) # pass position specified in URL to module through ModuleSystem system.set('position', position)