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
|
@@ -8,13 +8,16 @@ This module is part of MDB_ENGINE - MongoDB Engine.
|
|
|
8
8
|
|
|
9
9
|
import logging
|
|
10
10
|
from datetime import datetime, timedelta
|
|
11
|
-
from typing import Any
|
|
11
|
+
from typing import Any
|
|
12
12
|
|
|
13
13
|
from bson.objectid import ObjectId
|
|
14
14
|
|
|
15
15
|
try:
|
|
16
|
-
from pymongo.errors import (
|
|
17
|
-
|
|
16
|
+
from pymongo.errors import (
|
|
17
|
+
ConnectionFailure,
|
|
18
|
+
OperationFailure,
|
|
19
|
+
ServerSelectionTimeoutError,
|
|
20
|
+
)
|
|
18
21
|
except ImportError:
|
|
19
22
|
ConnectionFailure = Exception
|
|
20
23
|
OperationFailure = Exception
|
|
@@ -93,10 +96,10 @@ class SessionManager:
|
|
|
93
96
|
user_id: str,
|
|
94
97
|
device_id: str,
|
|
95
98
|
refresh_jti: str,
|
|
96
|
-
device_info:
|
|
97
|
-
ip_address:
|
|
98
|
-
session_fingerprint:
|
|
99
|
-
) ->
|
|
99
|
+
device_info: dict[str, Any] | None = None,
|
|
100
|
+
ip_address: str | None = None,
|
|
101
|
+
session_fingerprint: str | None = None,
|
|
102
|
+
) -> dict[str, Any] | None:
|
|
100
103
|
"""
|
|
101
104
|
Create a new user session.
|
|
102
105
|
|
|
@@ -120,9 +123,7 @@ class SessionManager:
|
|
|
120
123
|
# Remove oldest inactive session
|
|
121
124
|
await self.cleanup_inactive_sessions(user_id)
|
|
122
125
|
# Check again
|
|
123
|
-
active_sessions = await self.get_user_sessions(
|
|
124
|
-
user_id, active_only=True
|
|
125
|
-
)
|
|
126
|
+
active_sessions = await self.get_user_sessions(user_id, active_only=True)
|
|
126
127
|
if len(active_sessions) >= self.max_sessions:
|
|
127
128
|
# Force remove oldest session
|
|
128
129
|
if active_sessions:
|
|
@@ -168,13 +169,11 @@ class SessionManager:
|
|
|
168
169
|
ValueError,
|
|
169
170
|
TypeError,
|
|
170
171
|
) as e:
|
|
171
|
-
logger.error(
|
|
172
|
-
f"Error creating session for user {user_id}: {e}", exc_info=True
|
|
173
|
-
)
|
|
172
|
+
logger.error(f"Error creating session for user {user_id}: {e}", exc_info=True)
|
|
174
173
|
return None
|
|
175
174
|
|
|
176
175
|
async def update_session_activity(
|
|
177
|
-
self, refresh_jti: str, ip_address:
|
|
176
|
+
self, refresh_jti: str, ip_address: str | None = None
|
|
178
177
|
) -> bool:
|
|
179
178
|
"""
|
|
180
179
|
Update session last_seen timestamp (activity tracking).
|
|
@@ -205,14 +204,10 @@ class SessionManager:
|
|
|
205
204
|
ValueError,
|
|
206
205
|
TypeError,
|
|
207
206
|
) as e:
|
|
208
|
-
logger.error(
|
|
209
|
-
f"Error updating session activity for {refresh_jti}: {e}", exc_info=True
|
|
210
|
-
)
|
|
207
|
+
logger.error(f"Error updating session activity for {refresh_jti}: {e}", exc_info=True)
|
|
211
208
|
return False
|
|
212
209
|
|
|
213
|
-
async def get_session_by_refresh_token(
|
|
214
|
-
self, refresh_jti: str
|
|
215
|
-
) -> Optional[Dict[str, Any]]:
|
|
210
|
+
async def get_session_by_refresh_token(self, refresh_jti: str) -> dict[str, Any] | None:
|
|
216
211
|
"""
|
|
217
212
|
Get session by refresh token JWT ID.
|
|
218
213
|
|
|
@@ -223,9 +218,7 @@ class SessionManager:
|
|
|
223
218
|
Session document or None if not found
|
|
224
219
|
"""
|
|
225
220
|
try:
|
|
226
|
-
session = await self.collection.find_one(
|
|
227
|
-
{"refresh_jti": refresh_jti, "active": True}
|
|
228
|
-
)
|
|
221
|
+
session = await self.collection.find_one({"refresh_jti": refresh_jti, "active": True})
|
|
229
222
|
return session
|
|
230
223
|
except (
|
|
231
224
|
OperationFailure,
|
|
@@ -241,7 +234,7 @@ class SessionManager:
|
|
|
241
234
|
return None
|
|
242
235
|
|
|
243
236
|
async def validate_session_fingerprint(
|
|
244
|
-
self, refresh_jti: str, current_fingerprint: str, strict:
|
|
237
|
+
self, refresh_jti: str, current_fingerprint: str, strict: bool | None = None
|
|
245
238
|
) -> bool:
|
|
246
239
|
"""
|
|
247
240
|
Validate session fingerprint matches stored fingerprint.
|
|
@@ -267,9 +260,7 @@ class SessionManager:
|
|
|
267
260
|
stored_fingerprint = session.get("session_fingerprint")
|
|
268
261
|
|
|
269
262
|
if not stored_fingerprint:
|
|
270
|
-
strict_mode =
|
|
271
|
-
strict if strict is not None else self.fingerprinting_strict
|
|
272
|
-
)
|
|
263
|
+
strict_mode = strict if strict is not None else self.fingerprinting_strict
|
|
273
264
|
return not strict_mode
|
|
274
265
|
|
|
275
266
|
return stored_fingerprint == current_fingerprint
|
|
@@ -297,7 +288,7 @@ class SessionManager:
|
|
|
297
288
|
|
|
298
289
|
async def get_user_sessions(
|
|
299
290
|
self, user_id: str, active_only: bool = True
|
|
300
|
-
) ->
|
|
291
|
+
) -> list[dict[str, Any]]:
|
|
301
292
|
"""
|
|
302
293
|
Get all sessions for a user.
|
|
303
294
|
|
|
@@ -313,9 +304,7 @@ class SessionManager:
|
|
|
313
304
|
if active_only:
|
|
314
305
|
query["active"] = True
|
|
315
306
|
|
|
316
|
-
sessions = (
|
|
317
|
-
await self.collection.find(query).sort("last_seen", -1).to_list(None)
|
|
318
|
-
)
|
|
307
|
+
sessions = await self.collection.find(query).sort("last_seen", -1).to_list(None)
|
|
319
308
|
return sessions
|
|
320
309
|
except (
|
|
321
310
|
OperationFailure,
|
|
@@ -324,9 +313,7 @@ class SessionManager:
|
|
|
324
313
|
ValueError,
|
|
325
314
|
TypeError,
|
|
326
315
|
) as e:
|
|
327
|
-
logger.error(
|
|
328
|
-
f"Error getting sessions for user {user_id}: {e}", exc_info=True
|
|
329
|
-
)
|
|
316
|
+
logger.error(f"Error getting sessions for user {user_id}: {e}", exc_info=True)
|
|
330
317
|
return []
|
|
331
318
|
|
|
332
319
|
async def revoke_session(self, session_id: Any) -> bool:
|
|
@@ -367,9 +354,7 @@ class SessionManager:
|
|
|
367
354
|
logger.error(f"Error revoking session {session_id}: {e}", exc_info=True)
|
|
368
355
|
return False
|
|
369
356
|
|
|
370
|
-
async def revoke_user_sessions(
|
|
371
|
-
self, user_id: str, exclude_device_id: Optional[str] = None
|
|
372
|
-
) -> int:
|
|
357
|
+
async def revoke_user_sessions(self, user_id: str, exclude_device_id: str | None = None) -> int:
|
|
373
358
|
"""
|
|
374
359
|
Revoke all sessions for a user.
|
|
375
360
|
|
|
@@ -400,12 +385,10 @@ class SessionManager:
|
|
|
400
385
|
ValueError,
|
|
401
386
|
TypeError,
|
|
402
387
|
) as e:
|
|
403
|
-
logger.error(
|
|
404
|
-
f"Error revoking sessions for user {user_id}: {e}", exc_info=True
|
|
405
|
-
)
|
|
388
|
+
logger.error(f"Error revoking sessions for user {user_id}: {e}", exc_info=True)
|
|
406
389
|
return 0
|
|
407
390
|
|
|
408
|
-
async def cleanup_inactive_sessions(self, user_id:
|
|
391
|
+
async def cleanup_inactive_sessions(self, user_id: str | None = None) -> int:
|
|
409
392
|
"""
|
|
410
393
|
Clean up inactive sessions (beyond inactivity timeout).
|
|
411
394
|
|