diff --git a/app/Http/Controllers/Admin/DatabaseController.php b/app/Http/Controllers/Admin/DatabaseController.php index 3755166f3..67ed1bd68 100644 --- a/app/Http/Controllers/Admin/DatabaseController.php +++ b/app/Http/Controllers/Admin/DatabaseController.php @@ -9,6 +9,12 @@ use Illuminate\Http\RedirectResponse; use Prologue\Alerts\AlertsMessageBag; use Illuminate\View\Factory as ViewFactory; use Pterodactyl\Http\Controllers\Controller; +use Illuminate\Http\Request; +use Illuminate\Http\JsonResponse; +use Illuminate\Support\Facades\Log; + +use PDO; +use PDOException; use Pterodactyl\Services\Databases\Hosts\HostUpdateService; use Pterodactyl\Http\Requests\Admin\DatabaseHostFormRequest; use Pterodactyl\Services\Databases\Hosts\HostCreationService; @@ -31,8 +37,7 @@ class DatabaseController extends Controller private HostUpdateService $updateService, private LocationRepositoryInterface $locationRepository, private ViewFactory $view, - ) { - } + ) {} /** * Display database host index. @@ -126,4 +131,70 @@ class DatabaseController extends Controller return redirect()->route('admin.databases'); } + + /** + * Test database connection credentials. + * + * @throws \Illuminate\Validation\ValidationException + */ + public function testConnection(Request $request): JsonResponse + { + $this->validate($request, [ + 'host' => 'required|string', + 'port' => 'required|integer|min:1|max:65535', + 'username' => 'required|string', + 'password' => 'required|string', + ]); + Log::error("TestConnection", [ + "\nhost" => $request->host, + "\nport" => $request->port, + "\nusername" => $request->username, + "\npassword" => $request->password + ]); + + try { + $dsn = "mysql:host={$request->input('host')};port={$request->input('port')};charset=utf8"; + + $pdo = new PDO($dsn, $request->input('username'), $request->input('password'), [ + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + PDO::ATTR_TIMEOUT => 5, // 5 second timeout + ]); + + // Test basic query + $version = $pdo->query('SELECT VERSION() as version')->fetchColumn(); + + // Test GRANT permissions (this is what Pterodactyl needs) + $grants = $pdo->query('SHOW GRANTS FOR CURRENT_USER()')->fetchAll(PDO::FETCH_COLUMN); + + $hasGrantOption = false; + foreach ($grants as $grant) { + if (stripos($grant, 'GRANT OPTION') !== false) { + $hasGrantOption = true; + break; + } + } + + $message = "Successfully connected to MySQL server (Version: {$version})."; + if (!$hasGrantOption) { + $message .= " Warning: The user appears to lack GRANT OPTION permission which is required for creating databases and users."; + } + + return response()->json([ + 'success' => true, + 'message' => $message, + 'version' => $version, + 'has_grant_option' => $hasGrantOption + ]); + } catch (PDOException $e) { + return response()->json([ + 'success' => false, + 'message' => 'Connection failed: ' . $e->getMessage() + ], 422); + } catch (\Exception $e) { + return response()->json([ + 'success' => false, + 'message' => 'Error: ' . $e->getMessage() + ], 422); + } + } } diff --git a/resources/views/admin/databases/index.blade.php b/resources/views/admin/databases/index.blade.php index e4c69c513..e86ed7066 100644 --- a/resources/views/admin/databases/index.blade.php +++ b/resources/views/admin/databases/index.blade.php @@ -57,36 +57,39 @@ +