mdb-engine 0.4.4__tar.gz → 0.4.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.
- {mdb_engine-0.4.4/mdb_engine.egg-info → mdb_engine-0.4.6}/PKG-INFO +1 -1
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/auth/csrf.py +64 -1
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/core/engine.py +7 -3
- {mdb_engine-0.4.4 → mdb_engine-0.4.6/mdb_engine.egg-info}/PKG-INFO +1 -1
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/pyproject.toml +1 -1
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/LICENSE +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/MANIFEST.in +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/README.md +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/README.md +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/__init__.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/auth/ARCHITECTURE.md +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/auth/README.md +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/auth/__init__.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/auth/audit.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/auth/base.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/auth/casbin_factory.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/auth/casbin_models.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/auth/config_defaults.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/auth/config_helpers.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/auth/cookie_utils.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/auth/decorators.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/auth/dependencies.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/auth/helpers.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/auth/integration.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/auth/jwt.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/auth/middleware.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/auth/oso_factory.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/auth/provider.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/auth/rate_limiter.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/auth/restrictions.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/auth/session_manager.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/auth/shared_middleware.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/auth/shared_users.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/auth/token_lifecycle.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/auth/token_store.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/auth/users.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/auth/utils.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/cli/__init__.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/cli/commands/__init__.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/cli/commands/generate.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/cli/commands/migrate.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/cli/commands/show.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/cli/commands/validate.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/cli/main.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/cli/utils.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/config.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/constants.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/core/README.md +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/core/__init__.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/core/app_registration.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/core/app_secrets.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/core/connection.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/core/encryption.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/core/index_management.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/core/manifest.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/core/ray_integration.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/core/seeding.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/core/service_initialization.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/core/types.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/database/README.md +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/database/__init__.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/database/abstraction.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/database/connection.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/database/query_validator.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/database/resource_limiter.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/database/scoped_wrapper.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/dependencies.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/di/__init__.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/di/container.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/di/providers.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/di/scopes.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/embeddings/README.md +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/embeddings/__init__.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/embeddings/dependencies.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/embeddings/service.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/exceptions.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/indexes/README.md +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/indexes/__init__.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/indexes/helpers.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/indexes/manager.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/memory/README.md +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/memory/__init__.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/memory/service.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/observability/README.md +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/observability/__init__.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/observability/health.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/observability/logging.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/observability/metrics.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/repositories/__init__.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/repositories/base.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/repositories/mongo.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/repositories/unit_of_work.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/routing/README.md +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/routing/__init__.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/routing/websockets.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/utils/__init__.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine/utils/mongo.py +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine.egg-info/SOURCES.txt +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine.egg-info/dependency_links.txt +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine.egg-info/entry_points.txt +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine.egg-info/requires.txt +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/mdb_engine.egg-info/top_level.txt +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/setup.cfg +0 -0
- {mdb_engine-0.4.4 → mdb_engine-0.4.6}/setup.py +0 -0
|
@@ -195,6 +195,62 @@ class CSRFMiddleware(BaseHTTPMiddleware):
|
|
|
195
195
|
return True
|
|
196
196
|
return False
|
|
197
197
|
|
|
198
|
+
def _is_websocket_upgrade(self, request: Request) -> bool:
|
|
199
|
+
"""Check if request is a WebSocket upgrade request."""
|
|
200
|
+
upgrade_header = request.headers.get("upgrade", "").lower()
|
|
201
|
+
return upgrade_header == "websocket"
|
|
202
|
+
|
|
203
|
+
def _get_allowed_origins(self, request: Request) -> list[str]:
|
|
204
|
+
"""Get allowed origins from app state (CORS config) or use request host as fallback."""
|
|
205
|
+
try:
|
|
206
|
+
cors_config = getattr(request.app.state, "cors_config", None)
|
|
207
|
+
if cors_config and cors_config.get("allow_origins"):
|
|
208
|
+
return cors_config["allow_origins"]
|
|
209
|
+
except (AttributeError, TypeError, KeyError):
|
|
210
|
+
pass
|
|
211
|
+
|
|
212
|
+
try:
|
|
213
|
+
host = request.url.hostname
|
|
214
|
+
scheme = request.url.scheme
|
|
215
|
+
port = request.url.port
|
|
216
|
+
if port and port not in [80, 443]:
|
|
217
|
+
origin = f"{scheme}://{host}:{port}"
|
|
218
|
+
else:
|
|
219
|
+
origin = f"{scheme}://{host}"
|
|
220
|
+
return [origin]
|
|
221
|
+
except (AttributeError, TypeError):
|
|
222
|
+
return []
|
|
223
|
+
|
|
224
|
+
def _validate_websocket_origin(self, request: Request) -> bool:
|
|
225
|
+
"""
|
|
226
|
+
Validate Origin header for WebSocket upgrade requests.
|
|
227
|
+
|
|
228
|
+
Primary defense against Cross-Site WebSocket Hijacking (CSWSH).
|
|
229
|
+
Returns True if Origin is valid, False otherwise.
|
|
230
|
+
"""
|
|
231
|
+
origin = request.headers.get("origin")
|
|
232
|
+
if not origin:
|
|
233
|
+
logger.warning(f"WebSocket upgrade missing Origin header: {request.url.path}")
|
|
234
|
+
return False
|
|
235
|
+
|
|
236
|
+
allowed_origins = self._get_allowed_origins(request)
|
|
237
|
+
|
|
238
|
+
for allowed in allowed_origins:
|
|
239
|
+
if allowed == "*":
|
|
240
|
+
logger.warning(
|
|
241
|
+
"WebSocket Origin validation using wildcard '*' - "
|
|
242
|
+
"not recommended for production"
|
|
243
|
+
)
|
|
244
|
+
return True
|
|
245
|
+
if origin == allowed or origin.rstrip("/") == allowed.rstrip("/"):
|
|
246
|
+
return True
|
|
247
|
+
|
|
248
|
+
logger.warning(
|
|
249
|
+
f"WebSocket upgrade rejected - invalid Origin: {origin} "
|
|
250
|
+
f"(allowed: {allowed_origins})"
|
|
251
|
+
)
|
|
252
|
+
return False
|
|
253
|
+
|
|
198
254
|
async def dispatch(
|
|
199
255
|
self,
|
|
200
256
|
request: Request,
|
|
@@ -206,7 +262,14 @@ class CSRFMiddleware(BaseHTTPMiddleware):
|
|
|
206
262
|
path = request.url.path
|
|
207
263
|
method = request.method
|
|
208
264
|
|
|
209
|
-
|
|
265
|
+
if self._is_websocket_upgrade(request):
|
|
266
|
+
if not self._validate_websocket_origin(request):
|
|
267
|
+
return JSONResponse(
|
|
268
|
+
status_code=status.HTTP_403_FORBIDDEN,
|
|
269
|
+
content={"detail": "Invalid origin for WebSocket connection"},
|
|
270
|
+
)
|
|
271
|
+
return await call_next(request)
|
|
272
|
+
|
|
210
273
|
if self._is_exempt(path):
|
|
211
274
|
return await call_next(request)
|
|
212
275
|
|
|
@@ -2252,6 +2252,12 @@ class MongoDBEngine:
|
|
|
2252
2252
|
on_shutdown=on_shutdown,
|
|
2253
2253
|
)
|
|
2254
2254
|
|
|
2255
|
+
# CRITICAL: Set engine state BEFORE importing routes
|
|
2256
|
+
# Routes may use dependencies that need request.app.state.engine
|
|
2257
|
+
# This must be set before route decorators execute
|
|
2258
|
+
child_app.state.engine = engine
|
|
2259
|
+
child_app.state.app_slug = slug
|
|
2260
|
+
|
|
2255
2261
|
# Automatically import routes from app module
|
|
2256
2262
|
# This discovers and imports route modules (web.py, routes.py, etc.)
|
|
2257
2263
|
# so that route decorators are executed and routes are registered
|
|
@@ -2292,10 +2298,8 @@ class MongoDBEngine:
|
|
|
2292
2298
|
auth_hub_url = os.getenv("AUTH_HUB_URL", "/auth-hub")
|
|
2293
2299
|
|
|
2294
2300
|
# Store parent app reference and current app info for middleware
|
|
2301
|
+
# Note: engine and app_slug are already set above (before route import)
|
|
2295
2302
|
child_app.state.parent_app = app
|
|
2296
|
-
child_app.state.app_slug = slug
|
|
2297
|
-
# Required for get_scoped_db and other dependencies
|
|
2298
|
-
child_app.state.engine = engine
|
|
2299
2303
|
child_app.state.app_base_path = path_prefix
|
|
2300
2304
|
child_app.state.app_auth_hub_url = auth_hub_url
|
|
2301
2305
|
child_app.state.app_manifest = app_manifest_data
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|