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
10 changed files with 462 additions and 103 deletions
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;
|
||||
|
||||
use Alert;
|
||||
use Settings;
|
||||
use Validator;
|
||||
use Illuminate\Http\Request;
|
||||
use Krucas\Settings\Settings;
|
||||
use Prologue\Alerts\AlertsMessageBag;
|
||||
use Pterodactyl\Http\Controllers\Controller;
|
||||
use Pterodactyl\Http\Requests\Admin\BaseFormRequest;
|
||||
|
||||
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.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function getIndex(Request $request)
|
||||
public function getIndex()
|
||||
{
|
||||
return view('admin.index');
|
||||
}
|
||||
|
@ -46,10 +60,9 @@ class BaseController extends Controller
|
|||
/**
|
||||
* Return the admin settings view.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function getSettings(Request $request)
|
||||
public function getSettings()
|
||||
{
|
||||
return view('admin.settings');
|
||||
}
|
||||
|
@ -57,24 +70,14 @@ class BaseController extends Controller
|
|||
/**
|
||||
* Handle settings post request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Pterodactyl\Http\Requests\Admin\BaseFormRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function postSettings(Request $request)
|
||||
public function postSettings(BaseFormRequest $request)
|
||||
{
|
||||
$validator = Validator::make($request->all(), [
|
||||
'company' => 'required|between:1,256',
|
||||
// 'default_language' => 'required|alpha_dash|min:2|max:5',
|
||||
]);
|
||||
$this->settings->set('company', $request->input('company'));
|
||||
|
||||
if ($validator->fails()) {
|
||||
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();
|
||||
$this->alert->success('Settings have been successfully updated.')->flash();
|
||||
|
||||
return redirect()->route('admin.settings');
|
||||
}
|
||||
|
|
|
@ -24,112 +24,144 @@
|
|||
|
||||
namespace Pterodactyl\Http\Controllers\Admin;
|
||||
|
||||
use Log;
|
||||
use Alert;
|
||||
use Illuminate\Http\Request;
|
||||
use Pterodactyl\Models\Database;
|
||||
use Pterodactyl\Models\Location;
|
||||
use Pterodactyl\Models\DatabaseHost;
|
||||
use Pterodactyl\Exceptions\DisplayException;
|
||||
use Prologue\Alerts\AlertsMessageBag;
|
||||
use Pterodactyl\Http\Controllers\Controller;
|
||||
use Pterodactyl\Repositories\DatabaseRepository;
|
||||
use Pterodactyl\Exceptions\DisplayValidationException;
|
||||
use Pterodactyl\Services\DatabaseHostService;
|
||||
use Pterodactyl\Http\Requests\Admin\DatabaseHostFormRequest;
|
||||
|
||||
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.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index()
|
||||
{
|
||||
return view('admin.databases.index', [
|
||||
'locations' => Location::with('nodes')->get(),
|
||||
'hosts' => DatabaseHost::withCount('databases')->with('node')->get(),
|
||||
'locations' => $this->locationModel->with('nodes')->get(),
|
||||
'hosts' => $this->hostModel->withCount('databases')->with('node')->get(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display database host to user.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @param \Pterodactyl\Models\DatabaseHost $host
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function view(Request $request, $id)
|
||||
public function view(DatabaseHost $host)
|
||||
{
|
||||
$host->load('databases.server');
|
||||
|
||||
return view('admin.databases.view', [
|
||||
'locations' => Location::with('nodes')->get(),
|
||||
'host' => DatabaseHost::with('databases.server')->findOrFail($id),
|
||||
'locations' => $this->locationModel->with('nodes')->get(),
|
||||
'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
|
||||
*
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function create(Request $request)
|
||||
public function create(DatabaseHostFormRequest $request)
|
||||
{
|
||||
$repo = new DatabaseRepository;
|
||||
|
||||
try {
|
||||
$host = $repo->add($request->intersect([
|
||||
'name', 'username', 'password',
|
||||
'host', 'port', 'node_id',
|
||||
]));
|
||||
Alert::success('Successfully created new database host on the system.')->flash();
|
||||
$host = $this->service->create($request->normalize());
|
||||
$this->alert->success('Successfully created a new database host on the system.')->flash();
|
||||
|
||||
return redirect()->route('admin.databases.view', $host->id);
|
||||
} catch (\PDOException $ex) {
|
||||
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();
|
||||
$this->alert->danger($ex->getMessage())->flash();
|
||||
}
|
||||
|
||||
return redirect()->route('admin.databases');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle post request to update a database host.
|
||||
* Handle updating database host.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @param \Pterodactyl\Http\Requests\Admin\DatabaseHostFormRequest $request
|
||||
* @param \Pterodactyl\Models\DatabaseHost $host
|
||||
* @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);
|
||||
$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');
|
||||
}
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
|
|
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;
|
||||
|
||||
use Crypt;
|
||||
use Config;
|
||||
use Watson\Validating\ValidatingTrait;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class DatabaseHost extends Model
|
||||
{
|
||||
use ValidatingTrait;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @return void
|
||||
* @var array
|
||||
*/
|
||||
public function setDynamicConnection($connection = 'dynamic')
|
||||
{
|
||||
Config::set('database.connections.' . $connection, [
|
||||
'driver' => 'mysql',
|
||||
'host' => $this->host,
|
||||
'port' => $this->port,
|
||||
'database' => 'mysql',
|
||||
'username' => $this->username,
|
||||
'password' => Crypt::decrypt($this->password),
|
||||
'charset' => 'utf8',
|
||||
'collation' => 'utf8_unicode_ci',
|
||||
]);
|
||||
}
|
||||
protected $rules = [
|
||||
'name' => 'required|string|max:255',
|
||||
'host' => 'required|ip|unique:database_hosts,host',
|
||||
'port' => 'required|numeric|between:1,65535',
|
||||
'username' => 'required|string|max:32',
|
||||
'password' => 'sometimes|nullable|string',
|
||||
'node_id' => 'sometimes|required|nullable|exists:nodes,id',
|
||||
];
|
||||
|
||||
/**
|
||||
* Gets the node associated with a database host.
|
||||
|
|
|
@ -46,7 +46,7 @@ class Location extends Model
|
|||
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
|
||||
*/
|
||||
|
|
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 class="box-footer">
|
||||
{!! 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="edit" class="btn btn-sm btn-primary pull-right">Save</button>
|
||||
</div>
|
||||
|
|
|
@ -49,10 +49,10 @@ Route::group(['prefix' => 'locations'], function () {
|
|||
*/
|
||||
Route::group(['prefix' => 'databases'], function () {
|
||||
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('/view/{id}', 'DatabaseController@update');
|
||||
Route::patch('/view/{host}', 'DatabaseController@update');
|
||||
});
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue