Skip to content

Commit 024793c

Browse files
committed
✨ 0.3
1 parent ba72a52 commit 024793c

File tree

8 files changed

+224
-4
lines changed

8 files changed

+224
-4
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: Python package
2+
3+
on: [push, pull_request]
4+
5+
jobs:
6+
build:
7+
runs-on: ubuntu-latest
8+
9+
steps:
10+
- name: Check out repository code
11+
uses: actions/checkout@v2
12+
13+
- name: Set up Python
14+
uses: actions/setup-python@v2
15+
with:
16+
python-version: "3.x"
17+
18+
- name: Install dependencies
19+
run: |
20+
python -m pip install --upgrade pip
21+
pip install pytest
22+
pip install .
23+
24+
- name: Run tests
25+
run: |
26+
pytest tests

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,4 +159,8 @@ cython_debug/
159159
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
160160
# and can be added to the global gitignore or merged into this file. For a more nuclear
161161
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
162-
#.idea/
162+
#.idea/
163+
164+
# Project Specific
165+
166+
private/

MANIFEST.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
include README.md
2+
include LICENSE

README.md

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# Flask-Obfuscate
2+
3+
Flask-Obfuscate is a Flask extension that obfuscates HTML responses to help protect your HTML content from easy inspection or copying. This extension processes all HTML responses and converts them into obfuscated JavaScript that writes the HTML content when executed in a browser.
4+
5+
## Features
6+
7+
- Obfuscates HTML responses by converting them to JavaScript
8+
- Easy to integrate into existing Flask applications
9+
- Simple usage with minimal configuration
10+
11+
## Installation
12+
13+
You can install Flask-Obfuscate via pip:
14+
15+
```sh
16+
pip install Flask-Obfuscate
17+
```
18+
19+
## Usage
20+
21+
### Basic Usage
22+
23+
Integrate Flask-Obfuscate into your Flask application with minimal setup:
24+
25+
```python
26+
from flask import Flask
27+
from flask_obfuscate import Obfuscate
28+
29+
app = Flask(__name__)
30+
obfuscate = Obfuscate(app)
31+
32+
@app.route('/')
33+
def index():
34+
return '<div>Hello, World!</div>'
35+
36+
if __name__ == '__main__':
37+
app.run(debug=True)
38+
```
39+
40+
### Advanced Usage
41+
42+
You can also initialize Flask-Obfuscate later using the `init_app` method:
43+
44+
```python
45+
from flask import Flask
46+
from flask_obfuscate import Obfuscate
47+
48+
app = Flask(__name__)
49+
obfuscate = Obfuscate()
50+
obfuscate.init_app(app)
51+
52+
@app.route('/')
53+
def index():
54+
return '<div>Hello, World!</div>'
55+
56+
if __name__ == '__main__':
57+
app.run(debug=True)
58+
```
59+
60+
## Running Tests
61+
62+
To run the tests, first install the test dependencies:
63+
64+
```sh
65+
pip install pytest
66+
```
67+
68+
Then you can run the tests using pytest:
69+
70+
```sh
71+
pytest tests
72+
```
73+
74+
## Contributing
75+
76+
Contributions are welcome! Please submit a pull request or open an issue to discuss improvements or fixes.
77+
78+
1. Fork the repository.
79+
2. Create a new branch: `git checkout -b my-feature-branch`
80+
3. Make your changes and commit them: `git commit -am 'Add some feature'`
81+
4. Push to the branch: `git push origin my-feature-branch`
82+
5. Submit a pull request.
83+
84+
## License
85+
86+
This project is licensed under the MIT License.
87+
88+
## Acknowledgments
89+
90+
Inspired by the need to protect HTML content in Flask applications.

