mdb-engine 0.1.6__py3-none-any.whl → 0.4.12__py3-none-any.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.
Files changed (92) hide show
  1. mdb_engine/__init__.py +116 -11
  2. mdb_engine/auth/ARCHITECTURE.md +112 -0
  3. mdb_engine/auth/README.md +654 -11
  4. mdb_engine/auth/__init__.py +136 -29
  5. mdb_engine/auth/audit.py +592 -0
  6. mdb_engine/auth/base.py +252 -0
  7. mdb_engine/auth/casbin_factory.py +265 -70
  8. mdb_engine/auth/config_defaults.py +5 -5
  9. mdb_engine/auth/config_helpers.py +19 -18
  10. mdb_engine/auth/cookie_utils.py +12 -16
  11. mdb_engine/auth/csrf.py +483 -0
  12. mdb_engine/auth/decorators.py +10 -16
  13. mdb_engine/auth/dependencies.py +69 -71
  14. mdb_engine/auth/helpers.py +3 -3
  15. mdb_engine/auth/integration.py +61 -88
  16. mdb_engine/auth/jwt.py +11 -15
  17. mdb_engine/auth/middleware.py +79 -35
  18. mdb_engine/auth/oso_factory.py +21 -41
  19. mdb_engine/auth/provider.py +270 -171
  20. mdb_engine/auth/rate_limiter.py +505 -0
  21. mdb_engine/auth/restrictions.py +21 -36
  22. mdb_engine/auth/session_manager.py +24 -41
  23. mdb_engine/auth/shared_middleware.py +977 -0
  24. mdb_engine/auth/shared_users.py +775 -0
  25. mdb_engine/auth/token_lifecycle.py +10 -12
  26. mdb_engine/auth/token_store.py +17 -32
  27. mdb_engine/auth/users.py +99 -159
  28. mdb_engine/auth/utils.py +236 -42
  29. mdb_engine/cli/commands/generate.py +546 -10
  30. mdb_engine/cli/commands/validate.py +3 -7
  31. mdb_engine/cli/utils.py +7 -7
  32. mdb_engine/config.py +13 -28
  33. mdb_engine/constants.py +65 -0
  34. mdb_engine/core/README.md +117 -6
  35. mdb_engine/core/__init__.py +39 -7
  36. mdb_engine/core/app_registration.py +31 -50
  37. mdb_engine/core/app_secrets.py +289 -0
  38. mdb_engine/core/connection.py +20 -12
  39. mdb_engine/core/encryption.py +222 -0
  40. mdb_engine/core/engine.py +2862 -115
  41. mdb_engine/core/index_management.py +12 -16
  42. mdb_engine/core/manifest.py +628 -204
  43. mdb_engine/core/ray_integration.py +436 -0
  44. mdb_engine/core/seeding.py +13 -21
  45. mdb_engine/core/service_initialization.py +20 -30
  46. mdb_engine/core/types.py +40 -43
  47. mdb_engine/database/README.md +140 -17
  48. mdb_engine/database/__init__.py +17 -6
  49. mdb_engine/database/abstraction.py +37 -50
  50. mdb_engine/database/connection.py +51 -30
  51. mdb_engine/database/query_validator.py +367 -0
  52. mdb_engine/database/resource_limiter.py +204 -0
  53. mdb_engine/database/scoped_wrapper.py +747 -237
  54. mdb_engine/dependencies.py +427 -0
  55. mdb_engine/di/__init__.py +34 -0
  56. mdb_engine/di/container.py +247 -0
  57. mdb_engine/di/providers.py +206 -0
  58. mdb_engine/di/scopes.py +139 -0
  59. mdb_engine/embeddings/README.md +54 -24
  60. mdb_engine/embeddings/__init__.py +31 -24
  61. mdb_engine/embeddings/dependencies.py +38 -155
  62. mdb_engine/embeddings/service.py +78 -75
  63. mdb_engine/exceptions.py +104 -12
  64. mdb_engine/indexes/README.md +30 -13
  65. mdb_engine/indexes/__init__.py +1 -0
  66. mdb_engine/indexes/helpers.py +11 -11
  67. mdb_engine/indexes/manager.py +59 -123
  68. mdb_engine/memory/README.md +95 -4
  69. mdb_engine/memory/__init__.py +1 -2
  70. mdb_engine/memory/service.py +363 -1168
  71. mdb_engine/observability/README.md +4 -2
  72. mdb_engine/observability/__init__.py +26 -9
  73. mdb_engine/observability/health.py +17 -17
  74. mdb_engine/observability/logging.py +10 -10
  75. mdb_engine/observability/metrics.py +40 -19
  76. mdb_engine/repositories/__init__.py +34 -0
  77. mdb_engine/repositories/base.py +325 -0
  78. mdb_engine/repositories/mongo.py +233 -0
  79. mdb_engine/repositories/unit_of_work.py +166 -0
  80. mdb_engine/routing/README.md +1 -1
  81. mdb_engine/routing/__init__.py +1 -3
  82. mdb_engine/routing/websockets.py +41 -75
  83. mdb_engine/utils/__init__.py +3 -1
  84. mdb_engine/utils/mongo.py +117 -0
  85. mdb_engine-0.4.12.dist-info/METADATA +492 -0
  86. mdb_engine-0.4.12.dist-info/RECORD +97 -0
  87. {mdb_engine-0.1.6.dist-info → mdb_engine-0.4.12.dist-info}/WHEEL +1 -1
  88. mdb_engine-0.1.6.dist-info/METADATA +0 -213
  89. mdb_engine-0.1.6.dist-info/RECORD +0 -75
  90. {mdb_engine-0.1.6.dist-info → mdb_engine-0.4.12.dist-info}/entry_points.txt +0 -0
  91. {mdb_engine-0.1.6.dist-info → mdb_engine-0.4.12.dist-info}/licenses/LICENSE +0 -0
  92. {mdb_engine-0.1.6.dist-info → mdb_engine-0.4.12.dist-info}/top_level.txt +0 -0
