From 237788af96b790cb14a8f5bcc5d3d722e492c0fb Mon Sep 17 00:00:00 2001 From: Aiirondev Date: Fri, 31 Jul 2026 13:12:46 +0200 Subject: [PATCH] implementation of encryption for the username to avoid any recognission potetioal --- Web/modules/database/items.py | 116 ++++++++++++++++++++++------------ Web/modules/database/user.py | 1 + 2 files changed, 78 insertions(+), 39 deletions(-) diff --git a/Web/modules/database/items.py b/Web/modules/database/items.py index a4e8bc5..6288ab6 100755 --- a/Web/modules/database/items.py +++ b/Web/modules/database/items.py @@ -22,8 +22,57 @@ from bson.objectid import ObjectId import datetime import Web.modules.database.settings as cfg from Web.modules.database.settings import MongoClient +import Web.modules.inventarsystem.data_protection as dp +def safe_decrypt_user(encrypted_user): + """ + Safely decrypt an encrypted username string. + + Returns the original string if decryption fails or if input is empty/None. + """ + if not encrypted_user: + return encrypted_user + + try: + return dp.decrypt_text(encrypted_user) + except Exception as e: + print(f"Error decrypting user data: {e}") + # Return fallback value or None to prevent downstream crashes + return "[Decryption Failed]" + + +def decrypt_item_user_data(item): + """ + Decrypts encrypted user fields within an inventory item document in-place. + + Args: + item (dict): MongoDB document representing an item. + + Returns: + dict: The item with decrypted user fields. + """ + if not item: + return item + + # 1. Decrypt top-level 'User' field if present + if 'User' in item and item['User']: + item['User'] = safe_decrypt_user(item['User']) + + # 2. Decrypt nested 'user' field in 'NextAppointment' if present + if 'NextAppointment' in item and isinstance(item['NextAppointment'], dict): + if 'user' in item['NextAppointment']: + item['NextAppointment']['user'] = safe_decrypt_user(item['NextAppointment']['user']) + + return item + +def _to_object_id(id_str): + """Safely convert a string to ObjectId.""" + try: + return ObjectId(id_str) + except (InvalidId, TypeError): + return None + LIBRARY_ITEM_TYPES = ('book', 'cd', 'dvd', 'other', 'schoolbook', 'Buch', 'Schulbuch', 'schulbuch') @@ -206,14 +255,12 @@ def update_item(id, name, ort, beschreibung, images, verfuegbar, filter1, filter db = client[cfg.MONGODB_DB] items = db['items'] - # 1. Altes Item laden, um SeriesGroupId zu bestimmen old_item = items.find_one({'_id': ObjectId(id)}) if not old_item: return False series_group_id = old_item.get('SeriesGroupId') - # 2. Shared Data: Daten, die für ALLE in der Gruppe gleich sind shared_update = { 'Name': name, 'Ort': ort, @@ -227,18 +274,15 @@ def update_item(id, name, ort, beschreibung, images, verfuegbar, filter1, filter 'Reservierbar': reservierbar, 'ISBN': isbn, 'ItemType': item_type, - 'Verfuegbar': verfuegbar, # Wir behalten den Status bei + 'Verfuegbar': verfuegbar, 'LastUpdated': datetime.datetime.now() } - # 3. Spezifische Daten: Was NICHT synchronisiert wird specific_update = shared_update.copy() specific_update['Code_4'] = code_4 - # 4. Das aktuelle Item updaten items.update_one({'_id': ObjectId(id)}, {'$set': specific_update}) - # 5. Alle anderen Gruppen-Mitglieder synchronisieren if series_group_id: items.update_many( { @@ -279,7 +323,7 @@ def update_item_status(id, verfuegbar, user=None): update_query = {'$set': update_data} if user is not None: - update_data['User'] = user + update_data['User'] = dp.encrypt_text(user) elif verfuegbar: # If item is being marked as available, clear the user field update_query['$unset'] = {'User': ""} @@ -432,29 +476,29 @@ def get_borrowed_items(): print(f"Error retrieving borrowed items: {e}") return [] +def get_item(id, decrypt=True): + """ + Retrieve an inventory item by ID, with optional decryption. + """ + item_id = _to_object_id(id) + if not item_id: + return None -def get_item(id): - """ - Retrieve a specific inventory item by its ID. - - Args: - id (str): ID of the item to retrieve - - Returns: - dict: The inventory item document or None if not found - """ try: client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) db = client[cfg.MONGODB_DB] items = db['items'] - item = items.find_one(_active_record_query({'_id': ObjectId(id)})) - client.close() + query = _active_record_query({'_id': item_id}) + item = items.find_one(query) + if item: + item['_id'] = str(item['_id']) + if decrypt: + decrypt_item_user_data(item) return item except Exception as e: - print(f"Error retrieving item: {e}") + print(f"Error retrieving item {id}: {e}") return None - def get_item_by_name(name): """ Retrieve a specific inventory item by its name. @@ -1015,7 +1059,7 @@ def update_item_next_appointment(item_id, appointment_data): 'end_date': appointment_data.get('end_date', appointment_date), 'start_period': appointment_data['start_period'], 'end_period': appointment_data['end_period'], - 'user': appointment_data['user'], + 'user': dp.encrypt_text(appointment_data['user']), 'notes': appointment_data.get('notes', ''), 'appointment_id': appointment_data['appointment_id'], 'scheduled_at': datetime.datetime.now() @@ -1088,31 +1132,25 @@ def get_items_with_appointments(): print(f"Error retrieving items with appointments: {e}") return [] -def get_current_status(item_id): +def get_current_status(item_id, decrypt=True): """ - Retrieve the current status of an item, including availability and user. - - Args: - item_id (str): ID of the item to check - - Returns: - dict: Current status of the item or None if not found + Retrieve the current status of an item, decrypting the user field if present. """ + oid = _to_object_id(item_id) + if not oid: + return None + try: client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) db = client[cfg.MONGODB_DB] items = db['items'] - - item = items.find_one({'_id': ObjectId(item_id)}, {'Verfuegbar': 1, 'User': 1}) - + item = items.find_one({'_id': oid}, {'Verfuegbar': 1, 'User': 1}) if item: - # Convert ObjectId to string for consistency item['_id'] = str(item['_id']) - client.close() + if decrypt: + decrypt_item_user_data(item) return item - else: - client.close() - return None + return None except Exception as e: - print(f"Error retrieving current status: {e}") + print(f"Error retrieving current status for item {item_id}: {e}") return None \ No newline at end of file diff --git a/Web/modules/database/user.py b/Web/modules/database/user.py index 27e6f60..ad857e0 100755 --- a/Web/modules/database/user.py +++ b/Web/modules/database/user.py @@ -20,6 +20,7 @@ import string from bson.objectid import ObjectId import Web.modules.database.settings as cfg from Web.modules.database.settings import MongoClient +import Web.modules.inventarsystem.data_protection as dp import hmac import os