Enhance tenant database access: implement context-aware database retrieval for user operations
This commit is contained in:
@@ -14,6 +14,7 @@ import os
|
|||||||
import json
|
import json
|
||||||
import atexit
|
import atexit
|
||||||
from threading import Lock
|
from threading import Lock
|
||||||
|
from flask import has_request_context
|
||||||
from pymongo import MongoClient as _PyMongoClient
|
from pymongo import MongoClient as _PyMongoClient
|
||||||
|
|
||||||
# Base directory of this Web package
|
# Base directory of this Web package
|
||||||
@@ -250,8 +251,29 @@ class _MongoClientProxy:
|
|||||||
return getattr(self._client, name)
|
return getattr(self._client, name)
|
||||||
|
|
||||||
def __getitem__(self, name):
|
def __getitem__(self, name):
|
||||||
|
if has_request_context():
|
||||||
|
try:
|
||||||
|
from tenant import get_tenant_context
|
||||||
|
ctx = get_tenant_context()
|
||||||
|
if ctx and ctx.db_name:
|
||||||
|
if name == MONGODB_DB or name == MONGODB_DB.lower() or name == 'inventar_default':
|
||||||
|
return self._client[ctx.db_name]
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
return self._client[name]
|
return self._client[name]
|
||||||
|
|
||||||
|
def get_database(self, name=None, *args, **kwargs):
|
||||||
|
if has_request_context():
|
||||||
|
try:
|
||||||
|
from tenant import get_tenant_context
|
||||||
|
ctx = get_tenant_context()
|
||||||
|
if ctx and ctx.db_name:
|
||||||
|
if name is None or name == MONGODB_DB or name == MONGODB_DB.lower() or name == 'inventar_default':
|
||||||
|
return self._client.get_database(ctx.db_name, *args, **kwargs)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return self._client.get_database(name, *args, **kwargs)
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|||||||
+30
-39
@@ -45,6 +45,15 @@ def _clean_name_fragment(value):
|
|||||||
return cleaned
|
return cleaned
|
||||||
|
|
||||||
|
|
||||||
|
def _get_tenant_db(client):
|
||||||
|
"""Return the current tenant database for the request, or fall back to default."""
|
||||||
|
try:
|
||||||
|
from tenant import get_tenant_db
|
||||||
|
return get_tenant_db(client)
|
||||||
|
except Exception:
|
||||||
|
return client[cfg.MONGODB_DB]
|
||||||
|
|
||||||
|
|
||||||
def build_name_synonym(first_name, last_name=''):
|
def build_name_synonym(first_name, last_name=''):
|
||||||
"""Build a deterministic, non-personalized short alias from 2 letters each."""
|
"""Build a deterministic, non-personalized short alias from 2 letters each."""
|
||||||
first = _clean_name_fragment(first_name)
|
first = _clean_name_fragment(first_name)
|
||||||
@@ -303,7 +312,7 @@ def update_user_permissions(username, preset_key, action_permissions=None, page_
|
|||||||
}
|
}
|
||||||
|
|
||||||
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
||||||
db = client[cfg.MONGODB_DB]
|
db = _get_tenant_db(client)
|
||||||
users = db['users']
|
users = db['users']
|
||||||
result = users.update_one({'Username': username}, {'$set': update_data})
|
result = users.update_one({'Username': username}, {'$set': update_data})
|
||||||
|
|
||||||
@@ -318,7 +327,7 @@ def update_user_permissions(username, preset_key, action_permissions=None, page_
|
|||||||
def get_favorites(username):
|
def get_favorites(username):
|
||||||
"""Return a list of favorite item ObjectId strings for the user."""
|
"""Return a list of favorite item ObjectId strings for the user."""
|
||||||
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
||||||
db = client[cfg.MONGODB_DB]
|
db = _get_tenant_db(client)
|
||||||
users = db['users']
|
users = db['users']
|
||||||
user = users.find_one({'Username': username}) or users.find_one({'username': username})
|
user = users.find_one({'Username': username}) or users.find_one({'username': username})
|
||||||
client.close()
|
client.close()
|
||||||
@@ -332,7 +341,7 @@ def add_favorite(username, item_id):
|
|||||||
"""Add an item to user's favorites (idempotent)."""
|
"""Add an item to user's favorites (idempotent)."""
|
||||||
try:
|
try:
|
||||||
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
||||||
db = client[cfg.MONGODB_DB]
|
db = _get_tenant_db(client)
|
||||||
users = db['users']
|
users = db['users']
|
||||||
users.update_one(
|
users.update_one(
|
||||||
{'$or': [{'Username': username}, {'username': username}]},
|
{'$or': [{'Username': username}, {'username': username}]},
|
||||||
@@ -347,7 +356,7 @@ def remove_favorite(username, item_id):
|
|||||||
"""Remove an item from user's favorites."""
|
"""Remove an item from user's favorites."""
|
||||||
try:
|
try:
|
||||||
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
||||||
db = client[cfg.MONGODB_DB]
|
db = _get_tenant_db(client)
|
||||||
users = db['users']
|
users = db['users']
|
||||||
users.update_one(
|
users.update_one(
|
||||||
{'$or': [{'Username': username}, {'username': username}]},
|
{'$or': [{'Username': username}, {'username': username}]},
|
||||||
@@ -430,17 +439,7 @@ def check_nm_pwd(username, password):
|
|||||||
users = db['users']
|
users = db['users']
|
||||||
return users.find_one({'Username': username, 'Password': hashed_password}) or users.find_one({'username': username, 'Password': hashed_password})
|
return users.find_one({'Username': username, 'Password': hashed_password}) or users.find_one({'username': username, 'Password': hashed_password})
|
||||||
|
|
||||||
user = find_user_in_db(db_name)
|
return find_user_in_db(db_name)
|
||||||
if user:
|
|
||||||
return user
|
|
||||||
|
|
||||||
# Fallback: tenant context may not be available yet, so search all tenant databases.
|
|
||||||
for database_name in client.list_database_names():
|
|
||||||
if database_name == db_name or not database_name.startswith('inventar_'):
|
|
||||||
continue
|
|
||||||
user = find_user_in_db(database_name)
|
|
||||||
if user:
|
|
||||||
return user
|
|
||||||
finally:
|
finally:
|
||||||
client.close()
|
client.close()
|
||||||
|
|
||||||
@@ -470,7 +469,7 @@ def add_user(
|
|||||||
bool: True if user was added successfully, False if password was too weak
|
bool: True if user was added successfully, False if password was too weak
|
||||||
"""
|
"""
|
||||||
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
||||||
db = client[cfg.MONGODB_DB]
|
db = _get_tenant_db(client)
|
||||||
users = db['users']
|
users = db['users']
|
||||||
if not check_password_strength(password):
|
if not check_password_strength(password):
|
||||||
return False
|
return False
|
||||||
@@ -520,7 +519,7 @@ def student_card_exists(student_card_id):
|
|||||||
if not normalized:
|
if not normalized:
|
||||||
return False
|
return False
|
||||||
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
||||||
db = client[cfg.MONGODB_DB]
|
db = _get_tenant_db(client)
|
||||||
users = db['users']
|
users = db['users']
|
||||||
exists = users.find_one({'StudentCardId': normalized}) is not None
|
exists = users.find_one({'StudentCardId': normalized}) is not None
|
||||||
client.close()
|
client.close()
|
||||||
@@ -533,7 +532,7 @@ def get_user_by_student_card(student_card_id):
|
|||||||
if not normalized:
|
if not normalized:
|
||||||
return None
|
return None
|
||||||
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
||||||
db = client[cfg.MONGODB_DB]
|
db = _get_tenant_db(client)
|
||||||
users = db['users']
|
users = db['users']
|
||||||
found_user = users.find_one({'StudentCardId': normalized})
|
found_user = users.find_one({'StudentCardId': normalized})
|
||||||
client.close()
|
client.close()
|
||||||
@@ -551,7 +550,7 @@ def make_admin(username):
|
|||||||
bool: True if user was promoted successfully
|
bool: True if user was promoted successfully
|
||||||
"""
|
"""
|
||||||
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
||||||
db = client[cfg.MONGODB_DB]
|
db = _get_tenant_db(client)
|
||||||
users = db['users']
|
users = db['users']
|
||||||
result = users.update_one({'Username': username}, {'$set': {'Admin': True}})
|
result = users.update_one({'Username': username}, {'$set': {'Admin': True}})
|
||||||
if result.matched_count == 0:
|
if result.matched_count == 0:
|
||||||
@@ -570,7 +569,7 @@ def remove_admin(username):
|
|||||||
bool: True if user was demoted successfully
|
bool: True if user was demoted successfully
|
||||||
"""
|
"""
|
||||||
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
||||||
db = client[cfg.MONGODB_DB]
|
db = _get_tenant_db(client)
|
||||||
users = db['users']
|
users = db['users']
|
||||||
result = users.update_one({'Username': username}, {'$set': {'Admin': False}})
|
result = users.update_one({'Username': username}, {'$set': {'Admin': False}})
|
||||||
if result.matched_count == 0:
|
if result.matched_count == 0:
|
||||||
@@ -611,14 +610,6 @@ def get_user(username):
|
|||||||
if user:
|
if user:
|
||||||
return user
|
return user
|
||||||
|
|
||||||
# Last fallback: search all tenant databases if the user belongs to a tenant-specific DB
|
|
||||||
for database_name in client.list_database_names():
|
|
||||||
if database_name == cfg.MONGODB_DB or not database_name.startswith('inventar_'):
|
|
||||||
continue
|
|
||||||
user = find_in_db(database_name)
|
|
||||||
if user:
|
|
||||||
return user
|
|
||||||
|
|
||||||
return None
|
return None
|
||||||
finally:
|
finally:
|
||||||
client.close()
|
client.close()
|
||||||
@@ -651,7 +642,7 @@ def update_active_ausleihung(username, id_item, ausleihung):
|
|||||||
bool: True if successful
|
bool: True if successful
|
||||||
"""
|
"""
|
||||||
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
||||||
db = client[cfg.MONGODB_DB]
|
db = _get_tenant_db(client)
|
||||||
users = db['users']
|
users = db['users']
|
||||||
users.update_one({'Username': username}, {'$set': {'active_ausleihung': {'Item': id_item, 'Ausleihung': ausleihung}}})
|
users.update_one({'Username': username}, {'$set': {'active_ausleihung': {'Item': id_item, 'Ausleihung': ausleihung}}})
|
||||||
client.close()
|
client.close()
|
||||||
@@ -669,7 +660,7 @@ def get_active_ausleihung(username):
|
|||||||
dict: Active borrowing information or None
|
dict: Active borrowing information or None
|
||||||
"""
|
"""
|
||||||
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
||||||
db = client[cfg.MONGODB_DB]
|
db = _get_tenant_db(client)
|
||||||
users = db['users']
|
users = db['users']
|
||||||
user = users.find_one({'Username': username})
|
user = users.find_one({'Username': username})
|
||||||
return user['active_ausleihung']
|
return user['active_ausleihung']
|
||||||
@@ -687,7 +678,7 @@ def has_active_borrowing(username):
|
|||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
||||||
db = client[cfg.MONGODB_DB]
|
db = _get_tenant_db(client)
|
||||||
users = db['users']
|
users = db['users']
|
||||||
|
|
||||||
user = users.find_one({'username': username})
|
user = users.find_one({'username': username})
|
||||||
@@ -718,14 +709,14 @@ def delete_user(username):
|
|||||||
bool: True if user was deleted successfully, False otherwise
|
bool: True if user was deleted successfully, False otherwise
|
||||||
"""
|
"""
|
||||||
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
||||||
db = client[cfg.MONGODB_DB]
|
db = _get_tenant_db(client)
|
||||||
users = db['users']
|
users = db['users']
|
||||||
result = users.delete_one({'username': username})
|
result = users.delete_one({'username': username})
|
||||||
client.close()
|
client.close()
|
||||||
if result.deleted_count == 0:
|
if result.deleted_count == 0:
|
||||||
# Try with different field name
|
# Try with different field name
|
||||||
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
||||||
db = client[cfg.MONGODB_DB]
|
db = _get_tenant_db(client)
|
||||||
users = db['users']
|
users = db['users']
|
||||||
result = users.delete_one({'Username': username})
|
result = users.delete_one({'Username': username})
|
||||||
client.close()
|
client.close()
|
||||||
@@ -747,7 +738,7 @@ def update_active_borrowing(username, item_id, status):
|
|||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
||||||
db = client[cfg.MONGODB_DB]
|
db = _get_tenant_db(client)
|
||||||
users = db['users']
|
users = db['users']
|
||||||
result = users.update_one(
|
result = users.update_one(
|
||||||
{'username': username},
|
{'username': username},
|
||||||
@@ -780,7 +771,7 @@ def get_name(username):
|
|||||||
str: String of name
|
str: String of name
|
||||||
"""
|
"""
|
||||||
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
||||||
db = client[cfg.MONGODB_DB]
|
db = _get_tenant_db(client)
|
||||||
users = db['users']
|
users = db['users']
|
||||||
user = users.find_one({'Username': username})
|
user = users.find_one({'Username': username})
|
||||||
name = user.get("name")
|
name = user.get("name")
|
||||||
@@ -795,7 +786,7 @@ def get_last_name(username):
|
|||||||
str: String of last_name
|
str: String of last_name
|
||||||
"""
|
"""
|
||||||
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
||||||
db = client[cfg.MONGODB_DB]
|
db = _get_tenant_db(client)
|
||||||
users = db['users']
|
users = db['users']
|
||||||
user = users.find_one({'Username': username})
|
user = users.find_one({'Username': username})
|
||||||
name = user.get("last_name")
|
name = user.get("last_name")
|
||||||
@@ -812,7 +803,7 @@ def get_all_users():
|
|||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
||||||
db = client[cfg.MONGODB_DB]
|
db = _get_tenant_db(client)
|
||||||
users = db['users']
|
users = db['users']
|
||||||
all_users = list(users.find())
|
all_users = list(users.find())
|
||||||
client.close()
|
client.close()
|
||||||
@@ -836,7 +827,7 @@ def update_password(username, new_password):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
||||||
db = client[cfg.MONGODB_DB]
|
db = _get_tenant_db(client)
|
||||||
users = db['users']
|
users = db['users']
|
||||||
|
|
||||||
# Hash the new password
|
# Hash the new password
|
||||||
@@ -869,7 +860,7 @@ def update_user_name(username, name, last_name):
|
|||||||
try:
|
try:
|
||||||
name_alias = build_name_synonym(name, last_name)
|
name_alias = build_name_synonym(name, last_name)
|
||||||
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
||||||
db = client[cfg.MONGODB_DB]
|
db = _get_tenant_db(client)
|
||||||
users = db['users']
|
users = db['users']
|
||||||
|
|
||||||
result = users.update_one(
|
result = users.update_one(
|
||||||
|
|||||||
Reference in New Issue
Block a user