mdb_engine/__init__.py CHANGED
@@ -1,37 +1,142 @@
1
1
  """
2
2
  MDB_ENGINE - MongoDB Engine
3
3
 
4
- Enterprise-grade engine for building applications
5
- with automatic database scoping, authentication, and resource management.
4
+ Enterprise-grade engine for building applications with:
5
+ - Automatic database scoping and data isolation
6
+ - Proper dependency injection with service lifetimes
7
+ - Repository pattern for clean data access
8
+ - Authentication and authorization
9
+
10
+ Usage:
11
+ # Simple usage
12
+ from mdb_engine import MongoDBEngine
13
+ engine = MongoDBEngine(mongo_uri=..., db_name=...)
14
+ await engine.initialize()
15
+ db = engine.get_scoped_db("my_app")
16
+
17
+ # With FastAPI integration
18
+ app = engine.create_app(slug="my_app", manifest=Path("manifest.json"))
19
+
20
+ # In routes - use RequestContext for clean DI
21
+ from mdb_engine import RequestContext
22
+
23
+ @app.get("/users/{user_id}")
24
+ async def get_user(user_id: str, ctx: RequestContext = Depends()):
25
+ user = await ctx.uow.users.get(user_id)
26
+ return user
6
27
  """
7
28
 
8
29
  # Authentication
9
- from .auth import AuthorizationProvider, get_current_user, require_admin
30
+ from .auth import AuthorizationProvider, require_admin
31
+ from .auth import get_current_user as auth_get_current_user # noqa: F401
32
+
10
33
  # Core MongoDB Engine
11
- from .core import ManifestParser, ManifestValidator, MongoDBEngine
34
+ from .core import (
35
+ RAY_AVAILABLE,
36
+ AppRayActor,
37
+ ManifestParser,
38
+ ManifestValidator,
39
+ MongoDBEngine,
40
+ get_ray_actor_handle,
41
+ ray_actor_decorator,
42
+ )
43
+
12
44
  # Database layer
