django-bolt 0.1.0__cp310-abi3-win_amd64.whl → 0.1.1__cp310-abi3-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of django-bolt might be problematic. Click here for more details.

Files changed (56) hide show
  1. django_bolt/__init__.py +2 -2
  2. django_bolt/_core.pyd +0 -0
  3. django_bolt/_json.py +169 -0
  4. django_bolt/admin/static_routes.py +15 -21
  5. django_bolt/api.py +181 -61
  6. django_bolt/auth/__init__.py +2 -2
  7. django_bolt/decorators.py +15 -3
  8. django_bolt/dependencies.py +30 -24
  9. django_bolt/error_handlers.py +2 -1
  10. django_bolt/openapi/plugins.py +3 -2
  11. django_bolt/openapi/schema_generator.py +65 -20
  12. django_bolt/pagination.py +2 -1
  13. django_bolt/responses.py +3 -2
  14. django_bolt/serialization.py +5 -4
  15. {django_bolt-0.1.0.dist-info → django_bolt-0.1.1.dist-info}/METADATA +179 -197
  16. {django_bolt-0.1.0.dist-info → django_bolt-0.1.1.dist-info}/RECORD +18 -55
  17. django_bolt/auth/README.md +0 -464
  18. django_bolt/auth/REVOCATION_EXAMPLE.md +0 -391
  19. django_bolt/tests/__init__.py +0 -0
  20. django_bolt/tests/admin_tests/__init__.py +0 -1
  21. django_bolt/tests/admin_tests/conftest.py +0 -6
  22. django_bolt/tests/admin_tests/test_admin_with_django.py +0 -278
  23. django_bolt/tests/admin_tests/urls.py +0 -9
  24. django_bolt/tests/cbv/__init__.py +0 -0
  25. django_bolt/tests/cbv/test_class_views.py +0 -570
  26. django_bolt/tests/cbv/test_class_views_django_orm.py +0 -703
  27. django_bolt/tests/cbv/test_class_views_features.py +0 -1173
  28. django_bolt/tests/cbv/test_class_views_with_client.py +0 -622
  29. django_bolt/tests/conftest.py +0 -165
  30. django_bolt/tests/test_action_decorator.py +0 -399
  31. django_bolt/tests/test_auth_secret_key.py +0 -83
  32. django_bolt/tests/test_decorator_syntax.py +0 -159
  33. django_bolt/tests/test_error_handling.py +0 -481
  34. django_bolt/tests/test_file_response.py +0 -192
  35. django_bolt/tests/test_global_cors.py +0 -172
  36. django_bolt/tests/test_guards_auth.py +0 -441
  37. django_bolt/tests/test_guards_integration.py +0 -303
  38. django_bolt/tests/test_health.py +0 -283
  39. django_bolt/tests/test_integration_validation.py +0 -400
  40. django_bolt/tests/test_json_validation.py +0 -536
  41. django_bolt/tests/test_jwt_auth.py +0 -327
  42. django_bolt/tests/test_jwt_token.py +0 -458
  43. django_bolt/tests/test_logging.py +0 -837
  44. django_bolt/tests/test_logging_merge.py +0 -419
  45. django_bolt/tests/test_middleware.py +0 -492
  46. django_bolt/tests/test_middleware_server.py +0 -230
  47. django_bolt/tests/test_model_viewset.py +0 -323
  48. django_bolt/tests/test_models.py +0 -24
  49. django_bolt/tests/test_pagination.py +0 -1258
  50. django_bolt/tests/test_parameter_validation.py +0 -178
  51. django_bolt/tests/test_syntax.py +0 -626
  52. django_bolt/tests/test_testing_utilities.py +0 -163
  53. django_bolt/tests/test_testing_utilities_simple.py +0 -123
  54. django_bolt/tests/test_viewset_unified.py +0 -346
  55. {django_bolt-0.1.0.dist-info → django_bolt-0.1.1.dist-info}/WHEEL +0 -0
  56. {django_bolt-0.1.0.dist-info → django_bolt-0.1.1.dist-info}/entry_points.txt +0 -0
