Initial commit
This commit is contained in:
commit
536ff43ce4
158 files changed
+30355
No files matched your search
+474
@@ -0,0 +1,474 @@
|
||||
"""
|
||||
Rechtensysteem: wie mag wat, in welke school.
|
||||
|
||||
Gebruikers staan in de CENTRALE database (één account voor alle scholen).
|
||||
Per gebruiker wordt per school bijgehouden op welke onderdelen hij rechten heeft:
|
||||
|
||||
Gebruiker_rechten (Gebruiker_ID, School_ID, Onderdeel_ID)
|
||||
|
||||
Zo kan iemand in school A '2FA tijdelijk uitzetten' mogen en in school B niet.
|
||||
|
||||
Veiligheidsgroepen:
|
||||
1 = Administrator : alle rechten in alle scholen, beheert gebruikers, rechten en scholen
|
||||
2 = Gebruiker : enkel de rechten die per school zijn aangevinkt
|
||||
5 = Leerkracht : (geen account) personeelslid dat met Google inlogt → enkel de personeelsmodule
|
||||
|
||||
Gebruik in de code:
|
||||
@recht_vereist('herstellingen') # route
|
||||
if heeft_recht('tweestaps_uitzetten'): ... # in Python
|
||||
{% if mag('co2') %} ... {% endif %} # in templates
|
||||
"""
|
||||
import functools
|
||||
import sys
|
||||
from collections import OrderedDict
|
||||
|
||||
from flask import session, g, flash, redirect, url_for, request, has_request_context
|
||||
|
||||
ADMIN = 1
|
||||
GEBRUIKER = 2
|
||||
|
||||
VEILIGHEIDSGROEPEN = OrderedDict([
|
||||
(ADMIN, 'Administrator'),
|
||||
(GEBRUIKER, 'Gebruiker'),
|
||||
])
|
||||
|
||||
# (code, naam, categorie). De volgorde hier is de volgorde op het scherm.
|
||||
# Nieuwe onderdelen worden bij het opstarten automatisch in de tabel Onderdelen gezet.
|
||||
ONDERDELEN = [
|
||||
# --- Chromebooks ---
|
||||
('eigendom_bekijken', 'Eigendom bekijken', 'Chromebooks'),
|
||||
('toestellen_uitdelen', 'Toestellen uitdelen en inleveren', 'Chromebooks'),
|
||||
('toestellen_beheren', 'Toestelleninventaris beheren', 'Chromebooks'),
|
||||
('toestel_blokkeren', 'Chromebook blokkeren / deblokkeren', 'Chromebooks'),
|
||||
('herstellingen', 'Herstellingen', 'Chromebooks'),
|
||||
('signpost', 'Signpost-toestellen', 'Chromebooks'),
|
||||
# --- Leerlingen ---
|
||||
('leerlingen_bekijken', 'Leerlingen bekijken en bewerken', 'Leerlingen'),
|
||||
('leerlingen_synchroniseren', 'Leerlingen toevoegen en synchroniseren', 'Leerlingen'),
|
||||
('leerlingenaantal', 'Leerlingenaantallen (alle scholen)', 'Leerlingen'),
|
||||
# --- Basisonderwijs (blok enkel zichtbaar bij een basisschool) ---
|
||||
('bingel', 'Bingel: leerlingenlijst (Excel)', 'Basisonderwijs'),
|
||||
# --- Internaat ---
|
||||
('internen', 'Internaat: internen bekijken', 'Internaat'),
|
||||
('internaat_aanwezigheid', 'Internaat: aanwezigheden registreren', 'Internaat'),
|
||||
# --- Leerlingfacturatie ---
|
||||
('leerlingfacturatie', 'Leerlingfacturatie: facturen bekijken', 'Leerlingfacturatie'),
|
||||
# --- Google ---
|
||||
('google_wachtwoord', 'Google-wachtwoord resetten', 'Google'),
|
||||
('google_accounts', 'Google-accounts aanmaken', 'Google'),
|
||||
('tweestaps_codes', '2FA: back-upcodes tonen / aanmaken', 'Google'),
|
||||
('tweestaps_uitzetten', '2FA tijdelijk uitzetten (uitzondering)', 'Google'),
|
||||
('google_licenties', 'Google-licenties', 'Google'),
|
||||
('gmail_delegatie', 'Mailbox-delegatie', 'Google'),
|
||||
('verzendlijsten', 'Verzendlijsten (Google Groepen) beheren', 'Google'),
|
||||
('gmail_labels', 'E-mails met een label naar een andere mailbox', 'Google'),
|
||||
('gmail_handtekeningen', 'Gmail-handtekeningen instellen (functie/telefoon)', 'Google'),
|
||||
('gedeelde_drives', 'Gedeelde drives: leden en rechten beheren', 'Google'),
|
||||
('gmail_contacten', 'Contacten: contactlijsten in mailboxen, adresboek', 'Google'),
|
||||
# --- Smartschool ---
|
||||
('smartschool', 'Smartschool-wachtwoorden & info', 'Smartschool'),
|
||||
('smartschool_activiteit', 'Activiteit co-accounts & berichten', 'Smartschool'),
|
||||
('afwezigheden', 'Afwezigheden leerlingen (B-codes)', 'Smartschool'),
|
||||
('laatkomers', 'Laatkomers', 'Smartschool'),
|
||||
('skore', 'Skore-synchronisatie (starten en plannen)', 'Smartschool'),
|
||||
('sgr_groepen', 'SGR groepen: subgroepen en leden bekijken', 'Smartschool'),
|
||||
# --- Personeel ---
|
||||
('personeel_directie', 'Personeel: aanvragen goedkeuren (directie)', 'Personeel'),
|
||||
('personeel_secretariaat', 'Personeel: dagoverzicht (secretariaat)', 'Personeel'),
|
||||
('gopro', 'GO! Pro: personeel en rollen', 'Personeel'),
|
||||
('personeelsaantal', 'Personeelsaantallen (alle scholen)', 'Personeel'),
|
||||
# --- Tools ---
|
||||
('qr_codes', 'QR-code generator', 'Tools'),
|
||||
# --- IoT ---
|
||||
('co2', 'CO2-sensoren', 'IoT'),
|
||||
# --- Scholengroep ---
|
||||
# --- Beheer ---
|
||||
('bugs_bekijken', 'Bugs bekijken', 'Beheer'),
|
||||
('bugs_beheren', 'Status van bugs wijzigen', 'Beheer'),
|
||||
('nieuw_schooljaar', 'Nieuw schooljaar (accounts & toestellen)', 'Beheer'),
|
||||
('ip_whitelist', 'IP-adressen toestaan voor deze school', 'Beheer'),
|
||||
# --- PIVOT ---
|
||||
('gebruikersbeheer', 'Gebruikers & rechten van deze school', 'PIVOT'),
|
||||
('koppelingen', 'Koppelingen van deze school', 'PIVOT'),
|
||||
]
|
||||
CODES = [o[0] for o in ONDERDELEN]
|
||||
|
||||
|
||||
# =====================================================================
|
||||
# Tabellen (centrale database)
|
||||
# =====================================================================
|
||||
SCHEMA = [
|
||||
"""CREATE TABLE IF NOT EXISTS Veiligheidsgroepen (
|
||||
Veiligheidsgroep TINYINT NOT NULL PRIMARY KEY,
|
||||
Naam VARCHAR(50) NOT NULL,
|
||||
Omschrijving VARCHAR(255) NULL
|
||||
) ENGINE=InnoDB""",
|
||||
"""CREATE TABLE IF NOT EXISTS Gebruikers (
|
||||
Gebruiker_ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
Gebruikersnaam VARCHAR(100) NOT NULL,
|
||||
Veiligheidsgroep TINYINT NOT NULL DEFAULT 2,
|
||||
Passwoordhash VARCHAR(255) NULL,
|
||||
Emailadres VARCHAR(255) NULL,
|
||||
Last_login DATETIME NULL,
|
||||
IP_laatste_login VARCHAR(45) NULL,
|
||||
Laatste_school VARCHAR(32) NULL,
|
||||
Actief TINYINT NOT NULL DEFAULT 1,
|
||||
UNIQUE KEY uq_gebruikersnaam (Gebruikersnaam),
|
||||
UNIQUE KEY uq_emailadres (Emailadres),
|
||||
CONSTRAINT fk_gebruikers_groep FOREIGN KEY (Veiligheidsgroep)
|
||||
REFERENCES Veiligheidsgroepen (Veiligheidsgroep)
|
||||
) ENGINE=InnoDB""",
|
||||
"""CREATE TABLE IF NOT EXISTS Onderdelen (
|
||||
Onderdeel_ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
Code VARCHAR(50) NOT NULL,
|
||||
Naam VARCHAR(255) NOT NULL,
|
||||
Categorie VARCHAR(50) NOT NULL,
|
||||
Volgorde INT NOT NULL DEFAULT 0,
|
||||
UNIQUE KEY uq_onderdeel_code (Code)
|
||||
) ENGINE=InnoDB""",
|
||||
"""CREATE TABLE IF NOT EXISTS Gebruiker_rechten (
|
||||
Gebruiker_ID INT NOT NULL,
|
||||
School_ID INT NOT NULL,
|
||||
Onderdeel_ID INT NOT NULL,
|
||||
Toegekend_op DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
Toegekend_door VARCHAR(100) NULL,
|
||||
PRIMARY KEY (Gebruiker_ID, School_ID, Onderdeel_ID),
|
||||
KEY idx_rechten_school (School_ID),
|
||||
KEY idx_rechten_onderdeel (Onderdeel_ID),
|
||||
CONSTRAINT fk_rechten_gebruiker FOREIGN KEY (Gebruiker_ID)
|
||||
REFERENCES Gebruikers (Gebruiker_ID) ON DELETE CASCADE,
|
||||
CONSTRAINT fk_rechten_school FOREIGN KEY (School_ID)
|
||||
REFERENCES Scholen (School_ID) ON DELETE CASCADE,
|
||||
CONSTRAINT fk_rechten_onderdeel FOREIGN KEY (Onderdeel_ID)
|
||||
REFERENCES Onderdelen (Onderdeel_ID) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB""",
|
||||
"""CREATE TABLE IF NOT EXISTS Handleidingen (
|
||||
Handleiding_ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
Slug VARCHAR(100) NOT NULL,
|
||||
Titel VARCHAR(200) NOT NULL,
|
||||
Categorie VARCHAR(100) NULL,
|
||||
Samenvatting VARCHAR(300) NULL,
|
||||
Inhoud MEDIUMTEXT NULL,
|
||||
Zichtbaar VARCHAR(10) NOT NULL DEFAULT 'iedereen',
|
||||
Volgorde INT NOT NULL DEFAULT 0,
|
||||
Gewijzigd_op DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
Gewijzigd_door VARCHAR(100) NULL,
|
||||
UNIQUE KEY uq_handleiding_slug (Slug)
|
||||
) ENGINE=InnoDB""",
|
||||
"""CREATE TABLE IF NOT EXISTS Handleidingen_versies (
|
||||
Versie_ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
Handleiding_ID INT NOT NULL,
|
||||
Titel VARCHAR(200) NOT NULL,
|
||||
Inhoud MEDIUMTEXT NULL,
|
||||
Opgeslagen_op DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
Door VARCHAR(100) NULL,
|
||||
KEY idx_versie_handleiding (Handleiding_ID, Opgeslagen_op),
|
||||
CONSTRAINT fk_versie_handleiding FOREIGN KEY (Handleiding_ID)
|
||||
REFERENCES Handleidingen (Handleiding_ID) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB""",
|
||||
"""CREATE TABLE IF NOT EXISTS Leerlingenaantal_tellingen (
|
||||
Telling_ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
School_ID INT NOT NULL,
|
||||
Peildatum DATE NOT NULL,
|
||||
Schooljaar VARCHAR(10) NOT NULL,
|
||||
Aantal INT NOT NULL,
|
||||
Detail TEXT NULL,
|
||||
Opgevraagd_op DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
Door VARCHAR(100) NULL,
|
||||
UNIQUE KEY uq_telling (School_ID, Peildatum),
|
||||
KEY idx_telling_datum (Peildatum),
|
||||
CONSTRAINT fk_telling_school FOREIGN KEY (School_ID)
|
||||
REFERENCES Scholen (School_ID) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB""",
|
||||
"""CREATE TABLE IF NOT EXISTS Personeelsaantal_tellingen (
|
||||
Telling_ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
School_ID INT NOT NULL,
|
||||
Peildatum DATE NOT NULL,
|
||||
Schooljaar VARCHAR(10) NOT NULL,
|
||||
Aantal INT NOT NULL,
|
||||
Detail TEXT NULL,
|
||||
Opgevraagd_op DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
Door VARCHAR(100) NULL,
|
||||
UNIQUE KEY uq_ptelling (School_ID, Peildatum),
|
||||
KEY idx_ptelling_datum (Peildatum),
|
||||
CONSTRAINT fk_ptelling_school FOREIGN KEY (School_ID)
|
||||
REFERENCES Scholen (School_ID) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB""",
|
||||
"""CREATE TABLE IF NOT EXISTS Personeelsaantal_huidig (
|
||||
School_ID INT NOT NULL PRIMARY KEY,
|
||||
Aantal INT NOT NULL,
|
||||
Detail TEXT NULL,
|
||||
Gesynchroniseerd DATETIME NOT NULL,
|
||||
CONSTRAINT fk_phuidig_school FOREIGN KEY (School_ID)
|
||||
REFERENCES Scholen (School_ID) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB""",
|
||||
"""CREATE TABLE IF NOT EXISTS PIVOT_instellingen (
|
||||
Sleutel VARCHAR(50) NOT NULL PRIMARY KEY,
|
||||
Waarde VARCHAR(255) NULL,
|
||||
Bijgewerkt DATETIME NULL,
|
||||
Door VARCHAR(100) NULL
|
||||
) ENGINE=InnoDB""",
|
||||
"""CREATE TABLE IF NOT EXISTS IP_blokkades (
|
||||
ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
Reeks VARCHAR(64) NOT NULL,
|
||||
Soort VARCHAR(10) NOT NULL DEFAULT 'blokkeren',
|
||||
Opmerking VARCHAR(255) NULL,
|
||||
Scholen VARCHAR(1000) NULL,
|
||||
Aangemaakt DATETIME NOT NULL,
|
||||
Door VARCHAR(100) NULL,
|
||||
Gebruiker_ID INT NULL,
|
||||
Aantal_geweigerd INT NOT NULL DEFAULT 0,
|
||||
Laatst_geweigerd DATETIME NULL,
|
||||
UNIQUE KEY uq_ip_reeks (Reeks, Soort)
|
||||
) ENGINE=InnoDB""",
|
||||
"""CREATE TABLE IF NOT EXISTS Koppeling_tests (
|
||||
School_ID INT NOT NULL,
|
||||
Onderdeel VARCHAR(50) NOT NULL,
|
||||
Ok TINYINT NULL,
|
||||
Detail VARCHAR(500) NULL,
|
||||
Getest_op DATETIME NOT NULL,
|
||||
PRIMARY KEY (School_ID, Onderdeel),
|
||||
CONSTRAINT fk_ktest_school FOREIGN KEY (School_ID) REFERENCES Scholen (School_ID) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB""",
|
||||
"""CREATE TABLE IF NOT EXISTS Logs (
|
||||
Log_ID BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
Timestamp DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
Bezochte_url VARCHAR(2048) NOT NULL,
|
||||
Gebruiker_ID INT NULL,
|
||||
School_ID INT NULL,
|
||||
Actie VARCHAR(255) NULL,
|
||||
IP VARCHAR(45) NULL,
|
||||
KEY idx_logs_tijd (Timestamp),
|
||||
KEY idx_logs_gebruiker (Gebruiker_ID),
|
||||
CONSTRAINT fk_logs_gebruiker FOREIGN KEY (Gebruiker_ID)
|
||||
REFERENCES Gebruikers (Gebruiker_ID) ON DELETE SET NULL,
|
||||
CONSTRAINT fk_logs_school FOREIGN KEY (School_ID)
|
||||
REFERENCES Scholen (School_ID) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB""",
|
||||
"""CREATE TABLE IF NOT EXISTS Status (
|
||||
Bugstatus_ID TINYINT NOT NULL PRIMARY KEY,
|
||||
Omschrijving VARCHAR(50) NOT NULL,
|
||||
UNIQUE KEY uq_status_omschrijving (Omschrijving)
|
||||
) ENGINE=InnoDB""",
|
||||
"""CREATE TABLE IF NOT EXISTS Bugs (
|
||||
Bug_ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
Timestamp DATETIME NOT NULL,
|
||||
Omschrijving TEXT NOT NULL,
|
||||
Foutcode VARCHAR(100) NULL,
|
||||
Bugstatus_ID TINYINT NOT NULL DEFAULT 1,
|
||||
Gebruiker_ID INT NULL,
|
||||
Gebruikersnaam VARCHAR(255) NULL,
|
||||
School_ID INT NULL,
|
||||
Gemeld_op DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
KEY idx_bugs_status (Bugstatus_ID),
|
||||
CONSTRAINT fk_bugs_status FOREIGN KEY (Bugstatus_ID) REFERENCES Status (Bugstatus_ID),
|
||||
CONSTRAINT fk_bugs_gebruiker FOREIGN KEY (Gebruiker_ID)
|
||||
REFERENCES Gebruikers (Gebruiker_ID) ON DELETE SET NULL,
|
||||
CONSTRAINT fk_bugs_school FOREIGN KEY (School_ID)
|
||||
REFERENCES Scholen (School_ID) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB""",
|
||||
]
|
||||
|
||||
BUGSTATUS = [(1, 'Nieuw'), (2, 'In behandeling'), (3, 'Fixed')]
|
||||
|
||||
|
||||
def ensure_schema():
|
||||
"""Maakt de tabellen aan en zet de vaste lijsten (groepen, onderdelen, bugstatussen) goed."""
|
||||
from database import central_query
|
||||
for sql in SCHEMA:
|
||||
central_query(sql, commit=True)
|
||||
# Bestaande tabel Gebruikers van vóór "laatst actieve school" (het aanmeldscherm vraagt geen school meer)
|
||||
if 'laatste_school' not in {r['Field'].lower() for r in central_query("SHOW COLUMNS FROM Gebruikers") or []}:
|
||||
central_query("ALTER TABLE Gebruikers ADD COLUMN Laatste_school VARCHAR(32) NULL AFTER IP_laatste_login", commit=True)
|
||||
for nr, naam in VEILIGHEIDSGROEPEN.items():
|
||||
central_query("INSERT INTO Veiligheidsgroepen (Veiligheidsgroep, Naam) VALUES (%s, %s) "
|
||||
"ON DUPLICATE KEY UPDATE Naam = VALUES(Naam)", (nr, naam), commit=True)
|
||||
for i, (code, naam, cat) in enumerate(ONDERDELEN, start=1):
|
||||
central_query("INSERT INTO Onderdelen (Code, Naam, Categorie, Volgorde) VALUES (%s, %s, %s, %s) "
|
||||
"ON DUPLICATE KEY UPDATE Naam = VALUES(Naam), Categorie = VALUES(Categorie), "
|
||||
"Volgorde = VALUES(Volgorde)", (code, naam, cat, i * 10), commit=True)
|
||||
for nr, oms in BUGSTATUS:
|
||||
central_query("INSERT INTO Status (Bugstatus_ID, Omschrijving) VALUES (%s, %s) "
|
||||
"ON DUPLICATE KEY UPDATE Omschrijving = VALUES(Omschrijving)", (nr, oms), commit=True)
|
||||
# Standaardhandleidingen die nog niet bestaan (daarna beheer je ze in PIVOT; verwijderen = verbergen)
|
||||
from services.handleidingen_standaard import STANDAARD
|
||||
bestaand = {r['Slug'] for r in central_query("SELECT Slug FROM Handleidingen")}
|
||||
for i, h in enumerate(STANDAARD, start=1):
|
||||
if h['slug'] not in bestaand:
|
||||
central_query("INSERT IGNORE INTO Handleidingen (Slug, Titel, Categorie, Samenvatting, Inhoud, Volgorde, "
|
||||
"Gewijzigd_door) VALUES (%s, %s, %s, %s, %s, %s, 'PIVOT')",
|
||||
(h['slug'], h['titel'], h['categorie'], h['samenvatting'], h['inhoud'].strip(), i * 10),
|
||||
commit=True)
|
||||
|
||||
|
||||
# =====================================================================
|
||||
# Gebruikers
|
||||
# =====================================================================
|
||||
def zoek_gebruiker(naam_of_email):
|
||||
"""Actieve of inactieve gebruiker op gebruikersnaam of e-mailadres (hoofdletterongevoelig)."""
|
||||
from database import central_query
|
||||
w = (naam_of_email or '').strip()
|
||||
if not w:
|
||||
return None
|
||||
rows = central_query("SELECT * FROM Gebruikers WHERE Gebruikersnaam = %s OR Emailadres = %s "
|
||||
"ORDER BY Gebruikersnaam = %s DESC LIMIT 1", (w, w.lower(), w))
|
||||
return rows[0] if rows else None
|
||||
|
||||
|
||||
def gebruiker_op_id(gid):
|
||||
from database import central_query
|
||||
rows = central_query("SELECT * FROM Gebruikers WHERE Gebruiker_ID = %s", (gid,))
|
||||
return rows[0] if rows else None
|
||||
|
||||
|
||||
def registreer_login(gid, ip):
|
||||
from database import central_query
|
||||
try:
|
||||
central_query("UPDATE Gebruikers SET Last_login = NOW(), IP_laatste_login = %s WHERE Gebruiker_ID = %s",
|
||||
(ip, gid), commit=True)
|
||||
except Exception as e:
|
||||
sys.stderr.write(f"PIVOT: laatste login niet bewaard: {e}\n")
|
||||
|
||||
|
||||
def bewaar_laatste_school(gid, code):
|
||||
"""Onthoudt de school waarin de gebruiker het laatst werkte (die wordt bij de volgende aanmelding geladen)."""
|
||||
from database import central_query
|
||||
if not gid or not code:
|
||||
return
|
||||
try:
|
||||
central_query("UPDATE Gebruikers SET Laatste_school = %s WHERE Gebruiker_ID = %s", (code, gid), commit=True)
|
||||
except Exception as e:
|
||||
sys.stderr.write(f"PIVOT: laatst actieve school niet bewaard: {e}\n")
|
||||
|
||||
|
||||
def rechten_van(gid, school_id):
|
||||
"""Set met codes van onderdelen waarop gebruiker `gid` rechten heeft in school `school_id`."""
|
||||
from database import central_query
|
||||
rows = central_query(
|
||||
"SELECT o.Code FROM Gebruiker_rechten r JOIN Onderdelen o ON o.Onderdeel_ID = r.Onderdeel_ID "
|
||||
"WHERE r.Gebruiker_ID = %s AND r.School_ID = %s", (gid, school_id))
|
||||
return {r['Code'] for r in rows}
|
||||
|
||||
|
||||
def scholen_met_rechten(gid):
|
||||
"""School_ID's waar de gebruiker minstens één recht heeft."""
|
||||
from database import central_query
|
||||
rows = central_query("SELECT DISTINCT School_ID FROM Gebruiker_rechten WHERE Gebruiker_ID = %s", (gid,))
|
||||
return {r['School_ID'] for r in rows}
|
||||
|
||||
|
||||
def mag_in_school(gebruiker, school):
|
||||
"""Mag deze gebruiker (rij uit Gebruikers) in deze school inloggen?"""
|
||||
if not gebruiker or not school:
|
||||
return False
|
||||
if int(gebruiker['Veiligheidsgroep']) == ADMIN:
|
||||
return True
|
||||
return school.id in scholen_met_rechten(gebruiker['Gebruiker_ID'])
|
||||
|
||||
|
||||
def zet_rechten(gid, school_id, codes, door=None):
|
||||
"""Vervangt alle rechten van gebruiker `gid` in school `school_id` door `codes`."""
|
||||
from database import get_central_connection
|
||||
codes = [c for c in codes if c in CODES]
|
||||
conn = get_central_connection()
|
||||
cur = conn.cursor()
|
||||
try:
|
||||
conn.start_transaction()
|
||||
cur.execute("DELETE FROM Gebruiker_rechten WHERE Gebruiker_ID = %s AND School_ID = %s", (gid, school_id))
|
||||
if codes:
|
||||
plek = ','.join(['%s'] * len(codes))
|
||||
cur.execute(
|
||||
f"INSERT INTO Gebruiker_rechten (Gebruiker_ID, School_ID, Onderdeel_ID, Toegekend_door) "
|
||||
f"SELECT %s, %s, Onderdeel_ID, %s FROM Onderdelen WHERE Code IN ({plek})",
|
||||
(gid, school_id, door, *codes))
|
||||
conn.commit()
|
||||
except Exception:
|
||||
conn.rollback()
|
||||
raise
|
||||
finally:
|
||||
cur.close()
|
||||
conn.close()
|
||||
|
||||
|
||||
# =====================================================================
|
||||
# Huidige gebruiker
|
||||
# =====================================================================
|
||||
def is_admin():
|
||||
return bool(session.get('admin')) or bool(session.get('superbeheerder'))
|
||||
|
||||
|
||||
def huidige_rechten():
|
||||
"""Rechten van de ingelogde gebruiker in de huidige school (één keer per request opgehaald)."""
|
||||
if not has_request_context() or not session.get('auth'):
|
||||
return set()
|
||||
if is_admin():
|
||||
return set(CODES)
|
||||
if '_rechten' in g:
|
||||
return g._rechten
|
||||
gid = session.get('gebruiker_id')
|
||||
school = g.get('school')
|
||||
rechten = set()
|
||||
if gid and school:
|
||||
try:
|
||||
rechten = rechten_van(gid, school.id)
|
||||
except Exception as e:
|
||||
sys.stderr.write(f"PIVOT: rechten ophalen mislukt: {e}\n")
|
||||
g._rechten = rechten
|
||||
return rechten
|
||||
|
||||
|
||||
def heeft_recht(*codes):
|
||||
"""True als de ingelogde gebruiker in de huidige school minstens één van deze rechten heeft."""
|
||||
rechten = huidige_rechten()
|
||||
return any(c in rechten for c in codes)
|
||||
|
||||
|
||||
def recht_vereist(*codes):
|
||||
"""Decorator voor routes: de gebruiker moet in de huidige school één van deze rechten hebben."""
|
||||
for c in codes:
|
||||
if c not in CODES:
|
||||
raise ValueError(f"Onbekend onderdeel '{c}'")
|
||||
|
||||
def decorator(view):
|
||||
@functools.wraps(view)
|
||||
def wrapped(*a, **kw):
|
||||
if not session.get('auth') or not session.get('school'):
|
||||
return redirect(url_for('auth.login'))
|
||||
if not heeft_recht(*codes):
|
||||
flash("Je hebt geen rechten voor dit onderdeel in deze school.", "error")
|
||||
return redirect(url_for('main.dashboard'))
|
||||
return view(*a, **kw)
|
||||
return wrapped
|
||||
return decorator
|
||||
|
||||
|
||||
def admin_vereist(view):
|
||||
@functools.wraps(view)
|
||||
def wrapped(*a, **kw):
|
||||
if not session.get('auth'):
|
||||
return redirect(url_for('auth.login'))
|
||||
if not is_admin():
|
||||
flash("Enkel voor administrators.", "error")
|
||||
return redirect(url_for('main.dashboard'))
|
||||
return view(*a, **kw)
|
||||
return wrapped
|
||||
|
||||
|
||||
# =====================================================================
|
||||
# Logboek (tabel Logs)
|
||||
# =====================================================================
|
||||
def log(actie=None, url=None):
|
||||
"""Schrijft een regel in Logs. Fouten worden genegeerd (loggen mag PIVOT nooit blokkeren)."""
|
||||
from database import central_query
|
||||
try:
|
||||
school = g.get('school') if has_request_context() else None
|
||||
central_query(
|
||||
"INSERT INTO Logs (Bezochte_url, Gebruiker_ID, School_ID, Actie, IP) VALUES (%s, %s, %s, %s, %s)",
|
||||
((url or (request.full_path.rstrip('?') if has_request_context() else ''))[:2048],
|
||||
session.get('gebruiker_id') if has_request_context() else None,
|
||||
school.id if school else None,
|
||||
(actie or '')[:255] or None,
|
||||
request.remote_addr if has_request_context() else None),
|
||||
commit=True)
|
||||
except Exception as e:
|
||||
sys.stderr.write(f"PIVOT: loggen mislukt: {e}\n")
|
||||
Reference in new issue
Block a user