From a9af17c7ce67016e19b818dc24db3fdcf96ec5cb Mon Sep 17 00:00:00 2001 From: Aiirondev Date: Sat, 25 Jul 2026 20:15:55 +0200 Subject: [PATCH] Changes to the page permissions and action permissions to replace the old is_admin system --- Web/app.py | 373 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 258 insertions(+), 115 deletions(-) diff --git a/Web/app.py b/Web/app.py index d73c32a..2cb563c 100755 --- a/Web/app.py +++ b/Web/app.py @@ -1980,9 +1980,11 @@ def _upload_student_cards_excel(): flash('Nicht angemeldet.', 'error') return redirect(url_for('login')) - if not us.check_admin(session['username']): - flash('Administratorrechte erforderlich.', 'error') - return redirect(url_for('home_admin')) + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['actions'].get('can_manage_user', False): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error') + return redirect(url_for('library')) if not cfg.MODULES.is_enabled('student_cards'): flash('Schülerausweis-Modul ist deaktiviert.', 'error') @@ -2852,20 +2854,18 @@ def test_connection(): Returns: dict: Status information including version and status code """ - if 'username' not in session or not us.check_admin(session['username']): - return {'status': 'forbidden'}, 403 return {'status': 'success', 'message': 'Connection successful', 'status_code': 200} - +""" if sucess in deployment the funktion can be removed @app.route('/user_status') def user_status(): - """ + API endpoint to get the current user's status (username, admin status). Used by JavaScript in templates to personalize the UI. Returns: JSON: User status information or error if not authenticated - """ + if 'username' in session: is_admin = us.check_admin(session['username']) return jsonify({ @@ -2878,8 +2878,10 @@ def user_status(): 'authenticated': False, 'error': 'Not logged in' }), 401 +""" +##################################################### changes to be made to account for the new account permison managment system ############################## @app.route('/') def home(): """ @@ -2981,7 +2983,6 @@ def library_export_excel(scope='all'): return redirect(url_for('login')) username = session['username'] - is_admin_user = us.check_admin(username) # Base query query = { @@ -2996,8 +2997,10 @@ def library_export_excel(scope='all'): filename = f"Bibliothek_Ausgeliehen_{username}.xlsx" elif scope == 'all_borrowed': - if not is_admin_user: - # Consider adding a flash message here before redirecting + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['actions'].get('can_view_logs', False): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error') return redirect('/library') query['Verfuegbar'] = False filename = "Bibliothek_Alle_Ausleihen.xlsx" @@ -3055,7 +3058,7 @@ def library_view(): 'library_table.html', username=session['username'], library_module_enabled=cfg.MODULES.is_enabled('library'), - is_admin=us.check_admin(session['username']), + is_admin=us.check_admin(session['username']), # consider if this is needet student_cards_module_enabled=cfg.MODULES.is_enabled('student_cards'), student_default_borrow_days=cfg.STUDENT_DEFAULT_BORROW_DAYS, student_max_borrow_days=cfg.STUDENT_MAX_BORROW_DAYS @@ -3493,7 +3496,9 @@ def api_library_scan_action(): # Toggle back: item is currently borrowed -> return current_borrower = str(item_doc.get('User') or '').strip() - if current_borrower and current_borrower != borrower_name and not us.check_admin(session['username']): + current_permissions = us.get_effective_permissions(session['username']) + + if current_borrower and current_borrower != borrower_name and not current_permissions['actions'].get('can_edit', False): return jsonify({ 'ok': False, 'message': f"Medium ist aktuell an '{current_borrower}' ausgeliehen und kann mit diesem Ausweis nicht zurückgegeben werden." @@ -3666,8 +3671,11 @@ def api_library_item_update(item_id): """Admin-only API to edit library item core fields from the library table view.""" if 'username' not in session: return jsonify({'ok': False, 'message': 'Nicht angemeldet.'}), 401 - if not us.check_admin(session['username']): - return jsonify({'ok': False, 'message': 'Administratorrechte erforderlich.'}), 403 + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['actions'].get('can_edit', False): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error') + return redirect(url_for('library')) if not cfg.MODULES.is_enabled('library'): return jsonify({'ok': False, 'message': 'Bibliotheks-Modul ist deaktiviert.'}), 403 @@ -3896,9 +3904,11 @@ def student_cards_admin(): if 'username' not in session: flash('Ihnen ist es nicht gestattet auf dieser Internetanwendung, die eben besuchte Adrrese zu nutzen, versuchen sie es erneut nach dem sie sich mit einem berechtigten Nutzer angemeldet haben!', 'error') return redirect(url_for('login')) - if not us.check_admin(session['username']): - flash('Ihnen ist es nicht gestattet auf dieser Internetanwendung, die eben besuchte Adrrese zu nutzen, versuchen sie es erneut nach dem sie sich mit einem berechtigten Nutzer angemeldet haben!', 'error') - return redirect(url_for('login')) + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['actions'].get('can_manage_users', False): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error') + return redirect(url_for('library')) if not cfg.MODULES.is_enabled('student_cards'): flash('Schülerausweis-Modul ist deaktiviert.', 'error') return redirect(url_for('home_admin')) @@ -4039,9 +4049,11 @@ def student_cards_print(): if 'username' not in session: flash('Ihnen ist es nicht gestattet auf dieser Internetanwendung, die eben besuchte Adrrese zu nutzen, versuchen sie es erneut nach dem sie sich mit einem berechtigten Nutzer angemeldet haben!', 'error') return redirect(url_for('login')) - if not us.check_admin(session['username']): - flash('Ihnen ist es nicht gestattet auf dieser Internetanwendung, die eben besuchte Adrrese zu nutzen, versuchen sie es erneut nach dem sie sich mit einem berechtigten Nutzer angemeldet haben!', 'error') - return redirect(url_for('login')) + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['actions'].get('can_manage_users', False): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error') + return redirect(url_for('library')) if not cfg.MODULES.is_enabled('student_cards'): flash('Schülerausweis-Modul ist deaktiviert.', 'error') return redirect(url_for('home_admin')) @@ -4071,9 +4083,11 @@ def student_card_barcode_print(): if 'username' not in session: flash('Ihnen ist es nicht gestattet auf dieser Internetanwendung, die eben besuchte Adrrese zu nutzen, versuchen sie es erneut nach dem sie sich mit einem berechtigten Nutzer angemeldet haben!', 'error') return redirect(url_for('login')) - if not us.check_admin(session['username']): - flash('Ihnen ist es nicht gestattet auf dieser Internetanwendung, die eben besuchte Adrrese zu nutzen, versuchen sie es erneut nach dem sie sich mit einem berechtigten Nutzer angemeldet haben!', 'error') - return redirect(url_for('login')) + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['actions'].get('can_manage_users', False): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error') + return redirect(url_for('library')) if not cfg.MODULES.is_enabled('student_cards'): flash('Schülerausweis-Modul ist deaktiviert.', 'error') return redirect(url_for('home_admin')) @@ -4102,9 +4116,11 @@ def student_card_barcode_download(): """ if 'username' not in session: return redirect(url_for('login')) - if not us.check_admin(session['username']): - flash('Zugriff verweigert.', 'error') - return redirect(url_for('login')) + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['actions'].get('can_manage_users', False): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error') + return redirect(url_for('library')) if not cfg.MODULES.is_enabled('student_cards'): flash('Schülerausweis-Modul ist deaktiviert.', 'error') return redirect(url_for('home_admin')) @@ -4284,9 +4300,11 @@ def student_card_single_barcode_download(card_id): """ if 'username' not in session: return redirect(url_for('login')) - if not us.check_admin(session['username']): - flash('Zugriff verweigert.', 'error') - return redirect(url_for('login')) + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['actions'].get('can_manage_users', False): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error') + return redirect(url_for('library')) if not cfg.MODULES.is_enabled('student_cards'): flash('Schülerausweis-Modul ist deaktiviert.', 'error') return redirect(url_for('home_admin')) @@ -4981,13 +4999,14 @@ def api_booking_conflicts(): if 'username' not in session: return jsonify({'error': 'Not authenticated'}), 401 try: - is_admin = us.check_admin(session['username']) client = MongoClient(MONGODB_HOST, MONGODB_PORT) db = client[MONGODB_DB] ausleihungen = db['ausleihungen'] query = {'ConflictDetected': True, 'Status': 'active'} - if not is_admin: + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['actions'].get('can_view_logs', False): query['User'] = session['username'] conflicts = list(ausleihungen.find(query)) @@ -6144,8 +6163,11 @@ def duplicate_item(): # Check if user is admin username = session['username'] - if not us.check_admin(username): - return jsonify({'success': False, 'message': 'Keine Administratorrechte'}), 403 + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['actions'].get('can_edit', False): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error') + return redirect(url_for('home_admin')) # Detect if request is from mobile device is_mobile = 'Mobile' in request.headers.get('User-Agent', '') @@ -6859,8 +6881,11 @@ def mark_damage_repaired(id): """Mark all currently open damage reports of an item as repaired (admin only).""" if 'username' not in session: return jsonify({'success': False, 'message': 'Nicht angemeldet'}), 401 - if not us.check_admin(session['username']): - return jsonify({'success': False, 'message': 'Administratorrechte erforderlich'}), 403 + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['actions'].get('can_edit', False): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion (Löschen) auszuführen.', 'error') + return redirect(url_for('home_admin')) client = None try: @@ -6980,7 +7005,7 @@ def ausleihen(id): if requested_return_to == 'library' and cfg.MODULES.is_enabled('library'): redirect_target = 'library_view' else: - redirect_target = 'home_admin' if us.check_admin(username) else 'home' + redirect_target = 'home_admin' if us.check_admin(username) else 'home' # check for plausability item = it.get_item(id) if not item: @@ -7039,7 +7064,9 @@ def ausleihen(id): return redirect(url_for(redirect_target)) # Admins can borrow on behalf of students via student card id. - if us.check_admin(username) and not is_library_item: + current_permissions = us.get_effective_permissions(session['username']) + + if current_permissions['actions'].get('can_borrow') and not is_library_item: if student_card_id: student_user = us.get_user_by_student_card(student_card_id) if not student_user: @@ -7297,8 +7324,10 @@ def zurueckgeben(id): return redirect(url_for('home')) username = session['username'] - - if not item.get('Verfuegbar', True) and (us.check_admin(session['username']) or item.get('User') == username): + + current_permissions = us.get_effective_permissions(session['username']) + + if not item.get('Verfuegbar', True) and (current_permissions['actions'].get('can_manage_users', False)) or item.get('User') == username): try: # Get ALL active borrowing records for this item and complete them client = MongoClient(MONGODB_HOST, MONGODB_PORT) @@ -7364,8 +7393,6 @@ def zurueckgeben(id): if source_page == 'my_borrowed_items' or '/my_borrowed_items' in referrer: return redirect(url_for('my_borrowed_items')) - if 'username' in session and not us.check_admin(session['username']): - return redirect(url_for('home')) return redirect(url_for('home_admin')) @app.route('/get_filter', methods=['GET']) @@ -7407,22 +7434,20 @@ def get_ausleihung_by_item_route(id): user=session.get('username', None) ) ausleihung['VerifiedStatus'] = current_status - - # Admin users can see all borrowing details - # Regular users can only see their own borrowings - if ausleihung and (us.check_admin(session['username']) or ausleihung.get('User') == session['username']): + + current_permissions = us.get_effective_permissions(session['username']) + + if ausleihung and (current_permissions['actions'].get('can_manage_users')) or ausleihung.get('User') == session['username']: return {'ausleihung': ausleihung, 'status': 'success'} - # Get item name for better error message item = it.get_item(id) item_name = item.get('Name', 'Unknown') if item else 'Unknown' - # Return a more informative error return { 'error': 'No active borrowing record found for this item', 'item_name': item_name, 'status': 'not_found' - }, 200 # Return 200 instead of 404 to allow processing of the error message + }, 200 @app.route('/get_planned_bookings/') @@ -7430,8 +7455,11 @@ def get_planned_bookings(item_id): """ Return all planned bookings for a given item (admin only). """ - if 'username' not in session or not us.check_admin(session['username']): - return jsonify({'ok': False, 'error': 'unauthorized'}), 403 + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['pages'].get('admin_borrowings', False): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error') + return redirect(url_for('home_admin')) try: client = MongoClient(MONGODB_HOST, MONGODB_PORT) @@ -7849,8 +7877,10 @@ def cancel_booking(id): if not booking: return {"success": False, "error": "Booking not found"}, 404 + current_permissions = us.get_effective_permissions(session['username']) + # Check if user owns this booking - if booking.get('User') != session['username'] and not us.check_admin(session['username']): + if booking.get('User') != session['username'] and not current_permissions['actions'].get('can_manage_users', False): return {"success": False, "error": "Not authorized to cancel this booking"}, 403 # Cancel the booking @@ -8089,9 +8119,14 @@ def admin_borrowings(): """ Admin view: list all active and planned borrowings with ability to reset. """ - if 'username' not in session or not us.check_admin(session['username']): + if 'username' not in session: flash('Ihnen ist es nicht gestattet auf dieser Internetanwendung, die eben besuchte Adrrese zu nutzen, versuchen sie es erneut nach dem sie sich mit einem berechtigten Nutzer angemeldet haben!', 'error') return redirect(url_for('login')) + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['pages'].get('admin_borrowings', False): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error') + return redirect(url_for('home_admin')) _ensure_audit_indexes_once() @@ -8172,9 +8207,15 @@ def admin_borrowings(): @app.route('/admin/audit/verify', methods=['GET']) def admin_verify_audit_chain(): """Admin endpoint to verify audit chain integrity.""" - if 'username' not in session or not us.check_admin(session['username']): + if 'username' not in session: return jsonify({'ok': False, 'error': 'forbidden'}), 403 + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['pages'].get('admin_audit_dashboard', False): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error') + return redirect(url_for('home_admin')) + client = None try: client = MongoClient(MONGODB_HOST, MONGODB_PORT) @@ -8192,10 +8233,16 @@ def admin_verify_audit_chain(): @app.route('/admin/audit', methods=['GET']) def admin_audit_dashboard(): """Admin dashboard for audit chain status and recent events.""" - if 'username' not in session or not us.check_admin(session['username']): + if 'username' not in session: flash('Ihnen ist es nicht gestattet auf dieser Internetanwendung, die eben besuchte Adrrese zu nutzen, versuchen sie es erneut nach dem sie sich mit einem berechtigten Nutzer angemeldet haben!', 'error') return redirect(url_for('login')) + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['pages'].get('admin_audit_dashboard', False): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error') + return redirect(url_for('home_admin')) + client = None try: client = MongoClient(MONGODB_HOST, MONGODB_PORT) @@ -8247,9 +8294,15 @@ def admin_audit_dashboard(): @app.route('/admin/audit/export/pdf/official', methods=['GET']) def admin_audit_export_pdf_official(): """Export audit report as professional PDF (Official Report - full DIN 5008 compliant).""" - if 'username' not in session or not us.check_admin(session['username']): + if 'username' not in session: return jsonify({'ok': False, 'error': 'forbidden'}), 403 + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['pages'].get('admin_audit_dashboard', False): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error') + return redirect(url_for('home_admin')) + try: limit = int((request.args.get('limit') or '1000').strip()) except Exception: @@ -8436,10 +8489,16 @@ def admin_reset_borrowing(borrow_id): - If active: complete it and free the item - If planned: cancel it """ - if 'username' not in session or not us.check_admin(session['username']): + if 'username' not in session: flash('Ihnen ist es nicht gestattet auf dieser Internetanwendung, die eben besuchte Adrrese zu nutzen, versuchen sie es erneut nach dem sie sich mit einem berechtigten Nutzer angemeldet haben!', 'error') return redirect(url_for('login')) + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['actions'].get('can_manage_users', False): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error') + return redirect(url_for('home_admin')) + try: client = MongoClient(MONGODB_HOST, MONGODB_PORT) db = client[MONGODB_DB] @@ -8503,10 +8562,16 @@ def admin_reset_borrowing(borrow_id): @app.route('/admin/borrowings//invoice', methods=['POST']) def admin_create_invoice(borrow_id): """Create a PDF invoice for a destroyed borrowed item.""" - if 'username' not in session or not us.check_admin(session['username']): + if 'username' not in session: flash('Ihnen ist es nicht gestattet auf dieser Internetanwendung, die eben besuchte Adrrese zu nutzen, versuchen sie es erneut nach dem sie sich mit einem berechtigten Nutzer angemeldet haben!', 'error') return redirect(url_for('login')) + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['pages'].get('admin_borrowings', False): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error') + return redirect(url_for('home_admin')) + client = None try: client = MongoClient(MONGODB_HOST, MONGODB_PORT) @@ -8666,10 +8731,16 @@ def admin_create_invoice(borrow_id): @app.route('/admin/borrowings//invoice/mark-paid', methods=['POST']) def admin_mark_invoice_paid(borrow_id): """Mark an existing invoice as paid.""" - if 'username' not in session or not us.check_admin(session['username']): + if 'username' not in session: flash('Ihnen ist es nicht gestattet auf dieser Internetanwendung, die eben besuchte Adrrese zu nutzen, versuchen sie es erneut nach dem sie sich mit einem berechtigten Nutzer angemeldet haben!', 'error') return redirect(url_for('login')) + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['pages'].get('admin_borrowings', False): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error') + return redirect(url_for('home_admin')) + client = None try: client = MongoClient(MONGODB_HOST, MONGODB_PORT) @@ -8744,10 +8815,16 @@ def admin_mark_invoice_paid(borrow_id): @app.route('/admin/borrowings//invoice/finalize', methods=['POST']) def admin_finalize_invoice_and_repair(borrow_id): """Mark invoice as paid and item as repaired in one action.""" - if 'username' not in session or not us.check_admin(session['username']): + if 'username' not in session: flash('Ihnen ist es nicht gestattet auf dieser Internetanwendung, die eben besuchte Adrrese zu nutzen, versuchen sie es erneut nach dem sie sich mit einem berechtigten Nutzer angemeldet haben!', 'error') return redirect(url_for('login')) + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['pages'].get('admin_borrowings', False): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error') + return redirect(url_for('home_admin')) + client = None try: client = MongoClient(MONGODB_HOST, MONGODB_PORT) @@ -8864,10 +8941,16 @@ def admin_finalize_invoice_and_repair(borrow_id): @app.route('/admin/borrowings//invoice/pdf', methods=['GET']) def admin_view_invoice_pdf(borrow_id): """View a previously created invoice PDF for a borrowing.""" - if 'username' not in session or not us.check_admin(session['username']): + if 'username' not in session: flash('Ihnen ist es nicht gestattet auf dieser Internetanwendung, die eben besuchte Adrrese zu nutzen, versuchen sie es erneut nach dem sie sich mit einem berechtigten Nutzer angemeldet haben!', 'error') return redirect(url_for('login')) + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['pages'].get('admin_borrowings', False): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error') + return redirect(url_for('home_admin')) + client = None try: client = MongoClient(MONGODB_HOST, MONGODB_PORT) @@ -8914,10 +8997,16 @@ def admin_view_invoice_pdf(borrow_id): @app.route('/admin/borrowings//invoice/correction', methods=['POST']) def admin_add_invoice_correction(borrow_id): """Append an invoice correction entry without mutating the original invoice body.""" - if 'username' not in session or not us.check_admin(session['username']): + if 'username' not in session: flash('Ihnen ist es nicht gestattet auf dieser Internetanwendung, die eben besuchte Adrrese zu nutzen, versuchen sie es erneut nach dem sie sich mit einem berechtigten Nutzer angemeldet haben!', 'error') return redirect(url_for('login')) + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['pages'].get('admin_borrowings', False): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error') + return redirect(url_for('home_admin')) + client = None try: client = MongoClient(MONGODB_HOST, MONGODB_PORT) @@ -8990,12 +9079,17 @@ def admin_add_invoice_correction(borrow_id): @app.route('/admin/library/items//invoices', methods=['GET']) def library_item_invoices(item_id): """Show all stored invoices for one specific library item.""" - if 'username' not in session or not us.check_admin(session['username']): + if 'username' not in session: flash('Ihnen ist es nicht gestattet auf dieser Internetanwendung, die eben besuchte Adrrese zu nutzen, versuchen sie es erneut nach dem sie sich mit einem berechtigten Nutzer angemeldet haben!', 'error') return redirect(url_for('login')) if not cfg.MODULES.is_enabled('library'): flash('Bibliotheks-Modul ist deaktiviert.', 'error') return redirect(url_for('home_admin')) + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['pages'].get('library_loans_admin', False): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error') + return redirect(url_for('library')) client = None try: @@ -9125,10 +9219,15 @@ def admin_update_user_name(): Returns: flask.Response: Redirect to user management page """ - if 'username' not in session or not us.check_admin(session['username']): + if 'username' not in session: flash('Nicht autorisierter Zugriff', 'error') return redirect(url_for('login')) - + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['actions'].get('can_manage_users', False): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error') + return redirect(url_for('home_admin')) + username = request.form.get('username') name = html.escape(request.form.get('name')) last_name = html.escape(request.form.get('last_name')) @@ -9257,9 +9356,11 @@ def logs(): if 'username' not in session: flash('Ihnen ist es nicht gestattet auf dieser Internetanwendung, die eben besuchte Adrrese zu nutzen, versuchen sie es erneut nach dem sie sich mit einem berechtigten Nutzer angemeldet haben!', 'error') return redirect(url_for('login')) - if not us.check_admin(session['username']): - flash('Ihnen ist es nicht gestattet auf dieser Internetanwendung, die eben besuchte Adrrese zu nutzen, versuchen sie es erneut nach dem sie sich mit einem berechtigten Nutzer angemeldet haben!', 'error') - return redirect(url_for('login')) + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['pages'].get('logs', False): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error') + return redirect(url_for('home_admin')) # Get ausleihungen all_ausleihungen = au.get_ausleihungen() @@ -9425,16 +9526,10 @@ def get_usernames(): if 'username' not in session: flash('Ihnen ist es nicht gestattet auf dieser Internetanwendung, die eben besuchte Adrrese zu nutzen, versuchen sie es erneut nach dem sie sich mit einem berechtigten Nutzer angemeldet haben!', 'error') return redirect(url_for('login')) - if not us.check_admin(session['username']): - flash('Ihnen ist es nicht gestattet auf dieser Internetanwendung, die eben besuchte Adrrese zu nutzen, versuchen sie es erneut nach dem sie sich mit einem berechtigten Nutzer angemeldet haben!', 'error') - return redirect(url_for('logout')) - elif 'username' in session and us.check_admin(session['username']): - return jsonify(us.get_all_users()) # Fixed to use get_all_users - else: - flash('Bitte melden Sie sich an, um auf diese Funktion zuzugreifen', 'error') - return redirect(url_for('login')) # Added proper return - -# New routes for filter management + current_permissions = us.get_effective_permissions(session['username']) + + if current_permissions['actions'].get('can_manage_users', False): + return jsonify(us.get_all_users()) @app.route('/manage_filters') def manage_filters(): @@ -9448,9 +9543,11 @@ def manage_filters(): if 'username' not in session: flash('Ihnen ist es nicht gestattet auf dieser Internetanwendung, die eben besuchte Adrrese zu nutzen, versuchen sie es erneut nach dem sie sich mit einem berechtigten Nutzer angemeldet haben!', 'error') return redirect(url_for('login')) - if not us.check_admin(session['username']): - flash('Ihnen ist es nicht gestattet auf dieser Internetanwendung, die eben besuchte Adrrese zu nutzen, versuchen sie es erneut nach dem sie sich mit einem berechtigten Nutzer angemeldet haben!', 'error') - return redirect(url_for('login')) + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['pages'].get('manage_filters', False): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error') + return redirect(url_for('home_admin')) # Get predefined filter values filter1_values = it.get_predefined_filter_values(1) @@ -9481,8 +9578,13 @@ def add_filter_value(filter_num): Returns: flask.Response: Redirect to filter management page """ - if 'username' not in session or not us.check_admin(session['username']): + if 'username' not in session: return jsonify({'success': False, 'error': 'Not authorized'}), 403 + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['actions'].get('can_edit', False): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error') + return redirect(url_for('home_admin')) value = sanitize_form_value(request.form.get('value')) @@ -9516,8 +9618,14 @@ def remove_filter_value(filter_num, value): Returns: flask.Response: Redirect to filter management page """ - if 'username' not in session or not us.check_admin(session['username']): + if 'username' not in session: return jsonify({'success': False, 'error': 'Not authorized'}), 403 + + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['actions'].get('can_edit', False): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error') + return redirect(url_for('home_admin')) # Remove the value from the filter success = it.remove_predefined_filter_value(filter_num, value) @@ -9541,8 +9649,11 @@ def edit_filter_value(filter_num, old_value): Returns: flask.Response: Redirect to filter management page """ - if 'username' not in session or not us.check_admin(session['username']): - return jsonify({'success': False, 'error': 'Not authorized'}), 403 + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['actions'].get('can_edit', False): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error') + return redirect(url_for('home_admin')) new_value = sanitize_form_value(request.form.get('new_value')) @@ -9879,8 +9990,13 @@ def fetch_book_info(isbn): Optimized for global literature AND German educational books. """ # Authorization Checks - if 'username' not in session or not us.check_admin(session['username']): + if 'username' not in session: return jsonify({"error": "Not authorized"}), 403 + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['actions'].get('can_insert', False): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error') + return redirect(url_for('library')) if not cfg.MODULES.is_enabled('library'): return jsonify({"error": "Bibliotheks-Modul ist deaktiviert."}), 403 @@ -9927,8 +10043,11 @@ def download_book_cover(): """ if 'username' not in session: return jsonify({"error": "Not authorized"}), 403 - if not us.check_admin(session['username']): - return jsonify({"error": "Admin privileges required"}), 403 + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['actions'].get('can_insert', False): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error') + return redirect(url_for('library')) if not cfg.MODULES.is_enabled('library'): return jsonify({"error": "Bibliotheks-Modul ist deaktiviert."}), 403 @@ -10257,9 +10376,11 @@ def notifications_view(): username = session['username'] is_admin_user = False - try: - is_admin_user = us.check_admin(username) - except Exception: + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['actions'].get('can_manage_settings', False): + is_admin_user = True + else: is_admin_user = False client = None @@ -10341,9 +10462,12 @@ def mark_all_notifications_read(): username = session['username'] is_admin_user = False - try: - is_admin_user = us.check_admin(username) - except Exception: + + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['actions'].get('can_manage_settings', False): + is_admin_user = True + else: is_admin_user = False query = { @@ -10384,9 +10508,12 @@ def notifications_unread_status(): username = session['username'] is_admin_user = False - try: - is_admin_user = us.check_admin(username) - except Exception: + + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['actions'].get('can_manage_settings', False): + is_admin_user = True + else: is_admin_user = False cached_payload, version_tag = _get_cached_unread_status(username, is_admin=is_admin_user) @@ -10535,9 +10662,15 @@ def add_location_value(): Returns: flask.Response: Redirect to location management page """ - if 'username' not in session or not us.check_admin(session['username']): + if 'username' not in session: return jsonify({'success': False, 'error': 'Not authorized'}), 403 - + + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['actions'].get('can_insert', False) or not current_permissions['actions'].get('can_edit', True): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error') + return redirect(url_for('home_admin')) + value = sanitize_form_value(request.form.get('value')) if not value: @@ -10565,9 +10698,15 @@ def remove_location_value(value): Returns: flask.Response: Redirect to location management page """ - if 'username' not in session or not us.check_admin(session['username']): + if 'username' not in session: return jsonify({'success': False, 'error': 'Not authorized'}), 403 - + + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['actions'].get('can_delete', False): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error') + return redirect(url_for('home_admin')) + # Remove the value from locations success = it.remove_predefined_location(value) @@ -10589,9 +10728,11 @@ def manage_locations(): if 'username' not in session: flash('Ihnen ist es nicht gestattet auf dieser Internetanwendung, die eben besuchte Adrrese zu nutzen, versuchen sie es erneut nach dem sie sich mit einem berechtigten Nutzer angemeldet haben!', 'error') return redirect(url_for('login')) - if not us.check_admin(session['username']): - flash('Ihnen ist es nicht gestattet auf dieser Internetanwendung, die eben besuchte Adrrese zu nutzen, versuchen sie es erneut nach dem sie sich mit einem berechtigten Nutzer angemeldet haben!', 'error') - return redirect(url_for('login')) + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['actions'].get('can_edit', False): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error') + return redirect(url_for('home_admin')) # Get predefined location values location_values = it.get_predefined_locations() @@ -10610,13 +10751,10 @@ def admin_school_settings(): if 'username' not in session: flash('Bitte melden Sie sich mit einem administrativen Konto an.', 'error') return redirect(url_for('login')) - if not us.check_admin(session['username']): - flash('Für diese Seite sind Administratorrechte erforderlich.', 'error') - return redirect(url_for('login')) - - permissions = _get_current_user_permissions() - if not _action_access_allowed(permissions, 'can_manage_settings'): - flash('Sie haben keine Berechtigung, die Schulstammdaten zu ändern.', 'error') + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['actions'].get('can_manage_settings', False): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error') return redirect(url_for('home_admin')) current_school = _get_school_info_for_export() @@ -11024,10 +11162,12 @@ def cancel_ausleihung_route(id): # Log ausleihung details for debugging ausleihung_status = ausleihung.get('Status', 'unknown') ausleihung_user = ausleihung.get('User', 'unknown') - print(f"Found ausleihung: ID={id}, User={ausleihung_user}, Status={ausleihung_status}") + print(f"Found ausleihung: ID={id}, Status={ausleihung_status}") + + current_permissions = us.get_effective_permissions(session['username']) # Check if the ausleihung belongs to the current user - if ausleihung_user != username and not us.check_admin(username): + if ausleihung_user != username and not (current_permissions['actions'].get('can_manage_users', False)): print(f"Authorization failure: {username} attempted to cancel ausleihung belonging to {ausleihung_user}") flash('Sie sind nicht berechtigt, diese Ausleihung zu stornieren', 'error') return redirect(url_for('my_borrowed_items')) @@ -11092,8 +11232,11 @@ def reset_item(id): if 'username' not in session: return jsonify({'success': False, 'error': 'Not authenticated'}), 401 - if not us.check_admin(session['username']): - return jsonify({'success': False, 'error': 'Not authorized'}), 403 + current_permissions = us.get_effective_permissions(session['username']) + + if not current_permissions['actions'].get('can_manage_users', False): + flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error') + return redirect(url_for('home_admin')) try: # Import the ausleihung module