AccessControlTest prueft die Trennung ueber die echte Kette Auth -> AccessPolicy -> Repository, also genau so, wie die Controller sie benutzen - nicht gegen eine nachgebaute Logik. Abgedeckt sind unter anderem: ein Mitglied sieht nur die eigene Gruppe, der direkte Aufruf einer fremden Kennung findet nichts, ein Benutzer ohne Gruppe sieht gar nichts (die leere Liste darf nicht wie "keine Einschraenkung" wirken), Viewer duerfen lesen aber nicht schreiben, das Umhaengen einer Domain nimmt ihre Kurzlinks mit, fremde Logos werden nicht ausgeliefert, ein gesperrtes Konto verliert seine laufende Sitzung und ein Passwortwechsel macht bestehende Sitzungen ungueltig. MigrationUpgradeTest deckt zusaetzlich den Umstieg ab: das Bestandskonto wird mit unveraendertem Hash uebernommen, die alten settings-Schluessel verschwinden, Bestandsdomains landen in der Standardgruppe - und eine frische Installation bekommt kein erfundenes Konto. README: neuer Abschnitt "Benutzer, Gruppen und Rechte" mit dem Grundprinzip, den beiden Rollenebenen, der Einrichtung in drei Schritten und dem Umstieg von der Einbenutzer-Version. ADMIN_USER und ADMIN_PASSWORD_HASH sind als Notfallzugang neu beschrieben, in README und .env.example. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
101 lines
3.7 KiB
Bash
101 lines
3.7 KiB
Bash
# =============================================================
|
||
# urlshort-qr-gen – Konfiguration
|
||
# Diese Datei nach ".env" kopieren und anpassen.
|
||
# Alle Werte koennen alternativ als echte Umgebungsvariablen
|
||
# gesetzt werden (Docker); die .env hat dann Vorrang, wenn der
|
||
# Schluessel dort vorhanden ist.
|
||
# =============================================================
|
||
|
||
# --- Anwendung -----------------------------------------------
|
||
# Basis-URL OHNE abschliessenden Slash. Wird fuer die Kurzlinks
|
||
# und die QR-Codes verwendet.
|
||
APP_BASE_URL=http://localhost:8080
|
||
|
||
# production | development (development zeigt Fehlermeldungen an)
|
||
APP_ENV=production
|
||
|
||
APP_TIMEZONE=Europe/Berlin
|
||
|
||
# HTTP-Status fuer Weiterleitungen: 301 (permanent, wird vom
|
||
# Browser gecacht -> weniger Klicks werden gezaehlt) oder
|
||
# 302 / 307 (temporaer, empfohlen fuer korrekte Statistik).
|
||
REDIRECT_STATUS=302
|
||
|
||
# --- Datenbank ------------------------------------------------
|
||
# sqlite | mysql
|
||
DB_DRIVER=sqlite
|
||
|
||
# Nur fuer sqlite: Pfad zur Datenbankdatei.
|
||
# Relative Pfade werden vom Projekt-Stammverzeichnis aus aufgeloest.
|
||
DB_SQLITE_PATH=data/database.sqlite
|
||
|
||
# Nur fuer mysql:
|
||
DB_HOST=127.0.0.1
|
||
DB_PORT=3306
|
||
DB_NAME=urlshort
|
||
DB_USER=urlshort
|
||
DB_PASSWORD=
|
||
DB_CHARSET=utf8mb4
|
||
|
||
# --- Notfallzugang --------------------------------------------
|
||
# Die regulaeren Konten stehen in der Datenbank und werden unter
|
||
# "Benutzer" verwaltet. Das erste Konto legt der Setup-Assistent beim
|
||
# ersten Aufruf an; er verlangt zusaetzlich ein Einmal-Token aus
|
||
# data/setup-token.txt (und dem Serverprotokoll), damit niemand anderes
|
||
# die frische Installation uebernimmt.
|
||
#
|
||
# Die beiden folgenden Zeilen sind davon unabhaengig: sie beschreiben
|
||
# einen zusaetzlichen Zugang mit Administratorrechten, der nur hier
|
||
# steht. Er taucht in der Benutzerverwaltung nicht auf und laesst sich
|
||
# dort auch nicht aendern - gedacht fuer den Fall, dass das letzte
|
||
# Administratorkonto gesperrt wurde oder sein Passwort verloren ging.
|
||
# Wird er nicht gebraucht, beide Zeilen leer lassen oder entfernen.
|
||
#
|
||
# Hash erzeugen: php -r "echo password_hash('geheim', PASSWORD_DEFAULT), PHP_EOL;"
|
||
ADMIN_USER=admin
|
||
ADMIN_PASSWORD_HASH=
|
||
|
||
# --- Sessions / Sicherheit ------------------------------------
|
||
SESSION_NAME=urlshort_session
|
||
# Abmeldung nach Inaktivitaet (Sekunden)
|
||
SESSION_LIFETIME=7200
|
||
# Harte Obergrenze je Sitzung, unabhaengig von Aktivitaet (0 = aus)
|
||
SESSION_ABSOLUTE_LIFETIME=43200
|
||
# Cookies nur ueber HTTPS senden. Wird bei einer HTTPS-Anfrage
|
||
# automatisch aktiviert; hier auf true setzen, wenn die Anwendung
|
||
# ausschliesslich ueber HTTPS erreichbar ist.
|
||
SESSION_SECURE=false
|
||
|
||
# --- Betrieb hinter einem Proxy / Loadbalancer ----------------
|
||
# Nur IPs und CIDR-Bereiche aus dieser Liste duerfen X-Forwarded-For
|
||
# und X-Forwarded-Proto setzen. LEER LASSEN, wenn kein Proxy davor
|
||
# steht - sonst koennte jeder die Client-IP faelschen und damit die
|
||
# Login-Sperre umgehen.
|
||
# Beispiel: TRUSTED_PROXIES=10.0.0.0/8,172.18.0.1
|
||
TRUSTED_PROXIES=
|
||
|
||
# HTTP Strict Transport Security in Sekunden (0 = aus).
|
||
# Wird nur bei HTTPS-Anfragen gesendet.
|
||
HSTS_MAX_AGE=31536000
|
||
|
||
# Login-Ratenbegrenzung
|
||
LOGIN_MAX_ATTEMPTS=5
|
||
LOGIN_LOCKOUT_SECONDS=900
|
||
|
||
# --- Datenschutz ----------------------------------------------
|
||
# none = IP wird gar nicht gespeichert (Standard, DSGVO-freundlich)
|
||
# hash = nur ein gesalzener, gekuerzter Hash (fuer Unique-Zaehlung)
|
||
TRACK_IP=none
|
||
# Zufaelliger Salt, nur relevant bei TRACK_IP=hash
|
||
IP_HASH_SALT=
|
||
|
||
# Tage, nach denen einzelne Besuchsdatensaetze automatisch geloescht
|
||
# werden (0 = nie loeschen). Die Gesamt-Klickzahl bleibt erhalten.
|
||
VISIT_RETENTION_DAYS=365
|
||
|
||
# --- Uploads (QR-Logos) ---------------------------------------
|
||
# Ablage der Logos, relativ zum Projekt-Stammverzeichnis.
|
||
# Liegt bewusst ausserhalb des Webroots.
|
||
UPLOAD_DIR=data/uploads
|
||
UPLOAD_MAX_BYTES=2097152
|