from flask import Blueprint, render_template, request, redirect, url_for, flash, session, jsonify from tenancy import huidige_school, per_school from blueprints.auth import login_required from rechten import recht_vereist from services.gmail_delegation_service import GmailDelegationService, DelegationError, MAX_DELEGATES from services.gmail_delegatie_overzicht import DelegatieOverzicht gmail_delegatie_bp = Blueprint('gmail_delegatie', __name__) delegation_service = per_school(GmailDelegationService) _table_ready = set() # scholen waarvoor de tabellen al gecontroleerd zijn def _ensure_table(): if huidige_school().code not in _table_ready: try: delegation_service.ensure_table() _table_ready.add(huidige_school().code) except Exception as e: flash(f"Kon tabel gmail_delegatie_log niet aanmaken: {e}", "error") def _safe_log(actie, mailbox, gedelegeerde): try: delegation_service.log(session.get('user'), actie, mailbox, gedelegeerde) except Exception as e: flash(f"Wijziging is uitgevoerd, maar kon niet gelogd worden: {e}", "warning") #--------------------------------------------- # Overzicht: mailbox zoeken en gedelegeerden tonen #--------------------------------------------- @gmail_delegatie_bp.route('/', methods=['GET']) @login_required @recht_vereist('gmail_delegatie') def overzicht(): _ensure_table() zoek = (request.args.get('zoek') or '').strip() mailbox_param = (request.args.get('mailbox') or '').strip() zoekresultaten, mailbox, delegates, fout = [], None, [], None # Zoekterm zonder @ = zoeken op naam; met @ = direct die mailbox openen if zoek and '@' not in zoek: zoekresultaten = delegation_service.search_users(zoek) if not zoekresultaten: fout = f"Geen gebruikers gevonden voor '{zoek}'." elif zoek and not mailbox_param: mailbox_param = zoek if mailbox_param: try: mailbox = delegation_service.resolve_user(mailbox_param) delegates = delegation_service.list_delegates(mailbox['email']) DelegatieOverzicht().bewaar_mailbox(mailbox['email'], mailbox['naam'], delegates) # overzicht actueel houden except DelegationError as e: fout = str(e) try: geschiedenis = delegation_service.history(mailbox['email'] if mailbox else None) except Exception: geschiedenis = [] # Alle lopende machtigingen (achtergrondtaak, vanzelf vernieuwd als ze ouder zijn dan een dag) ov = DelegatieOverzicht() machtigingen, laatst, ov_fout = [], None, None try: ov.ensure_table() if ov.verouderd(): ov.sync_op_achtergrond() machtigingen, laatst = ov.alle(), ov.laatst_opgehaald() except Exception as e: ov_fout = f"Het overzicht kon niet gelezen worden: {e}" return render_template('gmail_delegatie.html', zoek=zoek, zoekresultaten=zoekresultaten, mailbox=mailbox, delegates=delegates, fout=fout, geschiedenis=geschiedenis, max_delegates=MAX_DELEGATES, machtigingen=machtigingen, laatst=laatst, ov_fout=ov_fout, ov_status=ov.status) @gmail_delegatie_bp.route('/overzicht/vernieuwen', methods=['POST']) @login_required @recht_vereist('gmail_delegatie') def overzicht_vernieuwen(): if DelegatieOverzicht().sync_op_achtergrond(): flash("Alle mailboxen worden nagekeken. Dit kan enkele minuten duren; de tabel vernieuwt vanzelf.", "info") else: flash("Er loopt al een ophaling.", "warning") return redirect(url_for('gmail_delegatie.overzicht')) @gmail_delegatie_bp.route('/overzicht/status.json', methods=['GET']) @login_required @recht_vereist('gmail_delegatie') def overzicht_status(): s = DelegatieOverzicht().status return jsonify(bezig=s['bezig'], voortgang=s['voortgang'], totaal=s['totaal'], fout=s['fout'], resultaat=s['resultaat']) def _ververs_mailbox(mailbox): """Na een wijziging: de rijen van deze mailbox in het overzicht opnieuw opvragen.""" try: m = delegation_service.resolve_user(mailbox) DelegatieOverzicht().bewaar_mailbox(m['email'], m['naam'], delegation_service.list_delegates(m['email'])) except Exception: pass #--------------------------------------------- # Gedelegeerde toevoegen #--------------------------------------------- @gmail_delegatie_bp.route('/toevoegen', methods=['POST']) @login_required @recht_vereist('gmail_delegatie') def toevoegen(): _ensure_table() mailbox_in = request.form.get('mailbox', '') delegate_in = request.form.get('delegate', '') try: mailbox = delegation_service.resolve_user(mailbox_in) delegate = delegation_service.resolve_user(delegate_in) if delegate['geschorst']: raise DelegationError(f"{delegate['email']} is geschorst en kan geen toegang krijgen.") if len(delegation_service.list_delegates(mailbox['email'])) >= MAX_DELEGATES: raise DelegationError(f"{mailbox['email']} heeft al het maximum van {MAX_DELEGATES} gedelegeerden.") delegation_service.add_delegate(mailbox['email'], delegate['email']) _safe_log('toegevoegd', mailbox['email'], delegate['email']) _ververs_mailbox(mailbox['email']) extra = f" (alias {delegate_in.strip()} omgezet naar hoofdadres)" if delegate['is_alias'] else "" flash(f"{delegate['email']} heeft nu toegang tot {mailbox['email']}{extra}. " "Het kan tot een minuut duren voor de mailbox zichtbaar is.", "success") return redirect(url_for('gmail_delegatie.overzicht', mailbox=mailbox['email'])) except DelegationError as e: flash(str(e), "error") return redirect(url_for('gmail_delegatie.overzicht', mailbox=mailbox_in.strip())) #--------------------------------------------- # Gedelegeerde verwijderen #--------------------------------------------- @gmail_delegatie_bp.route('/verwijderen', methods=['POST']) @login_required @recht_vereist('gmail_delegatie') def verwijderen(): _ensure_table() mailbox = (request.form.get('mailbox') or '').strip().lower() delegate = (request.form.get('delegate') or '').strip().lower() try: delegation_service.remove_delegate(mailbox, delegate) _safe_log('verwijderd', mailbox, delegate) _ververs_mailbox(mailbox) flash(f"Toegang van {delegate} tot {mailbox} is ingetrokken.", "success") except DelegationError as e: flash(str(e), "error") return redirect(url_for('gmail_delegatie.overzicht', mailbox=mailbox))