13
- from .database import AppDB, ScopedMongoWrapper, get_shared_mongo_client
45
+ from .database import AppDB, ScopedMongoWrapper
46
+
47
+ # FastAPI dependencies
48
+ from .dependencies import (
49
+ Inject,
50
+ RequestContext,
51
+ get_app_config,
52
+ get_app_slug,
53
+ get_authz_provider,
54
+ get_current_user,
55
+ get_embedding_service,
56
+ get_engine,
57
+ get_llm_client,
58
+ get_llm_model_name,
59
+ get_memory_service,
60
+ get_scoped_db,
61
+ get_unit_of_work,
62
+ get_user_roles,
63
+ inject,
64
+ require_role,
65
+ require_user,
66
+ )
67
+
68
+ # DI Container
69
+ from .di import Container, Scope, ScopeManager
70
+
14
71
  # Index management
15
- from .indexes import (AsyncAtlasIndexManager, AutoIndexManager,
16
- run_index_creation_for_collection)
72
+ from .indexes import (
73
+ AsyncAtlasIndexManager,
74
+ AutoIndexManager,
75
+ run_index_creation_for_collection,
76
+ )
77
+
78
+ # Repository pattern
79
+ from .repositories import Entity, MongoRepository, Repository, UnitOfWork
17
80
 
18
- __version__ = "0.1.6"
81
+ # Utilities
82
+ from .utils import clean_mongo_doc, clean_mongo_docs
83
+
84
+ __version__ = (
85
+ "0.4.12" # Fix CSRF middleware rejecting WebSocket connections
86
+ # - Skip CSRF middleware on child apps in multi-app setups (parent handles it)
87
+ # - Merge child app public routes into parent CSRF exempt list
88
+ # - WebSocket connections now work correctly in multi-app SSO setups
89
+ # - Security maintained: parent app CSRF middleware protects all routes
90
+ )
19
91
 
20
92
  __all__ = [
21
- # Core
93
+ # Core Engine
22
94
  "MongoDBEngine",
23
95
  "ManifestValidator",
24
96
  "ManifestParser",
97
+ # Ray Integration (optional)
98
+ "RAY_AVAILABLE",
99
+ "AppRayActor",
100
+ "get_ray_actor_handle",
101
+ "ray_actor_decorator",
25
102
  # Database
26
103
  "ScopedMongoWrapper",
27
104
  "AppDB",
28
- "get_shared_mongo_client",
105
+ # DI Container
106
+ "Container",
107
+ "Scope",
108
+ "ScopeManager",
109
+ # Repository Pattern
110
+ "Repository",
111
+ "MongoRepository",
112
+ "Entity",
113
+ "UnitOfWork",
29
114
  # Auth
30
115
  "AuthorizationProvider",
31
- "get_current_user",
32
116
  "require_admin",
117
+ # FastAPI Dependencies
118
+ "RequestContext",
119
+ "get_engine",
120
+ "get_app_slug",
121
+ "get_app_config",
122
+ "get_scoped_db",
123
+ "get_unit_of_work",
124
+ "get_embedding_service",
125
+ "get_memory_service",
126
+ "get_llm_client",
127
+ "get_llm_model_name",
128
+ "get_authz_provider",
129
+ "get_current_user",
130
+ "get_user_roles",
131
+ "require_user",
132
+ "require_role",
133
+ "inject",
134
+ "Inject",
33
135
  # Indexes
34
136
  "AsyncAtlasIndexManager",
35
137
  "AutoIndexManager",
36
138
  "run_index_creation_for_collection",
139
+ # Utilities
140
+ "clean_mongo_doc",
141
+ "clean_mongo_docs",
37
142
  ]
