Skip to content

Commit df3a9c3

Browse files
andrecsilvadrdavella
authored andcommitted
Tests and docs for flask-enable-csrf-protection
1 parent 9578c99 commit df3a9c3

6 files changed

Lines changed: 148 additions & 2 deletions

File tree

‎integration_tests/base_test.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ def _lines_from_codepath(code_path):
204204
def _replace_lines_with(lines, replacements):
205205
total_lines = len(lines)
206206
for lineno, replacement in replacements:
207-
if lineno > total_lines:
207+
if lineno >= total_lines:
208208
lines.extend(replacement)
209209
continue
210210
lines[lineno] = replacement
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
from core_codemods.flask_enable_csrf_protection import FlaskEnableCSRFProtection
2+
from integration_tests.base_test import (
3+
BaseIntegrationTest,
4+
original_and_expected_from_code_path,
5+
)
6+
7+
8+
class TestFlaskEnableCSRFProtection(BaseIntegrationTest):
9+
codemod = FlaskEnableCSRFProtection
10+
code_path = "tests/samples/flask_enable_csrf_protection.py"
11+
original_code, expected_new_code = original_and_expected_from_code_path(
12+
code_path,
13+
[
14+
(1, """from flask_wtf.csrf import CSRFProtect\n"""),
15+
(2, """\n"""),
16+
(3, """app = Flask(__name__)\n"""),
17+
(4, """csrf_app = CSRFProtect(app)\n"""),
18+
],
19+
)
20+
21+
# fmt: off
22+
expected_diff =(
23+
"""--- \n"""
24+
"""+++ \n"""
25+
"""@@ -1,3 +1,5 @@\n"""
26+
""" from flask import Flask\n"""
27+
"""+from flask_wtf.csrf import CSRFProtect\n"""
28+
""" \n"""
29+
""" app = Flask(__name__)\n"""
30+
"""+csrf_app = CSRFProtect(app)\n"""
31+
)
32+
# fmt: on
33+
34+
expected_line_change = "3"
35+
change_description = FlaskEnableCSRFProtection.CHANGE_DESCRIPTION
36+
num_changed_files = 2

‎src/codemodder/scripts/generate_docs.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,10 @@ class DocMetadata:
202202
importance="Low",
203203
guidance_explained="This change fixes deprecated uses and is safe.",
204204
),
205+
"flask-enable-csrf-protection": DocMetadata(
206+
importance="High",
207+
guidance_explained="Flask views may require proper handling of CSRF to function as expected and thus this change may break some views.",
208+
),
205209
}
206210

207211

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Flask views using `FlaskForm` have CSRF protection enabled by default. However other views may use AJAX to perform unsafe HTTP methods. FlaskWTF provides a way to enable CSRF protection globally for all views of a Flask app.
2+
Our changes look something like this:
3+
4+
```diff
5+
from flask import Flask
6+
+from flask_wtf.csrf import CSRFProtect
7+
8+
app = Flask(__name__)
9+
+csrf_app = CSRFProtect(app)
10+
```
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
from core_codemods.flask_enable_csrf_protection import FlaskEnableCSRFProtection
2+
from tests.codemods.base_codemod_test import BaseCodemodTest
3+
from textwrap import dedent
4+
5+
6+
class TestFlaskEnableCSRFProtection(BaseCodemodTest):
7+
codemod = FlaskEnableCSRFProtection
8+
9+
def test_name(self):
10+
assert self.codemod.name() == "flask-enable-csrf-protection"
11+
12+
def test_simple(self, tmpdir):
13+
input_code = """\
14+
from flask import Flask
15+
app = Flask(__name__)
16+
"""
17+
expected = """\
18+
from flask import Flask
19+
from flask_wtf.csrf import CSRFProtect
20+
21+
app = Flask(__name__)
22+
csrf_app = CSRFProtect(app)
23+
"""
24+
self.run_and_assert(tmpdir, dedent(input_code), dedent(expected))
25+
assert len(self.file_context.codemod_changes) == 1
26+
27+
def test_simple_alias(self, tmpdir):
28+
input_code = """\
29+
from flask import Flask as Flosk
30+
app = Flosk(__name__)
31+
"""
32+
expected = """\
33+
from flask import Flask as Flosk
34+
from flask_wtf.csrf import CSRFProtect
35+
36+
app = Flosk(__name__)
37+
csrf_app = CSRFProtect(app)
38+
"""
39+
self.run_and_assert(tmpdir, dedent(input_code), dedent(expected))
40+
assert len(self.file_context.codemod_changes) == 1
41+
42+
def test_multiple(self, tmpdir):
43+
input_code = """\
44+
from flask import Flask
45+
app = Flask(__name__)
46+
app2 = Flask(__name__)
47+
"""
48+
expected = """\
49+
from flask import Flask
50+
from flask_wtf.csrf import CSRFProtect
51+
52+
app = Flask(__name__)
53+
csrf_app = CSRFProtect(app)
54+
app2 = Flask(__name__)
55+
csrf_app2 = CSRFProtect(app2)
56+
"""
57+
self.run_and_assert(tmpdir, dedent(input_code), dedent(expected))
58+
assert len(self.file_context.codemod_changes) == 2
59+
60+
def test_multiple_inline(self, tmpdir):
61+
input_code = """\
62+
from flask import Flask
63+
app = Flask(__name__); app2 = Flask(__name__)
64+
"""
65+
expected = """\
66+
from flask import Flask
67+
from flask_wtf.csrf import CSRFProtect
68+
69+
app = Flask(__name__); app2 = Flask(__name__); csrf_app = CSRFProtect(app); csrf_app2 = CSRFProtect(app2)
70+
"""
71+
self.run_and_assert(tmpdir, dedent(input_code), dedent(expected))
72+
assert len(self.file_context.codemod_changes) == 1
73+
74+
def test_multiple_inline_suite(self, tmpdir):
75+
input_code = """\
76+
from flask import Flask
77+
if True: app = Flask(__name__); app2 = Flask(__name__)
78+
"""
79+
expected = """\
80+
from flask import Flask
81+
from flask_wtf.csrf import CSRFProtect
82+
83+
if True: app = Flask(__name__); app2 = Flask(__name__); csrf_app = CSRFProtect(app); csrf_app2 = CSRFProtect(app2)
84+
"""
85+
self.run_and_assert(tmpdir, dedent(input_code), dedent(expected))
86+
assert len(self.file_context.codemod_changes) == 1
87+
88+
def test_simple_protected(self, tmpdir):
89+
input_code = """\
90+
from flask import Flask
91+
from flask_wtf.csrf import CSRFProtect
92+
93+
app = Flask(__name__)
94+
csrf_app = CSRFProtect(app)
95+
"""
96+
self.run_and_assert(tmpdir, dedent(input_code), dedent(input_code))
97+
assert len(self.file_context.codemod_changes) == 0
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
from flask import Flask
2-
from flask_wtf.csrf import CSRFProtect
32

43
app = Flask(__name__)

0 commit comments

Comments
 (0)