core-framework 0.12.4__tar.gz → 0.12.6__tar.gz
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.
- {core_framework-0.12.4 → core_framework-0.12.6}/PKG-INFO +1 -1
- {core_framework-0.12.4 → core_framework-0.12.6}/core/__init__.py +1 -1
- {core_framework-0.12.4 → core_framework-0.12.6}/core/auth/__init__.py +15 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/auth/backends.py +5 -5
- {core_framework-0.12.4 → core_framework-0.12.6}/core/auth/decorators.py +7 -6
- core_framework-0.12.6/core/auth/helpers.py +104 -0
- core_framework-0.12.6/core/auth/middleware.py +473 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/auth/tokens.py +17 -3
- {core_framework-0.12.4 → core_framework-0.12.6}/core/auth/views.py +27 -7
- {core_framework-0.12.4 → core_framework-0.12.6}/core/cli/main.py +6 -4
- {core_framework-0.12.4 → core_framework-0.12.6}/core/dependencies.py +3 -1
- {core_framework-0.12.4 → core_framework-0.12.6}/core/permissions.py +8 -6
- {core_framework-0.12.4 → core_framework-0.12.6}/core/tenancy.py +3 -2
- {core_framework-0.12.4 → core_framework-0.12.6}/pyproject.toml +1 -1
- core_framework-0.12.4/core/auth/middleware.py +0 -355
- {core_framework-0.12.4 → core_framework-0.12.6}/.gitignore +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/README.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/app.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/auth/base.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/auth/hashers.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/auth/models.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/auth/permissions.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/auth/schemas.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/choices.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/cli/__init__.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/config.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/database.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/datetime.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/deployment/__init__.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/deployment/docker.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/deployment/kubernetes.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/deployment/pm2.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/exceptions.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/fields.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/__init__.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/avro.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/base.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/config.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/confluent/__init__.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/confluent/consumer.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/confluent/producer.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/decorators.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/kafka/__init__.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/kafka/admin.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/kafka/broker.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/kafka/consumer.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/kafka/producer.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/rabbitmq/__init__.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/rabbitmq/broker.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/rabbitmq/consumer.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/rabbitmq/producer.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/redis/__init__.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/redis/broker.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/redis/consumer.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/redis/producer.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/registry.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/topics.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/workers.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/middleware.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/migrations/__init__.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/migrations/analyzer.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/migrations/cli.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/migrations/engine.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/migrations/migration.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/migrations/operations.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/migrations/state.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/models.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/querysets.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/relations.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/routing.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/serializers.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/tasks/__init__.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/tasks/base.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/tasks/config.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/tasks/decorators.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/tasks/registry.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/tasks/scheduler.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/tasks/worker.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/validators.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/core/views.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/01-quickstart.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/02-viewsets.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/03-authentication.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/04-messaging.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/05-multi-service.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/06-tasks.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/07-deployment.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/08-complete-example.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/09-settings.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/10-migrations.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/11-permissions.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/12-auth-backends.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/13-validators.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/14-querysets.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/15-routing.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/16-serializers.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/17-datetime.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/18-dependencies.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/19-views.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/20-fields.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/21-tenancy.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/22-replicas.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/23-soft-delete.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/24-relations.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/25-exceptions.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/26-choices.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/27-workers.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/28-avro.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/29-topics.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/30-changelog-0.12.2.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/31-middleware.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/32-migration-guide-0.12.2.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/33-changelog-0.12.3.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/99-faq-troubleshooting.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/GUIDE.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/docs/README.md +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/example/__init__.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/example/app.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/example/auth.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/example/models.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/example/schemas.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/example/views.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/libs/__init__.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/main.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/tests/__init__.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/tests/conftest.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/tests/test_models.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/tests/test_querysets.py +0 -0
- {core_framework-0.12.4 → core_framework-0.12.6}/tests/test_serializers.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: core-framework
|
|
3
|
-
Version: 0.12.
|
|
3
|
+
Version: 0.12.6
|
|
4
4
|
Summary: Core Framework - Django-inspired, FastAPI-powered. Alta performance, baixo acoplamento, produtividade extrema.
|
|
5
5
|
Project-URL: Homepage, https://github.com/SorPuti/core-framework
|
|
6
6
|
Project-URL: Documentation, https://github.com/SorPuti/core-framework#readme
|
|
@@ -121,9 +121,18 @@ from core.auth.views import (
|
|
|
121
121
|
from core.auth.middleware import (
|
|
122
122
|
AuthenticationMiddleware,
|
|
123
123
|
OptionalAuthenticationMiddleware,
|
|
124
|
+
JWTAuthBackend,
|
|
125
|
+
AuthenticatedUser,
|
|
124
126
|
ensure_auth_middleware,
|
|
125
127
|
)
|
|
126
128
|
|
|
129
|
+
# Helper functions for consistent user access
|
|
130
|
+
from core.auth.helpers import (
|
|
131
|
+
get_request_user,
|
|
132
|
+
is_authenticated,
|
|
133
|
+
set_request_user,
|
|
134
|
+
)
|
|
135
|
+
|
|
127
136
|
__all__ = [
|
|
128
137
|
# Base
|
|
129
138
|
"AuthBackend",
|
|
@@ -196,5 +205,11 @@ __all__ = [
|
|
|
196
205
|
# Middleware
|
|
197
206
|
"AuthenticationMiddleware",
|
|
198
207
|
"OptionalAuthenticationMiddleware",
|
|
208
|
+
"JWTAuthBackend",
|
|
209
|
+
"AuthenticatedUser",
|
|
199
210
|
"ensure_auth_middleware",
|
|
211
|
+
# Helpers
|
|
212
|
+
"get_request_user",
|
|
213
|
+
"is_authenticated",
|
|
214
|
+
"set_request_user",
|
|
200
215
|
]
|
|
@@ -161,14 +161,14 @@ class ModelBackend(AuthBackend):
|
|
|
161
161
|
|
|
162
162
|
async def login(self, request: "Request", user: Any) -> None:
|
|
163
163
|
"""Executa ações pós-login."""
|
|
164
|
-
# Armazena usuário no request.state
|
|
165
|
-
|
|
164
|
+
# Armazena usuário no request.state (for backward compatibility)
|
|
165
|
+
from core.auth.helpers import set_request_user
|
|
166
|
+
set_request_user(request, user)
|
|
166
167
|
|
|
167
168
|
async def logout(self, request: "Request", user: Any) -> None:
|
|
168
169
|
"""Executa ações de logout."""
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
request.state.user = None
|
|
170
|
+
from core.auth.helpers import set_request_user
|
|
171
|
+
set_request_user(request, None)
|
|
172
172
|
|
|
173
173
|
|
|
174
174
|
class TokenAuthBackend(AuthBackend):
|
|
@@ -24,6 +24,7 @@ from typing import Any, TYPE_CHECKING
|
|
|
24
24
|
from fastapi import Depends, HTTPException, Request, status
|
|
25
25
|
|
|
26
26
|
from core.permissions import Permission as PermissionBase
|
|
27
|
+
from core.auth.helpers import get_request_user
|
|
27
28
|
|
|
28
29
|
if TYPE_CHECKING:
|
|
29
30
|
pass
|
|
@@ -70,7 +71,7 @@ class HasPermission(PermissionBase):
|
|
|
70
71
|
request: Request,
|
|
71
72
|
view: Any = None,
|
|
72
73
|
) -> bool:
|
|
73
|
-
user =
|
|
74
|
+
user = get_request_user(request)
|
|
74
75
|
|
|
75
76
|
if user is None:
|
|
76
77
|
return False
|
|
@@ -135,7 +136,7 @@ class IsInGroup(PermissionBase):
|
|
|
135
136
|
request: Request,
|
|
136
137
|
view: Any = None,
|
|
137
138
|
) -> bool:
|
|
138
|
-
user =
|
|
139
|
+
user = get_request_user(request)
|
|
139
140
|
|
|
140
141
|
if user is None:
|
|
141
142
|
return False
|
|
@@ -179,7 +180,7 @@ class IsSuperuser(PermissionBase):
|
|
|
179
180
|
request: Request,
|
|
180
181
|
view: Any = None,
|
|
181
182
|
) -> bool:
|
|
182
|
-
user =
|
|
183
|
+
user = get_request_user(request)
|
|
183
184
|
|
|
184
185
|
if user is None:
|
|
185
186
|
return False
|
|
@@ -207,7 +208,7 @@ class IsStaff(PermissionBase):
|
|
|
207
208
|
request: Request,
|
|
208
209
|
view: Any = None,
|
|
209
210
|
) -> bool:
|
|
210
|
-
user =
|
|
211
|
+
user = get_request_user(request)
|
|
211
212
|
|
|
212
213
|
if user is None:
|
|
213
214
|
return False
|
|
@@ -235,7 +236,7 @@ class IsActive(PermissionBase):
|
|
|
235
236
|
request: Request,
|
|
236
237
|
view: Any = None,
|
|
237
238
|
) -> bool:
|
|
238
|
-
user =
|
|
239
|
+
user = get_request_user(request)
|
|
239
240
|
|
|
240
241
|
if user is None:
|
|
241
242
|
return False
|
|
@@ -371,7 +372,7 @@ def login_required():
|
|
|
371
372
|
...
|
|
372
373
|
"""
|
|
373
374
|
async def check(request: Request):
|
|
374
|
-
user =
|
|
375
|
+
user = get_request_user(request)
|
|
375
376
|
|
|
376
377
|
if user is None:
|
|
377
378
|
raise HTTPException(
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Helper functions for authentication.
|
|
3
|
+
|
|
4
|
+
Provides consistent user access across the framework, supporting both:
|
|
5
|
+
- request.user (Starlette AuthenticationMiddleware pattern - preferred)
|
|
6
|
+
- request.state.user (legacy pattern - backward compatibility)
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import logging
|
|
12
|
+
from typing import Any, TYPE_CHECKING
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from starlette.requests import Request
|
|
16
|
+
|
|
17
|
+
logger = logging.getLogger("core.auth")
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def get_request_user(request: "Request") -> Any | None:
|
|
21
|
+
"""
|
|
22
|
+
Get authenticated user from request.
|
|
23
|
+
|
|
24
|
+
Checks both patterns for compatibility:
|
|
25
|
+
1. request.user (Starlette AuthenticationMiddleware - preferred)
|
|
26
|
+
2. request.state.user (legacy pattern)
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
request: The Starlette/FastAPI request object
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
The authenticated user model or None if not authenticated
|
|
33
|
+
|
|
34
|
+
Example:
|
|
35
|
+
from core.auth.helpers import get_request_user
|
|
36
|
+
|
|
37
|
+
async def my_view(request: Request):
|
|
38
|
+
user = get_request_user(request)
|
|
39
|
+
if user is None:
|
|
40
|
+
raise HTTPException(401, "Not authenticated")
|
|
41
|
+
"""
|
|
42
|
+
# Pattern 1: request.user (Starlette AuthenticationMiddleware)
|
|
43
|
+
user = getattr(request, "user", None)
|
|
44
|
+
if user is not None:
|
|
45
|
+
# Check if it's an authenticated user (has is_authenticated = True)
|
|
46
|
+
if getattr(user, "is_authenticated", False):
|
|
47
|
+
# If it's our AuthenticatedUser wrapper, return the underlying model
|
|
48
|
+
if hasattr(user, "_user"):
|
|
49
|
+
return user._user
|
|
50
|
+
return user
|
|
51
|
+
|
|
52
|
+
# Pattern 2: request.state.user (legacy)
|
|
53
|
+
user = getattr(request.state, "user", None) if hasattr(request, "state") else None
|
|
54
|
+
|
|
55
|
+
return user
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def is_authenticated(request: "Request") -> bool:
|
|
59
|
+
"""
|
|
60
|
+
Check if request has an authenticated user.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
request: The Starlette/FastAPI request object
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
True if authenticated, False otherwise
|
|
67
|
+
"""
|
|
68
|
+
# Pattern 1: request.user with is_authenticated
|
|
69
|
+
user = getattr(request, "user", None)
|
|
70
|
+
if user is not None and getattr(user, "is_authenticated", False):
|
|
71
|
+
return True
|
|
72
|
+
|
|
73
|
+
# Pattern 2: request.state.user
|
|
74
|
+
if hasattr(request, "state"):
|
|
75
|
+
user = getattr(request.state, "user", None)
|
|
76
|
+
if user is not None:
|
|
77
|
+
return True
|
|
78
|
+
|
|
79
|
+
return False
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def set_request_user(request: "Request", user: Any | None) -> None:
|
|
83
|
+
"""
|
|
84
|
+
Set the authenticated user on the request.
|
|
85
|
+
|
|
86
|
+
Sets both patterns for maximum compatibility:
|
|
87
|
+
- request.state.user (for dependencies and legacy code)
|
|
88
|
+
|
|
89
|
+
Note: request.user is set by Starlette's AuthenticationMiddleware
|
|
90
|
+
via scope["user"] and cannot be set directly.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
request: The Starlette/FastAPI request object
|
|
94
|
+
user: The user model or None
|
|
95
|
+
"""
|
|
96
|
+
if hasattr(request, "state"):
|
|
97
|
+
request.state.user = user
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
__all__ = [
|
|
101
|
+
"get_request_user",
|
|
102
|
+
"is_authenticated",
|
|
103
|
+
"set_request_user",
|
|
104
|
+
]
|