mdb-engine 0.4.9__tar.gz → 0.4.10__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.
Files changed (104) hide show
  1. {mdb_engine-0.4.9/mdb_engine.egg-info → mdb_engine-0.4.10}/PKG-INFO +1 -1
  2. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/__init__.py +5 -5
  3. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/core/engine.py +109 -15
  4. {mdb_engine-0.4.9 → mdb_engine-0.4.10/mdb_engine.egg-info}/PKG-INFO +1 -1
  5. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/pyproject.toml +1 -1
  6. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/LICENSE +0 -0
  7. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/MANIFEST.in +0 -0
  8. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/README.md +0 -0
  9. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/README.md +0 -0
  10. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/auth/ARCHITECTURE.md +0 -0
  11. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/auth/README.md +0 -0
  12. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/auth/__init__.py +0 -0
  13. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/auth/audit.py +0 -0
  14. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/auth/base.py +0 -0
  15. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/auth/casbin_factory.py +0 -0
  16. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/auth/casbin_models.py +0 -0
  17. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/auth/config_defaults.py +0 -0
  18. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/auth/config_helpers.py +0 -0
  19. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/auth/cookie_utils.py +0 -0
  20. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/auth/csrf.py +0 -0
  21. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/auth/decorators.py +0 -0
  22. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/auth/dependencies.py +0 -0
  23. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/auth/helpers.py +0 -0
  24. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/auth/integration.py +0 -0
  25. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/auth/jwt.py +0 -0
  26. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/auth/middleware.py +0 -0
  27. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/auth/oso_factory.py +0 -0
  28. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/auth/provider.py +0 -0
  29. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/auth/rate_limiter.py +0 -0
  30. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/auth/restrictions.py +0 -0
  31. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/auth/session_manager.py +0 -0
  32. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/auth/shared_middleware.py +0 -0
  33. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/auth/shared_users.py +0 -0
  34. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/auth/token_lifecycle.py +0 -0
  35. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/auth/token_store.py +0 -0
  36. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/auth/users.py +0 -0
  37. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/auth/utils.py +0 -0
  38. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/cli/__init__.py +0 -0
  39. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/cli/commands/__init__.py +0 -0
  40. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/cli/commands/generate.py +0 -0
  41. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/cli/commands/migrate.py +0 -0
  42. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/cli/commands/show.py +0 -0
  43. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/cli/commands/validate.py +0 -0
  44. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/cli/main.py +0 -0
  45. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/cli/utils.py +0 -0
  46. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/config.py +0 -0
  47. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/constants.py +0 -0
  48. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/core/README.md +0 -0
  49. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/core/__init__.py +0 -0
  50. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/core/app_registration.py +0 -0
  51. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/core/app_secrets.py +0 -0
  52. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/core/connection.py +0 -0
  53. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/core/encryption.py +0 -0
  54. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/core/index_management.py +0 -0
  55. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/core/manifest.py +0 -0
  56. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/core/ray_integration.py +0 -0
  57. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/core/seeding.py +0 -0
  58. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/core/service_initialization.py +0 -0
  59. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/core/types.py +0 -0
  60. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/database/README.md +0 -0
  61. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/database/__init__.py +0 -0
  62. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/database/abstraction.py +0 -0
  63. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/database/connection.py +0 -0
  64. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/database/query_validator.py +0 -0
  65. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/database/resource_limiter.py +0 -0
  66. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/database/scoped_wrapper.py +0 -0
  67. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/dependencies.py +0 -0
  68. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/di/__init__.py +0 -0
  69. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/di/container.py +0 -0
  70. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/di/providers.py +0 -0
  71. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/di/scopes.py +0 -0
  72. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/embeddings/README.md +0 -0
  73. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/embeddings/__init__.py +0 -0
  74. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/embeddings/dependencies.py +0 -0
  75. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/embeddings/service.py +0 -0
  76. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/exceptions.py +0 -0
  77. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/indexes/README.md +0 -0
  78. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/indexes/__init__.py +0 -0
  79. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/indexes/helpers.py +0 -0
  80. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/indexes/manager.py +0 -0
  81. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/memory/README.md +0 -0
  82. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/memory/__init__.py +0 -0
  83. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/memory/service.py +0 -0
  84. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/observability/README.md +0 -0
  85. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/observability/__init__.py +0 -0
  86. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/observability/health.py +0 -0
  87. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/observability/logging.py +0 -0
  88. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/observability/metrics.py +0 -0
  89. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/repositories/__init__.py +0 -0
  90. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/repositories/base.py +0 -0
  91. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/repositories/mongo.py +0 -0
  92. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/repositories/unit_of_work.py +0 -0
  93. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/routing/README.md +0 -0
  94. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/routing/__init__.py +0 -0
  95. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/routing/websockets.py +0 -0
  96. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/utils/__init__.py +0 -0
  97. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine/utils/mongo.py +0 -0
  98. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine.egg-info/SOURCES.txt +0 -0
  99. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine.egg-info/dependency_links.txt +0 -0
  100. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine.egg-info/entry_points.txt +0 -0
  101. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine.egg-info/requires.txt +0 -0
  102. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/mdb_engine.egg-info/top_level.txt +0 -0
  103. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/setup.cfg +0 -0
  104. {mdb_engine-0.4.9 → mdb_engine-0.4.10}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mdb-engine
