Commit a0904cff by Carson Gee

Merge pull request #5 from mitocw/mitx-hotfix-rc-20140828

Mitx hotfix rc 20140828
parents c99ac45a de9ff565
"""
Script for exporting all courseware from Mongo to a directory
Script for exporting all courseware from Mongo to a directory and listing the courses which failed to export
"""
from django.core.management.base import BaseCommand, CommandError
from xmodule.modulestore.xml_exporter import export_to_xml
......@@ -8,35 +8,52 @@ from xmodule.contentstore.django import contentstore
class Command(BaseCommand):
"""Export all courses from mongo to the specified data directory"""
help = 'Export all courses from mongo to the specified data directory'
"""
Export all courses from mongo to the specified data directory and list the courses which failed to export
"""
help = 'Export all courses from mongo to the specified data directory and list the courses which failed to export'
def handle(self, *args, **options):
"Execute the command"
"""
Execute the command
"""
if len(args) != 1:
raise CommandError("export requires one argument: <output path>")
output_path = args[0]
cs = contentstore()
ms = modulestore()
root_dir = output_path
courses = ms.get_courses()
print("%d courses to export:" % len(courses))
cids = [x.id for x in courses]
print(cids)
for course_id in cids:
print("-"*77)
print("Exporting course id = {0} to {1}".format(course_id, output_path))
if 1:
try:
course_dir = course_id.replace('/', '...')
export_to_xml(ms, cs, course_id, root_dir, course_dir)
except Exception as err:
print("="*30 + "> Oops, failed to export %s" % course_id)
print("Error:")
print(err)
courses, failed_export_courses = export_courses_to_output_path(output_path)
print("=" * 80)
print(u"=" * 30 + u"> Export summary")
print(u"Total number of courses to export: {0}".format(len(courses)))
print(u"Total number of courses which failed to export: {0}".format(len(failed_export_courses)))
print(u"List of export failed courses ids:")
print(u"\n".join(failed_export_courses))
print("=" * 80)
def export_courses_to_output_path(output_path):
"""
Export all courses to target directory and return the list of courses which failed to export
"""
content_store = contentstore()
module_store = modulestore()
root_dir = output_path
courses = module_store.get_courses()
course_ids = [x.id for x in courses]
failed_export_courses = []
for course_id in course_ids:
print(u"-" * 80)
print(u"Exporting course id = {0} to {1}".format(course_id, output_path))
try:
course_dir = course_id.to_deprecated_string().replace('/', '...')
export_to_xml(module_store, content_store, course_id, root_dir, course_dir)
except Exception as err: # pylint: disable=broad-except
failed_export_courses.append(unicode(course_id))
print(u"=" * 30 + u"> Oops, failed to export {0}".format(course_id))
print(u"Error:")
print(err)
return courses, failed_export_courses
"""
Test for export all courses.
"""
import shutil
from tempfile import mkdtemp
from contentstore.management.commands.export_all_courses import export_courses_to_output_path
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
class ExportAllCourses(ModuleStoreTestCase):
"""
Tests exporting all courses.
"""
def setUp(self):
""" Common setup. """
self.store = modulestore()._get_modulestore_by_type(ModuleStoreEnum.Type.mongo)
self.temp_dir = mkdtemp()
self.first_course = CourseFactory.create(org="test", course="course1", display_name="run1")
self.second_course = CourseFactory.create(org="test", course="course2", display_name="run2")
def test_export_all_courses(self):
"""
Test exporting good and faulty courses
"""
# check that both courses exported successfully
courses, failed_export_courses = export_courses_to_output_path(self.temp_dir)
self.assertEqual(len(courses), 2)
self.assertEqual(len(failed_export_courses), 0)
# manually make second course faulty and check that it fails on export
second_course_id = self.second_course.id
self.store.collection.update(
{'_id.org': second_course_id.org, '_id.course': second_course_id.course, '_id.name': second_course_id.run},
{'$set': {'metadata.tags': 'crash'}}
)
courses, failed_export_courses = export_courses_to_output_path(self.temp_dir)
self.assertEqual(len(courses), 2)
self.assertEqual(len(failed_export_courses), 1)
self.assertEqual(failed_export_courses[0], unicode(second_course_id))
def tearDown(self):
""" Common cleanup. """
shutil.rmtree(self.temp_dir)
......@@ -734,16 +734,18 @@ oauth_consumer_key="", oauth_signature="frVp4JuvT1mVXlxktiAUjQ7%2F1cw%3D"'}
oauth_headers = dict(oauth_params)
oauth_signature = oauth_headers.pop('oauth_signature')
mock_request = mock.Mock(
uri=unicode(urllib.unquote(request.url)),
uri=unicode(urllib.unquote(self.get_outcome_service_url())),
http_method=unicode(request.method),
params=oauth_headers.items(),
signature=oauth_signature
)
if oauth_body_hash != oauth_headers.get('oauth_body_hash'):
log.error("OAuth body hash verification failed, provided: {} calculated: {}, for url: {}, body is: {}".format(oauth_headers.get('oauth_body_hash'),oauth_body_hash,self.get_outcome_service_url(),request.body))
raise LTIError("OAuth body hash verification is failed.")
if not signature.verify_hmac_sha1(mock_request, client_secret):
log.error("OAuth signature verification failed, for url:{}".format(oauth_headers,self.get_outcome_service_url()))
raise LTIError("OAuth signature verification is failed.")
def get_client_key_secret(self):
......
......@@ -55,7 +55,10 @@ class CustomTagDescriptor(RawDescriptor):
# cdodge: look up the template as a module
template_loc = self.location.replace(category='custom_tag_template', name=template_name)
template_module = system.load_item(template_loc)
try:
template_module = system.load_item(template_loc)
except:
template_module = system.load_item(template_loc.for_branch('draft'))
template_module_data = template_module.data
template = Template(template_module_data)
return template.render(**params)
......
......@@ -331,6 +331,49 @@ class LTIModuleTest(LogicTest):
except LTIError as err:
self.fail("verify_oauth_body_sign() raised LTIError: " + err.message)
@patch('xmodule.lti_module.LTIModule.get_outcome_service_url', Mock(return_value=u'https://testurl/'))
@patch('xmodule.lti_module.LTIModule.get_client_key_secret',
Mock(return_value=(u'__consumer_key__', u'__lti_secret__')))
def test_failed_verify_oauth_body_sign_proxy_mangle_url(self):
"""
Oauth signing verify fail.
"""
try:
request = self.get_signed_grade_mock_request_with_correct_signature()
self.xmodule.verify_oauth_body_sign(request)
# we should verify against get_outcome_service_url not request url
# proxy and load balancer along the way may change url presented to the method
request.uri = 'http://testurl/'
self.xmodule.verify_oauth_body_sign(request)
except LTIError as err:
self.fail("verify_oauth_body_sign() raised LTIError: " + err.message)
pass
def get_signed_grade_mock_request_with_correct_signature(self):
mock_request = Mock()
mock_request.headers = {
'X-Requested-With': 'XMLHttpRequest',
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': u'OAuth realm="https://testurl/", oauth_body_hash="wwzA3s8gScKD1VpJ7jMt9b%2BMj9Q%3D", \
oauth_nonce="18821463", oauth_timestamp="1409321145", \
oauth_consumer_key="__consumer_key__", oauth_signature_method="HMAC-SHA1", \
oauth_version="1.0", oauth_signature="fHsE1hhIz76/msUoMR3Lyb7Aou4%3D"'
}
mock_request.url = u'https://testurl'
mock_request.http_method = u'POST'
mock_request.method = mock_request.http_method
mock_request.body = '<?xml version=\'1.0\' encoding=\'utf-8\'?>\n\
<imsx_POXEnvelopeRequest xmlns="http://www.imsglobal.org/services/ltiv1p1/xsd/imsoms_v1p0">\
<imsx_POXHeader><imsx_POXRequestHeaderInfo><imsx_version>V1.0</imsx_version>\
<imsx_messageIdentifier>edX_fix</imsx_messageIdentifier></imsx_POXRequestHeaderInfo>\
</imsx_POXHeader><imsx_POXBody><replaceResultRequest><resultRecord><sourcedGUID>\
<sourcedId>MITxLTI/MITxLTI/201x:localhost%3A8000-i4x-MITxLTI-MITxLTI-lti-3751833a214a4f66a0d18f63234207f2:363979ef768ca171b50f9d1bfb322131</sourcedId>\
</sourcedGUID><result><resultScore><language>en</language><textString>0.32</textString></resultScore>\
</result></resultRecord></replaceResultRequest></imsx_POXBody></imsx_POXEnvelopeRequest>'
return mock_request
def test_wrong_xml_namespace(self):
"""
Test wrong XML Namespace.
......
......@@ -76,8 +76,9 @@ Annotator.Plugin.Flagging = (function(_super) {
*/
Flagging.prototype.updateField = function(field, annotation) {
// figure out whether annotation is of image or not
var user_email = annotation.media === "image" ?
// figure out whether annotation is of type image or if ova is not defined (meaning it
// it doesn't have a type yet, but it is still an image).
var user_email = (annotation.media === "image" || typeof ova === 'undefined') ?
osda.options.optionsAnnotator.permissions.user.id:
ova.options.optionsAnnotator.permissions.user.id;
......
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