Fix JwtAuthExtension initialization & complete Django 6 migration - #1
Merged
Conversation
…ash, and add test suite
| @@ -1,5 +1,5 @@ | |||
| import jwt | |||
| from django.utils.timezone import datetime, timedelta | |||
There was a problem hiding this comment.
Use Django timezone as it will read the timezone from the client Django application's settings.
from django.utils import timezone
…ash, and add test suite
…owkidar-update-2026-06-09-15_28_32.png
…312.3 to apply high severity security patches
Make execution_context optional in __init__ (strawberry now sets it after construction), and replace removed on_request_start with the on_operation generator hook.
- Add ruff.toml for linter/formatter configuration - Add .pre-commit-config.yaml for pre-commit hook setup - Add [options.extras_require] dev section in setup.cfg with ruff and pre-commit - Installable via `pip install -e ".[dev]"`
- Fix trailing whitespace in README.md, LICENSE, and manifest.in - Reformat setup.py with consistent quoting and multi-line calls - Bump version to 0.3.3 in setup.cfg to match prior release - Simplify line wrapping in chowkidar/settings.py - Clean up test imports (remove unused, sort, split) - Add missing trailing newline to conftest.py - Remove unused import in tests/django_settings.py
- Add detailed NumPy-style docstrings with Parameters, Returns, Raises, and Notes sections to all public and private functions and classes - Covers authentication.py, decorators.py, extension.py, models.py, view.py, wrappers.py, and all utils modules - Follow the docstring template established by get_context() in utils/__init__.py - Includes type annotations and behavioral notes for each symbol - Linter-driven import and formatting changes included where applicable
- Move get_context() from utils/__init__.py to utils/context.py - Move validate_email() from utils/__init__.py to utils/validation.py - Re-export both functions from utils/__init__.py for backward compat - Keeps the public API unchanged while improving module organization
- Increase test JWT_SECRET_KEY to 50 bytes to satisfy PyJWT's HS256 minimum key length (RFC 7518 §3.2), eliminating InsecureKeyLengthWarning - Add TYPE_CHECKING import and annotate return types as AbstractUser instead of the dynamic User model reference
- Add pytest, pytest-cov, and parameterized to dev extras - Configure [tool:pytest] with --cov=chowkidar and term-missing report - Set testpaths to tests directory
…ge cases - Rewrite test_extension.py and test_models.py from pytest-style to unittest.TestCase for consistency with the rest of the suite - Add new test files: test_authentication.py, test_decorators.py, test_view.py, test_wrappers.py, and utils/ test modules - Add security edge-case tests across all modules: - JWT: alg=none attack, garbage tokens, wrong issuer, empty tokens - Email: newline/null-byte/XSS/SQL injection attempts, unicode homograph - Auth: empty/whitespace passwords, header injection via email - Decorators: falsy userID bypass (False, empty string vs 0, negative) - Cookies: Secure, HttpOnly, SameSite=Strict flags, max-age=0 on delete - Extension: state leakage between requests, revoked refresh tokens - Wrappers: process_request_before_save ordering, missing userID logout - Models: token uniqueness, entropy sufficiency, no regen on second save - Fix wrong-key test to use HS256-compliant key length - Total: 178 tests, all passing, 100% code coverage (391/391 statements)
- install_requires under [metadata] is ignored by pip; dependencies (Django, PyJWT, strawberry-graphql) were not being installed - Move the declaration to [options] where setuptools actually reads it - Fixes ModuleNotFoundError for django in CI
☂️ Python Coverage
Overall Coverage
New FilesNo new covered files... Modified FilesNo covered modified files...
|
ChangelogSecurity
Bug Fixes
Features
Refactoring
Testing
Documentation
Tooling & Chores
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This update addresses critical lifecycle initialization bugs within the Strawberry GraphQL JWT Auth Extension, completes the Django 6 deprecation migration path, and implements modern Python timezone/datetime standards.
##Changes Made
1. Strawberry Extension State Lifecycle Fixes (
chowkidar/extension.py)__init__Initialization: Added back the__init__constructor and routed it to populate the base state variables (user,_request,_new_jwt_access_token, etc.) upon instantiation viaself._request_state(). This prevents theAttributeError: object has no attributethat occurs when Strawberry resolves fields beforeon_request_start()completes.resolve(): Addedhasattrchecks directly inresolve()to ensure that even if the extension lifecycle is completely bypassed (e.g. during specific complex field resolution schemas or test edge-cases), the authentication variables safely default toNoneorFalse.2. Django 6 Database Constraints (
chowkidar/models.py)unique_together: Removed the legacyunique_togetherMeta attribute.UniqueConstraint: Replaced it with the modern DjangoUniqueConstraintstructure. BecauseAbstractRefreshTokenis an abstract model, string interpolation%(app_label)s_%(class)s_unique_token_revokedwas utilized in the constraint name to ensure child classes inherit unique constraint names in the database.3. Timezone & Datetime Modernization (
chowkidar/settings.py,chowkidar/utils/jwt.py)django.utils.timezone.timedeltaRemoval: Replaced all usages of the deprecated Djangotimedeltaalias with Python's standardfrom datetime import timedelta.datetime.utcnow()Deprecation: Replaceddatetime.utcnow()with the timezone-awaredjango.utils.timezone.now()to comply with standard Python 3.12+ warnings and Django best practices.JWT_ALGORITHMsetting.4. Package Infrastructure (
setup.cfg)3.10through3.134.0through6.05. Testing Enhancements (
tests/test_extension.py)test_init_sets_state_via_init_after_initandtest_resolve_defensive_guardsthat rigorously verify that context state maintains integrity when edge case execution orders are simulated.