Legacy-Abbau Schritt 2: Legacy-Authentifizierung entfernt
Die Zugriffspruefung lief bisher in 19 Dateien auf einen Fallback gegen die Legacy-Tabelle kl_Mitarbeiter (checkKaffeelisteAdmin/-Access). Der Zugang haengt jetzt ausschliesslich an der SaaS-Anmeldung. - Fallback-Bloecke in allen 19 Dateien entfernt, ebenso getUserName/getUserId - functions.php besteht nur noch aus der SaaS-Anmeldung; die per String zusammengebaute Abfrage "WHERE Email like '<eingabe>'" ist damit weg - config.php baut keine sqlsrv-Verbindung mehr auf, der Kompatibilitaetslayer lib/sqlsrv_mysql_compat.php ist verwaist und entfaellt - Auto-Login per DEV_AUTH_EMAIL gibt es nicht mehr: er meldete jeden Besucher an und machte damit den Login-Schutz unpruefbar. Angemeldet wird auch lokal ueber login.php; die Variable dient nur noch scripts/init-mysql-dev.php http-smoke war an die Golden-Master-Daten des Default-Mandanten gebunden und hatte deshalb sechs dauerhaft rote Pruefungen. Der Test legt sich jetzt einen eigenen Mandanten mit bekannten Salden an, meldet sich per HTTP an und raeumt danach auf. Geschuetzte Seiten werden nicht mehr ueber das Wort "Login" im Text geprueft, sondern ueber die tatsaechliche 302-Umleitung. http-smoke 27 PASS / 6 FAIL -> 33 PASS / 0 FAIL role-matrix 55 PASS / 0 FAIL -> unveraendert tenant-isolation 9 PASS / 1 FAIL -> 11 PASS / 1 FAIL (Altfehler) Ausserdem "keine Zugang" -> "keinen Zugang" in zwei Fehlermeldungen; der Rollentest erkannte die Ablehnung an genau diesem Tippfehler und wurde mitgezogen. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
-20
@@ -3,23 +3,3 @@
|
|||||||
require_once __DIR__ . '/app/bootstrap.php';
|
require_once __DIR__ . '/app/bootstrap.php';
|
||||||
|
|
||||||
app_start_session();
|
app_start_session();
|
||||||
|
|
||||||
if ((getenv('APP_DB_DRIVER') ?: '') === 'mysql' && !function_exists('sqlsrv_connect')) {
|
|
||||||
require_once __DIR__ . '/lib/sqlsrv_mysql_compat.php';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verbindung zur Datenbank herstellen (ersetze die Platzhalter durch deine Daten)
|
|
||||||
$serverName = getenv('DB_HOST') ?: "";
|
|
||||||
$connectionOptions = array(
|
|
||||||
"Database" => getenv('DB_NAME') ?: "",
|
|
||||||
"Uid" => getenv('DB_USER') ?: "",
|
|
||||||
"PWD" => getenv('DB_PASS') ?: "",
|
|
||||||
"TrustServerCertificate"=>true
|
|
||||||
);
|
|
||||||
|
|
||||||
$conn = sqlsrv_connect($serverName, $connectionOptions);
|
|
||||||
// Überprüfen der Verbindung
|
|
||||||
if (!$conn) {
|
|
||||||
die(print_r(sqlsrv_errors(), true));
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
|
|||||||
@@ -28,14 +28,6 @@ if ($saasUser !== null && saas_user_has_role(['owner', 'admin', 'treasurer'], $s
|
|||||||
$hasAccess = true;
|
$hasAccess = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$hasAccess && $saasUser === null && checkKaffeelisteAdmin($conn, $mailadress)) {
|
|
||||||
$tenant = ledger_fetch_default_tenant($pdo);
|
|
||||||
if ($tenant !== null) {
|
|
||||||
$tenantId = (int)$tenant['id'];
|
|
||||||
$hasAccess = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$hasAccess) {
|
if (!$hasAccess) {
|
||||||
echo "<h2>Kein Zugriff</h2>";
|
echo "<h2>Kein Zugriff</h2>";
|
||||||
include "footer.php";
|
include "footer.php";
|
||||||
|
|||||||
@@ -28,14 +28,6 @@ if ($saasUser !== null && saas_user_has_role(['owner', 'admin', 'treasurer'], $s
|
|||||||
$hasAccess = true;
|
$hasAccess = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$hasAccess && $saasUser === null && checkKaffeelisteAdmin($conn, $mailadress)) {
|
|
||||||
$tenant = ledger_fetch_default_tenant($pdo);
|
|
||||||
if ($tenant !== null) {
|
|
||||||
$tenantId = (int)$tenant['id'];
|
|
||||||
$hasAccess = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$hasAccess) {
|
if (!$hasAccess) {
|
||||||
echo "<h2>Kein Zugriff</h2>";
|
echo "<h2>Kein Zugriff</h2>";
|
||||||
include "footer.php";
|
include "footer.php";
|
||||||
|
|||||||
@@ -57,8 +57,7 @@ putenv('PAYPAL_IMAP_USER=');
|
|||||||
putenv('PAYPAL_IMAP_PASS=');
|
putenv('PAYPAL_IMAP_PASS=');
|
||||||
putenv('PAYPAL_IMAP_MAILBOX=INBOX');
|
putenv('PAYPAL_IMAP_MAILBOX=INBOX');
|
||||||
|
|
||||||
// WICHTIG: DEV_AUTH_EMAIL hier NICHT setzen (auch nicht auskommentiert
|
// Hinweis: Den frueheren Login-Bypass ueber DEV_AUTH_EMAIL gibt es nicht mehr -
|
||||||
// stehen lassen und aus Versehen aktivieren). Ist diese Variable gesetzt,
|
// die Anmeldung laeuft immer ueber login.php, auch lokal. Die Variable wird nur
|
||||||
// wird JEDER Besucher ohne echten Login automatisch als dieser Nutzer
|
// noch von scripts/init-mysql-dev.php gelesen, um beim Aufsetzen einer
|
||||||
// behandelt (Login-Bypass fuer die alte Default-Mandant-Pruefung,
|
// Entwicklungsdatenbank den ersten Benutzer anzulegen.
|
||||||
// siehe functions.php). Nur fuer den lokalen Dev-Server gedacht.
|
|
||||||
|
|||||||
@@ -14,14 +14,6 @@ if ($saasUser !== null && saas_user_has_role(['owner', 'admin', 'treasurer'], $s
|
|||||||
$hasAccess = true;
|
$hasAccess = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$hasAccess && $saasUser === null && checkKaffeelisteAdmin($conn, $mailadress)) {
|
|
||||||
$tenant = ledger_fetch_default_tenant($pdo);
|
|
||||||
if ($tenant !== null) {
|
|
||||||
$tenantId = (int)$tenant['id'];
|
|
||||||
$hasAccess = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$hasAccess) {
|
if (!$hasAccess) {
|
||||||
http_response_code(403);
|
http_response_code(403);
|
||||||
exit('Kein Zugriff.');
|
exit('Kein Zugriff.');
|
||||||
|
|||||||
@@ -31,15 +31,6 @@ if ($saasUser !== null) {
|
|||||||
$kannVerwalten = saas_user_has_role(['owner', 'admin'], $saasUser);
|
$kannVerwalten = saas_user_has_role(['owner', 'admin'], $saasUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$hasAccess && $saasUser === null && checkKaffeelisteAccess($conn, $mailadress)) {
|
|
||||||
$tenant = ledger_fetch_default_tenant($pdo);
|
|
||||||
if ($tenant !== null) {
|
|
||||||
$tenantId = (int)$tenant['id'];
|
|
||||||
$hasAccess = true;
|
|
||||||
$kannVerwalten = checkKaffeelisteAdmin($conn, $mailadress);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$hasAccess) {
|
if (!$hasAccess) {
|
||||||
echo "<h2>Kein Zugriff</h2>";
|
echo "<h2>Kein Zugriff</h2>";
|
||||||
include "footer.php";
|
include "footer.php";
|
||||||
|
|||||||
+2
-3
@@ -13,11 +13,10 @@ $saasNavUser = function_exists('saas_current_user') ? saas_current_user() : null
|
|||||||
$saasCanUseLedgerNav = $saasNavUser !== null
|
$saasCanUseLedgerNav = $saasNavUser !== null
|
||||||
&& function_exists('saas_user_has_role')
|
&& function_exists('saas_user_has_role')
|
||||||
&& saas_user_has_role(['owner', 'admin', 'treasurer'], $saasNavUser);
|
&& saas_user_has_role(['owner', 'admin', 'treasurer'], $saasNavUser);
|
||||||
$legacyCanUseAdminNav = checkKaffeelisteAdmin($conn, $mailadress);
|
|
||||||
$saasCanManageMembersNav = $saasNavUser !== null
|
$saasCanManageMembersNav = $saasNavUser !== null
|
||||||
&& function_exists('saas_user_has_role')
|
&& function_exists('saas_user_has_role')
|
||||||
&& saas_user_has_role(['owner', 'admin'], $saasNavUser);
|
&& saas_user_has_role(['owner', 'admin'], $saasNavUser);
|
||||||
$canUseVerwaltungGroup = $saasCanUseLedgerNav || $legacyCanUseAdminNav;
|
$canUseVerwaltungGroup = $saasCanUseLedgerNav;
|
||||||
?>
|
?>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
@@ -37,7 +36,7 @@ $canUseVerwaltungGroup = $saasCanUseLedgerNav || $legacyCanUseAdminNav;
|
|||||||
<li><a href="kaffeeliste.php">Kaffeeliste anzeigen</a></li>
|
<li><a href="kaffeeliste.php">Kaffeeliste anzeigen</a></li>
|
||||||
<li><a href="ledger-preview.php">Journal-Vorschau</a></li>
|
<li><a href="ledger-preview.php">Journal-Vorschau</a></li>
|
||||||
<li><a href="jahresauswertung.php">Jahresabschluss</a></li>
|
<li><a href="jahresauswertung.php">Jahresabschluss</a></li>
|
||||||
<?php if ($saasCanManageMembersNav || $legacyCanUseAdminNav): ?>
|
<?php if ($saasCanManageMembersNav): ?>
|
||||||
<li><a href="mitarbeiterverwalten.php">Mitglieder verwalten</a></li>
|
<li><a href="mitarbeiterverwalten.php">Mitglieder verwalten</a></li>
|
||||||
<li><a href="hinweise.php">Hinweise verwalten</a></li>
|
<li><a href="hinweise.php">Hinweise verwalten</a></li>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|||||||
+1
-85
@@ -3,90 +3,6 @@
|
|||||||
include_once "config.php";
|
include_once "config.php";
|
||||||
require_once __DIR__ . "/app/saas-auth.php";
|
require_once __DIR__ . "/app/saas-auth.php";
|
||||||
|
|
||||||
$mailadress = '';
|
|
||||||
$kennung = '';
|
|
||||||
|
|
||||||
$saasUser = saas_current_user();
|
$saasUser = saas_current_user();
|
||||||
if ($saasUser !== null) {
|
$mailadress = $saasUser !== null ? strtolower(trim((string)$saasUser['email'])) : '';
|
||||||
$mailadress = strtolower(trim((string)$saasUser['email']));
|
|
||||||
$kennung = $mailadress;
|
$kennung = $mailadress;
|
||||||
} else {
|
|
||||||
$devAuthEmail = getenv('DEV_AUTH_EMAIL') ?: '';
|
|
||||||
if ($devAuthEmail !== '') {
|
|
||||||
$mailadress = strtolower(trim($devAuthEmail));
|
|
||||||
$kennung = $mailadress;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getUserName($conn, $mail){
|
|
||||||
if (trim((string)$mail) === '') {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
$sqlMitglieder = "SELECT Name FROM kl_Mitarbeiter WHERE Email like '" . strtolower($mail) . "' ";
|
|
||||||
$stmtMitglieder = sqlsrv_query($conn, $sqlMitglieder);
|
|
||||||
#$row = sqlsrv_fetch_array($stmtMitglieder, SQLSRV_FETCH_ASSOC)
|
|
||||||
while( $row = sqlsrv_fetch_array( $stmtMitglieder, SQLSRV_FETCH_ASSOC) ) {
|
|
||||||
return trim($row['Name']);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function getUserId($conn, $mail){
|
|
||||||
if (trim((string)$mail) === '') {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$sqlMitglieder = "SELECT MitarbeiterID FROM kl_Mitarbeiter WHERE Email like '" . strtolower($mail) . "' ";
|
|
||||||
$stmtMitglieder = sqlsrv_query($conn, $sqlMitglieder);
|
|
||||||
#$row = sqlsrv_fetch_array($stmtMitglieder, SQLSRV_FETCH_ASSOC)
|
|
||||||
while( $row = sqlsrv_fetch_array( $stmtMitglieder, SQLSRV_FETCH_ASSOC) ) {
|
|
||||||
return trim($row['MitarbeiterID']);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function checkKaffeelisteAccess($conn, $mail)
|
|
||||||
{
|
|
||||||
if (trim((string)$mail) === '') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mitarbeiter aus der Datenbank abrufen und nach Namen sortieren
|
|
||||||
$sqlMitarbeiter = "SELECT MitarbeiterID FROM kl_Mitarbeiter WHERE Email like '" . strtolower($mail) . "' AND aktiv='1'";
|
|
||||||
|
|
||||||
$stmtMitarbeiter = sqlsrv_query($conn, $sqlMitarbeiter, array(), array("Scrollable"=>"buffered"));
|
|
||||||
$row_count = sqlsrv_num_rows( $stmtMitarbeiter );
|
|
||||||
#return $row_count;
|
|
||||||
if ($row_count == 1)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}else{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkKaffeelisteAdmin($conn, $mail)
|
|
||||||
{
|
|
||||||
if (trim((string)$mail) === '') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mitarbeiter aus der Datenbank abrufen und nach Namen sortieren
|
|
||||||
$sqlMitarbeiter = "SELECT MitarbeiterID FROM kl_Mitarbeiter WHERE Email like '" . strtolower($mail) . "' AND admin='1'";
|
|
||||||
|
|
||||||
$stmtMitarbeiter = sqlsrv_query($conn, $sqlMitarbeiter, array(), array("Scrollable"=>"buffered"));
|
|
||||||
$row_count = sqlsrv_num_rows( $stmtMitarbeiter );
|
|
||||||
#return $row_count;
|
|
||||||
if ($row_count == 1)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}else{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|||||||
+1
-9
@@ -30,14 +30,6 @@ if ($saasUser !== null && saas_user_has_role(['owner', 'admin'], $saasUser)) {
|
|||||||
$hasAccess = true;
|
$hasAccess = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$hasAccess && $saasUser === null && checkKaffeelisteAdmin($conn, $mailadress)) {
|
|
||||||
$tenant = ledger_fetch_default_tenant($pdo);
|
|
||||||
if ($tenant !== null) {
|
|
||||||
$tenantId = (int)$tenant['id'];
|
|
||||||
$hasAccess = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if($hasAccess){
|
if($hasAccess){
|
||||||
|
|
||||||
echo "<h2>Kaffeeliste - Hinweise</h2>";
|
echo "<h2>Kaffeeliste - Hinweise</h2>";
|
||||||
@@ -101,7 +93,7 @@ if($hasAccess){
|
|||||||
|
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
echo "<h2>Sie haben keine Zugang zu dieser Webseite</h2>";
|
echo "<h2>Sie haben keinen Zugang zu dieser Webseite</h2>";
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ $pdo = app_db_pdo();
|
|||||||
$saasUser = saas_current_user($pdo);
|
$saasUser = saas_current_user($pdo);
|
||||||
$tenantId = 0;
|
$tenantId = 0;
|
||||||
$hasAccess = false;
|
$hasAccess = false;
|
||||||
$emailNorm = strtolower(trim($mailadress));
|
$emailNorm = '';
|
||||||
|
|
||||||
if ($saasUser !== null) {
|
if ($saasUser !== null) {
|
||||||
$tenantId = (int)$saasUser['tenant_id'];
|
$tenantId = (int)$saasUser['tenant_id'];
|
||||||
@@ -29,14 +29,6 @@ if ($saasUser !== null) {
|
|||||||
$hasAccess = true;
|
$hasAccess = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$hasAccess && checkKaffeelisteAccess($conn, $mailadress)) {
|
|
||||||
$tenant = ledger_fetch_default_tenant($pdo);
|
|
||||||
if ($tenant !== null) {
|
|
||||||
$tenantId = (int)$tenant['id'];
|
|
||||||
$hasAccess = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$participant = null;
|
$participant = null;
|
||||||
if ($hasAccess) {
|
if ($hasAccess) {
|
||||||
// Eingeloggte SaaS-Nutzer werden primaer ueber die feste user_id-
|
// Eingeloggte SaaS-Nutzer werden primaer ueber die feste user_id-
|
||||||
@@ -90,19 +82,14 @@ function dashboard_date(string $value): string
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function dashboard_current_name(?array $saasUser, ?array $participant, mixed $conn, string $mailadress): string
|
function dashboard_current_name(?array $saasUser, ?array $participant): string
|
||||||
{
|
{
|
||||||
$name = trim((string)($saasUser['display_name'] ?? ''));
|
$name = trim((string)($saasUser['display_name'] ?? ''));
|
||||||
if ($name !== '') {
|
if ($name !== '') {
|
||||||
return $name;
|
return $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
$name = trim((string)($participant['display_name'] ?? ''));
|
return trim((string)($participant['display_name'] ?? ''));
|
||||||
if ($name !== '') {
|
|
||||||
return $name;
|
|
||||||
}
|
|
||||||
|
|
||||||
return trim((string)getUserName($conn, $mailadress));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function dashboard_paypal_action(string $template, string $amount): string
|
function dashboard_paypal_action(string $template, string $amount): string
|
||||||
@@ -235,7 +222,7 @@ include "nav.php";
|
|||||||
if ($hasAccess && $participant !== null && $settings !== null) {
|
if ($hasAccess && $participant !== null && $settings !== null) {
|
||||||
$balanceCents = (int)$participant['balance_cents'];
|
$balanceCents = (int)$participant['balance_cents'];
|
||||||
$balance = dashboard_money($balanceCents);
|
$balance = dashboard_money($balanceCents);
|
||||||
$currentName = dashboard_current_name($saasUser, $participant, $conn, $mailadress);
|
$currentName = dashboard_current_name($saasUser, $participant);
|
||||||
$selfEntryEnabled = (int)$settings['self_entry_enabled'] === 1;
|
$selfEntryEnabled = (int)$settings['self_entry_enabled'] === 1;
|
||||||
$paypalEnabled = (int)$settings['paypal_enabled'] === 1
|
$paypalEnabled = (int)$settings['paypal_enabled'] === 1
|
||||||
&& trim((string)$settings['paypal_url_template']) !== '';
|
&& trim((string)$settings['paypal_url_template']) !== '';
|
||||||
|
|||||||
@@ -16,14 +16,6 @@ if ($saasUser !== null && saas_user_has_role(['owner', 'admin', 'treasurer'], $s
|
|||||||
$hasAccess = true;
|
$hasAccess = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$hasAccess && $saasUser === null && checkKaffeelisteAdmin($conn, $mailadress)) {
|
|
||||||
$tenant = ledger_fetch_default_tenant($pdo);
|
|
||||||
if ($tenant !== null) {
|
|
||||||
$tenantId = (int)$tenant['id'];
|
|
||||||
$hasAccess = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$jahr = (int)date('Y');
|
$jahr = (int)date('Y');
|
||||||
$fehler = null;
|
$fehler = null;
|
||||||
$ergebnisse = null;
|
$ergebnisse = null;
|
||||||
|
|||||||
@@ -18,14 +18,6 @@ if ($saasUser !== null && saas_user_has_role(['owner', 'admin', 'treasurer'], $s
|
|||||||
$hasAccess = true;
|
$hasAccess = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$hasAccess && $saasUser === null && checkKaffeelisteAdmin($conn, $mailadress)) {
|
|
||||||
$tenant = ledger_fetch_default_tenant($pdo);
|
|
||||||
if ($tenant !== null) {
|
|
||||||
$tenantId = (int)$tenant['id'];
|
|
||||||
$hasAccess = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$participants = $hasAccess
|
$participants = $hasAccess
|
||||||
? ledger_fetch_participant_summaries($pdo, $tenantId, ['active_only' => true])
|
? ledger_fetch_participant_summaries($pdo, $tenantId, ['active_only' => true])
|
||||||
: [];
|
: [];
|
||||||
|
|||||||
@@ -15,21 +15,6 @@ if ($saasUser !== null && saas_user_has_role(['owner', 'admin', 'treasurer'], $s
|
|||||||
$tenantId = (int)$saasUser['tenant_id'];
|
$tenantId = (int)$saasUser['tenant_id'];
|
||||||
$tenantName = (string)$saasUser['tenant_name'];
|
$tenantName = (string)$saasUser['tenant_name'];
|
||||||
$tenantSlug = (string)$saasUser['tenant_slug'];
|
$tenantSlug = (string)$saasUser['tenant_slug'];
|
||||||
} elseif (checkKaffeelisteAdmin($conn, $mailadress)) {
|
|
||||||
$defaultTenantSlug = getenv('M3_DEFAULT_TENANT_SLUG');
|
|
||||||
$defaultTenantSlug = $defaultTenantSlug !== false && trim($defaultTenantSlug) !== ''
|
|
||||||
? trim($defaultTenantSlug)
|
|
||||||
: 'default';
|
|
||||||
$stmt = $pdo->prepare('SELECT id, name, slug FROM tenants WHERE slug = ? LIMIT 1');
|
|
||||||
$stmt->execute([$defaultTenantSlug]);
|
|
||||||
$tenant = $stmt->fetch();
|
|
||||||
|
|
||||||
if ($tenant !== false) {
|
|
||||||
$hasAccess = true;
|
|
||||||
$tenantId = (int)$tenant['id'];
|
|
||||||
$tenantName = (string)$tenant['name'];
|
|
||||||
$tenantSlug = (string)$tenant['slug'];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$year = ledger_current_year();
|
$year = ledger_current_year();
|
||||||
|
|||||||
@@ -27,14 +27,6 @@ if ($saasUser !== null && saas_user_has_role(['owner', 'admin', 'treasurer'], $s
|
|||||||
$hasAccess = true;
|
$hasAccess = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$hasAccess && $saasUser === null && checkKaffeelisteAdmin($conn, $mailadress)) {
|
|
||||||
$tenant = ledger_fetch_default_tenant($pdo);
|
|
||||||
if ($tenant !== null) {
|
|
||||||
$tenantId = (int)$tenant['id'];
|
|
||||||
$hasAccess = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if($hasAccess){
|
if($hasAccess){
|
||||||
|
|
||||||
// Stornieren einer Einzahlung. Gearbeitet wird auf der Ledger-ID, weil nur die
|
// Stornieren einer Einzahlung. Gearbeitet wird auf der Ledger-ID, weil nur die
|
||||||
|
|||||||
@@ -1,245 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
if (!defined('SQLSRV_FETCH_ASSOC')) {
|
|
||||||
define('SQLSRV_FETCH_ASSOC', 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!defined('SQLSRV_FETCH_NUMERIC')) {
|
|
||||||
define('SQLSRV_FETCH_NUMERIC', 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
final class MysqlSqlsrvConnection
|
|
||||||
{
|
|
||||||
public PDO $pdo;
|
|
||||||
public ?array $lastError = null;
|
|
||||||
|
|
||||||
public function __construct(PDO $pdo)
|
|
||||||
{
|
|
||||||
$this->pdo = $pdo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final class MysqlSqlsrvStatement
|
|
||||||
{
|
|
||||||
/** @var array<int, array<string, mixed>> */
|
|
||||||
public array $rows;
|
|
||||||
public int $index = 0;
|
|
||||||
public int $affectedRows = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param array<int, array<string, mixed>> $rows
|
|
||||||
*/
|
|
||||||
public function __construct(array $rows = [], int $affectedRows = 0)
|
|
||||||
{
|
|
||||||
$this->rows = $rows;
|
|
||||||
$this->affectedRows = $affectedRows;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function sqlsrv_connect($serverName, array $connectionOptions = [])
|
|
||||||
{
|
|
||||||
$database = getenv('DB_NAME') ?: ($connectionOptions['Database'] ?? '');
|
|
||||||
$user = getenv('DB_USER') ?: ($connectionOptions['Uid'] ?? '');
|
|
||||||
$password = getenv('DB_PASS') ?: ($connectionOptions['PWD'] ?? '');
|
|
||||||
$host = getenv('DB_HOST') ?: (string)$serverName;
|
|
||||||
$port = getenv('DB_PORT') ?: '3306';
|
|
||||||
|
|
||||||
try {
|
|
||||||
$dsn = sprintf('mysql:host=%s;port=%s;dbname=%s;charset=utf8mb4', $host, $port, $database);
|
|
||||||
$pdo = new PDO($dsn, $user, $password, [
|
|
||||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
|
||||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
|
||||||
PDO::ATTR_EMULATE_PREPARES => true,
|
|
||||||
]);
|
|
||||||
|
|
||||||
return new MysqlSqlsrvConnection($pdo);
|
|
||||||
} catch (Throwable $e) {
|
|
||||||
$GLOBALS['__sqlsrv_mysql_last_error'] = [[
|
|
||||||
'SQLSTATE' => $e->getCode(),
|
|
||||||
'message' => $e->getMessage(),
|
|
||||||
]];
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function sqlsrv_query($conn, string $sql, array $params = [], array $options = [])
|
|
||||||
{
|
|
||||||
if (!$conn instanceof MysqlSqlsrvConnection) {
|
|
||||||
$GLOBALS['__sqlsrv_mysql_last_error'] = [[
|
|
||||||
'SQLSTATE' => 'HY000',
|
|
||||||
'message' => 'Invalid MySQL compatibility connection.',
|
|
||||||
]];
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$translatedSql = sqlsrv_mysql_translate_query($sql);
|
|
||||||
|
|
||||||
try {
|
|
||||||
$stmt = $conn->pdo->prepare($translatedSql);
|
|
||||||
$stmt->execute(sqlsrv_mysql_normalize_params($translatedSql, $params));
|
|
||||||
|
|
||||||
if ($stmt->columnCount() > 0) {
|
|
||||||
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
||||||
foreach ($rows as &$row) {
|
|
||||||
$row = sqlsrv_mysql_normalize_row($row);
|
|
||||||
}
|
|
||||||
unset($row);
|
|
||||||
|
|
||||||
return new MysqlSqlsrvStatement($rows, $stmt->rowCount());
|
|
||||||
}
|
|
||||||
|
|
||||||
return new MysqlSqlsrvStatement([], $stmt->rowCount());
|
|
||||||
} catch (Throwable $e) {
|
|
||||||
$conn->lastError = [[
|
|
||||||
'SQLSTATE' => $e->getCode(),
|
|
||||||
'message' => $e->getMessage(),
|
|
||||||
'sql' => $translatedSql,
|
|
||||||
]];
|
|
||||||
$GLOBALS['__sqlsrv_mysql_last_error'] = $conn->lastError;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function sqlsrv_fetch_array($stmt, int $fetchType = SQLSRV_FETCH_ASSOC)
|
|
||||||
{
|
|
||||||
if (!$stmt instanceof MysqlSqlsrvStatement) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!array_key_exists($stmt->index, $stmt->rows)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$row = $stmt->rows[$stmt->index++];
|
|
||||||
|
|
||||||
if ($fetchType === SQLSRV_FETCH_NUMERIC) {
|
|
||||||
return array_values($row);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $row;
|
|
||||||
}
|
|
||||||
|
|
||||||
function sqlsrv_num_rows($stmt): int
|
|
||||||
{
|
|
||||||
if (!$stmt instanceof MysqlSqlsrvStatement) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return count($stmt->rows);
|
|
||||||
}
|
|
||||||
|
|
||||||
function sqlsrv_errors()
|
|
||||||
{
|
|
||||||
return $GLOBALS['__sqlsrv_mysql_last_error'] ?? null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function sqlsrv_close($conn): bool
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function sqlsrv_begin_transaction($conn): bool
|
|
||||||
{
|
|
||||||
return $conn instanceof MysqlSqlsrvConnection && $conn->pdo->beginTransaction();
|
|
||||||
}
|
|
||||||
|
|
||||||
function sqlsrv_commit($conn): bool
|
|
||||||
{
|
|
||||||
return $conn instanceof MysqlSqlsrvConnection && $conn->pdo->commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
function sqlsrv_rollback($conn): bool
|
|
||||||
{
|
|
||||||
return $conn instanceof MysqlSqlsrvConnection && $conn->pdo->rollBack();
|
|
||||||
}
|
|
||||||
|
|
||||||
function sqlsrv_mysql_translate_query(string $sql): string
|
|
||||||
{
|
|
||||||
$query = str_replace(["\r\n", "\r"], "\n", $sql);
|
|
||||||
$query = preg_replace('/\bdbo\./i', '', $query);
|
|
||||||
$query = preg_replace('/\[([A-Za-z0-9_]+)\]/', '`$1`', $query);
|
|
||||||
|
|
||||||
$query = preg_replace('/FORMAT\(([^,]+),\s*\'yyyy\'\)\s*=\s*FORMAT\(GETDATE\(\),\s*\'yyyy\'\)/i', 'YEAR($1) = YEAR(NOW())', $query);
|
|
||||||
$query = preg_replace('/CAST\(GETDATE\(\)\s+AS\s+DATE\)/i', 'CURDATE()', $query);
|
|
||||||
$query = preg_replace('/GETDATE\(\)/i', 'NOW()', $query);
|
|
||||||
$query = preg_replace('/SYSDATETIME\(\)/i', 'NOW()', $query);
|
|
||||||
$query = preg_replace('/CONVERT\(VARCHAR,\s*([^)]+),\s*23\)/i', 'DATE($1)', $query);
|
|
||||||
|
|
||||||
$query = preg_replace(
|
|
||||||
'/DATEADD\(DAY,\s*(-?\d+),\s*\(SELECT\s+MAX\(Datum\)\s+FROM\s+kl_Kaffeeverbrauch\s+WHERE\s+Datum\s+<\s+CURDATE\(\)\)\)/i',
|
|
||||||
'DATE_ADD((SELECT MAX(Datum) FROM kl_Kaffeeverbrauch WHERE Datum < CURDATE()), INTERVAL $1 DAY)',
|
|
||||||
$query
|
|
||||||
);
|
|
||||||
$query = preg_replace(
|
|
||||||
'/DATEADD\(DAY,\s*(-?\d+),\s*\(SELECT\s+MAX\(Datum\)\s+FROM\s+kl_Kaffeeverbrauch\s*\)\)/i',
|
|
||||||
'DATE_ADD((SELECT MAX(Datum) FROM kl_Kaffeeverbrauch), INTERVAL $1 DAY)',
|
|
||||||
$query
|
|
||||||
);
|
|
||||||
$query = preg_replace('/DATEADD\(DAY,\s*(-?\d+),\s*NOW\(\)\)/i', 'DATE_ADD(NOW(), INTERVAL $1 DAY)', $query);
|
|
||||||
|
|
||||||
$limit = null;
|
|
||||||
$query = preg_replace_callback('/^\s*SELECT\s+TOP\s+\(?\s*(\d+)\s*\)?\s+/i', function (array $matches) use (&$limit): string {
|
|
||||||
$limit = (int)$matches[1];
|
|
||||||
return 'SELECT ';
|
|
||||||
}, $query);
|
|
||||||
|
|
||||||
if ($limit !== null && !preg_match('/\bLIMIT\s+\d+\s*$/i', trim($query))) {
|
|
||||||
$query = rtrim($query, " \t\n\r\0\x0B;") . ' LIMIT ' . $limit;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $query;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PDO is stricter than the SQL Server driver used by the legacy app. Some
|
|
||||||
* legacy calls pass unused parameters, and one CSV lookup passes one value for
|
|
||||||
* two equivalent placeholders. Normalize this only in the dev adapter.
|
|
||||||
*
|
|
||||||
* @param array<int, mixed> $params
|
|
||||||
* @return array<int, mixed>
|
|
||||||
*/
|
|
||||||
function sqlsrv_mysql_normalize_params(string $sql, array $params): array
|
|
||||||
{
|
|
||||||
$normalized = array_values($params);
|
|
||||||
$placeholderCount = substr_count($sql, '?');
|
|
||||||
|
|
||||||
if ($placeholderCount === 0) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count($normalized) > $placeholderCount) {
|
|
||||||
return array_slice($normalized, 0, $placeholderCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count($normalized) < $placeholderCount && count($normalized) > 0) {
|
|
||||||
$last = $normalized[count($normalized) - 1];
|
|
||||||
while (count($normalized) < $placeholderCount) {
|
|
||||||
$normalized[] = $last;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $normalized;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param array<string, mixed> $row
|
|
||||||
* @return array<string, mixed>
|
|
||||||
*/
|
|
||||||
function sqlsrv_mysql_normalize_row(array $row): array
|
|
||||||
{
|
|
||||||
foreach ($row as $key => $value) {
|
|
||||||
if ($value === null || $value instanceof DateTimeInterface) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_string($value) && preg_match('/(datum|date|gueltig_bis|valid_)/i', (string)$key)) {
|
|
||||||
try {
|
|
||||||
$row[$key] = new DateTime($value);
|
|
||||||
} catch (Throwable $e) {
|
|
||||||
$row[$key] = $value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $row;
|
|
||||||
}
|
|
||||||
@@ -16,14 +16,6 @@ if ($saasUser !== null && saas_user_has_role(['owner', 'admin', 'treasurer'], $s
|
|||||||
$hasAccess = true;
|
$hasAccess = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$hasAccess && $saasUser === null && checkKaffeelisteAdmin($conn, $mailadress)) {
|
|
||||||
$tenant = ledger_fetch_default_tenant($pdo);
|
|
||||||
if ($tenant !== null) {
|
|
||||||
$tenantId = (int)$tenant['id'];
|
|
||||||
$hasAccess = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$ergebnisse = null;
|
$ergebnisse = null;
|
||||||
$dryRun = true;
|
$dryRun = true;
|
||||||
$liveFlash = false;
|
$liveFlash = false;
|
||||||
|
|||||||
@@ -32,14 +32,6 @@ if ($saasUser !== null && saas_user_has_role(['owner', 'admin'], $saasUser)) {
|
|||||||
$hasAccess = true;
|
$hasAccess = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$hasAccess && $saasUser === null && checkKaffeelisteAdmin($conn, $mailadress)) {
|
|
||||||
$tenant = ledger_fetch_default_tenant($pdo);
|
|
||||||
if ($tenant !== null) {
|
|
||||||
$tenantId = (int)$tenant['id'];
|
|
||||||
$hasAccess = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if($hasAccess){
|
if($hasAccess){
|
||||||
|
|
||||||
$meldung = null;
|
$meldung = null;
|
||||||
@@ -421,7 +413,7 @@ if($hasAccess){
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
echo "<h2>Sie haben keine Zugang zu dieser Webseite</h2>";
|
echo "<h2>Sie haben keinen Zugang zu dieser Webseite</h2>";
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ $hasAccess = false;
|
|||||||
|
|
||||||
if ($saasUser !== null && saas_user_has_role(['owner', 'admin'], $saasUser)) {
|
if ($saasUser !== null && saas_user_has_role(['owner', 'admin'], $saasUser)) {
|
||||||
$hasAccess = true;
|
$hasAccess = true;
|
||||||
} elseif ($saasUser === null && checkKaffeelisteAdmin($conn, $mailadress)) {
|
|
||||||
$hasAccess = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$hasAccess) {
|
if (!$hasAccess) {
|
||||||
|
|||||||
@@ -20,14 +20,6 @@ if ($saasUser !== null) {
|
|||||||
$emailNorm = strtolower(trim((string)$saasUser['email_norm']));
|
$emailNorm = strtolower(trim((string)$saasUser['email_norm']));
|
||||||
$hasAccess = true;
|
$hasAccess = true;
|
||||||
$isAdmin = saas_user_has_role(['owner', 'admin'], $saasUser);
|
$isAdmin = saas_user_has_role(['owner', 'admin'], $saasUser);
|
||||||
} elseif (checkKaffeelisteAccess($conn, $mailadress)) {
|
|
||||||
$tenant = ledger_fetch_default_tenant($pdo);
|
|
||||||
if ($tenant !== null) {
|
|
||||||
$tenantId = (int)$tenant['id'];
|
|
||||||
$hasAccess = true;
|
|
||||||
$emailNorm = strtolower(trim($mailadress));
|
|
||||||
$isAdmin = checkKaffeelisteAdmin($conn, $mailadress);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$meldung = null;
|
$meldung = null;
|
||||||
|
|||||||
@@ -15,14 +15,6 @@ if ($saasUser !== null && saas_user_has_role(['owner', 'admin', 'treasurer'], $s
|
|||||||
$hasAccess = true;
|
$hasAccess = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$hasAccess && $saasUser === null && checkKaffeelisteAdmin($conn, $mailadress)) {
|
|
||||||
$tenant = ledger_fetch_default_tenant($pdo);
|
|
||||||
if ($tenant !== null) {
|
|
||||||
$tenantId = (int)$tenant['id'];
|
|
||||||
$hasAccess = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$flash = null;
|
$flash = null;
|
||||||
if ($hasAccess && isset($_SESSION['flash_paypal'])) {
|
if ($hasAccess && isset($_SESSION['flash_paypal'])) {
|
||||||
$flash = $_SESSION['flash_paypal'];
|
$flash = $_SESSION['flash_paypal'];
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ $pages = [
|
|||||||
'mandant-einstellungen.php' => ['owner', 'admin'],
|
'mandant-einstellungen.php' => ['owner', 'admin'],
|
||||||
];
|
];
|
||||||
|
|
||||||
$denialMarkers = ['kein zugriff', 'keine zugang', 'keine berechtigung'];
|
$denialMarkers = ['kein zugriff', 'keinen zugang', 'keine berechtigung'];
|
||||||
|
|
||||||
function m8rm_looks_denied(string $body): bool
|
function m8rm_looks_denied(string $body): bool
|
||||||
{
|
{
|
||||||
|
|||||||
+208
-29
@@ -2,14 +2,31 @@
|
|||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
require __DIR__ . '/dev-db.php';
|
||||||
|
|
||||||
$baseUrl = rtrim((string)(getenv('SMOKE_BASE_URL') ?: 'http://127.0.0.1:8080'), '/');
|
$baseUrl = rtrim((string)(getenv('SMOKE_BASE_URL') ?: 'http://127.0.0.1:8080'), '/');
|
||||||
$issuePattern = '~(?:Deprecated|Warning|Fatal error|Parse error|Notice|Uncaught (?:Error|Exception))~i';
|
$issuePattern = '~(?:Deprecated|Warning|Fatal error|Parse error|Notice|Uncaught (?:Error|Exception))~i';
|
||||||
|
|
||||||
|
// Der Smoke-Test legt sich seinen eigenen Mandanten mit bekannten Zahlen an und
|
||||||
|
// meldet sich per HTTP an, statt sich auf vorhandene Daten oder eine
|
||||||
|
// Auto-Anmeldung zu verlassen. Nur so lassen sich angemeldete Seiten UND der
|
||||||
|
// Login-Schutz in einem Lauf pruefen.
|
||||||
|
$pdo = dev_pdo();
|
||||||
|
$suffix = bin2hex(random_bytes(4));
|
||||||
|
$smokeSlug = "smoke-{$suffix}";
|
||||||
|
$smokeEmail = "smoke-owner-{$suffix}@test.local";
|
||||||
|
$smokePassword = 'HttpSmokeTest123!';
|
||||||
|
$smokeTenantId = null;
|
||||||
|
|
||||||
|
// Erwartete Betraege der Testdaten (siehe smoke_seed()).
|
||||||
|
$erwartetGuthaben = '15,00 €';
|
||||||
|
$erwartetSchulden = '-4,00 €';
|
||||||
|
|
||||||
$checks = [
|
$checks = [
|
||||||
[
|
[
|
||||||
'label' => 'Landingpage',
|
'label' => 'Landingpage',
|
||||||
'path' => 'landing.php',
|
'path' => 'landing.php',
|
||||||
'contains' => ['Kaffeeliste', 'Kundenkonto anlegen', 'Mandantenfähig'],
|
'contains' => ['Kaffeeliste', 'Kundenkonto anlegen'],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'label' => 'Impressum',
|
'label' => 'Impressum',
|
||||||
@@ -34,62 +51,71 @@ $checks = [
|
|||||||
[
|
[
|
||||||
'label' => 'Dashboard',
|
'label' => 'Dashboard',
|
||||||
'path' => 'index.php',
|
'path' => 'index.php',
|
||||||
'contains' => ['Hallo Test Admin', 'Aktueller Stand', 'Jahresübersicht', 'Letzte Einzahlungen'],
|
'auth' => true,
|
||||||
|
'contains' => ['Aktueller Stand', 'Jahresübersicht', 'Letzte Einzahlungen'],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'label' => 'Striche erfassen',
|
'label' => 'Striche erfassen',
|
||||||
'path' => 'stricheintragen.php',
|
'path' => 'stricheintragen.php',
|
||||||
|
'auth' => true,
|
||||||
'contains' => ['Anzahl der Striche'],
|
'contains' => ['Anzahl der Striche'],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'label' => 'Einzahlungen erfassen',
|
'label' => 'Einzahlungen erfassen',
|
||||||
'path' => 'einzahlung.php',
|
'path' => 'einzahlung.php',
|
||||||
'contains' => ['Einzahlungen'],
|
'auth' => true,
|
||||||
|
'contains' => ['Einzahlungen', 'Bemerkung'],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'label' => 'Kaffeeliste',
|
'label' => 'Kaffeeliste',
|
||||||
'path' => 'kaffeeliste.php',
|
'path' => 'kaffeeliste.php',
|
||||||
|
'auth' => true,
|
||||||
'contains' => [
|
'contains' => [
|
||||||
'Aktive Mitarbeiter',
|
'Aktive Mitarbeiter',
|
||||||
'teilnehmerauswertung.php?participant_id=',
|
'teilnehmerauswertung.php?participant_id=',
|
||||||
'GM Negativ',
|
'Smoke Guthaben',
|
||||||
'gm-negative@test.local',
|
$erwartetGuthaben,
|
||||||
'-2,00 €',
|
'Smoke Schulden',
|
||||||
'GM Positiv',
|
$erwartetSchulden,
|
||||||
'23,60 €',
|
'Smoke Ohne Buchungen',
|
||||||
'GM Ohne Buchungen',
|
|
||||||
'0,00 €',
|
'0,00 €',
|
||||||
],
|
],
|
||||||
'not_contains' => ['GM Inaktiv'],
|
'not_contains' => ['Smoke Inaktiv'],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'label' => 'Ledger Preview',
|
'label' => 'Ledger Preview',
|
||||||
'path' => 'ledger-preview.php',
|
'path' => 'ledger-preview.php',
|
||||||
'contains' => ['Ledger Preview', 'Tenant-Summen', 'Letzte Ledger-Buchungen'],
|
'auth' => true,
|
||||||
|
'contains' => ['Journal-Vorschau', 'Tenant-Summen', 'Letzte Ledger-Buchungen'],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'label' => 'Mitgliederverwaltung',
|
'label' => 'Mitgliederverwaltung',
|
||||||
'path' => 'mitarbeiterverwalten.php',
|
'path' => 'mitarbeiterverwalten.php',
|
||||||
|
'auth' => true,
|
||||||
'contains' => ['Mitglieder verwalten', 'PayPal-Name'],
|
'contains' => ['Mitglieder verwalten', 'PayPal-Name'],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'label' => 'Letzte Einträge',
|
'label' => 'Letzte Einträge',
|
||||||
'path' => 'letzteneintraege.php',
|
'path' => 'letzteneintraege.php',
|
||||||
'contains' => ['Letzte 100 Einzahlungen'],
|
'auth' => true,
|
||||||
|
'contains' => ['Letzte 100 Einzahlungen', 'Stornieren'],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'label' => 'CSV-Upload',
|
'label' => 'CSV-Upload',
|
||||||
'path' => 'csvupload.php',
|
'path' => 'csvupload.php',
|
||||||
'contains' => ['CSV Verarbeitung'],
|
'auth' => true,
|
||||||
|
'contains' => ['CSV-Import'],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'label' => 'Hinweise',
|
'label' => 'Hinweise',
|
||||||
'path' => 'hinweise.php',
|
'path' => 'hinweise.php',
|
||||||
|
'auth' => true,
|
||||||
'contains' => ['Kaffeeliste - Hinweise'],
|
'contains' => ['Kaffeeliste - Hinweise'],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'label' => 'FAQ',
|
'label' => 'FAQ',
|
||||||
'path' => 'faq.php',
|
'path' => 'faq.php',
|
||||||
|
'auth' => true,
|
||||||
'contains' => ['FAQ - Kaffeeliste'],
|
'contains' => ['FAQ - Kaffeeliste'],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
@@ -110,7 +136,8 @@ $checks = [
|
|||||||
[
|
[
|
||||||
'label' => 'Mandantenauswahl Login-Schutz',
|
'label' => 'Mandantenauswahl Login-Schutz',
|
||||||
'path' => 'mandant-auswahl.php',
|
'path' => 'mandant-auswahl.php',
|
||||||
'contains' => ['Login'],
|
'expect_redirect' => 'login.php',
|
||||||
|
'contains' => [],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'label' => 'Passwort zurücksetzen Invalid',
|
'label' => 'Passwort zurücksetzen Invalid',
|
||||||
@@ -125,61 +152,73 @@ $checks = [
|
|||||||
[
|
[
|
||||||
'label' => 'Mandant-Einstellungen Login-Schutz',
|
'label' => 'Mandant-Einstellungen Login-Schutz',
|
||||||
'path' => 'mandant-einstellungen.php',
|
'path' => 'mandant-einstellungen.php',
|
||||||
'contains' => ['Login'],
|
'expect_redirect' => 'login.php',
|
||||||
|
'contains' => [],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'label' => 'Namensanpassung',
|
'label' => 'Namensanpassung',
|
||||||
'path' => 'namenanpassen.php',
|
'path' => 'namenanpassen.php',
|
||||||
|
'auth' => true,
|
||||||
'contains' => ['Anzeigenamen aktualisieren'],
|
'contains' => ['Anzeigenamen aktualisieren'],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'label' => 'Datenexport Login-Schutz',
|
'label' => 'Datenexport Login-Schutz',
|
||||||
'path' => 'datenexport.php',
|
'path' => 'datenexport.php',
|
||||||
'contains' => ['Login'],
|
'expect_redirect' => 'login.php',
|
||||||
|
'contains' => [],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'label' => 'Abo-Upgrade GET-Redirect',
|
'label' => 'Abo-Upgrade GET-Redirect',
|
||||||
'path' => 'abo-upgrade.php',
|
'path' => 'abo-upgrade.php',
|
||||||
'contains' => ['Login'],
|
'expect_redirect' => 'login.php',
|
||||||
|
'contains' => [],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'label' => 'Abo-Portal GET-Redirect',
|
'label' => 'Abo-Portal GET-Redirect',
|
||||||
'path' => 'abo-portal.php',
|
'path' => 'abo-portal.php',
|
||||||
'contains' => ['Login'],
|
'expect_redirect' => 'login.php',
|
||||||
|
'contains' => [],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'label' => 'Mandant löschen Login-Schutz',
|
'label' => 'Mandant löschen Login-Schutz',
|
||||||
'path' => 'mandant-loeschen.php',
|
'path' => 'mandant-loeschen.php',
|
||||||
'contains' => ['Login'],
|
'expect_redirect' => 'login.php',
|
||||||
|
'contains' => [],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'label' => 'Back-Office Login-Schutz',
|
'label' => 'Back-Office Login-Schutz',
|
||||||
'path' => 'backoffice.php',
|
'path' => 'backoffice.php',
|
||||||
'contains' => ['Login'],
|
'expect_redirect' => 'login.php',
|
||||||
|
'contains' => [],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'label' => 'Back-Office Mandantendetail Login-Schutz',
|
'label' => 'Back-Office Mandantendetail Login-Schutz',
|
||||||
'path' => 'backoffice-mandant.php?tenant_id=1',
|
'path' => 'backoffice-mandant.php?tenant_id=1',
|
||||||
'contains' => ['Login'],
|
'expect_redirect' => 'login.php',
|
||||||
|
'contains' => [],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'label' => 'Teilnehmerauswertung',
|
'label' => 'Teilnehmerauswertung',
|
||||||
'path' => 'teilnehmerauswertung.php?user_id=1',
|
'path' => 'PLATZHALTER_TEILNEHMER',
|
||||||
'contains' => ['Auswertung', 'Test Admin', 'Jahresübersicht', 'Letzte Einzahlungen'],
|
'auth' => true,
|
||||||
|
'contains' => ['Auswertung', 'Smoke Guthaben', 'Jahresübersicht', 'Letzte Einzahlungen'],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'label' => 'PDF-Export',
|
'label' => 'PDF-Export',
|
||||||
'path' => 'exportKaffeeliste.php',
|
'path' => 'exportKaffeeliste.php',
|
||||||
|
'auth' => true,
|
||||||
'contains' => ['%PDF'],
|
'contains' => ['%PDF'],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'label' => 'Mailversand',
|
'label' => 'Mailversand',
|
||||||
'path' => 'mailversenden.php',
|
'path' => 'mailversenden.php',
|
||||||
|
'auth' => true,
|
||||||
'contains' => ['Info-Mail versenden', 'Dry-Run', 'Versandlog'],
|
'contains' => ['Info-Mail versenden', 'Dry-Run', 'Versandlog'],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'label' => 'Jahresabschluss',
|
'label' => 'Jahresabschluss',
|
||||||
'path' => 'jahresauswertung.php',
|
'path' => 'jahresauswertung.php',
|
||||||
|
'auth' => true,
|
||||||
'contains' => ['Jahresabschluss', 'Dry-Run', 'Jahresstriche gesamt'],
|
'contains' => ['Jahresabschluss', 'Dry-Run', 'Jahresstriche gesamt'],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
@@ -190,25 +229,52 @@ $knownIssueChecks = [
|
|||||||
$skippedUnsafe = [
|
$skippedUnsafe = [
|
||||||
];
|
];
|
||||||
|
|
||||||
function smoke_fetch(string $url): array
|
/**
|
||||||
|
* HTTP-Request mit optionalem Cookie-Jar. $cookies wird per Referenz
|
||||||
|
* aktualisiert, damit die Session ueber mehrere Requests erhalten bleibt.
|
||||||
|
*
|
||||||
|
* @param array<string,string>|null $cookies null = bewusst ohne Session
|
||||||
|
*/
|
||||||
|
function smoke_fetch(string $url, ?array &$cookies = null, string $method = 'GET', ?string $postBody = null): array
|
||||||
{
|
{
|
||||||
|
$header = "User-Agent: KaffeelisteHttpSmoke/1.0\r\n";
|
||||||
|
if ($cookies !== null && $cookies !== []) {
|
||||||
|
$pairs = [];
|
||||||
|
foreach ($cookies as $name => $value) {
|
||||||
|
$pairs[] = "{$name}={$value}";
|
||||||
|
}
|
||||||
|
$header .= 'Cookie: ' . implode('; ', $pairs) . "\r\n";
|
||||||
|
}
|
||||||
|
if ($postBody !== null) {
|
||||||
|
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
|
||||||
|
}
|
||||||
|
|
||||||
$context = stream_context_create([
|
$context = stream_context_create([
|
||||||
'http' => [
|
'http' => [
|
||||||
'method' => 'GET',
|
'method' => $method,
|
||||||
'timeout' => 15,
|
'timeout' => 15,
|
||||||
'ignore_errors' => true,
|
'ignore_errors' => true,
|
||||||
'header' => "User-Agent: KaffeelisteHttpSmoke/1.0\r\n",
|
'follow_location' => 0,
|
||||||
|
'header' => $header,
|
||||||
|
'content' => $postBody ?? '',
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$body = @file_get_contents($url, false, $context);
|
$body = @file_get_contents($url, false, $context);
|
||||||
$headers = $http_response_header ?? [];
|
$headers = $http_response_header ?? [];
|
||||||
$status = 0;
|
$status = 0;
|
||||||
|
$location = null;
|
||||||
|
|
||||||
foreach ($headers as $header) {
|
foreach ($headers as $h) {
|
||||||
if (preg_match('~^HTTP/\S+\s+(\d{3})~', $header, $matches) === 1) {
|
if (preg_match('~^HTTP/\S+\s+(\d{3})~', $h, $matches) === 1) {
|
||||||
$status = (int)$matches[1];
|
$status = (int)$matches[1];
|
||||||
}
|
}
|
||||||
|
if (preg_match('/^Location:\s*(.+)$/i', $h, $m) === 1) {
|
||||||
|
$location = trim($m[1]);
|
||||||
|
}
|
||||||
|
if ($cookies !== null && preg_match('/^Set-Cookie:\s*([^=;]+)=([^;]+)/i', $h, $m) === 1) {
|
||||||
|
$cookies[$m[1]] = $m[2];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($body === false) {
|
if ($body === false) {
|
||||||
@@ -216,6 +282,7 @@ function smoke_fetch(string $url): array
|
|||||||
return [
|
return [
|
||||||
'status' => $status,
|
'status' => $status,
|
||||||
'body' => '',
|
'body' => '',
|
||||||
|
'location' => $location,
|
||||||
'error' => $error['message'] ?? 'Unknown HTTP error',
|
'error' => $error['message'] ?? 'Unknown HTTP error',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -223,10 +290,69 @@ function smoke_fetch(string $url): array
|
|||||||
return [
|
return [
|
||||||
'status' => $status,
|
'status' => $status,
|
||||||
'body' => $body,
|
'body' => $body,
|
||||||
|
'location' => $location,
|
||||||
'error' => null,
|
'error' => null,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Legt einen eigenen Mandanten mit bekannten Zahlen an:
|
||||||
|
* - "Smoke Guthaben" +20,00 € Einzahlung, 25 Striche a 0,20 € = 15,00 €
|
||||||
|
* - "Smoke Schulden" keine Einzahlung, 20 Striche a 0,20 € = -4,00 €
|
||||||
|
* - "Smoke Ohne Buchungen" nichts = 0,00 €
|
||||||
|
* - "Smoke Inaktiv" inaktiv, darf in der Kaffeeliste fehlen
|
||||||
|
*
|
||||||
|
* @return array{tenant_id:int, participant_id:int}
|
||||||
|
*/
|
||||||
|
function smoke_seed(PDO $pdo, string $slug, string $email, string $password, string $suffix): array
|
||||||
|
{
|
||||||
|
$pdo->prepare('INSERT INTO tenants (slug, name, status) VALUES (?, ?, ?)')
|
||||||
|
->execute([$slug, 'HTTP-Smoke Mandant', 'active']);
|
||||||
|
$tenantId = (int)$pdo->lastInsertId();
|
||||||
|
$pdo->prepare('INSERT INTO tenant_settings (tenant_id) VALUES (?)')->execute([$tenantId]);
|
||||||
|
|
||||||
|
$pdo->prepare('INSERT INTO users (email, email_norm, display_name, password_hash, status) VALUES (?, ?, ?, ?, ?)')
|
||||||
|
->execute([$email, $email, 'Smoke Owner', password_hash($password, PASSWORD_DEFAULT), 'active']);
|
||||||
|
$userId = (int)$pdo->lastInsertId();
|
||||||
|
$pdo->prepare('INSERT INTO tenant_memberships (tenant_id, user_id, role, status, joined_at) VALUES (?, ?, ?, ?, NOW())')
|
||||||
|
->execute([$tenantId, $userId, 'owner', 'active']);
|
||||||
|
|
||||||
|
$insertParticipant = $pdo->prepare(
|
||||||
|
'INSERT INTO participants (tenant_id, user_id, display_name, email, email_norm, active) VALUES (?, ?, ?, ?, ?, ?)'
|
||||||
|
);
|
||||||
|
$ids = [];
|
||||||
|
foreach ([['Smoke Guthaben', $userId, 1], ['Smoke Schulden', null, 1], ['Smoke Ohne Buchungen', null, 1], ['Smoke Inaktiv', null, 0]] as [$name, $uid, $active]) {
|
||||||
|
$mail = strtolower(str_replace(' ', '-', $name)) . "-{$suffix}@test.local";
|
||||||
|
$insertParticipant->execute([$tenantId, $uid, $name, $mail, $mail, $active]);
|
||||||
|
$ids[$name] = (int)$pdo->lastInsertId();
|
||||||
|
}
|
||||||
|
|
||||||
|
$payment = $pdo->prepare(
|
||||||
|
"INSERT INTO ledger_entries (tenant_id, participant_id, type, amount_cents, booked_at, source) VALUES (?, ?, 'payment', ?, NOW(), 'manual_bulk')"
|
||||||
|
);
|
||||||
|
$consumption = $pdo->prepare(
|
||||||
|
"INSERT INTO ledger_entries (tenant_id, participant_id, type, amount_cents, marks_count, unit_price_cents, booked_at, source) VALUES (?, ?, 'consumption', ?, ?, 20, NOW(), 'manual_bulk')"
|
||||||
|
);
|
||||||
|
$payment->execute([$tenantId, $ids['Smoke Guthaben'], 2000]);
|
||||||
|
$consumption->execute([$tenantId, $ids['Smoke Guthaben'], -500, 25]);
|
||||||
|
$consumption->execute([$tenantId, $ids['Smoke Schulden'], -400, 20]);
|
||||||
|
|
||||||
|
return ['tenant_id' => $tenantId, 'participant_id' => $ids['Smoke Guthaben']];
|
||||||
|
}
|
||||||
|
|
||||||
|
function smoke_cleanup(PDO $pdo, ?int $tenantId, string $email): void
|
||||||
|
{
|
||||||
|
if ($tenantId === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$pdo->prepare('DELETE FROM ledger_entries WHERE tenant_id = ?')->execute([$tenantId]);
|
||||||
|
$pdo->prepare('DELETE FROM participants WHERE tenant_id = ?')->execute([$tenantId]);
|
||||||
|
$pdo->prepare('DELETE FROM tenant_memberships WHERE tenant_id = ?')->execute([$tenantId]);
|
||||||
|
$pdo->prepare('DELETE FROM tenant_settings WHERE tenant_id = ?')->execute([$tenantId]);
|
||||||
|
$pdo->prepare('DELETE FROM tenants WHERE id = ?')->execute([$tenantId]);
|
||||||
|
$pdo->prepare('DELETE FROM users WHERE email_norm = ?')->execute([strtolower($email)]);
|
||||||
|
}
|
||||||
|
|
||||||
function smoke_url(string $baseUrl, string $path): string
|
function smoke_url(string $baseUrl, string $path): string
|
||||||
{
|
{
|
||||||
return $baseUrl . '/' . ltrim($path, '/');
|
return $baseUrl . '/' . ltrim($path, '/');
|
||||||
@@ -237,9 +363,45 @@ $passes = 0;
|
|||||||
|
|
||||||
echo "HTTP smoke base URL: {$baseUrl}\n";
|
echo "HTTP smoke base URL: {$baseUrl}\n";
|
||||||
|
|
||||||
|
// Testmandant anlegen und per HTTP anmelden.
|
||||||
|
try {
|
||||||
|
$seeded = smoke_seed($pdo, $smokeSlug, $smokeEmail, $smokePassword, $suffix);
|
||||||
|
$smokeTenantId = $seeded['tenant_id'];
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
fwrite(STDERR, "HTTP smoke setup failed: {$e->getMessage()}\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pfad der Teilnehmerauswertung steht erst nach dem Seeden fest.
|
||||||
|
foreach ($checks as $i => $check) {
|
||||||
|
if ($check['path'] === 'PLATZHALTER_TEILNEHMER') {
|
||||||
|
$checks[$i]['path'] = 'teilnehmerauswertung.php?participant_id=' . $seeded['participant_id'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$authCookies = [];
|
||||||
|
$loginPage = smoke_fetch(smoke_url($baseUrl, 'login.php'), $authCookies);
|
||||||
|
preg_match('/name="csrf_token" value="([^"]+)"/', $loginPage['body'], $csrfMatch);
|
||||||
|
smoke_fetch(smoke_url($baseUrl, 'login.php'), $authCookies, 'POST', http_build_query([
|
||||||
|
'csrf_token' => $csrfMatch[1] ?? '',
|
||||||
|
'email' => $smokeEmail,
|
||||||
|
'password' => $smokePassword,
|
||||||
|
'tenant_slug' => $smokeSlug,
|
||||||
|
]));
|
||||||
|
|
||||||
|
if (empty($authCookies)) {
|
||||||
|
smoke_cleanup($pdo, $smokeTenantId, $smokeEmail);
|
||||||
|
fwrite(STDERR, "HTTP smoke: Anmeldung fehlgeschlagen (keine Session).\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($checks as $check) {
|
foreach ($checks as $check) {
|
||||||
$url = smoke_url($baseUrl, $check['path']);
|
$url = smoke_url($baseUrl, $check['path']);
|
||||||
$response = smoke_fetch($url);
|
// Angemeldete Seiten mit Session, alles andere bewusst ohne - nur so
|
||||||
|
// laesst sich der Login-Schutz ueberhaupt pruefen.
|
||||||
|
$needsAuth = !empty($check['auth']);
|
||||||
|
$jar = $needsAuth ? $authCookies : null;
|
||||||
|
$response = smoke_fetch($url, $jar);
|
||||||
$label = $check['label'] . ' (' . $check['path'] . ')';
|
$label = $check['label'] . ' (' . $check['path'] . ')';
|
||||||
|
|
||||||
if ($response['error'] !== null) {
|
if ($response['error'] !== null) {
|
||||||
@@ -248,6 +410,21 @@ foreach ($checks as $check) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Geschuetzte Seiten muessen ohne Session auf den Login umleiten. Das
|
||||||
|
// explizit zu pruefen ist belastbarer, als der Umleitung zu folgen und im
|
||||||
|
// Ergebnis nach dem Wort "Login" zu suchen.
|
||||||
|
if (isset($check['expect_redirect'])) {
|
||||||
|
$ziel = (string)$response['location'];
|
||||||
|
if ($response['status'] !== 302 || !str_contains($ziel, $check['expect_redirect'])) {
|
||||||
|
$failures[] = "{$label}: erwartete Umleitung auf {$check['expect_redirect']}, kam HTTP {$response['status']} nach '{$ziel}'";
|
||||||
|
echo "FAIL {$label}\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$passes++;
|
||||||
|
echo "PASS {$label}\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if ($response['status'] !== 200) {
|
if ($response['status'] !== 200) {
|
||||||
$failures[] = "{$label}: expected HTTP 200, got HTTP {$response['status']}";
|
$failures[] = "{$label}: expected HTTP 200, got HTTP {$response['status']}";
|
||||||
echo "FAIL {$label}\n";
|
echo "FAIL {$label}\n";
|
||||||
@@ -308,6 +485,8 @@ foreach ($skippedUnsafe as $skip) {
|
|||||||
echo "SKIP {$skip['path']}: {$skip['reason']}\n";
|
echo "SKIP {$skip['path']}: {$skip['reason']}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
smoke_cleanup($pdo, $smokeTenantId, $smokeEmail);
|
||||||
|
|
||||||
if ($failures !== []) {
|
if ($failures !== []) {
|
||||||
echo "\nHTTP smoke failed with " . count($failures) . " failure(s):\n";
|
echo "\nHTTP smoke failed with " . count($failures) . " failure(s):\n";
|
||||||
foreach ($failures as $failure) {
|
foreach ($failures as $failure) {
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ PHP_LIB_DIR="$ROOT_DIR/.local/php/usr/lib/x86_64-linux-gnu"
|
|||||||
export LD_LIBRARY_PATH="${LD_LIBRARY_PATH:-$PHP_LIB_DIR}"
|
export LD_LIBRARY_PATH="${LD_LIBRARY_PATH:-$PHP_LIB_DIR}"
|
||||||
export APP_DB_DRIVER="${APP_DB_DRIVER:-mysql}"
|
export APP_DB_DRIVER="${APP_DB_DRIVER:-mysql}"
|
||||||
export APP_ENV="${APP_ENV:-dev}"
|
export APP_ENV="${APP_ENV:-dev}"
|
||||||
export DEV_AUTH_EMAIL="${DEV_AUTH_EMAIL:-admin@test.local}"
|
# Kein Auto-Login mehr: die Anmeldung laeuft auch lokal ueber login.php.
|
||||||
export DEV_AUTH_NAME="${DEV_AUTH_NAME:-Test Admin}"
|
# DEV_AUTH_EMAIL/DEV_AUTH_NAME werden nur noch von scripts/init-mysql-dev.php
|
||||||
|
# ausgewertet, um den ersten Entwicklungsbenutzer anzulegen.
|
||||||
|
|
||||||
exec "$PHP_BIN" -c "$PHP_INI" -S "${HOST:-127.0.0.1}:${PORT:-8080}" -t "$ROOT_DIR"
|
exec "$PHP_BIN" -c "$PHP_INI" -S "${HOST:-127.0.0.1}:${PORT:-8080}" -t "$ROOT_DIR"
|
||||||
|
|||||||
@@ -29,14 +29,6 @@ if ($saasUser !== null && saas_user_has_role(['owner', 'admin', 'treasurer'], $s
|
|||||||
$hasAccess = true;
|
$hasAccess = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$hasAccess && $saasUser === null && checkKaffeelisteAdmin($conn, $mailadress)) {
|
|
||||||
$tenant = ledger_fetch_default_tenant($pdo);
|
|
||||||
if ($tenant !== null) {
|
|
||||||
$tenantId = (int)$tenant['id'];
|
|
||||||
$hasAccess = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$hasAccess) {
|
if (!$hasAccess) {
|
||||||
echo "<h2>Kein Zugriff</h2>";
|
echo "<h2>Kein Zugriff</h2>";
|
||||||
include "footer.php";
|
include "footer.php";
|
||||||
|
|||||||
@@ -28,14 +28,6 @@ if ($saasUser !== null && saas_user_has_role(['owner', 'admin', 'treasurer'], $s
|
|||||||
$hasAccess = true;
|
$hasAccess = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$hasAccess && $saasUser === null && checkKaffeelisteAdmin($conn, $mailadress)) {
|
|
||||||
$tenant = ledger_fetch_default_tenant($pdo);
|
|
||||||
if ($tenant !== null) {
|
|
||||||
$tenantId = (int)$tenant['id'];
|
|
||||||
$hasAccess = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$participant = $hasAccess
|
$participant = $hasAccess
|
||||||
? ledger_fetch_participant_summary($pdo, $tenantId, $participantId)
|
? ledger_fetch_participant_summary($pdo, $tenantId, $participantId)
|
||||||
: null;
|
: null;
|
||||||
@@ -69,14 +61,9 @@ function teilnehmerauswertung_date(string $value): string
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function teilnehmerauswertung_current_name(?array $saasUser, mixed $conn, string $mailadress): string
|
function teilnehmerauswertung_current_name(?array $saasUser): string
|
||||||
{
|
{
|
||||||
$name = trim((string)($saasUser['display_name'] ?? ''));
|
return trim((string)($saasUser['display_name'] ?? ''));
|
||||||
if ($name !== '') {
|
|
||||||
return $name;
|
|
||||||
}
|
|
||||||
|
|
||||||
return trim((string)getUserName($conn, $mailadress));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function teilnehmerauswertung_paypal_action(string $template, string $amount): string
|
function teilnehmerauswertung_paypal_action(string $template, string $amount): string
|
||||||
@@ -128,7 +115,7 @@ include "nav.php";
|
|||||||
if ($hasAccess && $participant !== null) {
|
if ($hasAccess && $participant !== null) {
|
||||||
$balanceCents = (int)$participant['balance_cents'];
|
$balanceCents = (int)$participant['balance_cents'];
|
||||||
$balance = teilnehmerauswertung_money($balanceCents);
|
$balance = teilnehmerauswertung_money($balanceCents);
|
||||||
$currentName = teilnehmerauswertung_current_name($saasUser, $conn, $mailadress);
|
$currentName = teilnehmerauswertung_current_name($saasUser);
|
||||||
$paypalEnabled = $settings !== null
|
$paypalEnabled = $settings !== null
|
||||||
&& (int)$settings['paypal_enabled'] === 1
|
&& (int)$settings['paypal_enabled'] === 1
|
||||||
&& trim((string)$settings['paypal_url_template']) !== '';
|
&& trim((string)$settings['paypal_url_template']) !== '';
|
||||||
|
|||||||
Reference in New Issue
Block a user