@@ -1,327 +0,0 @@
1
- """
2
- Tests for JWT authentication and Django User integration.
3
-
4
- Tests JWT token creation, validation, and Django User model integration
5
- with type-safe dependency injection.
6
-
7
- Uses pytest-django for proper Django configuration.
8
- """
9
- import pytest
10
- import jwt
11
- import time
12
- from django_bolt.auth import (
13
- create_jwt_for_user,
14
- get_current_user,
15
- extract_user_id_from_context,
16
- get_auth_context,
17
- )
18
-
19
- # Mark all tests to use Django DB
20
- pytestmark = pytest.mark.django_db
21
-
22
-
23
- def test_create_jwt_for_user():
24
- """Test creating JWT tokens for Django users."""
25
- from django.contrib.auth import get_user_model
26
- User = get_user_model()
27
-
28
- # Create a test user
29
- user = User.objects.create(
30
- username="testuser",
31
- email="test@example.com",
32
- is_staff=True,
33
- is_superuser=False
34
- )
35
-
36
- # Create JWT token
37
- token = create_jwt_for_user(user, secret="my-secret")
38
-
39
- # Decode and verify
40
- decoded = jwt.decode(token, "my-secret", algorithms=["HS256"])
41
-
42
- assert decoded["sub"] == str(user.id)
43
- assert decoded["username"] == "testuser"
44
- assert decoded["email"] == "test@example.com"
45
- assert decoded["is_staff"] is True
46
- assert decoded["is_superuser"] is False
47
- assert "exp" in decoded
48
- assert "iat" in decoded
49
-
50
- # Clean up
51
- user.delete()
52
- print("✓ JWT token creation for user works correctly")
53
-
54
-
55
- def test_create_jwt_with_extra_claims():
56
- """Test creating JWT tokens with custom claims."""
57
- from django.contrib.auth import get_user_model
58
- User = get_user_model()
59
-
60
- user = User.objects.create(
61
- username="admin",
62
- email="admin@example.com",
63
- is_staff=True,
64
- is_superuser=True
65
- )
66
-
67
- # Create token with extra claims
68
- token = create_jwt_for_user(
69
- user,
70
- secret="secret",
71
- extra_claims={
72
- "permissions": ["users.create", "users.delete"],
73
- "role": "admin",
74
- "department": "engineering"
75
- }
76
- )
77
-
78
- # Decode and verify
79
- decoded = jwt.decode(token, "secret", algorithms=["HS256"])
80
-
81
- assert decoded["sub"] == str(user.id)
82
- assert decoded["permissions"] == ["users.create", "users.delete"]
83
- assert decoded["role"] == "admin"
84
- assert decoded["department"] == "engineering"
85
-
86
- # Clean up
87
- user.delete()
88
- print("✓ JWT with extra claims works correctly")
89
-
90
-
91
- def test_jwt_authentication_with_django_user():
92
- """Test JWT authentication extracts correct user data."""
93
- from django.contrib.auth import get_user_model
94
- from django_bolt import BoltAPI
95
- from django_bolt.auth import JWTAuthentication
96
- from django_bolt.auth import IsAuthenticated
97
- User = get_user_model()
98
-
99
- # Create test user
100
- user = User.objects.create(
101
- username="jwtuser",
102
- email="jwt@example.com",
103
- is_staff=False,
104
- is_superuser=False
105
- )
106
-
107
- # Create API with JWT auth
108
- api = BoltAPI()
109
-
110
- @api.get(
111
- "/protected",
112
- auth=[JWTAuthentication(secret="test-secret")],
113
- guards=[IsAuthenticated()]
114
- )
115
- async def protected_endpoint(request: dict):
116
- context = request["context"]
117
- return {
118
- "user_id": context.get("user_id"),
119
- "is_staff": context.get("is_staff"),
120
- "is_admin": context.get("is_admin"),
121
- "auth_backend": context.get("auth_backend"),
122
- }
123
-
124
- # Verify route registered
125
- assert len(api._routes) == 1
126
-
127
- # Clean up
128
- user.delete()
129
- print("✓ JWT authentication with Django User works")
130
-
131
-
132
- def test_django_user_dependency_injection():
133
- """Test type-safe Django User dependency injection with Depends()."""
134
- from django_bolt import BoltAPI
135
- from django_bolt.auth import JWTAuthentication
136
- from django_bolt.auth import IsAuthenticated
137
- from django_bolt.params import Depends
138
-
139
- # Create API with the dependency (using imported get_current_user)
140
- api = BoltAPI()
141
-
142
- @api.get(
143
- "/me",
144
- auth=[JWTAuthentication(secret="test-secret")],
145
- guards=[IsAuthenticated()]
146
- )
147
- async def get_current_user_endpoint(user=Depends(get_current_user)):
148
- """
149
- Endpoint that receives Django User instance via dependency injection.
150
-
151
- The 'user' parameter is the actual Django User model instance,
152
- not just a dictionary. You have full access to:
153
- - user.id, user.username, user.email
154
- - user.is_staff, user.is_superuser, user.is_active
155
- - user.first_name, user.last_name, user.date_joined
156
- - All custom fields if using a custom User model
157
- - All User model methods
158
- """
159
- if user is None:
160
- return {"error": "User not found"}
161
-
162
- return {
163
- "id": user.id,
164
- "username": user.username,
165
- "email": user.email,
166
- "is_staff": user.is_staff,
167
- "is_superuser": user.is_superuser,
168
- }
169
-
170
- # Verify the route was registered correctly
171
- assert len(api._routes) == 1
172
- method, path, _, handler_fn = api._routes[0]
173
- assert method == "GET"
174
- assert path == "/me"
175
-
176
- # Verify handler metadata
177
- assert handler_fn in api._handler_meta
178
- meta = api._handler_meta[handler_fn]
179
- assert "params" in meta
180
-
181
- # Check that the dependency parameter was detected
182
- params = meta["params"]
183
- user_param = next((p for p in params if p["name"] == "user"), None)
184
- assert user_param is not None
185
- assert user_param["source"] == "dependency"
186
- assert user_param["dependency"] is not None
187
-
188
- print("✓ Django User dependency injection metadata correct")
189
-
190
-
191
- def test_jwt_utils_extract_user_id():
192
- """Test extracting user_id from request context."""
193
- # Mock request with context
194
- request = {
195
- "context": {
196
- "user_id": "123",
197
- "is_staff": True,
198
- "auth_backend": "jwt"
199
- }
200
- }
201
-
202
- user_id = extract_user_id_from_context(request)
203
- assert user_id == "123"
204
-
205
- # Test with missing context
206
- empty_request = {}
207
- user_id = extract_user_id_from_context(empty_request)
208
- assert user_id is None
209
-
210
- print("✓ extract_user_id_from_context works correctly")
211
-
212
-
213
- def test_jwt_utils_get_auth_context():
214
- """Test getting full auth context."""
215
- request = {
216
- "context": {
217
- "user_id": "456",
218
- "is_staff": False,
219
- "is_admin": True,
220
- "auth_backend": "jwt",
221
- "permissions": ["read", "write"]
222
- }
223
- }
224
-
225
- ctx = get_auth_context(request)
226
- assert ctx["user_id"] == "456"
227
- assert ctx["is_staff"] is False
228
- assert ctx["is_admin"] is True
229
- assert ctx["auth_backend"] == "jwt"
230
- assert ctx["permissions"] == ["read", "write"]
231
-
232
- print("✓ get_auth_context works correctly")
233
-
234
-
235
- def test_jwt_claims_stored_in_context():
236
- """Test that JWT claims are properly stored in request context."""
237
- from django.contrib.auth import get_user_model
238
- User = get_user_model()
239
-
240
- user = User.objects.create(
241
- username="claimsuser",
242
- email="claims@example.com",
243
- is_staff=True,
244
- is_superuser=False
245
- )
246
-
247
- # Create token with custom claims
248
- token = create_jwt_for_user(
249
- user,
250
- secret="secret",
251
- extra_claims={
252
- "permissions": ["read", "write"],
253
- "tenant_id": "tenant123",
254
- }
255
- )
256
-
257
- # Decode to verify claims are there
258
- decoded = jwt.decode(token, "secret", algorithms=["HS256"])
259
- assert decoded["permissions"] == ["read", "write"]
260
- assert decoded["tenant_id"] == "tenant123"
261
-
262
- # Clean up
263
- user.delete()
264
- print("✓ JWT claims storage verified")
265
-
266
-
267
- def test_jwt_expiration():
268
- """Test JWT expiration handling."""
269
- from django.contrib.auth import get_user_model
270
- User = get_user_model()
271
-
272
- user = User.objects.create(username="expuser")
273
-
274
- # Create an expired token
275
- expired_payload = {
276
- "sub": str(user.id),
277
- "exp": int(time.time()) - 100, # Expired 100 seconds ago
278
- "iat": int(time.time()) - 200,
279
- }
280
- expired_token = jwt.encode(expired_payload, "secret", algorithm="HS256")
281
-
282
- # Verify it's expired
283
- try:
284
- jwt.decode(expired_token, "secret", algorithms=["HS256"])
285
- assert False, "Should have raised ExpiredSignatureError"
286
- except jwt.ExpiredSignatureError:
287
- pass # Expected
288
-
289
- # Create a valid token
290
- valid_token = create_jwt_for_user(user, secret="secret")
291
- decoded = jwt.decode(valid_token, "secret", algorithms=["HS256"])
292
- assert decoded["sub"] == str(user.id)
293
-
294
- # Clean up
295
- user.delete()
296
- print("✓ JWT expiration handling works")
297
-
298
-
299
- def test_jwt_uses_django_secret_key():
300
- """Test that JWTAuthentication uses Django SECRET_KEY by default."""
301
- from django.conf import settings
302
- from django_bolt.auth import JWTAuthentication
303
-
304
- # Create JWT auth without explicit secret
305
- auth = JWTAuthentication()
306
-
307
- # Should use Django's SECRET_KEY
308
- assert auth.secret == settings.SECRET_KEY
309
- print("✓ JWT uses Django SECRET_KEY by default")
310
-
311
-
312
- def test_jwt_custom_secret_overrides():
313
- """Test that explicit secret overrides Django SECRET_KEY."""
314
- from django.conf import settings
315
- from django_bolt.auth import JWTAuthentication
316
-
317
- # Create with explicit secret
318
- auth = JWTAuthentication(secret="custom-secret")
319
-
320
- # Should use the explicit secret, not Django's
321
- assert auth.secret == "custom-secret"
322
- assert auth.secret != settings.SECRET_KEY
323
- print("✓ Explicit JWT secret overrides Django SECRET_KEY")
324
-
325
-
326
- if __name__ == "__main__":
327
- pytest.main([__file__, "-v", "-s"])