@@ -0,0 +1,112 @@
1
+ # Authorization Provider Architecture
2
+
3
+ ## Overview
4
+
5
+ The authorization system uses the **Adapter Pattern** with a strict abstract base class to ensure type safety, fail-closed security, and proper abstraction from third-party libraries.
6
+
7
+ ## Design Principles
8
+
9
+ 1. **Adapter Pattern**: We wrap third-party libraries (Casbin, OSO) without modifying their source code
10
+ 2. **Fail-Closed Security**: If authorization evaluation fails, access is denied (never granted)
11
+ 3. **Type Safety**: Clear contracts with proper type hints and abstract methods
12
+ 4. **Interface Segregation**: Application code only needs `check()`, not engine internals
13
+ 5. **Observability**: Structured logging for all authorization decisions and errors
14
+
15
+ ## Architecture
16
+
17
+ ```
18
+ BaseAuthorizationProvider (ABC)
19
+ ├── CasbinAdapter
20
+ │ └── Wraps casbin.AsyncEnforcer
21
+ └── OsoAdapter
22
+ └── Wraps oso_cloud.Client or oso.Oso
23
+ ```
24
+
25
+ ## Base Class: `BaseAuthorizationProvider`
26
+
27
+ Defines the contract that all authorization providers must implement:
28
+
29
+ - `check(subject, resource, action)` - Primary authorization decision method
30
+ - `add_policy(*params)` - Add policy rules
31
+ - `add_role_for_user(*params)` - Assign roles to users
32
+ - `save_policy()` - Persist policies to storage
33
+ - `has_policy(*params)` - Check if policy exists
34
+ - `has_role_for_user(*params)` - Check if user has role
35
+ - `clear_cache()` - Clear authorization cache
36
+
37
+ ### Fail-Closed Security
38
+
39
+ All `check()` implementations must:
40
+ 1. Catch all exceptions during evaluation
41
+ 2. Log errors with full context
42
+ 3. Return `False` (deny access) on any error
43
+ 4. Never raise exceptions from evaluation failures
44
+
45
+ ### Error Handling
46
+
47
+ - **Evaluation Errors**: Handled by `_handle_evaluation_error()` - denies access, logs critically
48
+ - **Operation Errors**: Handled by `_handle_operation_error()` - returns False, logs warning
49
+
50
+ ## CasbinAdapter
51
+
52
+ Wraps `casbin.AsyncEnforcer` and handles:
53
+ - Casbin's `(subject, object, action)` format
54
+ - Thread pool execution to prevent blocking
55
+ - Caching for performance
56
+ - MongoDB persistence via MotorAdapter
57
+
58
+ ### Format Mapping
59
+
60
+ - `check(subject, resource, action)` → `enforcer.enforce(subject, resource, action)`
61
+ - `add_policy(role, resource, action)` → `enforcer.add_policy(role, resource, action)`
62
+ - `add_role_for_user(user, role)` → `enforcer.add_role_for_user(user, role)`
63
+
64
+ ## OsoAdapter
65
+
66
+ Wraps OSO Cloud client and handles:
67
+ - OSO's `authorize(actor, action, resource)` format
68
+ - Type marshalling (strings → TypedObject)
69
+ - Thread pool execution
70
+ - Caching for performance
71
+
72
+ ### Format Mapping
73
+
74
+ - `check(subject, resource, action)` → `client.authorize(TypedObject("User", subject), action, TypedObject("Document", resource))`
75
+ - `add_policy(role, resource, action)` → `client.insert(["grants_permission", role, action, resource])`
76
+ - `add_role_for_user(user, role, [resource])` → `client.insert(["has_role", Value("User", user), role, Value("Document", resource)])`
77
+
78
+ ## Backward Compatibility
79
+
80
+ The `AuthorizationProvider` Protocol is maintained for backward compatibility. All adapters implement both:
81
+ - The Protocol (for structural typing)
82
+ - The BaseAuthorizationProvider ABC (for inheritance)
83
+
84
+ ## Usage
85
+
86
+ ```python
87
+ from mdb_engine.auth import BaseAuthorizationProvider, CasbinAdapter, OsoAdapter
88
+
89
+ # Type checking works with both Protocol and ABC
90
+ async def check_permission(
91
+ provider: BaseAuthorizationProvider, # or AuthorizationProvider
92
+ user: str,
93
+ resource: str,
94
+ action: str,
95
+ ) -> bool:
96
+ return await provider.check(user, resource, action)
97
+
98
+ # Runtime type checking
99
+ if provider.is_casbin():
100
+ # Casbin-specific operations
101
+ enforcer = provider._enforcer # Still accessible
102
+ elif provider.is_oso():
103
+ # OSO-specific operations
104
+ client = provider._oso # Still accessible
105
+ ```
106
+
107
+ ## Migration Notes
108
+
109
+ - Existing code using `AuthorizationProvider` Protocol continues to work
110
+ - Code checking `hasattr(provider, "_enforcer")` continues to work
111
+ - New code should use `BaseAuthorizationProvider` for better type safety
112
+ - Helper methods `is_casbin()` and `is_oso()` available for type checking