implementation of encryption for the username to avoid any recognission potetioal
This commit is contained in:
@@ -22,8 +22,57 @@ from bson.objectid import ObjectId
|
|||||||
import datetime
|
import datetime
|
||||||
import Web.modules.database.settings as cfg
|
import Web.modules.database.settings as cfg
|
||||||
from Web.modules.database.settings import MongoClient
|
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')
|
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]
|
db = client[cfg.MONGODB_DB]
|
||||||
items = db['items']
|
items = db['items']
|
||||||
|
|
||||||
# 1. Altes Item laden, um SeriesGroupId zu bestimmen
|
|
||||||
old_item = items.find_one({'_id': ObjectId(id)})
|
old_item = items.find_one({'_id': ObjectId(id)})
|
||||||
if not old_item:
|
if not old_item:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
series_group_id = old_item.get('SeriesGroupId')
|
series_group_id = old_item.get('SeriesGroupId')
|
||||||
|
|
||||||
# 2. Shared Data: Daten, die für ALLE in der Gruppe gleich sind
|
|
||||||
shared_update = {
|
shared_update = {
|
||||||
'Name': name,
|
'Name': name,
|
||||||
'Ort': ort,
|
'Ort': ort,
|
||||||
@@ -227,18 +274,15 @@ def update_item(id, name, ort, beschreibung, images, verfuegbar, filter1, filter
|
|||||||
'Reservierbar': reservierbar,
|
'Reservierbar': reservierbar,
|
||||||
'ISBN': isbn,
|
'ISBN': isbn,
|
||||||
'ItemType': item_type,
|
'ItemType': item_type,
|
||||||
'Verfuegbar': verfuegbar, # Wir behalten den Status bei
|
'Verfuegbar': verfuegbar,
|
||||||
'LastUpdated': datetime.datetime.now()
|
'LastUpdated': datetime.datetime.now()
|
||||||
}
|
}
|
||||||
|
|
||||||
# 3. Spezifische Daten: Was NICHT synchronisiert wird
|
|
||||||
specific_update = shared_update.copy()
|
specific_update = shared_update.copy()
|
||||||
specific_update['Code_4'] = code_4
|
specific_update['Code_4'] = code_4
|
||||||
|
|
||||||
# 4. Das aktuelle Item updaten
|
|
||||||
items.update_one({'_id': ObjectId(id)}, {'$set': specific_update})
|
items.update_one({'_id': ObjectId(id)}, {'$set': specific_update})
|
||||||
|
|
||||||
# 5. Alle anderen Gruppen-Mitglieder synchronisieren
|
|
||||||
if series_group_id:
|
if series_group_id:
|
||||||
items.update_many(
|
items.update_many(
|
||||||
{
|
{
|
||||||
@@ -279,7 +323,7 @@ def update_item_status(id, verfuegbar, user=None):
|
|||||||
update_query = {'$set': update_data}
|
update_query = {'$set': update_data}
|
||||||
|
|
||||||
if user is not None:
|
if user is not None:
|
||||||
update_data['User'] = user
|
update_data['User'] = dp.encrypt_text(user)
|
||||||
elif verfuegbar:
|
elif verfuegbar:
|
||||||
# If item is being marked as available, clear the user field
|
# If item is being marked as available, clear the user field
|
||||||
update_query['$unset'] = {'User': ""}
|
update_query['$unset'] = {'User': ""}
|
||||||
@@ -432,29 +476,29 @@ def get_borrowed_items():
|
|||||||
print(f"Error retrieving borrowed items: {e}")
|
print(f"Error retrieving borrowed items: {e}")
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
def get_item(id, decrypt=True):
|
||||||
def get_item(id):
|
|
||||||
"""
|
"""
|
||||||
Retrieve a specific inventory item by its ID.
|
Retrieve an inventory item by ID, with optional decryption.
|
||||||
|
|
||||||
Args:
|
|
||||||
id (str): ID of the item to retrieve
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
dict: The inventory item document or None if not found
|
|
||||||
"""
|
"""
|
||||||
|
item_id = _to_object_id(id)
|
||||||
|
if not item_id:
|
||||||
|
return None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
||||||
db = client[cfg.MONGODB_DB]
|
db = client[cfg.MONGODB_DB]
|
||||||
items = db['items']
|
items = db['items']
|
||||||
item = items.find_one(_active_record_query({'_id': ObjectId(id)}))
|
query = _active_record_query({'_id': item_id})
|
||||||
client.close()
|
item = items.find_one(query)
|
||||||
|
if item:
|
||||||
|
item['_id'] = str(item['_id'])
|
||||||
|
if decrypt:
|
||||||
|
decrypt_item_user_data(item)
|
||||||
return item
|
return item
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error retrieving item: {e}")
|
print(f"Error retrieving item {id}: {e}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def get_item_by_name(name):
|
def get_item_by_name(name):
|
||||||
"""
|
"""
|
||||||
Retrieve a specific inventory item by its 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),
|
'end_date': appointment_data.get('end_date', appointment_date),
|
||||||
'start_period': appointment_data['start_period'],
|
'start_period': appointment_data['start_period'],
|
||||||
'end_period': appointment_data['end_period'],
|
'end_period': appointment_data['end_period'],
|
||||||
'user': appointment_data['user'],
|
'user': dp.encrypt_text(appointment_data['user']),
|
||||||
'notes': appointment_data.get('notes', ''),
|
'notes': appointment_data.get('notes', ''),
|
||||||
'appointment_id': appointment_data['appointment_id'],
|
'appointment_id': appointment_data['appointment_id'],
|
||||||
'scheduled_at': datetime.datetime.now()
|
'scheduled_at': datetime.datetime.now()
|
||||||
@@ -1088,31 +1132,25 @@ def get_items_with_appointments():
|
|||||||
print(f"Error retrieving items with appointments: {e}")
|
print(f"Error retrieving items with appointments: {e}")
|
||||||
return []
|
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.
|
Retrieve the current status of an item, decrypting the user field if present.
|
||||||
|
|
||||||
Args:
|
|
||||||
item_id (str): ID of the item to check
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
dict: Current status of the item or None if not found
|
|
||||||
"""
|
"""
|
||||||
|
oid = _to_object_id(item_id)
|
||||||
|
if not oid:
|
||||||
|
return None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
|
||||||
db = client[cfg.MONGODB_DB]
|
db = client[cfg.MONGODB_DB]
|
||||||
items = db['items']
|
items = db['items']
|
||||||
|
item = items.find_one({'_id': oid}, {'Verfuegbar': 1, 'User': 1})
|
||||||
item = items.find_one({'_id': ObjectId(item_id)}, {'Verfuegbar': 1, 'User': 1})
|
|
||||||
|
|
||||||
if item:
|
if item:
|
||||||
# Convert ObjectId to string for consistency
|
|
||||||
item['_id'] = str(item['_id'])
|
item['_id'] = str(item['_id'])
|
||||||
client.close()
|
if decrypt:
|
||||||
|
decrypt_item_user_data(item)
|
||||||
return item
|
return item
|
||||||
else:
|
return None
|
||||||
client.close()
|
except Exception as e:
|
||||||
return None
|
print(f"Error retrieving current status for item {item_id}: {e}")
|
||||||
except Exception as e:
|
|
||||||
print(f"Error retrieving current status: {e}")
|
|
||||||
return None
|
return None
|
||||||
@@ -20,6 +20,7 @@ import string
|
|||||||
from bson.objectid import ObjectId
|
from bson.objectid import ObjectId
|
||||||
import Web.modules.database.settings as cfg
|
import Web.modules.database.settings as cfg
|
||||||
from Web.modules.database.settings import MongoClient
|
from Web.modules.database.settings import MongoClient
|
||||||
|
import Web.modules.inventarsystem.data_protection as dp
|
||||||
import hmac
|
import hmac
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user