- Moved app.py, db.py, gateway.py, templates.py, embeddings.py, rns_client.py, and handlers/ into src/tinyweb/ - Created root app.py shim (adds src/ to sys.path, imports main) - Created pyproject.toml with setuptools config (where = ["src"]) - Added src/tinyweb/__init__.py - Updated all internal imports to use tinyweb. prefix (73 occurrences) - Removed sys.path.insert hack from conftest.py - Updated Dockerfile: pip install -e /app before running - Updated gateway.py usage message: python -m tinyweb.gateway - Updated README.md gateway usage instructions
60 lines
1.7 KiB
Python
60 lines
1.7 KiB
Python
"""Tests for `_check_csrf` — form-submission CSRF protection.
|
|
|
|
Every POST handler calls this to verify the submitted _csrf field matches
|
|
the token stored in the thread-local (which is seeded from the cookie by
|
|
`dispatch_request`). Missing or mismatched tokens must fail closed.
|
|
"""
|
|
import tinyweb.handlers as handlers_module
|
|
from tinyweb.handlers import _check_csrf, _csrf_field, _get_csrf_token
|
|
|
|
|
|
def _set_token(token):
|
|
handlers_module._request_local.csrf_token = token
|
|
|
|
|
|
def _clear_token():
|
|
if hasattr(handlers_module._request_local, "csrf_token"):
|
|
del handlers_module._request_local.csrf_token
|
|
|
|
|
|
def teardown_function(_):
|
|
_clear_token()
|
|
|
|
|
|
def test_rejects_missing_token_in_body():
|
|
_set_token("server-side-token")
|
|
assert _check_csrf({}) is False
|
|
|
|
|
|
def test_rejects_empty_token_in_body():
|
|
_set_token("server-side-token")
|
|
assert _check_csrf({"_csrf": [""]}) is False
|
|
|
|
|
|
def test_rejects_mismatched_token():
|
|
_set_token("server-side-token")
|
|
assert _check_csrf({"_csrf": ["attacker-token"]}) is False
|
|
|
|
|
|
def test_accepts_matching_token():
|
|
_set_token("server-side-token")
|
|
assert _check_csrf({"_csrf": ["server-side-token"]}) is True
|
|
|
|
|
|
def test_rejects_when_server_token_missing():
|
|
"""If the server-side token is empty (shouldn't happen after dispatch_request
|
|
seeds it, but be defensive), the check must fail closed."""
|
|
_clear_token()
|
|
assert _check_csrf({"_csrf": ["anything"]}) is False
|
|
|
|
|
|
def test_csrf_field_renders_current_token():
|
|
_set_token("abc123")
|
|
field = _csrf_field()
|
|
assert 'name="_csrf"' in field
|
|
assert 'value="abc123"' in field
|
|
|
|
|
|
def test_get_csrf_token_returns_empty_when_unset():
|
|
_clear_token()
|
|
assert _get_csrf_token() == ""
|