From dac52d29e99598f38aceb4497192cd5397a17dd0 Mon Sep 17 00:00:00 2001 From: r1cardohj <2413302357@qq.com> Date: Sat, 9 Dec 2023 16:28:14 +0800 Subject: [PATCH 1/5] add:create `cleanify` into `utils` moudel --- CHANGES.rst | 7 +++++++ flask_ckeditor/utils.py | 26 ++++++++++++++++++++++- requirements/dev.txt | 2 +- requirements/example.txt | 1 + requirements/tests.in | 1 + requirements/tests.txt | 1 + test_flask_ckeditor.py | 45 +++++++++++++++++++++++++++++++++++++++- 7 files changed, 80 insertions(+), 3 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 9e7a871..6799d3d 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -6,6 +6,13 @@ Changelog Release date: - +0.5.2 +----- + +Release date: 2023/12/09 + +- add ``cleanify`` function to ``flask_ckeditor.utils`` + 0.5.1 ----- diff --git a/flask_ckeditor/utils.py b/flask_ckeditor/utils.py index 711a00e..c68dc85 100644 --- a/flask_ckeditor/utils.py +++ b/flask_ckeditor/utils.py @@ -1,8 +1,13 @@ import os import uuid - +import warnings from flask import url_for +try: + import bleach +except ImportError: + warnings.warn('bleach is not installed,`cleanify` function will not be available') + def get_url(endpoint_or_url): if endpoint_or_url.startswith(('https://', 'http://', '/')): @@ -15,3 +20,22 @@ def random_filename(old_filename): ext = os.path.splitext(old_filename)[1] new_filename = uuid.uuid4().hex + ext return new_filename + + +def cleanify(text, *, allow_tags=None): + """clean the input from client, this function rely on bleach, + + + Args: + text (str): input + allow_tags (Iterable[str], optional): if you don't want to use default `allow_tags` + you can provide a Iterable which include html tag string like ['a', 'li',...] + """ + if allow_tags: + return bleach.linkify(bleach.clean(text, tags=allow_tags)) + default_allowed_tags = {'a', 'abbr', 'b', 'blockquote', 'code', + 'em', 'i', 'li', 'ol', 'pre', 'strong', 'ul', + 'h1', 'h2', 'h3', 'h4', 'h5', 'p'} + return bleach.linkify(bleach.clean(text, tags=default_allowed_tags)) + + \ No newline at end of file diff --git a/requirements/dev.txt b/requirements/dev.txt index 873576f..aa3b04b 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -164,7 +164,7 @@ wtforms==3.1.1 # via # flask-admin # flask-wtf - +bleach==6.1.0 # The following packages are considered to be unsafe in a requirements file: # pip # setuptools diff --git a/requirements/example.txt b/requirements/example.txt index eab17f8..e66159b 100644 --- a/requirements/example.txt +++ b/requirements/example.txt @@ -48,3 +48,4 @@ wtforms==3.1.1 # via # flask-admin # flask-wtf + \ No newline at end of file diff --git a/requirements/tests.in b/requirements/tests.in index da0230e..d747657 100644 --- a/requirements/tests.in +++ b/requirements/tests.in @@ -5,3 +5,4 @@ flask-wtf flask-admin flask-sqlalchemy tablib +bleach diff --git a/requirements/tests.txt b/requirements/tests.txt index 721c0dc..f9f6928 100644 --- a/requirements/tests.txt +++ b/requirements/tests.txt @@ -61,3 +61,4 @@ wtforms==3.1.1 # via # flask-admin # flask-wtf +bleach==6.1.0 diff --git a/test_flask_ckeditor.py b/test_flask_ckeditor.py index 015dd94..c80a81b 100644 --- a/test_flask_ckeditor.py +++ b/test_flask_ckeditor.py @@ -14,6 +14,7 @@ from flask_wtf import FlaskForm, CSRFProtect from flask_ckeditor import CKEditorField, _CKEditor, CKEditor, upload_success, upload_fail +from flask_ckeditor.utils import cleanify class CKEditorTestCase(unittest.TestCase): @@ -286,7 +287,49 @@ def test_upload_fail(self): json.loads(rv.data), {'uploaded': 0, 'error': {'message': 'new error message'}} ) - + + def test_cleanify_input_js(self): + input = 'an example' + clean_ouput = cleanify(input) + self.assertEqual(clean_ouput, + u'an <script>evil()</script> example') + + def test_cleanify_input_url(self): + input = 'abc http://example.com def' + clean_output = cleanify(input) + self.assertEqual(clean_output, + u'abc http://example.com def') + + def test_cleanify_by_allow_tags(self): + input = ' hello this is a url !
xxxxxxx+
print(hello)
+ xxxxx
+ xxxxxx
+ xxxxxx+ xxxxxx +
xxxxxxxx
+ """ + clean_out = cleanify(input) + self.assertEqual(clean_out,input) + if __name__ == '__main__': unittest.main() From ab448fcf68efa09a3eafc519f0b0675eb7625842 Mon Sep 17 00:00:00 2001 From: r1cardohj <2413302357@qq.com> Date: Sat, 9 Dec 2023 18:11:31 +0800 Subject: [PATCH 2/5] fix:pass flake8 and tox --- flask_ckeditor/utils.py | 4 +--- test_flask_ckeditor.py | 22 +++++++++++----------- tox.ini | 1 + 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/flask_ckeditor/utils.py b/flask_ckeditor/utils.py index c68dc85..706132a 100644 --- a/flask_ckeditor/utils.py +++ b/flask_ckeditor/utils.py @@ -25,7 +25,7 @@ def random_filename(old_filename): def cleanify(text, *, allow_tags=None): """clean the input from client, this function rely on bleach, - + Args: text (str): input allow_tags (Iterable[str], optional): if you don't want to use default `allow_tags` @@ -37,5 +37,3 @@ def cleanify(text, *, allow_tags=None): 'em', 'i', 'li', 'ol', 'pre', 'strong', 'ul', 'h1', 'h2', 'h3', 'h4', 'h5', 'p'} return bleach.linkify(bleach.clean(text, tags=default_allowed_tags)) - - \ No newline at end of file diff --git a/test_flask_ckeditor.py b/test_flask_ckeditor.py index c80a81b..70b9580 100644 --- a/test_flask_ckeditor.py +++ b/test_flask_ckeditor.py @@ -287,25 +287,25 @@ def test_upload_fail(self): json.loads(rv.data), {'uploaded': 0, 'error': {'message': 'new error message'}} ) - + def test_cleanify_input_js(self): input = 'an example' clean_ouput = cleanify(input) - self.assertEqual(clean_ouput, - u'an <script>evil()</script> example') - + self.assertEqual(clean_ouput, + u'an <script>evil()</script> example') + def test_cleanify_input_url(self): input = 'abc http://example.com def' clean_output = cleanify(input) - self.assertEqual(clean_output, - u'abc http://example.com def') - + self.assertEqual(clean_output, + u'abc http://example.com def') + def test_cleanify_by_allow_tags(self): input = ' hello this is a url !xxxxxxxx
""" clean_out = cleanify(input) - self.assertEqual(clean_out,input) - + self.assertEqual(clean_out, input) + if __name__ == '__main__': unittest.main() diff --git a/tox.ini b/tox.ini index 642b196..95abc78 100644 --- a/tox.ini +++ b/tox.ini @@ -10,6 +10,7 @@ deps = pytest coverage flask_wtf + bleach [testenv:coverage] commands = From 8ef17b4a3620efa410b3a94030f5c88226368269 Mon Sep 17 00:00:00 2001 From: r1cardohj <2413302357@qq.com> Date: Mon, 11 Dec 2023 19:30:30 +0800 Subject: [PATCH 3/5] fix some question about change request --- CHANGES.rst | 4 ++-- flask_ckeditor/utils.py | 16 ++++++---------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 6799d3d..2865b7c 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -9,9 +9,9 @@ Release date: - 0.5.2 ----- -Release date: 2023/12/09 +Release date: N/A -- add ``cleanify`` function to ``flask_ckeditor.utils`` +- Add ``cleanify`` function to ``flask_ckeditor.utils`` for HTML sanity. 0.5.1 diff --git a/flask_ckeditor/utils.py b/flask_ckeditor/utils.py index 706132a..c8e6d26 100644 --- a/flask_ckeditor/utils.py +++ b/flask_ckeditor/utils.py @@ -6,7 +6,7 @@ try: import bleach except ImportError: - warnings.warn('bleach is not installed,`cleanify` function will not be available') + warnings.warn('The "bleach" library is not installed, `cleanify` function will not be available.') def get_url(endpoint_or_url): @@ -23,17 +23,13 @@ def random_filename(old_filename): def cleanify(text, *, allow_tags=None): - """clean the input from client, this function rely on bleach, + """Clean the input from client, this function rely on bleach. - - Args: - text (str): input - allow_tags (Iterable[str], optional): if you don't want to use default `allow_tags` - you can provide a Iterable which include html tag string like ['a', 'li',...] + :parm text: input str + :parm allow_tags: if you don't want to use default `allow_tags`, + you can provide a Iterable which include html tag string like ['a', 'li',...]. """ - if allow_tags: - return bleach.linkify(bleach.clean(text, tags=allow_tags)) default_allowed_tags = {'a', 'abbr', 'b', 'blockquote', 'code', 'em', 'i', 'li', 'ol', 'pre', 'strong', 'ul', 'h1', 'h2', 'h3', 'h4', 'h5', 'p'} - return bleach.linkify(bleach.clean(text, tags=default_allowed_tags)) + return bleach.linkify(bleach.clean(text, tags=allow_tags or default_allowed_tags)) From 49828345e1976a526ac5d6b32e821c729b9c5830 Mon Sep 17 00:00:00 2001 From: r1cardohj <2413302357@qq.com> Date: Mon, 11 Dec 2023 23:07:13 +0800 Subject: [PATCH 4/5] add test_case about without install bleach --- test_flask_ckeditor.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/test_flask_ckeditor.py b/test_flask_ckeditor.py index 70b9580..2ad2a69 100644 --- a/test_flask_ckeditor.py +++ b/test_flask_ckeditor.py @@ -330,6 +330,32 @@ def test_cleanify_by_default_allow_tags(self): clean_out = cleanify(input) self.assertEqual(clean_out, input) + def test_import_cleanify_without_install_bleach(self): + import sys + import builtins + origin_import = builtins.__import__ + origin_modules = sys.modules.copy() + + def import_hook(name, *args, **kwargs): + if name == 'bleach': + raise ImportError('test case module') + else: + return origin_import(name, *args, **kwargs) + + if 'flask_ckeditor.utils' in sys.modules: + del sys.modules['flask_ckeditor.utils'] + builtins.__import__ = import_hook + + with self.assertWarns(UserWarning) as w: + from flask_ckeditor.utils import cleanify # noqa: F401 + + self.assertEqual(str(w.warning), + 'The "bleach" library is not installed, `cleanify` function will not be available.') + + # recover default + builtins.__import__ = origin_import + sys.modules = origin_modules + if __name__ == '__main__': unittest.main() From 16779d887cb3cdb2a327e0cda77a42deb0636fc5 Mon Sep 17 00:00:00 2001 From: Grey Li