mirror of
https://github.com/pterodactyl/panel.git
synced 2024-11-26 11:02:31 +01:00
Push more changes to DBHost service.
Currently updating via the frontend is broken if you don't provide an actual node to attach it to.
This commit is contained in:
parent
cede747442
commit
0111ca7768
93
app/Extensions/DynamicDatabaseConnection.php
Normal file
93
app/Extensions/DynamicDatabaseConnection.php
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Pterodactyl - Panel
|
||||||
|
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Pterodactyl\Extensions;
|
||||||
|
|
||||||
|
use Illuminate\Config\Repository as ConfigRepository;
|
||||||
|
use Illuminate\Contracts\Encryption\Encrypter;
|
||||||
|
use Pterodactyl\Models\DatabaseHost;
|
||||||
|
|
||||||
|
class DynamicDatabaseConnection
|
||||||
|
{
|
||||||
|
const DB_CHARSET = 'utf8';
|
||||||
|
const DB_COLLATION = 'utf8_unicode_ci';
|
||||||
|
const DB_DRIVER = 'mysql';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Illuminate\Config\Repository
|
||||||
|
*/
|
||||||
|
protected $config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Illuminate\Contracts\Encryption\Encrypter
|
||||||
|
*/
|
||||||
|
protected $encrypter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Models\DatabaseHost
|
||||||
|
*/
|
||||||
|
protected $model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DynamicDatabaseConnection constructor.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Config\Repository $config
|
||||||
|
* @param \Illuminate\Contracts\Encryption\Encrypter $encrypter
|
||||||
|
* @param \Pterodactyl\Models\DatabaseHost $model
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
ConfigRepository $config,
|
||||||
|
Encrypter $encrypter,
|
||||||
|
DatabaseHost $model
|
||||||
|
) {
|
||||||
|
$this->config = $config;
|
||||||
|
$this->encrypter = $encrypter;
|
||||||
|
$this->model = $model;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a dynamic database connection entry to the runtime config.
|
||||||
|
*
|
||||||
|
* @param string $connection
|
||||||
|
* @param \Pterodactyl\Models\DatabaseHost|int $host
|
||||||
|
* @param string $database
|
||||||
|
*/
|
||||||
|
public function set($connection, $host, $database = 'mysql')
|
||||||
|
{
|
||||||
|
if (! $host instanceof DatabaseHost) {
|
||||||
|
$host = $this->model->findOrFail($host);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->config->set('database.connections.' . $connection, [
|
||||||
|
'driver' => self::DB_DRIVER,
|
||||||
|
'host' => $host->host,
|
||||||
|
'port' => $host->port,
|
||||||
|
'database' => $database,
|
||||||
|
'username' => $host->username,
|
||||||
|
'password' => $this->encrypter->decrypt($host->password),
|
||||||
|
'charset' => self::DB_CHARSET,
|
||||||
|
'collation' => self::DB_COLLATION,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
@ -24,21 +24,35 @@
|
|||||||
|
|
||||||
namespace Pterodactyl\Http\Controllers\Admin;
|
namespace Pterodactyl\Http\Controllers\Admin;
|
||||||
|
|
||||||
use Alert;
|
use Krucas\Settings\Settings;
|
||||||
use Settings;
|
use Prologue\Alerts\AlertsMessageBag;
|
||||||
use Validator;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Pterodactyl\Http\Controllers\Controller;
|
use Pterodactyl\Http\Controllers\Controller;
|
||||||
|
use Pterodactyl\Http\Requests\Admin\BaseFormRequest;
|
||||||
|
|
||||||
class BaseController extends Controller
|
class BaseController extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var \Prologue\Alerts\AlertsMessageBag
|
||||||
|
*/
|
||||||
|
protected $alert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Krucas\Settings\Settings
|
||||||
|
*/
|
||||||
|
protected $settings;
|
||||||
|
|
||||||
|
public function __construct(AlertsMessageBag $alert, Settings $settings)
|
||||||
|
{
|
||||||
|
$this->alert = $alert;
|
||||||
|
$this->settings = $settings;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the admin index view.
|
* Return the admin index view.
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Http\Request $request
|
|
||||||
* @return \Illuminate\View\View
|
* @return \Illuminate\View\View
|
||||||
*/
|
*/
|
||||||
public function getIndex(Request $request)
|
public function getIndex()
|
||||||
{
|
{
|
||||||
return view('admin.index');
|
return view('admin.index');
|
||||||
}
|
}
|
||||||
@ -46,10 +60,9 @@ class BaseController extends Controller
|
|||||||
/**
|
/**
|
||||||
* Return the admin settings view.
|
* Return the admin settings view.
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Http\Request $request
|
|
||||||
* @return \Illuminate\View\View
|
* @return \Illuminate\View\View
|
||||||
*/
|
*/
|
||||||
public function getSettings(Request $request)
|
public function getSettings()
|
||||||
{
|
{
|
||||||
return view('admin.settings');
|
return view('admin.settings');
|
||||||
}
|
}
|
||||||
@ -57,24 +70,14 @@ class BaseController extends Controller
|
|||||||
/**
|
/**
|
||||||
* Handle settings post request.
|
* Handle settings post request.
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Http\Request $request
|
* @param \Pterodactyl\Http\Requests\Admin\BaseFormRequest $request
|
||||||
* @return \Illuminate\Http\RedirectResponse
|
* @return \Illuminate\Http\RedirectResponse
|
||||||
*/
|
*/
|
||||||
public function postSettings(Request $request)
|
public function postSettings(BaseFormRequest $request)
|
||||||
{
|
{
|
||||||
$validator = Validator::make($request->all(), [
|
$this->settings->set('company', $request->input('company'));
|
||||||
'company' => 'required|between:1,256',
|
|
||||||
// 'default_language' => 'required|alpha_dash|min:2|max:5',
|
|
||||||
]);
|
|
||||||
|
|
||||||
if ($validator->fails()) {
|
$this->alert->success('Settings have been successfully updated.')->flash();
|
||||||
return redirect()->route('admin.settings')->withErrors($validator->errors())->withInput();
|
|
||||||
}
|
|
||||||
|
|
||||||
Settings::set('company', $request->input('company'));
|
|
||||||
// Settings::set('default_language', $request->input('default_language'));
|
|
||||||
|
|
||||||
Alert::success('Settings have been successfully updated.')->flash();
|
|
||||||
|
|
||||||
return redirect()->route('admin.settings');
|
return redirect()->route('admin.settings');
|
||||||
}
|
}
|
||||||
|
@ -24,112 +24,144 @@
|
|||||||
|
|
||||||
namespace Pterodactyl\Http\Controllers\Admin;
|
namespace Pterodactyl\Http\Controllers\Admin;
|
||||||
|
|
||||||
use Log;
|
|
||||||
use Alert;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Pterodactyl\Models\Database;
|
|
||||||
use Pterodactyl\Models\Location;
|
use Pterodactyl\Models\Location;
|
||||||
use Pterodactyl\Models\DatabaseHost;
|
use Pterodactyl\Models\DatabaseHost;
|
||||||
use Pterodactyl\Exceptions\DisplayException;
|
use Prologue\Alerts\AlertsMessageBag;
|
||||||
use Pterodactyl\Http\Controllers\Controller;
|
use Pterodactyl\Http\Controllers\Controller;
|
||||||
use Pterodactyl\Repositories\DatabaseRepository;
|
use Pterodactyl\Services\DatabaseHostService;
|
||||||
use Pterodactyl\Exceptions\DisplayValidationException;
|
use Pterodactyl\Http\Requests\Admin\DatabaseHostFormRequest;
|
||||||
|
|
||||||
class DatabaseController extends Controller
|
class DatabaseController extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var \Prologue\Alerts\AlertsMessageBag
|
||||||
|
*/
|
||||||
|
protected $alert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Models\DatabaseHost
|
||||||
|
*/
|
||||||
|
protected $hostModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Models\Location
|
||||||
|
*/
|
||||||
|
protected $locationModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Services\DatabaseHostService
|
||||||
|
*/
|
||||||
|
protected $service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DatabaseController constructor.
|
||||||
|
*
|
||||||
|
* @param \Prologue\Alerts\AlertsMessageBag $alert
|
||||||
|
* @param \Pterodactyl\Models\DatabaseHost $hostModel
|
||||||
|
* @param \Pterodactyl\Models\Location $locationModel
|
||||||
|
* @param \Pterodactyl\Services\DatabaseHostService $service
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
AlertsMessageBag $alert,
|
||||||
|
DatabaseHost $hostModel,
|
||||||
|
Location $locationModel,
|
||||||
|
DatabaseHostService $service
|
||||||
|
) {
|
||||||
|
$this->alert = $alert;
|
||||||
|
$this->hostModel = $hostModel;
|
||||||
|
$this->locationModel = $locationModel;
|
||||||
|
$this->service = $service;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display database host index.
|
* Display database host index.
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Http\Request $request
|
|
||||||
* @return \Illuminate\View\View
|
* @return \Illuminate\View\View
|
||||||
*/
|
*/
|
||||||
public function index(Request $request)
|
public function index()
|
||||||
{
|
{
|
||||||
return view('admin.databases.index', [
|
return view('admin.databases.index', [
|
||||||
'locations' => Location::with('nodes')->get(),
|
'locations' => $this->locationModel->with('nodes')->get(),
|
||||||
'hosts' => DatabaseHost::withCount('databases')->with('node')->get(),
|
'hosts' => $this->hostModel->withCount('databases')->with('node')->get(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display database host to user.
|
* Display database host to user.
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Http\Request $request
|
* @param \Pterodactyl\Models\DatabaseHost $host
|
||||||
* @param int $id
|
|
||||||
* @return \Illuminate\View\View
|
* @return \Illuminate\View\View
|
||||||
*/
|
*/
|
||||||
public function view(Request $request, $id)
|
public function view(DatabaseHost $host)
|
||||||
{
|
{
|
||||||
|
$host->load('databases.server');
|
||||||
|
|
||||||
return view('admin.databases.view', [
|
return view('admin.databases.view', [
|
||||||
'locations' => Location::with('nodes')->get(),
|
'locations' => $this->locationModel->with('nodes')->get(),
|
||||||
'host' => DatabaseHost::with('databases.server')->findOrFail($id),
|
'host' => $host,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle post request to create database host.
|
* Handle request to create a new database host.
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Http\Request $request
|
* @param \Pterodactyl\Http\Requests\Admin\DatabaseHostFormRequest $request
|
||||||
* @return \Illuminate\Http\RedirectResponse
|
* @return \Illuminate\Http\RedirectResponse
|
||||||
|
*
|
||||||
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
public function create(Request $request)
|
public function create(DatabaseHostFormRequest $request)
|
||||||
{
|
{
|
||||||
$repo = new DatabaseRepository;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$host = $repo->add($request->intersect([
|
$host = $this->service->create($request->normalize());
|
||||||
'name', 'username', 'password',
|
$this->alert->success('Successfully created a new database host on the system.')->flash();
|
||||||
'host', 'port', 'node_id',
|
|
||||||
]));
|
|
||||||
Alert::success('Successfully created new database host on the system.')->flash();
|
|
||||||
|
|
||||||
return redirect()->route('admin.databases.view', $host->id);
|
return redirect()->route('admin.databases.view', $host->id);
|
||||||
} catch (\PDOException $ex) {
|
} catch (\PDOException $ex) {
|
||||||
Alert::danger($ex->getMessage())->flash();
|
$this->alert->danger($ex->getMessage())->flash();
|
||||||
} catch (DisplayValidationException $ex) {
|
|
||||||
return redirect()->route('admin.databases')->withErrors(json_decode($ex->getMessage()));
|
|
||||||
} catch (\Exception $ex) {
|
|
||||||
Log::error($ex);
|
|
||||||
Alert::danger('An error was encountered while trying to process this request. This error has been logged.')->flash();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return redirect()->route('admin.databases');
|
return redirect()->route('admin.databases');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle post request to update a database host.
|
* Handle updating database host.
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Http\Request $request
|
* @param \Pterodactyl\Http\Requests\Admin\DatabaseHostFormRequest $request
|
||||||
* @param int $id
|
* @param \Pterodactyl\Models\DatabaseHost $host
|
||||||
* @return \Illuminate\Http\RedirectResponse
|
* @return \Illuminate\Http\RedirectResponse
|
||||||
|
*
|
||||||
|
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||||
*/
|
*/
|
||||||
public function update(Request $request, $id)
|
public function update(DatabaseHostFormRequest $request, DatabaseHost $host)
|
||||||
{
|
{
|
||||||
$repo = new DatabaseRepository;
|
if ($request->input('action') === 'delete') {
|
||||||
|
return $this->delete($host);
|
||||||
try {
|
|
||||||
if ($request->input('action') !== 'delete') {
|
|
||||||
$host = $repo->update($id, $request->intersect([
|
|
||||||
'name', 'username', 'password',
|
|
||||||
'host', 'port', 'node_id',
|
|
||||||
]));
|
|
||||||
Alert::success('Database host was updated successfully.')->flash();
|
|
||||||
} else {
|
|
||||||
$repo->delete($id);
|
|
||||||
|
|
||||||
return redirect()->route('admin.databases');
|
|
||||||
}
|
|
||||||
} catch (\PDOException $ex) {
|
|
||||||
Alert::danger($ex->getMessage())->flash();
|
|
||||||
} catch (DisplayException $ex) {
|
|
||||||
Alert::danger($ex->getMessage())->flash();
|
|
||||||
} catch (DisplayValidationException $ex) {
|
|
||||||
return redirect()->route('admin.databases.view', $id)->withErrors(json_decode($ex->getMessage()));
|
|
||||||
} catch (\Exception $ex) {
|
|
||||||
Log::error($ex);
|
|
||||||
Alert::danger('An error was encountered while trying to process this request. This error has been logged.')->flash();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return redirect()->route('admin.databases.view', $id);
|
try {
|
||||||
|
$host = $this->service->update($host->id, $request->normalize());
|
||||||
|
$this->alert->success('Database host was updated successfully.')->flash();
|
||||||
|
} catch (\PDOException $ex) {
|
||||||
|
$this->alert->danger($ex->getMessage())->flash();
|
||||||
|
}
|
||||||
|
|
||||||
|
return redirect()->route('admin.databases.view', $host->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle request to delete a database host.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Models\DatabaseHost $host
|
||||||
|
* @return \Illuminate\Http\RedirectResponse
|
||||||
|
*
|
||||||
|
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||||
|
*/
|
||||||
|
public function delete(DatabaseHost $host)
|
||||||
|
{
|
||||||
|
$this->service->delete($host->id);
|
||||||
|
$this->alert->success('The requested database host has been deleted from the system.')->flash();
|
||||||
|
|
||||||
|
return redirect()->route('admin.databases');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
35
app/Http/Requests/Admin/BaseFormRequest.php
Normal file
35
app/Http/Requests/Admin/BaseFormRequest.php
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Pterodactyl - Panel
|
||||||
|
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Pterodactyl\Http\Requests\Admin;
|
||||||
|
|
||||||
|
class BaseFormRequest extends AdminFormRequest
|
||||||
|
{
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'company' => 'required|between:1,256',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
49
app/Http/Requests/Admin/DatabaseHostFormRequest.php
Normal file
49
app/Http/Requests/Admin/DatabaseHostFormRequest.php
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Pterodactyl - Panel
|
||||||
|
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Pterodactyl\Http\Requests\Admin;
|
||||||
|
|
||||||
|
use Pterodactyl\Models\DatabaseHost;
|
||||||
|
|
||||||
|
class DatabaseHostFormRequest extends AdminFormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
$this->merge([
|
||||||
|
'node_id' => ($this->input('node_id') < 1) ? null : $this->input('node_id'),
|
||||||
|
'host' => gethostbyname($this->input('host')),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$rules = app()->make(DatabaseHost::class)->getRules();
|
||||||
|
|
||||||
|
if ($this->method() === 'PATCH') {
|
||||||
|
$rules['host'] = $rules['host'] . ',' . $this->route()->parameter('host')->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $rules;
|
||||||
|
}
|
||||||
|
}
|
@ -24,12 +24,13 @@
|
|||||||
|
|
||||||
namespace Pterodactyl\Models;
|
namespace Pterodactyl\Models;
|
||||||
|
|
||||||
use Crypt;
|
use Watson\Validating\ValidatingTrait;
|
||||||
use Config;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
class DatabaseHost extends Model
|
class DatabaseHost extends Model
|
||||||
{
|
{
|
||||||
|
use ValidatingTrait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The table associated with the model.
|
* The table associated with the model.
|
||||||
*
|
*
|
||||||
@ -65,24 +66,18 @@ class DatabaseHost extends Model
|
|||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the database connection name with the details of the host.
|
* Validation rules to assign to this model.
|
||||||
*
|
*
|
||||||
* @param string $connection
|
* @var array
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function setDynamicConnection($connection = 'dynamic')
|
protected $rules = [
|
||||||
{
|
'name' => 'required|string|max:255',
|
||||||
Config::set('database.connections.' . $connection, [
|
'host' => 'required|ip|unique:database_hosts,host',
|
||||||
'driver' => 'mysql',
|
'port' => 'required|numeric|between:1,65535',
|
||||||
'host' => $this->host,
|
'username' => 'required|string|max:32',
|
||||||
'port' => $this->port,
|
'password' => 'sometimes|nullable|string',
|
||||||
'database' => 'mysql',
|
'node_id' => 'sometimes|required|nullable|exists:nodes,id',
|
||||||
'username' => $this->username,
|
];
|
||||||
'password' => Crypt::decrypt($this->password),
|
|
||||||
'charset' => 'utf8',
|
|
||||||
'collation' => 'utf8_unicode_ci',
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the node associated with a database host.
|
* Gets the node associated with a database host.
|
||||||
|
@ -46,7 +46,7 @@ class Location extends Model
|
|||||||
protected $guarded = ['id', 'created_at', 'updated_at'];
|
protected $guarded = ['id', 'created_at', 'updated_at'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validation rules to apply when attempting to save a model to the DB.
|
* Validation rules to apply to this model.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
|
151
app/Services/DatabaseHostService.php
Normal file
151
app/Services/DatabaseHostService.php
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Pterodactyl - Panel
|
||||||
|
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Pterodactyl\Services;
|
||||||
|
|
||||||
|
use Pterodactyl\Models\DatabaseHost;
|
||||||
|
use Illuminate\Database\DatabaseManager;
|
||||||
|
use Pterodactyl\Exceptions\DisplayException;
|
||||||
|
use Illuminate\Contracts\Encryption\Encrypter;
|
||||||
|
use Pterodactyl\Extensions\DynamicDatabaseConnection;
|
||||||
|
|
||||||
|
class DatabaseHostService
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var \Illuminate\Database\DatabaseManager
|
||||||
|
*/
|
||||||
|
protected $database;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Extensions\DynamicDatabaseConnection
|
||||||
|
*/
|
||||||
|
protected $dynamic;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Illuminate\Contracts\Encryption\Encrypter
|
||||||
|
*/
|
||||||
|
protected $encrypter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Models\DatabaseHost
|
||||||
|
*/
|
||||||
|
protected $model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DatabaseHostService constructor.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Database\DatabaseManager $database
|
||||||
|
* @param \Pterodactyl\Extensions\DynamicDatabaseConnection $dynamic
|
||||||
|
* @param \Illuminate\Contracts\Encryption\Encrypter $encrypter
|
||||||
|
* @param \Pterodactyl\Models\DatabaseHost $model
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
DatabaseManager $database,
|
||||||
|
DynamicDatabaseConnection $dynamic,
|
||||||
|
Encrypter $encrypter,
|
||||||
|
DatabaseHost $model
|
||||||
|
) {
|
||||||
|
$this->database = $database;
|
||||||
|
$this->dynamic = $dynamic;
|
||||||
|
$this->encrypter = $encrypter;
|
||||||
|
$this->model = $model;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new database host and persist it to the database.
|
||||||
|
*
|
||||||
|
* @param array $data
|
||||||
|
* @return \Pterodactyl\Models\DatabaseHost
|
||||||
|
*
|
||||||
|
* @throws \Throwable
|
||||||
|
* @throws \PDOException
|
||||||
|
*/
|
||||||
|
public function create(array $data)
|
||||||
|
{
|
||||||
|
$instance = $this->model->newInstance();
|
||||||
|
$instance->password = $this->encrypter->encrypt(array_get($data, 'password'));
|
||||||
|
|
||||||
|
$instance->fill([
|
||||||
|
'name' => array_get($data, 'name'),
|
||||||
|
'host' => array_get($data, 'host'),
|
||||||
|
'port' => array_get($data, 'port'),
|
||||||
|
'username' => array_get($data, 'username'),
|
||||||
|
'max_databases' => null,
|
||||||
|
'node_id' => array_get($data, 'node_id'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Check Access
|
||||||
|
$this->dynamic->set('dynamic', $instance);
|
||||||
|
$this->database->connection('dynamic')->select('SELECT 1 FROM dual');
|
||||||
|
|
||||||
|
$instance->saveOrFail();
|
||||||
|
|
||||||
|
return $instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a database host and persist to the database.
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @param array $data
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \PDOException
|
||||||
|
*/
|
||||||
|
public function update($id, array $data)
|
||||||
|
{
|
||||||
|
$model = $this->model->findOrFail($id);
|
||||||
|
|
||||||
|
if (! empty(array_get($data, 'password'))) {
|
||||||
|
$model->password = $this->encrypter->encrypt($data['password']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$model->fill($data);
|
||||||
|
$this->dynamic->set('dynamic', $model);
|
||||||
|
$this->database->connection('dynamic')->select('SELECT 1 FROM dual');
|
||||||
|
|
||||||
|
$model->saveOrFail();
|
||||||
|
|
||||||
|
return $model;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a database host if it has no active databases attached to it.
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return bool|null
|
||||||
|
*
|
||||||
|
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||||
|
*/
|
||||||
|
public function delete($id)
|
||||||
|
{
|
||||||
|
$model = $this->model->withCount('databases')->findOrFail($id);
|
||||||
|
|
||||||
|
if ($model->databases_count > 0) {
|
||||||
|
throw new DisplayException('Cannot delete a database host that has active databases attached to it.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $model->delete();
|
||||||
|
}
|
||||||
|
}
|
@ -93,6 +93,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="box-footer">
|
<div class="box-footer">
|
||||||
{!! csrf_field() !!}
|
{!! csrf_field() !!}
|
||||||
|
{!! method_field('PATCH') !!}
|
||||||
<button name="action" value="delete" class="btn btn-sm btn-danger pull-left muted muted-hover"><i class="fa fa-trash-o"></i></button>
|
<button name="action" value="delete" class="btn btn-sm btn-danger pull-left muted muted-hover"><i class="fa fa-trash-o"></i></button>
|
||||||
<button name="action" value="edit" class="btn btn-sm btn-primary pull-right">Save</button>
|
<button name="action" value="edit" class="btn btn-sm btn-primary pull-right">Save</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -49,10 +49,10 @@ Route::group(['prefix' => 'locations'], function () {
|
|||||||
*/
|
*/
|
||||||
Route::group(['prefix' => 'databases'], function () {
|
Route::group(['prefix' => 'databases'], function () {
|
||||||
Route::get('/', 'DatabaseController@index')->name('admin.databases');
|
Route::get('/', 'DatabaseController@index')->name('admin.databases');
|
||||||
Route::get('/view/{id}', 'DatabaseController@view')->name('admin.databases.view');
|
Route::get('/view/{host}', 'DatabaseController@view')->name('admin.databases.view');
|
||||||
|
|
||||||
Route::post('/', 'DatabaseController@create');
|
Route::post('/', 'DatabaseController@create');
|
||||||
Route::post('/view/{id}', 'DatabaseController@update');
|
Route::patch('/view/{host}', 'DatabaseController@update');
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user