$val) { $content .= "{$key}={$val}\n"; } return file_put_contents($filepath, $content) !== false; } // Main logic wrapped in a reusable function function sync_and_create_db_users( ?string $overrideUser = null, ?string $overrideUserPass = null, ?string $overrideGuest = null, ?string $overrideGuestPass = null ): array { $baseDir = dirname(__DIR__, 2); $configDir = $baseDir . '/config'; $dbEnvFile = $configDir . '/.env.db'; $userEnvFile = $configDir . '/.env.db-wkvs-user'; $guestEnvFile = $configDir . '/.env.db-guest'; // 1. Load Root DB config $dbEnv = parse_env_file_simple($dbEnvFile); $rootPass = $dbEnv['MYSQL_ROOT_PASSWORD'] ?? ''; $dbName = $dbEnv['MYSQL_DATABASE'] ?? 'devdb_'; // Target host for MySQL connection from PHP script // If running inside Docker container or host, determine host $dbHost = getenv('DB_HOST') ?: ($dbEnv['DB_HOST'] ?? 'mariadb'); $dbPort = (int)($dbEnv['DB_PORT'] ?? 3306); // Fallback connection attempt hosts $hostsToTry = [$dbHost, '127.0.0.1', 'mariadb', 'localhost']; $mysqli = null; $connectedHost = null; foreach ($hostsToTry as $tryHost) { try { $testConn = @new mysqli($tryHost, 'root', $rootPass, '', $dbPort); if (!$testConn->connect_error) { $mysqli = $testConn; $connectedHost = $tryHost; break; } } catch (Throwable $e) { continue; } } if (!$mysqli) { return [ 'success' => false, 'message' => "Konnte keine Verbindung als 'root' zu MariaDB herstellen. Bitte prüfen Sie MYSQL_ROOT_PASSWORD in config/.env.db." ]; } // 2. Load existing user env files or generate defaults $userEnv = parse_env_file_simple($userEnvFile); $guestEnv = parse_env_file_simple($guestEnvFile); // Prefix helper for usernames if creating new $dbUser = $overrideUser ?: ($userEnv['DB_USER'] ?? 'wkvs_user'); $dbPass = $overrideUserPass ?: ($userEnv['DB_PASSWORD'] ?? bin2hex(random_bytes(16))); $dbGuestUser = $overrideGuest ?: ($guestEnv['DB_GUEST_USER'] ?? 'wkvs_guest'); $dbGuestPass = $overrideGuestPass?: ($guestEnv['DB_GUEST_PASSWORD'] ?? bin2hex(random_bytes(16))); $appDbHost = $userEnv['DB_HOST'] ?? 'mariadb'; $appDbPort = $userEnv['DB_PORT'] ?? 3306; // 3. Create database if it does not exist $mysqli->query("CREATE DATABASE IF NOT EXISTS `$dbName` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"); // 4. Create or Update Normal User (SELECT, INSERT, UPDATE, DELETE) // Access is isolated to the Docker network container level via compose.yaml $escapedUser = $mysqli->real_escape_string($dbUser); $escapedPass = $mysqli->real_escape_string($dbPass); $escapedDb = $mysqli->real_escape_string($dbName); // Clean up legacy per-host entries if present $mysqli->query("DROP USER IF EXISTS '{$escapedUser}'@'%'"); // Normal User (1 user entry) $mysqli->query("CREATE USER IF NOT EXISTS '{$escapedUser}'@'%' IDENTIFIED BY '{$escapedPass}'"); $mysqli->query("ALTER USER '{$escapedUser}'@'%' IDENTIFIED BY '{$escapedPass}'"); $mysqli->query("GRANT SELECT, INSERT, UPDATE, DELETE ON `{$escapedDb}`.* TO '{$escapedUser}'@'%'"); // Guest User (SELECT only) $escapedGuest = $mysqli->real_escape_string($dbGuestUser); $escapedGuestPass = $mysqli->real_escape_string($dbGuestPass); // Clean up legacy per-host entries if present foreach (['127.0.0.1', 'localhost', '172.%.%.%', '10.%.%.%', '192.168.%.%.%'] as $oldHost) { $mysqli->query("DROP USER IF EXISTS '{$escapedGuest}'@'{$oldHost}'"); } // Guest User (1 user entry) $mysqli->query("CREATE USER IF NOT EXISTS '{$escapedGuest}'@'%' IDENTIFIED BY '{$escapedGuestPass}'"); $mysqli->query("ALTER USER '{$escapedGuest}'@'%' IDENTIFIED BY '{$escapedGuestPass}'"); $mysqli->query("GRANT SELECT ON `{$escapedDb}`.* TO '{$escapedGuest}'@'%'"); $mysqli->query("FLUSH PRIVILEGES"); $mysqli->close(); // 5. Update .env files $newUserEnvData = [ 'DB_USER' => $dbUser, 'DB_PASSWORD' => $dbPass, 'DB_NAME' => $dbName, 'DB_HOST' => $appDbHost, 'DB_PORT' => $appDbPort, ]; $newGuestEnvData = [ 'DB_GUEST_USER' => $dbGuestUser, 'DB_GUEST_PASSWORD' => $dbGuestPass, 'DB_NAME' => $dbName, 'DB_HOST' => $appDbHost, 'DB_PORT' => $appDbPort, ]; write_env_file_simple($userEnvFile, $newUserEnvData); write_env_file_simple($guestEnvFile, $newGuestEnvData); return [ 'success' => true, 'message' => 'Datenbank-Benutzer erfolgreich erstellt/aktualisiert.', 'normal_user' => [ 'username' => $dbUser, 'password' => $dbPass, ], 'guest_user' => [ 'username' => $dbGuestUser, 'password' => $dbGuestPass, ] ]; } // If invoked directly from CLI if (php_sapi_name() === 'cli' && realpath($argv[0] ?? '') === __FILE__) { echo "=== WKVS Database User Auto-Generator ===\n"; $user = $argv[1] ?? null; $userPass = $argv[2] ?? null; $guest = $argv[3] ?? null; $guestPass = $argv[4] ?? null; $result = sync_and_create_db_users($user, $userPass, $guest, $guestPass); if ($result['success']) { echo "✓ " . $result['message'] . "\n\n"; echo "Normal User (SELECT, INSERT, UPDATE, DELETE):\n"; echo " Benutzername: " . $result['normal_user']['username'] . "\n"; echo " Passwort: " . $result['normal_user']['password'] . "\n\n"; echo "Guest User (SELECT only):\n"; echo " Benutzername: " . $result['guest_user']['username'] . "\n"; echo " Passwort: " . $result['guest_user']['password'] . "\n"; } else { echo "❌ Fehler: " . $result['message'] . "\n"; exit(1); } }