3
- Version: 0.4.9
3
+ Version: 0.4.10
4
4
  Summary: MongoDB Engine
5
5
  Home-page: https://github.com/ranfysvalle02/mdb-engine
6
6
  Author: Fabian Valle
@@ -82,11 +82,11 @@ from .repositories import Entity, MongoRepository, Repository, UnitOfWork
82
82
  from .utils import clean_mongo_doc, clean_mongo_docs
83
83
 
84
84
  __version__ = (
85
- "0.4.9" # Fix: WebSocket + CSRF + Multi-App architecture
86
- # - CSRF middleware now added to parent app when child apps use shared auth
87
- # - CORS config properly merged from child apps to parent app
88
- # - WebSocket origin validation uses parent app's CORS config
89
- # - Comprehensive integration tests added
85
+ "0.4.10" # Fix: allow_credentials preserved in CORS config merge
86
+ # - Fixed bug where allow_credentials was set to False even when child apps require True
87
+ # - Dynamic CORS middleware reads from app.state.cors_config at request time
88
+ # - Merge logic now ensures if ANY child app has allow_credentials: True, parent gets True
89
+ # - Essential for SSO cookie-based authentication in WebSocket connections
90
90
  )
91
91
 
92
92
  __all__ = [
@@ -2213,15 +2213,29 @@ class MongoDBEngine:
2213
2213
  child_origins = child_cors.get("allow_origins", [])
2214
2214
  parent_origins = parent_cors.get("allow_origins", [])
2215
2215
  merged_origins = list(set(parent_origins + child_origins))
2216
+
2217
+ # CRITICAL: If ANY child app requires credentials, parent must allow them
2218
+ # This is essential for SSO cookie-based authentication
2219
+ child_requires_credentials = child_cors.get("allow_credentials", False)
2220
+ parent_allows_credentials = parent_cors.get("allow_credentials", False)
2221
+ merged_allow_credentials = (
2222
+ child_requires_credentials or parent_allows_credentials
2223
+ )
2224
+
2216
2225
  parent_app.state.cors_config = {
2217
2226
  **parent_cors,
2218
2227
  **child_cors,
2219
2228
  "allow_origins": merged_origins if merged_origins else ["*"],
2229
+ # If ANY child requires credentials, parent gets True (for SSO)
2230
+ "allow_credentials": merged_allow_credentials,
2220
2231
  }
2221
2232
  else:
2222
2233
  # Parent has no CORS config, use child's
2223
2234
  parent_app.state.cors_config = child_cors
2224
- logger.debug(f"✅ Merged CORS config from child app '{slug}' to parent app")
2235
+ logger.debug(
2236
+ f"✅ Merged CORS config from child app '{slug}' to parent app "
2237
+ f"(allow_credentials={parent_app.state.cors_config.get('allow_credentials')})"
2238
+ )
2225
2239
 
2226
2240
  async def _register_websocket_routes(
2227
2241
  parent_app: "FastAPI",
@@ -2670,11 +2684,14 @@ class MongoDBEngine:
2670
2684
  # Set default CORS config on parent app for WebSocket origin validation
2671
2685
  # This ensures CSRF middleware can validate WebSocket origins even if child apps
2672
2686
  # don't configure CORS
2687
+ # NOTE: allow_credentials defaults to False here, but will be set to True
2688
+ # during merge if any child app requires it (essential for SSO cookie-based auth)
2673
2689
  from ..auth.config_helpers import CORS_DEFAULTS
2674
2690
 
2675
2691
  parent_app.state.cors_config = CORS_DEFAULTS.copy()
2676
2692
  parent_app.state.cors_config["enabled"] = True
2677
2693
  parent_app.state.cors_config["allow_origins"] = ["*"] # Default to allow all for WebSocket
2694
+ # Keep allow_credentials as False initially - will be merged from child apps
2678
2695
  logger.debug("Set default CORS config on parent app for WebSocket origin validation")
2679
2696
 
2680
2697
  # Store app reference in engine for get_mounted_apps()
@@ -2716,22 +2733,99 @@ class MongoDBEngine:
2716
2733
  logger.info("CSRFMiddleware added to parent app for WebSocket origin validation")
2717
2734
 
2718
2735
  # Add shared CORS middleware if configured
2719
- # (Individual apps can add their own CORS, but parent-level is useful)
2736
+ # NOTE: We create a dynamic CORS middleware that reads from app.state.cors_config
2737
+ # This allows the config to be updated after child apps are mounted and merged
2720
2738
  try:
2721
- from fastapi.middleware.cors import CORSMiddleware
2722
-
2723
- # Use CORS config from parent app state (set above)
2724
- cors_origins = parent_app.state.cors_config.get("allow_origins", ["*"])
2725
- cors_credentials = parent_app.state.cors_config.get("allow_credentials", True)
2726
-
2727
- parent_app.add_middleware(
2728
- CORSMiddleware,
2729
- allow_origins=cors_origins,
2730
- allow_credentials=cors_credentials,
2731
- allow_methods=["*"],
2732
- allow_headers=["*"],
2739
+ from starlette.middleware.base import BaseHTTPMiddleware
2740
+ from starlette.requests import Request
2741
+ from starlette.responses import Response
2742
+
2743
+ class DynamicCORSMiddleware(BaseHTTPMiddleware):
2744
+ """
2745
+ Dynamic CORS middleware that reads config from app.state.cors_config.
2746
+
2747
+ This allows CORS config to be updated after child apps are mounted
2748
+ and their configs are merged, which is essential for SSO multi-app
2749
+ setups where allow_credentials must be True for cookie-based auth.
2750
+ """
2751
+
2752
+ async def dispatch(self, request: Request, call_next):
2753
+ # Read CORS config from app.state (may have been merged from child apps)
2754
+ cors_config = getattr(request.app.state, "cors_config", {})
2755
+
2756
+ if not cors_config.get("enabled", False):
2757
+ # CORS not enabled, pass through
2758
+ return await call_next(request)
2759
+
2760
+ # Handle preflight OPTIONS request
2761
+ if request.method == "OPTIONS":
2762
+ origin = request.headers.get("origin")
2763
+ allowed_origins = cors_config.get("allow_origins", ["*"])
2764
+ allow_credentials = cors_config.get("allow_credentials", False)
2765
+
2766
+ # Check if origin is allowed
2767
+ origin_allowed = False
2768
+ if "*" in allowed_origins:
2769
+ origin_allowed = True
2770
+ elif origin in allowed_origins:
2771
+ origin_allowed = True
2772
+
2773
+ if origin_allowed:
2774
+ headers = {
2775
+ "Access-Control-Allow-Methods": ", ".join(
2776
+ cors_config.get("allow_methods", ["*"])
2777
+ ),
2778
+ "Access-Control-Allow-Headers": ", ".join(
2779
+ cors_config.get("allow_headers", ["*"])
2780
+ ),
2781
+ "Access-Control-Max-Age": str(cors_config.get("max_age", 3600)),
2782
+ }
2783
+ if allow_credentials:
2784
+ headers["Access-Control-Allow-Credentials"] = "true"
2785
+ if origin:
2786
+ headers["Access-Control-Allow-Origin"] = origin
2787
+
2788
+ expose_headers = cors_config.get("expose_headers", [])
2789
+ if expose_headers:
2790
+ headers["Access-Control-Expose-Headers"] = ", ".join(expose_headers)
2791
+
2792
+ return Response(status_code=200, headers=headers)
2793
+ else:
2794
+ return Response(status_code=403)
2795
+
2796
+ # Handle actual request
2797
+ response = await call_next(request)
2798
+
2799
+ # Add CORS headers to response
2800
+ origin = request.headers.get("origin")
2801
+ allowed_origins = cors_config.get("allow_origins", ["*"])
2802
+ allow_credentials = cors_config.get("allow_credentials", False)
2803
+
2804
+ # Check if origin is allowed
2805
+ origin_allowed = False
2806
+ if "*" in allowed_origins:
2807
+ origin_allowed = True
2808
+ elif origin and origin in allowed_origins:
2809
+ origin_allowed = True
2810
+
2811
+ if origin_allowed:
2812
+ if origin:
2813
+ response.headers["Access-Control-Allow-Origin"] = origin
2814
+ if allow_credentials:
2815
+ response.headers["Access-Control-Allow-Credentials"] = "true"
2816
+
2817
+ expose_headers = cors_config.get("expose_headers", [])
2818
+ if expose_headers:
2819
+ response.headers["Access-Control-Expose-Headers"] = ", ".join(
2820
+ expose_headers
2821
+ )
2822
+
2823
+ return response
2824
+
2825
+ parent_app.add_middleware(DynamicCORSMiddleware)
2826
+ logger.debug(
2827
+ "Dynamic CORS middleware added for parent app (reads from app.state.cors_config)"
2733
2828
  )
2734
- logger.debug("CORS middleware added for parent app")
2735
2829
  except ImportError:
2736
2830
  logger.warning("CORS middleware not available")
2737
2831
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mdb-engine
3
- Version: 0.4.9
3
+ Version: 0.4.10
4
4
  Summary: MongoDB Engine
5
5
  Home-page: https://github.com/ranfysvalle02/mdb-engine
6
6
  Author: Fabian Valle
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "mdb-engine"
7
- version = "0.4.9"
7
+ version = "0.4.10"
8
8
  description = "MongoDB Engine"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
File without changes
File without changes
File without changes
File without changes
File without changes