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.
- mdb_engine/__init__.py +116 -11
- mdb_engine/auth/ARCHITECTURE.md +112 -0
- mdb_engine/auth/README.md +654 -11
- mdb_engine/auth/__init__.py +136 -29
- mdb_engine/auth/audit.py +592 -0
- mdb_engine/auth/base.py +252 -0
- mdb_engine/auth/casbin_factory.py +265 -70
- mdb_engine/auth/config_defaults.py +5 -5
- mdb_engine/auth/config_helpers.py +19 -18
- mdb_engine/auth/cookie_utils.py +12 -16
- mdb_engine/auth/csrf.py +483 -0
- mdb_engine/auth/decorators.py +10 -16
- mdb_engine/auth/dependencies.py +69 -71
- mdb_engine/auth/helpers.py +3 -3
- mdb_engine/auth/integration.py +61 -88
- mdb_engine/auth/jwt.py +11 -15
- mdb_engine/auth/middleware.py +79 -35
- mdb_engine/auth/oso_factory.py +21 -41
- mdb_engine/auth/provider.py +270 -171
- mdb_engine/auth/rate_limiter.py +505 -0
- mdb_engine/auth/restrictions.py +21 -36
- mdb_engine/auth/session_manager.py +24 -41
- mdb_engine/auth/shared_middleware.py +977 -0
- mdb_engine/auth/shared_users.py +775 -0
- mdb_engine/auth/token_lifecycle.py +10 -12
- mdb_engine/auth/token_store.py +17 -32
- mdb_engine/auth/users.py +99 -159
- mdb_engine/auth/utils.py +236 -42
- mdb_engine/cli/commands/generate.py +546 -10
- mdb_engine/cli/commands/validate.py +3 -7
- mdb_engine/cli/utils.py +7 -7
- mdb_engine/config.py +13 -28
- mdb_engine/constants.py +65 -0
- mdb_engine/core/README.md +117 -6
- mdb_engine/core/__init__.py +39 -7
- mdb_engine/core/app_registration.py +31 -50
- mdb_engine/core/app_secrets.py +289 -0
- mdb_engine/core/connection.py +20 -12
- mdb_engine/core/encryption.py +222 -0
- mdb_engine/core/engine.py +2862 -115
- mdb_engine/core/index_management.py +12 -16
- mdb_engine/core/manifest.py +628 -204
- mdb_engine/core/ray_integration.py +436 -0
- mdb_engine/core/seeding.py +13 -21
- mdb_engine/core/service_initialization.py +20 -30
- mdb_engine/core/types.py +40 -43
- mdb_engine/database/README.md +140 -17
- mdb_engine/database/__init__.py +17 -6
- mdb_engine/database/abstraction.py +37 -50
- mdb_engine/database/connection.py +51 -30
- mdb_engine/database/query_validator.py +367 -0
- mdb_engine/database/resource_limiter.py +204 -0
- mdb_engine/database/scoped_wrapper.py +747 -237
- mdb_engine/dependencies.py +427 -0
- mdb_engine/di/__init__.py +34 -0
- mdb_engine/di/container.py +247 -0
- mdb_engine/di/providers.py +206 -0
- mdb_engine/di/scopes.py +139 -0
- mdb_engine/embeddings/README.md +54 -24
- mdb_engine/embeddings/__init__.py +31 -24
- mdb_engine/embeddings/dependencies.py +38 -155
- mdb_engine/embeddings/service.py +78 -75
- mdb_engine/exceptions.py +104 -12
- mdb_engine/indexes/README.md +30 -13
- mdb_engine/indexes/__init__.py +1 -0
- mdb_engine/indexes/helpers.py +11 -11
- mdb_engine/indexes/manager.py +59 -123
- mdb_engine/memory/README.md +95 -4
- mdb_engine/memory/__init__.py +1 -2
- mdb_engine/memory/service.py +363 -1168
- mdb_engine/observability/README.md +4 -2
- mdb_engine/observability/__init__.py +26 -9
- mdb_engine/observability/health.py +17 -17
- mdb_engine/observability/logging.py +10 -10
- mdb_engine/observability/metrics.py +40 -19
- mdb_engine/repositories/__init__.py +34 -0
- mdb_engine/repositories/base.py +325 -0
- mdb_engine/repositories/mongo.py +233 -0
- mdb_engine/repositories/unit_of_work.py +166 -0
- mdb_engine/routing/README.md +1 -1
- mdb_engine/routing/__init__.py +1 -3
- mdb_engine/routing/websockets.py +41 -75
- mdb_engine/utils/__init__.py +3 -1
- mdb_engine/utils/mongo.py +117 -0
- mdb_engine-0.4.12.dist-info/METADATA +492 -0
- mdb_engine-0.4.12.dist-info/RECORD +97 -0
- {mdb_engine-0.1.6.dist-info → mdb_engine-0.4.12.dist-info}/WHEEL +1 -1
- mdb_engine-0.1.6.dist-info/METADATA +0 -213
- mdb_engine-0.1.6.dist-info/RECORD +0 -75
- {mdb_engine-0.1.6.dist-info → mdb_engine-0.4.12.dist-info}/entry_points.txt +0 -0
- {mdb_engine-0.1.6.dist-info → mdb_engine-0.4.12.dist-info}/licenses/LICENSE +0 -0
- {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
|
-
|
|
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,
|
|
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
|
|
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
|
|
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 (
|
|
16
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|