From 67eafec570c251178e3e47f7b43914336da4501d Mon Sep 17 00:00:00 2001 From: Ahtisham Shahid <ahtisham300@gmail.com> Date: Fri, 28 Feb 2020 17:02:20 +0500 Subject: [PATCH] Added img to bleach safe tags updated bleach Added img to bleach safe tags Added img to bleach safe tags Added img to bleach safe tags added test added test added test added test added test for attr image added test for attr image fixed style bug Updated format xoe removed extra formatting --- lti_consumer/lti_consumer.py | 24 ++++++++------------ lti_consumer/tests/unit/test_lti_consumer.py | 23 +++++++++++++++++++ setup.py | 2 +- 3 files changed, 33 insertions(+), 16 deletions(-) diff --git a/lti_consumer/lti_consumer.py b/lti_consumer/lti_consumer.py index 9afcff0..6474341 100644 --- a/lti_consumer/lti_consumer.py +++ b/lti_consumer/lti_consumer.py @@ -574,8 +574,8 @@ class LtiConsumerXBlock(StudioEditableXBlockMixin, XBlock): try: lti_id, key, secret = [i.strip() for i in lti_passport.split(':')] except ValueError: - msg = self.ugettext('Could not parse LTI passport: {lti_passport}. Should be "id:key:secret" string.').\ - format(lti_passport='{0!r}'.format(lti_passport)) + msg = 'Could not parse LTI passport: {lti_passport!r}. Should be "id:key:secret" string.' + msg = self.ugettext(msg).format(lti_passport=lti_passport) raise LtiError(msg) if lti_id == self.lti_id.strip(): @@ -694,9 +694,8 @@ class LtiConsumerXBlock(StudioEditableXBlockMixin, XBlock): param_name, param_value = [p.strip() for p in custom_parameter.split('=', 1)] except ValueError: _ = self.runtime.service(self, "i18n").ugettext - # pylint: disable=line-too-long - msg = self.ugettext('Could not parse custom parameter: {custom_parameter}. Should be "x=y" string.').\ - format(custom_parameter="{0!r}".format(custom_parameter)) + msg = 'Could not parse custom parameter: {custom_parameter!r}. Should be "x=y" string.' + msg = self.ugettext(msg).format(custom_parameter=custom_parameter) raise LtiError(msg) # LTI specs: 'custom_' should be prepended before each custom parameter, as pointed in link above. @@ -923,17 +922,12 @@ class LtiConsumerXBlock(StudioEditableXBlockMixin, XBlock): dict: Context variables for templates """ - # use bleach defaults. see https://github.com/jsocol/bleach/blob/master/bleach/__init__.py - # ALLOWED_TAGS are - # ['a', 'abbr', 'acronym', 'b', 'blockquote', 'code', 'em', 'i', 'li', 'ol', 'strong', 'ul'] - # - # ALLOWED_ATTRIBUTES are - # 'a': ['href', 'title'], - # 'abbr': ['title'], - # 'acronym': ['title'], - # + # For more context on ALLOWED_TAGS and ALLOWED_ATTRIBUTES + # Look into this documentation URL see https://bleach.readthedocs.io/en/latest/clean.html#allowed-tags-tags # This lets all plaintext through. - sanitized_comment = bleach.clean(self.score_comment) + allowed_tags = bleach.sanitizer.ALLOWED_TAGS + ['img'] + allowed_attributes = dict(bleach.sanitizer.ALLOWED_ATTRIBUTES, **{'img': ['src', 'alt']}) + sanitized_comment = bleach.clean(self.score_comment, tags=allowed_tags, attributes=allowed_attributes) return { 'launch_url': self.launch_url.strip(), diff --git a/lti_consumer/tests/unit/test_lti_consumer.py b/lti_consumer/tests/unit/test_lti_consumer.py index 6bae920..5767ee6 100644 --- a/lti_consumer/tests/unit/test_lti_consumer.py +++ b/lti_consumer/tests/unit/test_lti_consumer.py @@ -303,6 +303,7 @@ class TestEditableFields(TestLtiConsumerXBlock): """ Unit tests for LtiConsumerXBlock.editable_fields """ + def get_mock_lti_configuration(self, editable): """ Returns a mock object of lti-configuration service @@ -805,6 +806,7 @@ class TestParseSuffix(TestLtiConsumerXBlock): self.assertEqual(parsed, FAKE_USER_ID) +@ddt.ddt class TestGetContext(TestLtiConsumerXBlock): """ Unit tests for LtiConsumerXBlock._get_context_for_template() @@ -825,6 +827,27 @@ class TestGetContext(TestLtiConsumerXBlock): for key in context_keys: self.assertIn(key, context) + @ddt.data('a', 'abbr', 'acronym', 'b', 'blockquote', 'code', 'em', 'i', 'li', 'ol', 'strong', 'ul', 'img') + def test_comment_allowed_tags(self, tag): + """ + Test that allowed tags are not escaped in context['comment'] + """ + comment = u'<{0}>This is a comment</{0}>!'.format(tag) + self.xblock.set_user_module_score(Mock(), 0.92, 1.0, comment) + context = self.xblock._get_context_for_template() # pylint: disable=protected-access + + self.assertIn('<{}>'.format(tag), context['comment']) + + def test_comment_retains_image_src(self): + """ + Test that image tag has src and other attrs are sanitized + """ + comment = u'<img src="example.com/image.jpeg" onerror="myFunction()">' + self.xblock.set_user_module_score(Mock(), 0.92, 1.0, comment) + context = self.xblock._get_context_for_template() # pylint: disable=protected-access + + self.assertIn(u'<img src="example.com/image.jpeg">', context['comment']) + @ddt.ddt class TestProcessorSettings(TestLtiConsumerXBlock): diff --git a/setup.py b/setup.py index f623e7e..99d1da9 100644 --- a/setup.py +++ b/setup.py @@ -25,7 +25,7 @@ def package_data(pkg, roots): setup( name='lti_consumer-xblock', - version='1.2.3', + version='1.2.4', description='This XBlock implements the consumer side of the LTI specification.', packages=[ 'lti_consumer', -- GitLab