changes to the encryption to the users and Items

This commit is contained in:
2026-07-31 15:15:09 +02:00
parent 237788af96
commit 9b12d9a3d0
2 changed files with 593 additions and 1026 deletions
File diff suppressed because it is too large Load Diff
+128 -251
View File
@@ -110,13 +110,6 @@ def build_username_from_name(first_name, last_name=''):
""" """
Build a deterministic username abbreviation from first and last name. Build a deterministic username abbreviation from first and last name.
Uses 3 letters from each name and stores it lowercase. Uses 3 letters from each name and stores it lowercase.
Args:
first_name (str): First name
last_name (str): Last name (optional)
Returns:
str: Generated username
""" """
alias = build_name_synonym(first_name, last_name) alias = build_name_synonym(first_name, last_name)
return alias.lower() return alias.lower()
@@ -325,7 +318,6 @@ def get_effective_permissions(username):
return build_default_permission_payload('full_access') return build_default_permission_payload('full_access')
preset_key = user.get('PermissionPreset') preset_key = user.get('PermissionPreset')
print(preset_key)
payload = build_default_permission_payload(preset_key) payload = build_default_permission_payload(preset_key)
payload['actions'] = _normalize_bool_map(user.get('ActionPermissions', {}), payload['actions']) payload['actions'] = _normalize_bool_map(user.get('ActionPermissions', {}), payload['actions'])
payload['pages'] = _normalize_bool_map(user.get('PagePermissions', {}), payload['pages']) payload['pages'] = _normalize_bool_map(user.get('PagePermissions', {}), payload['pages'])
@@ -353,10 +345,10 @@ 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 = _get_tenant_db(client) 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': dp.encrypt_text(username)}, {'$set': update_data})
if result.matched_count == 0: if result.matched_count == 0:
result = users.update_one({'username': username}, {'$set': update_data}) result = users.update_one({'username': dp.encrypt_text(username)}, {'$set': update_data})
client.close() client.close()
return result.matched_count > 0 return result.matched_count > 0
@@ -368,7 +360,7 @@ def get_favorites(username):
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = _get_tenant_db(client) 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': dp.encrypt_text(username)}) or users.find_one({'username': dp.encrypt_text(username)})
client.close() client.close()
if not user: if not user:
return [] return []
@@ -383,7 +375,7 @@ def add_favorite(username, item_id):
db = _get_tenant_db(client) db = _get_tenant_db(client)
users = db['users'] users = db['users']
users.update_one( users.update_one(
{'$or': [{'Username': username}, {'username': username}]}, {'$or': [{'Username': dp.encrypt_text(username)}, {'username': dp.encrypt_text(username)}]},
{'$addToSet': {'favorites': ObjectId(item_id)}} {'$addToSet': {'favorites': ObjectId(item_id)}}
) )
client.close() client.close()
@@ -398,7 +390,7 @@ def remove_favorite(username, item_id):
db = _get_tenant_db(client) db = _get_tenant_db(client)
users = db['users'] users = db['users']
users.update_one( users.update_one(
{'$or': [{'Username': username}, {'username': username}]}, {'$or': [{'Username': dp.encrypt_text(username)}, {'username': dp.encrypt_text(username)}]},
{'$pull': {'favorites': ObjectId(item_id)}} {'$pull': {'favorites': ObjectId(item_id)}}
) )
client.close() client.close()
@@ -407,16 +399,9 @@ def remove_favorite(username, item_id):
return False return False
def check_password_strength(password): def check_password_strength(password):
""" """
Check if a password meets minimum security requirements. Check if a password meets minimum security requirements.
Args:
password (str): Password to check
Returns:
bool: True if password is strong enough, False otherwise
""" """
if password is None: if password is None:
return False return False
@@ -436,19 +421,15 @@ def check_password_strength(password):
def hashing(password, salt=None): def hashing(password, salt=None):
""" """
Hasht ein Passwort mit scrypt. Hasht ein Passwort mit scrypt.
- Wenn kein Salt übergeben wird, wird ein sicherer, zufälliger Salt generiert (für neue Passwörter).
- Format für neue Hashes: v1$<salt_hex>$<hash_hex>
""" """
password_bytes = password.encode('utf-8') # Explizit UTF-8 für Plattformunabhängigkeit password_bytes = password.encode('utf-8')
if salt is None: if salt is None:
# Neuer Benutzer / Passwortänderung -> Dynamischer Salt
random_salt = os.urandom(16) random_salt = os.urandom(16)
hashed = hashlib.scrypt(password_bytes, salt=random_salt, n=16384, r=8, p=1) hashed = hashlib.scrypt(password_bytes, salt=random_salt, n=16384, r=8, p=1)
return f"v1${random_salt.hex()}${hashed.hex()}" return f"v1${random_salt.hex()}${hashed.hex()}"
else: else:
# Bestehender Benutzer (wird zur Verifizierung aufgerufen)
hashed = hashlib.scrypt(password_bytes, salt=salt, n=16384, r=8, p=1) hashed = hashlib.scrypt(password_bytes, salt=salt, n=16384, r=8, p=1)
return hashed.hex() return hashed.hex()
@@ -456,25 +437,20 @@ def hashing(password, salt=None):
def verify_password(provided_password, stored_password_string): def verify_password(provided_password, stored_password_string):
""" """
Verifiziert ein Passwort gegen einen gespeicherten Hash-String. Verifiziert ein Passwort gegen einen gespeicherten Hash-String.
Unterstützt das alte Format (statischer Salt) und das neue Format (v1$...).
""" """
if not stored_password_string: if not stored_password_string:
return False return False
# Überprüfung für das neue, sichere Format
if stored_password_string.startswith("v1$"): if stored_password_string.startswith("v1$"):
try: try:
_, salt_hex, hash_hex = stored_password_string.split("$") _, salt_hex, hash_hex = stored_password_string.split("$")
salt_bytes = bytes.fromhex(salt_hex) salt_bytes = bytes.fromhex(salt_hex)
# Berechne den Hash des eingegebenen Passworts mit dem extrahierten Salt
calculated_hash = hashing(provided_password, salt=salt_bytes) calculated_hash = hashing(provided_password, salt=salt_bytes)
# Timing-Attack-sicherer Vergleich
return hmac.compare_digest(calculated_hash, hash_hex) return hmac.compare_digest(calculated_hash, hash_hex)
except (ValueError, TypeError): except (ValueError, TypeError):
logger.error("Ungültiges Hash-Format in der Datenbank entdeckt.") logger.error("Ungültiges Hash-Format in der Datenbank entdeckt.")
return False return False
else: else:
# Abwärtskompatibilität: Altes Format mit statischem Salt b'some_salt'
old_static_salt = b'some_salt' old_static_salt = b'some_salt'
calculated_hash = hashing(provided_password, salt=old_static_salt) calculated_hash = hashing(provided_password, salt=old_static_salt)
return hmac.compare_digest(calculated_hash, stored_password_string) return hmac.compare_digest(calculated_hash, stored_password_string)
@@ -495,22 +471,21 @@ def check_nm_pwd(username, password):
try: try:
db = client[db_name] db = client[db_name]
users = db['users'] users = db['users']
query = {'$or': [{'Username': username}, {'username': username}]} query = {'$or': [{'Username': dp.encrypt_text(username)}, {'username': dp.encrypt_text(username)}]}
user_record = users.find_one(query) user_record = users.find_one(query)
if user_record is None: if user_record is None:
logger.warning("Kein Benutzer für %r in DB %r gefunden.", username, db_name) logger.warning("Kein Benutzer für %r in DB %r gefunden.", dp.encrypt_text(username), db_name)
return None return None
stored_password = user_record.get('Password') or user_record.get('password') stored_password = user_record.get('Password') or user_record.get('password')
if not verify_password(password, stored_password): if not verify_password(password, stored_password):
logger.warning("Falsches Passwort für Benutzer %r in DB %r.", username, db_name) logger.warning("Falsches Passwort für Benutzer %r in DB %r.", dp.encrypt_text(username), db_name)
return None return None
# Automatische Migration alter Hashes auf das neue Format if stored_password and not stored_password.startswith("v1$"):
if not stored_password.startswith("v1$"):
users.update_one({'_id': user_record['_id']}, {'$set': {'Password': hashing(password)}}) users.update_one({'_id': user_record['_id']}, {'$set': {'Password': hashing(password)}})
return user_record return user_record
@@ -532,40 +507,35 @@ def add_user(
): ):
""" """
Add a new user to the database. Add a new user to the database.
Args:
username (str): Username for the new user
password (str): Password for the new user
Returns:
bool: True if user was added successfully, False if password was too weak
""" """
if not check_password_strength(password):
return False
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
try: try:
db = _get_tenant_db(client) db = _get_tenant_db(client)
users = db['users'] users = db['users']
if not check_password_strength(password):
return False
permission_defaults = build_default_permission_payload(permission_preset) permission_defaults = build_default_permission_payload(permission_preset)
if isinstance(action_permissions, dict): if isinstance(action_permissions, dict):
for key, value in action_permissions.items(): for key, value in action_permissions.items():
permission_defaults['actions'][str(key)] = bool(value) permission_defaults['actions'][str(key)] = bool(value)
if isinstance(page_permissions, dict): if isinstance(page_permissions, dict):
for key, value in page_permissions.items(): for key, value in page_permissions.items():
permission_defaults['pages'][str(key)] = bool(value) permission_defaults['pages'][str(key)] = bool(value)
if permission_preset == "full_access": safe_name = name.strip() if name else ''
can_admin_preset_based = True safe_last_name = last_name.strip() if last_name else ''
else:
can_admin_preset_based = False
user_doc = { user_doc = {
'Username': username, 'Username': dp.encrypt_text(username),
'Password': hashing(password), 'Password': hashing(password),
'Admin': can_admin_preset_based, 'Admin': (permission_preset == "full_access"),
'active_ausleihung': None, 'active_ausleihung': None,
'name': name.strip() if name else '', 'name': dp.encrypt_text(safe_name) if safe_name else '',
'last_name': last_name.strip() if last_name else '', 'last_name': dp.encrypt_text(safe_last_name) if safe_last_name else '',
'IsStudent': bool(is_student), 'IsStudent': bool(is_student),
'PermissionPreset': permission_defaults['preset'], 'PermissionPreset': permission_defaults['preset'],
'ActionPermissions': permission_defaults['actions'], 'ActionPermissions': permission_defaults['actions'],
@@ -602,7 +572,7 @@ def student_card_exists(student_card_id):
def get_user_by_student_card(student_card_id): def get_user_by_student_card(student_card_id):
"""Return user by student card id or None.""" """Return user dict by student card id or None."""
normalized = normalize_student_card_id(student_card_id) normalized = normalize_student_card_id(student_card_id)
if not normalized: if not normalized:
return None return None
@@ -611,65 +581,44 @@ def get_user_by_student_card(student_card_id):
users = db['student_cards'] users = db['student_cards']
found_user = users.find_one({'SchülerName': normalized}) found_user = users.find_one({'SchülerName': normalized})
client.close() client.close()
# Do not call dp.decrypt_text() here because found_user is a MongoDB dictionary.
return found_user return found_user
def make_admin(username): def make_admin(username):
""" """Grant administrator privileges to a user."""
Grant administrator privileges to a user.
Args:
username (str): Username of the user to promote
Returns:
bool: True if user was promoted successfully
"""
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = _get_tenant_db(client) 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': dp.encrypt_text(username)}, {'$set': {'Admin': True}})
if result.matched_count == 0: if result.matched_count == 0:
result = users.update_one({'username': username}, {'$set': {'Admin': True}}) result = users.update_one({'username': dp.encrypt_text(username)}, {'$set': {'Admin': True}})
client.close() client.close()
return result.matched_count > 0 return result.matched_count > 0
def remove_admin(username): def remove_admin(username):
""" """Remove administrator privileges from a user."""
Remove administrator privileges from a user.
Args:
username (str): Username of the user to demote
Returns:
bool: True if user was demoted successfully
"""
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = _get_tenant_db(client) 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': dp.encrypt_text(username)}, {'$set': {'Admin': False}})
if result.matched_count == 0: if result.matched_count == 0:
result = users.update_one({'username': username}, {'$set': {'Admin': False}}) result = users.update_one({'username': dp.encrypt_text(username)}, {'$set': {'Admin': False}})
client.close() client.close()
return result.matched_count > 0 return result.matched_count > 0
def get_user(username): def get_user(username):
""" """Retrieve a specific user by username."""
Retrieve a specific user by username.
Args:
username (str): Username to search for
Returns:
dict: User document or None if not found
"""
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
try: try:
def find_in_db(database_name): def find_in_db(database_name):
db = client[database_name] db = client[database_name]
users = db['users'] users = db['users']
return users.find_one({'Username': username}) or users.find_one({'username': username}) return users.find_one({'Username': dp.encrypt_text(username)}) or users.find_one({'username': dp.encrypt_text(username)})
# Try current tenant first when available
tenant_db, tenant_id = _resolve_request_tenant_db() tenant_db, tenant_id = _resolve_request_tenant_db()
if tenant_db: if tenant_db:
user = find_in_db(tenant_db) user = find_in_db(tenant_db)
@@ -682,7 +631,6 @@ def get_user(username):
) )
return None return None
# Fallback to default configured database
user = find_in_db(cfg.MONGODB_DB) user = find_in_db(cfg.MONGODB_DB)
if user: if user:
return user return user
@@ -693,147 +641,89 @@ def get_user(username):
def check_admin(username): def check_admin(username):
""" """Check if a user has administrator privileges."""
Check if a user has administrator privileges.
Args:
username (str): Username to check
Returns:
bool: True if user is an administrator, False otherwise
"""
user = get_user(username) user = get_user(username)
return bool(user and user.get('Admin', False)) return bool(user and user.get('Admin', False))
def update_active_ausleihung(username, id_item, ausleihung): def update_active_ausleihung(username, id_item, ausleihung):
""" """Update a user's active borrowing record."""
Update a user's active borrowing record.
Args:
username (str): Username of the user
id_item (str): ID of the borrowed item
ausleihung (str): ID of the borrowing record
Returns:
bool: True if successful
"""
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = _get_tenant_db(client) db = _get_tenant_db(client)
users = db['users'] users = db['users']
users.update_one({'Username': username}, {'$set': {'active_ausleihung': {'Item': id_item, 'Ausleihung': ausleihung}}})
result = users.update_one(
{'Username': dp.encrypt_text(username)},
{'$set': {'active_ausleihung': {'Item': id_item, 'Ausleihung': ausleihung}}}
)
if result.matched_count == 0:
users.update_one(
{'username': dp.encrypt_text(username)},
{'$set': {'active_ausleihung': {'Item': id_item, 'Ausleihung': ausleihung}}}
)
client.close() client.close()
return True return True
def get_active_ausleihung(username): def get_active_ausleihung(username):
""" """Get a user's active borrowing record."""
Get a user's active borrowing record.
Args:
username (str): Username of the user
Returns:
dict: Active borrowing information or None
"""
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = _get_tenant_db(client) db = _get_tenant_db(client)
users = db['users'] users = db['users']
user = users.find_one({'Username': username})
return user['active_ausleihung'] user = users.find_one({'Username': dp.encrypt_text(username)}) or users.find_one({'username': dp.encrypt_text(username)})
client.close()
if not user:
return None
return user.get('active_ausleihung')
def has_active_borrowing(username): def has_active_borrowing(username):
""" """Check if a user currently has an active borrowing."""
Check if a user currently has an active borrowing.
Args:
username (str): Username to check
Returns:
bool: True if user has an active borrowing, False otherwise
"""
try: try:
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = _get_tenant_db(client) db = _get_tenant_db(client)
users = db['users'] users = db['users']
user = users.find_one({'username': username}) user = users.find_one({'username': dp.encrypt_text(username)}) or users.find_one({'Username': dp.encrypt_text(username)})
if not user:
user = users.find_one({'Username': username})
if not user:
client.close()
return False
has_active = user.get('active_borrowing', False)
client.close() client.close()
return has_active
if not user:
return False
return user.get('active_borrowing', False)
except Exception as e: except Exception as e:
return False return False
def delete_user(username): def delete_user(username):
""" """Delete a user from the database."""
Delete a user from the database.
Administrative function for removing user accounts.
Args:
username (str): Username of the account to delete
Returns:
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 = _get_tenant_db(client) db = _get_tenant_db(client)
users = db['users'] users = db['users']
result = users.delete_one({'username': username})
client.close() result = users.delete_one({'username': dp.encrypt_text(username)})
if result.deleted_count == 0: if result.deleted_count == 0:
# Try with different field name result = users.delete_one({'Username': dp.encrypt_text(username)})
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = _get_tenant_db(client) client.close()
users = db['users']
result = users.delete_one({'Username': username})
client.close()
return result.deleted_count > 0 return result.deleted_count > 0
def update_active_borrowing(username, item_id, status): def update_active_borrowing(username, item_id, status):
""" """Update a user's active borrowing status."""
Update a user's active borrowing status.
Args:
username (str): Username of the user
item_id (str): ID of the borrowed item or None if returning
status (bool): True if borrowing, False if returning
Returns:
bool: True if successful, False on error
"""
try: try:
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = _get_tenant_db(client) db = _get_tenant_db(client)
users = db['users'] users = db['users']
result = users.update_one(
{'username': username}, update_data = {'$set': {'active_borrowing': status, 'borrowed_item': item_id if status else None}}
{'$set': {
'active_borrowing': status, result = users.update_one({'username': dp.encrypt_text(username)}, update_data)
'borrowed_item': item_id if status else None
}}
)
if result.matched_count == 0: if result.matched_count == 0:
result = users.update_one( result = users.update_one({'Username': dp.encrypt_text(username)}, update_data)
{'Username': username},
{'$set': {
'active_borrowing': status,
'borrowed_item': item_id if status else None
}}
)
client.close() client.close()
return result.modified_count > 0 return result.modified_count > 0
except Exception as e: except Exception as e:
@@ -841,43 +731,37 @@ def update_active_borrowing(username, item_id, status):
def get_name(username): def get_name(username):
""" """Retrieve the name that is associated with the username."""
Retrieve the name that is assosiated with the username.
Returns:
str: String of name
"""
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = _get_tenant_db(client) db = _get_tenant_db(client)
users = db['users'] users = db['users']
user = users.find_one({'Username': username})
name = user.get("name") user = users.find_one({'Username': dp.encrypt_text(username)}) or users.find_one({'username': dp.encrypt_text(username)})
return name client.close()
if not user or not user.get("name"):
return ""
return dp.decrypt_text(user.get("name"))
def get_last_name(username): def get_last_name(username):
""" """Retrieve the last_name that is associated with the username."""
Retrieve the last_name that is assosiated with the username.
Returns:
str: String of last_name
"""
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = _get_tenant_db(client) db = _get_tenant_db(client)
users = db['users'] users = db['users']
user = users.find_one({'Username': username})
name = user.get("last_name") user = users.find_one({'Username': dp.encrypt_text(username)}) or users.find_one({'username': dp.encrypt_text(username)})
return name client.close()
if not user or not user.get("last_name"):
return ""
return dp.decrypt_text(user.get("last_name"))
def get_all_users(): def get_all_users():
""" """Retrieve all users from the database."""
Retrieve all users from the database.
Administrative function for user management.
Returns:
list: List of all user documents
"""
try: try:
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = _get_tenant_db(client) db = _get_tenant_db(client)
@@ -888,65 +772,58 @@ def get_all_users():
except Exception as e: except Exception as e:
return [] return []
def update_password(username, new_password): def update_password(username, new_password):
""" """Update a user's password with a new one."""
Update a user's password with a new one.
Args:
username (str): Username of the user
new_password (str): New password to set
Returns:
bool: True if password was updated successfully, False otherwise
"""
try: try:
if not check_password_strength(new_password): if not check_password_strength(new_password):
return False return False
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db = _get_tenant_db(client) db = _get_tenant_db(client)
users = db['users'] users = db['users']
# Hash the new password
hashed_password = hashing(new_password) hashed_password = hashing(new_password)
# Update the user's password
result = users.update_one( result = users.update_one(
{'Username': username}, {'Username': dp.encrypt_text(username)},
{'$set': {'Password': hashed_password}} {'$set': {'Password': hashed_password}}
) )
if result.matched_count == 0:
result = users.update_one(
{'username': dp.encrypt_text(username)},
{'$set': {'Password': hashed_password}}
)
client.close() client.close()
return result.modified_count > 0 return result.modified_count > 0
except Exception as e: except Exception as e:
print(f"Error updating password: {e}") print(f"Error updating password: {e}")
return False return False
def update_user_name(username, name, last_name): def update_user_name(username, name, last_name):
""" """Update a user's name and last name."""
Update a user's name and last name.
Args:
username (str): Username of the user
name (str): New first name
last_name (str): New last name
Returns:
bool: True if updated successfully, False otherwise
"""
try: try:
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 = _get_tenant_db(client) db = _get_tenant_db(client)
users = db['users'] users = db['users']
safe_name = dp.encrypt_text(name.strip()) if name else ''
safe_last_name = dp.encrypt_text(last_name.strip()) if last_name else ''
result = users.update_one( result = users.update_one(
{'Username': username}, {'Username': dp.encrypt_text(username)},
{'$set': {'name': name_alias, 'last_name': ''}} {'$set': {'name': safe_name, 'last_name': safe_last_name}}
) )
if result.matched_count == 0:
result = users.update_one(
{'username': dp.encrypt_text(username)},
{'$set': {'name': safe_name, 'last_name': safe_last_name}}
)
client.close() client.close()
return True return True
except Exception as e: except Exception as e:
print(f"Error updating user name: {e}") print(f"Error updating user name: {e}")
return False return False