flask_obfuscate/obfuscate.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,15 @@ def obfuscate_response(response: Response) -> Response:
5050
Returns:
5151
Response: The modified response with obfuscated HTML content.
5252
"""
53-
if response.content_type == "text/html; charset=utf-8":
53+
54+
# Check if the response is an HTML document and contains content
55+
56+
if (
57+
response.content_type == "text/html; charset=utf-8"
58+
and response.get_data(as_text=True).strip()
59+
):
5460
response.set_data(self.obfuscate_html(response.get_data(as_text=True)))
61+
5562
return response
5663

5764
def obfuscate_html(self, html_str: str) -> str:

setup.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
from setuptools import setup, find_packages
22

3+
with open("README.md", "r") as f:
4+
long_description = f.read()
5+
36
setup(
47
name="Flask-Obfuscate",
5-
version="0.1",
8+
version="0.3",
69
packages=find_packages(),
710
include_package_data=True,
811
install_requires=[
@@ -11,7 +14,7 @@
1114
author="Zachariah Michael Lagden",
1215
author_email="zach@zachlagden.uk",
1316
description="A Flask extension to obfuscate HTML responses.",
14-
long_description=open("README.md").read(),
17+
long_description=long_description,
1518
long_description_content_type="text/markdown",
1619
url="https://github.com/Lagden-Development/flask-obfuscate",
1720
classifiers=[

tests/__init__.py

Whitespace-only changes.

tests/test_obfuscate.py

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import pytest
2+
from flask import Flask, Blueprint
3+
from flask_obfuscate import Obfuscate
4+
5+
6+
@pytest.fixture
7+
def app():
8+
app = Flask(__name__)
9+
obfuscate = Obfuscate(app)
10+
return app
11+
12+
13+
def test_obfuscate(app):
14+
@app.route("/")
15+
def index():
16+
return "<div>Hello, World!</div>"
17+
18+
with app.test_client() as client:
19+
response = client.get("/")
20+
assert response.status_code == 200
21+
assert "document.write(unescape" in response.get_data(as_text=True)
22+
assert "<div>Hello, World!</div>" not in response.get_data(as_text=True)
23+
24+
25+
def test_non_html_response(app):
26+
@app.route("/json")
27+
def json_route():
28+
return {"message": "Hello, World!"}
29+
30+
with app.test_client() as client:
31+
response = client.get("/json")
32+
assert response.status_code == 200
33+
assert response.is_json
34+
assert response.get_json() == {"message": "Hello, World!"}
35+
36+
37+
def test_large_html_document(app):
38+
@app.route("/large")
39+
def large_route():
40+
large_html = "<div>" + "Hello, World! " * 1000 + "</div>"
41+
return large_html
42+
43+
with app.test_client() as client:
44+
response = client.get("/large")
45+
assert response.status_code == 200
46+
assert "document.write(unescape" in response.get_data(as_text=True)
47+
assert "Hello, World!" not in response.get_data(as_text=True)
48+
49+
50+
def test_special_characters(app):
51+
@app.route("/special")
52+
def special_route():
53+
return "<div>Special characters: <>&'\"</div>"
54+
55+
with app.test_client() as client:
56+
response = client.get("/special")
57+
assert response.status_code == 200
58+
assert "document.write(unescape" in response.get_data(as_text=True)
59+
assert "<div>Special characters: <>&'\"</div>" not in response.get_data(
60+
as_text=True
61+
)
62+
63+
64+
def test_empty_html(app):
65+
@app.route("/empty")
66+
def empty_route():
67+
return ""
68+
69+
with app.test_client() as client:
70+
response = client.get("/empty")
71+
assert response.status_code == 200
72+
assert response.get_data(as_text=True) == ""
73+
74+
75+
def test_blueprint_integration(app):
76+
bp = Blueprint("bp", __name__)
77+
78+
@bp.route("/bp")
79+
def bp_route():
80+
return "<div>Blueprint route</div>"
81+
82+
app.register_blueprint(bp, url_prefix="/bp")
83+
84+
with app.test_client() as client:
85+
response = client.get("/bp/bp")
86+
assert response.status_code == 200
87+
assert "document.write(unescape" in response.get_data(as_text=True)
88+
assert "<div>Blueprint route</div>" not in response.get_data(as_text=True)

0 commit comments

Comments
 (0)