Repository interface improvements
This commit is contained in:
parent
1f4f6024cc
commit
bc3366b10d
23 changed files with 829 additions and 179 deletions
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Contracts\Repository;
|
namespace Pterodactyl\Contracts\Repository;
|
||||||
|
|
||||||
interface DatabaseHostInterface extends RepositoryInterface
|
interface DatabaseHostRepositoryInterface extends RepositoryInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Delete a database host from the DB if there are no databases using it.
|
* Delete a database host from the DB if there are no databases using it.
|
98
app/Contracts/Repository/DatabaseRepositoryInterface.php
Normal file
98
app/Contracts/Repository/DatabaseRepositoryInterface.php
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
<?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\Contracts\Repository;
|
||||||
|
|
||||||
|
interface DatabaseRepositoryInterface extends RepositoryInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create a new database if it does not already exist on the host with
|
||||||
|
* the provided details.
|
||||||
|
*
|
||||||
|
* @param array $data
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||||
|
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||||
|
*/
|
||||||
|
public function createIfNotExists(array $data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new database on a given connection.
|
||||||
|
*
|
||||||
|
* @param string $database
|
||||||
|
* @param null|string $connection
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function createDatabase($database, $connection = null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new database user on a given connection.
|
||||||
|
*
|
||||||
|
* @param string $username
|
||||||
|
* @param string $remote
|
||||||
|
* @param string $password
|
||||||
|
* @param null|string $connection
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function createUser($username, $remote, $password, $connection = null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Give a specific user access to a given database.
|
||||||
|
*
|
||||||
|
* @param string $database
|
||||||
|
* @param string $username
|
||||||
|
* @param string $remote
|
||||||
|
* @param null|string $connection
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function assignUserToDatabase($database, $username, $remote, $connection = null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flush the privileges for a given connection.
|
||||||
|
*
|
||||||
|
* @param null|string $connection
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function flush($connection = null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drop a given database on a specific connection.
|
||||||
|
*
|
||||||
|
* @param string $database
|
||||||
|
* @param null|string $connection
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function dropDatabase($database, $connection = null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drop a given user on a specific connection.
|
||||||
|
*
|
||||||
|
* @param string $username
|
||||||
|
* @param string $remote
|
||||||
|
* @param null|string $connection
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function dropUser($username, $remote, $connection = null);
|
||||||
|
}
|
|
@ -138,4 +138,11 @@ interface RepositoryInterface
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function massUpdate(array $where, array $fields);
|
public function massUpdate(array $where, array $fields);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return all records from the model.
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function all();
|
||||||
}
|
}
|
||||||
|
|
38
app/Contracts/Repository/ServerRepositoryInterface.php
Normal file
38
app/Contracts/Repository/ServerRepositoryInterface.php
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
<?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\Contracts\Repository;
|
||||||
|
|
||||||
|
use Pterodactyl\Contracts\Repository\Attributes\SearchableInterface;
|
||||||
|
|
||||||
|
interface ServerRepositoryInterface extends RepositoryInterface, SearchableInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Returns a listing of all servers that exist including relationships.
|
||||||
|
*
|
||||||
|
* @param int $paginate
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getAllServers($paginate);
|
||||||
|
}
|
36
app/Contracts/Repository/ServiceRepositoryInterface.php
Normal file
36
app/Contracts/Repository/ServiceRepositoryInterface.php
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
<?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\Contracts\Repository;
|
||||||
|
|
||||||
|
interface ServiceRepositoryInterface extends RepositoryInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Return a service or all services with their associated options, variables, and packs.
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
public function getWithOptions($id = null);
|
||||||
|
}
|
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Extensions;
|
namespace Pterodactyl\Extensions;
|
||||||
|
|
||||||
use Pterodactyl\Contracts\Repository\DatabaseHostInterface;
|
use Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface;
|
||||||
use Pterodactyl\Models\DatabaseHost;
|
use Pterodactyl\Models\DatabaseHost;
|
||||||
use Illuminate\Contracts\Encryption\Encrypter;
|
use Illuminate\Contracts\Encryption\Encrypter;
|
||||||
use Illuminate\Config\Repository as ConfigRepository;
|
use Illuminate\Config\Repository as ConfigRepository;
|
||||||
|
@ -46,7 +46,7 @@ class DynamicDatabaseConnection
|
||||||
protected $encrypter;
|
protected $encrypter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Pterodactyl\Contracts\Repository\DatabaseHostInterface
|
* @var \Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface
|
||||||
*/
|
*/
|
||||||
protected $repository;
|
protected $repository;
|
||||||
|
|
||||||
|
@ -54,12 +54,12 @@ class DynamicDatabaseConnection
|
||||||
* DynamicDatabaseConnection constructor.
|
* DynamicDatabaseConnection constructor.
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Config\Repository $config
|
* @param \Illuminate\Config\Repository $config
|
||||||
* @param \Pterodactyl\Contracts\Repository\DatabaseHostInterface $repository
|
* @param \Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface $repository
|
||||||
* @param \Illuminate\Contracts\Encryption\Encrypter $encrypter
|
* @param \Illuminate\Contracts\Encryption\Encrypter $encrypter
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
ConfigRepository $config,
|
ConfigRepository $config,
|
||||||
DatabaseHostInterface $repository,
|
DatabaseHostRepositoryInterface $repository,
|
||||||
Encrypter $encrypter
|
Encrypter $encrypter
|
||||||
) {
|
) {
|
||||||
$this->config = $config;
|
$this->config = $config;
|
||||||
|
|
|
@ -28,7 +28,7 @@ use Pterodactyl\Models\Location;
|
||||||
use Pterodactyl\Models\DatabaseHost;
|
use Pterodactyl\Models\DatabaseHost;
|
||||||
use Prologue\Alerts\AlertsMessageBag;
|
use Prologue\Alerts\AlertsMessageBag;
|
||||||
use Pterodactyl\Http\Controllers\Controller;
|
use Pterodactyl\Http\Controllers\Controller;
|
||||||
use Pterodactyl\Services\Administrative\DatabaseHostService;
|
use Pterodactyl\Services\Database\DatabaseHostService;
|
||||||
use Pterodactyl\Http\Requests\Admin\DatabaseHostFormRequest;
|
use Pterodactyl\Http\Requests\Admin\DatabaseHostFormRequest;
|
||||||
|
|
||||||
class DatabaseController extends Controller
|
class DatabaseController extends Controller
|
||||||
|
@ -49,7 +49,7 @@ class DatabaseController extends Controller
|
||||||
protected $locationModel;
|
protected $locationModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Pterodactyl\Services\Administrative\DatabaseHostService
|
* @var \Pterodactyl\Services\Database\DatabaseHostService
|
||||||
*/
|
*/
|
||||||
protected $service;
|
protected $service;
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ class DatabaseController extends Controller
|
||||||
* @param \Prologue\Alerts\AlertsMessageBag $alert
|
* @param \Prologue\Alerts\AlertsMessageBag $alert
|
||||||
* @param \Pterodactyl\Models\DatabaseHost $hostModel
|
* @param \Pterodactyl\Models\DatabaseHost $hostModel
|
||||||
* @param \Pterodactyl\Models\Location $locationModel
|
* @param \Pterodactyl\Models\Location $locationModel
|
||||||
* @param \Pterodactyl\Services\Administrative\DatabaseHostService $service
|
* @param \Pterodactyl\Services\Database\DatabaseHostService $service
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
AlertsMessageBag $alert,
|
AlertsMessageBag $alert,
|
||||||
|
|
|
@ -24,9 +24,14 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Http\Controllers\Admin;
|
namespace Pterodactyl\Http\Controllers\Admin;
|
||||||
|
|
||||||
|
use Illuminate\Contracts\Config\Repository as ConfigRepository;
|
||||||
use Log;
|
use Log;
|
||||||
use Alert;
|
use Alert;
|
||||||
use Javascript;
|
use Javascript;
|
||||||
|
use Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface;
|
||||||
|
use Pterodactyl\Contracts\Repository\LocationRepositoryInterface;
|
||||||
|
use Pterodactyl\Contracts\Repository\ServerRepositoryInterface;
|
||||||
|
use Pterodactyl\Contracts\Repository\ServiceRepositoryInterface;
|
||||||
use Pterodactyl\Models;
|
use Pterodactyl\Models;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use GuzzleHttp\Exception\TransferException;
|
use GuzzleHttp\Exception\TransferException;
|
||||||
|
@ -40,33 +45,69 @@ use Pterodactyl\Exceptions\DisplayValidationException;
|
||||||
class ServersController extends Controller
|
class ServersController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Display the index page with all servers currently on the system.
|
* @var \Illuminate\Contracts\Config\Repository
|
||||||
*
|
|
||||||
* @param \Illuminate\Http\Request $request
|
|
||||||
* @return \Illuminate\View\View
|
|
||||||
*/
|
*/
|
||||||
public function index(Request $request)
|
protected $config;
|
||||||
{
|
|
||||||
$servers = Models\Server::with('node', 'user', 'allocation');
|
|
||||||
|
|
||||||
if (! is_null($request->input('query'))) {
|
/**
|
||||||
$servers->search($request->input('query'));
|
* @var \Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface
|
||||||
|
*/
|
||||||
|
protected $databaseRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Contracts\Repository\LocationRepositoryInterface
|
||||||
|
*/
|
||||||
|
protected $locationRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Contracts\Repository\ServerRepositoryInterface
|
||||||
|
*/
|
||||||
|
protected $repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Contracts\Repository\ServiceRepositoryInterface
|
||||||
|
*/
|
||||||
|
protected $serviceRepository;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
ConfigRepository $config,
|
||||||
|
DatabaseRepositoryInterface $databaseRepository,
|
||||||
|
LocationRepositoryInterface $locationRepository,
|
||||||
|
ServerRepositoryInterface $repository,
|
||||||
|
ServiceRepositoryInterface $serviceRepository
|
||||||
|
) {
|
||||||
|
$this->config = $config;
|
||||||
|
$this->databaseRepository = $databaseRepository;
|
||||||
|
$this->locationRepository = $locationRepository;
|
||||||
|
$this->repository = $repository;
|
||||||
|
$this->serviceRepository = $serviceRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the index page with all servers currently on the system.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\View\View
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
return view('admin.servers.index', [
|
return view('admin.servers.index', [
|
||||||
'servers' => $servers->paginate(25),
|
'servers' => $this->repository->getAllServers(
|
||||||
|
$this->config->get('pterodactyl.paginate.admin.servers')
|
||||||
|
),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display create new server page.
|
* Display create new server page.
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Http\Request $request
|
|
||||||
* @return \Illuminate\View\View
|
* @return \Illuminate\View\View
|
||||||
|
*
|
||||||
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function create(Request $request)
|
public function create()
|
||||||
{
|
{
|
||||||
$services = Models\Service::with('options.packs', 'options.variables')->get();
|
$services = $this->serviceRepository->getWithOptions();
|
||||||
|
|
||||||
Javascript::put([
|
Javascript::put([
|
||||||
'services' => $services->map(function ($item) {
|
'services' => $services->map(function ($item) {
|
||||||
return array_merge($item->toArray(), [
|
return array_merge($item->toArray(), [
|
||||||
|
@ -76,7 +117,7 @@ class ServersController extends Controller
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return view('admin.servers.new', [
|
return view('admin.servers.new', [
|
||||||
'locations' => Models\Location::all(),
|
'locations' => $this->locationRepository->all(),
|
||||||
'services' => $services,
|
'services' => $services,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -115,7 +156,7 @@ class ServersController extends Controller
|
||||||
* Returns a tree of all avaliable nodes in a given location.
|
* Returns a tree of all avaliable nodes in a given location.
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Http\Request $request
|
* @param \Illuminate\Http\Request $request
|
||||||
* @return array
|
* @return \Illuminate\Support\Collection
|
||||||
*/
|
*/
|
||||||
public function nodes(Request $request)
|
public function nodes(Request $request)
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,9 +25,13 @@
|
||||||
namespace Pterodactyl\Models;
|
namespace Pterodactyl\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Sofa\Eloquence\Eloquence;
|
||||||
|
use Sofa\Eloquence\Validable;
|
||||||
|
|
||||||
class Database extends Model
|
class Database extends Model
|
||||||
{
|
{
|
||||||
|
use Eloquence, Validable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The table associated with the model.
|
* The table associated with the model.
|
||||||
*
|
*
|
||||||
|
@ -61,6 +65,22 @@ class Database extends Model
|
||||||
'database_host_id' => 'integer',
|
'database_host_id' => 'integer',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
protected static $applicationRules = [
|
||||||
|
'server_id' => 'required',
|
||||||
|
'database_host_id' => 'required',
|
||||||
|
'database' => 'required',
|
||||||
|
'remote' => 'required',
|
||||||
|
];
|
||||||
|
|
||||||
|
protected static $dataIntegrityRules = [
|
||||||
|
'server_id' => 'numeric|exists:servers,id',
|
||||||
|
'database_host_id' => 'exists:database_hosts,id',
|
||||||
|
'database' => 'string|alpha_dash|between:3,100',
|
||||||
|
'username' => 'string|alpha_dash|between:3,100',
|
||||||
|
'remote' => 'string|regex:/^[0-9%.]{1,15}$/',
|
||||||
|
'password' => 'string',
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the host database server associated with a database.
|
* Gets the host database server associated with a database.
|
||||||
*
|
*
|
||||||
|
|
|
@ -24,12 +24,13 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Models;
|
namespace Pterodactyl\Models;
|
||||||
|
|
||||||
use Watson\Validating\ValidatingTrait;
|
use Sofa\Eloquence\Eloquence;
|
||||||
|
use Sofa\Eloquence\Validable;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
class DatabaseHost extends Model
|
class DatabaseHost extends Model
|
||||||
{
|
{
|
||||||
use ValidatingTrait;
|
use Eloquence, Validable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The table associated with the model.
|
* The table associated with the model.
|
||||||
|
@ -65,18 +66,31 @@ class DatabaseHost extends Model
|
||||||
'node_id' => 'integer',
|
'node_id' => 'integer',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Application validation rules.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected static $applicationRules = [
|
||||||
|
'name' => 'required',
|
||||||
|
'host' => 'required',
|
||||||
|
'port' => 'required',
|
||||||
|
'username' => 'required',
|
||||||
|
'node_id' => 'sometimes|required',
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validation rules to assign to this model.
|
* Validation rules to assign to this model.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $rules = [
|
protected static $dataIntegrityRules = [
|
||||||
'name' => 'required|string|max:255',
|
'name' => 'string|max:255',
|
||||||
'host' => 'required|ip|unique:database_hosts,host',
|
'host' => 'ip|unique:database_hosts,host',
|
||||||
'port' => 'required|numeric|between:1,65535',
|
'port' => 'numeric|between:1,65535',
|
||||||
'username' => 'required|string|max:32',
|
'username' => 'string|max:32',
|
||||||
'password' => 'sometimes|nullable|string',
|
'password' => 'nullable|string',
|
||||||
'node_id' => 'sometimes|required|nullable|exists:nodes,id',
|
'node_id' => 'nullable|exists:nodes,id',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -27,12 +27,18 @@ namespace Pterodactyl\Providers;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
use Pterodactyl\Contracts\Repository\ApiKeyRepositoryInterface;
|
use Pterodactyl\Contracts\Repository\ApiKeyRepositoryInterface;
|
||||||
use Pterodactyl\Contracts\Repository\ApiPermissionRepositoryInterface;
|
use Pterodactyl\Contracts\Repository\ApiPermissionRepositoryInterface;
|
||||||
use Pterodactyl\Contracts\Repository\DatabaseHostInterface;
|
use Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface;
|
||||||
|
use Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface;
|
||||||
use Pterodactyl\Contracts\Repository\LocationRepositoryInterface;
|
use Pterodactyl\Contracts\Repository\LocationRepositoryInterface;
|
||||||
|
use Pterodactyl\Contracts\Repository\ServerRepositoryInterface;
|
||||||
|
use Pterodactyl\Contracts\Repository\ServiceRepositoryInterface;
|
||||||
use Pterodactyl\Repositories\Eloquent\ApiKeyRepository;
|
use Pterodactyl\Repositories\Eloquent\ApiKeyRepository;
|
||||||
use Pterodactyl\Repositories\Eloquent\ApiPermissionRepository;
|
use Pterodactyl\Repositories\Eloquent\ApiPermissionRepository;
|
||||||
use Pterodactyl\Repositories\Eloquent\DatabaseHostRepository;
|
use Pterodactyl\Repositories\Eloquent\DatabaseHostRepository;
|
||||||
|
use Pterodactyl\Repositories\Eloquent\DatabaseRepository;
|
||||||
use Pterodactyl\Repositories\Eloquent\LocationRepository;
|
use Pterodactyl\Repositories\Eloquent\LocationRepository;
|
||||||
|
use Pterodactyl\Repositories\Eloquent\ServerRepository;
|
||||||
|
use Pterodactyl\Repositories\Eloquent\ServiceRepository;
|
||||||
use Pterodactyl\Repositories\Eloquent\UserRepository;
|
use Pterodactyl\Repositories\Eloquent\UserRepository;
|
||||||
use Pterodactyl\Contracts\Repository\UserRepositoryInterface;
|
use Pterodactyl\Contracts\Repository\UserRepositoryInterface;
|
||||||
|
|
||||||
|
@ -45,8 +51,11 @@ class RepositoryServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
$this->app->bind(ApiKeyRepositoryInterface::class, ApiKeyRepository::class);
|
$this->app->bind(ApiKeyRepositoryInterface::class, ApiKeyRepository::class);
|
||||||
$this->app->bind(ApiPermissionRepositoryInterface::class, ApiPermissionRepository::class);
|
$this->app->bind(ApiPermissionRepositoryInterface::class, ApiPermissionRepository::class);
|
||||||
$this->app->bind(DatabaseHostInterface::class, DatabaseHostRepository::class);
|
$this->app->bind(DatabaseRepositoryInterface::class, DatabaseRepository::class);
|
||||||
|
$this->app->bind(DatabaseHostRepositoryInterface::class, DatabaseHostRepository::class);
|
||||||
$this->app->bind(LocationRepositoryInterface::class, LocationRepository::class);
|
$this->app->bind(LocationRepositoryInterface::class, LocationRepository::class);
|
||||||
|
$this->app->bind(ServerRepositoryInterface::class, ServerRepository::class);
|
||||||
|
$this->app->bind(ServiceRepositoryInterface::class, ServiceRepository::class);
|
||||||
$this->app->bind(UserRepositoryInterface::class, UserRepository::class);
|
$this->app->bind(UserRepositoryInterface::class, UserRepository::class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
<?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\Repositories\Eloquent\Attributes;
|
||||||
|
|
||||||
|
use Pterodactyl\Repositories\Eloquent\EloquentRepository;
|
||||||
|
use Pterodactyl\Contracts\Repository\Attributes\SearchableInterface;
|
||||||
|
|
||||||
|
abstract class SearchableRepository extends EloquentRepository implements SearchableInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var bool|string
|
||||||
|
*/
|
||||||
|
protected $searchTerm = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function search($term)
|
||||||
|
{
|
||||||
|
if (empty($term)) {
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
$clone = clone $this;
|
||||||
|
$clone->searchTerm = $term;
|
||||||
|
|
||||||
|
return $clone;
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,12 +24,12 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Repositories\Eloquent;
|
namespace Pterodactyl\Repositories\Eloquent;
|
||||||
|
|
||||||
use Pterodactyl\Contracts\Repository\DatabaseHostInterface;
|
use Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface;
|
||||||
use Pterodactyl\Exceptions\DisplayException;
|
use Pterodactyl\Exceptions\DisplayException;
|
||||||
use Pterodactyl\Exceptions\Repository\RecordNotFoundException;
|
use Pterodactyl\Exceptions\Repository\RecordNotFoundException;
|
||||||
use Pterodactyl\Models\DatabaseHost;
|
use Pterodactyl\Models\DatabaseHost;
|
||||||
|
|
||||||
class DatabaseHostRepository extends EloquentRepository implements DatabaseHostInterface
|
class DatabaseHostRepository extends EloquentRepository implements DatabaseHostRepositoryInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
|
|
155
app/Repositories/Eloquent/DatabaseRepository.php
Normal file
155
app/Repositories/Eloquent/DatabaseRepository.php
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
<?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\Repositories\Eloquent;
|
||||||
|
|
||||||
|
use Pterodactyl\Models\Database;
|
||||||
|
use Illuminate\Foundation\Application;
|
||||||
|
use Illuminate\Database\ConnectionResolver;
|
||||||
|
use Pterodactyl\Exceptions\DisplayException;
|
||||||
|
use Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface;
|
||||||
|
|
||||||
|
class DatabaseRepository extends EloquentRepository implements DatabaseRepositoryInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var \Illuminate\Database\ConnectionResolverInterface
|
||||||
|
*/
|
||||||
|
protected $connection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DatabaseRepository constructor.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Foundation\Application $application
|
||||||
|
* @param \Illuminate\Database\ConnectionResolver $connection
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
Application $application,
|
||||||
|
ConnectionResolver $connection
|
||||||
|
) {
|
||||||
|
parent::__construct($application);
|
||||||
|
|
||||||
|
$this->connection = $connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function model()
|
||||||
|
{
|
||||||
|
return Database::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
* @return bool|\Illuminate\Database\Eloquent\Model
|
||||||
|
*/
|
||||||
|
public function createIfNotExists(array $data)
|
||||||
|
{
|
||||||
|
$instance = $this->getBuilder()->where([
|
||||||
|
['server_id', $data['server_id']],
|
||||||
|
['database_host_id', $data['database_host_id']],
|
||||||
|
['database', $data['database']],
|
||||||
|
])->count();
|
||||||
|
|
||||||
|
if ($instance > 0) {
|
||||||
|
throw new DisplayException('A database with those details already exists for the specified server.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->create($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function createDatabase($database, $connection = null)
|
||||||
|
{
|
||||||
|
return $this->runStatement(
|
||||||
|
sprintf('CREATE DATABASE IF NOT EXISTS `%s`', $database), $connection
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function createUser($username, $remote, $password, $connection = null)
|
||||||
|
{
|
||||||
|
return $this->runStatement(
|
||||||
|
sprintf('CREATE USER `%s`@`%s` IDENTIFIED BY \'%s\'', $username, $remote, $password), $connection
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function assignUserToDatabase($database, $username, $remote, $connection = null)
|
||||||
|
{
|
||||||
|
return $this->runStatement(
|
||||||
|
sprintf(
|
||||||
|
'GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, INDEX ON `%s`.* TO `%s`@`%s`',
|
||||||
|
$database, $username, $remote
|
||||||
|
),
|
||||||
|
$connection
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function flush($connection = null)
|
||||||
|
{
|
||||||
|
return $this->runStatement('FLUSH PRIVILEGES', $connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function dropDatabase($database, $connection = null)
|
||||||
|
{
|
||||||
|
return $this->runStatement(
|
||||||
|
sprintf('DROP DATABASE IF EXISTS `%s`', $database), $connection
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function dropUser($username, $remote, $connection = null)
|
||||||
|
{
|
||||||
|
return $this->runStatement(
|
||||||
|
sprintf('DROP USER IF EXISTS `%s`@`%s`', $username, $remote), $connection
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the provided statement against the database on a given connection.
|
||||||
|
*
|
||||||
|
* @param string $statement
|
||||||
|
* @param null|string $connection
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function runStatement($statement, $connection = null)
|
||||||
|
{
|
||||||
|
return $this->connection->connection($connection)->statement($statement);
|
||||||
|
}
|
||||||
|
}
|
|
@ -152,4 +152,12 @@ abstract class EloquentRepository extends Repository implements RepositoryInterf
|
||||||
{
|
{
|
||||||
// TODO: Implement massUpdate() method.
|
// TODO: Implement massUpdate() method.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function all()
|
||||||
|
{
|
||||||
|
return $this->getBuilder()->get($this->getColumns());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
54
app/Repositories/Eloquent/ServerRepository.php
Normal file
54
app/Repositories/Eloquent/ServerRepository.php
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
<?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\Repositories\Eloquent;
|
||||||
|
|
||||||
|
use Pterodactyl\Models\Server;
|
||||||
|
use Pterodactyl\Contracts\Repository\ServerRepositoryInterface;
|
||||||
|
use Pterodactyl\Repositories\Eloquent\Attributes\SearchableRepository;
|
||||||
|
|
||||||
|
class ServerRepository extends SearchableRepository implements ServerRepositoryInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function model()
|
||||||
|
{
|
||||||
|
return Server::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getAllServers($paginate = 25)
|
||||||
|
{
|
||||||
|
$instance = $this->getBuilder()->with('node', 'user', 'allocation');
|
||||||
|
|
||||||
|
if ($this->searchTerm) {
|
||||||
|
$instance->search($this->searchTerm);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $instance->paginate($paginate);
|
||||||
|
}
|
||||||
|
}
|
60
app/Repositories/Eloquent/ServiceRepository.php
Normal file
60
app/Repositories/Eloquent/ServiceRepository.php
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
<?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\Repositories\Eloquent;
|
||||||
|
|
||||||
|
use Pterodactyl\Contracts\Repository\ServiceRepositoryInterface;
|
||||||
|
use Pterodactyl\Exceptions\Repository\RecordNotFoundException;
|
||||||
|
use Pterodactyl\Models\Service;
|
||||||
|
|
||||||
|
class ServiceRepository extends EloquentRepository implements ServiceRepositoryInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function model()
|
||||||
|
{
|
||||||
|
return Service::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getWithOptions($id = null)
|
||||||
|
{
|
||||||
|
$instance = $this->getBuilder()->with('options.packs', 'options.variables');
|
||||||
|
|
||||||
|
if (! is_null($id)) {
|
||||||
|
$instance = $instance->find($id, $this->getColumns());
|
||||||
|
|
||||||
|
if (! $instance) {
|
||||||
|
throw new RecordNotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $instance->get($this->getColumns());
|
||||||
|
}
|
||||||
|
}
|
|
@ -30,19 +30,15 @@ use Pterodactyl\Contracts\Repository\UserRepositoryInterface;
|
||||||
use Pterodactyl\Exceptions\DisplayException;
|
use Pterodactyl\Exceptions\DisplayException;
|
||||||
use Pterodactyl\Exceptions\Repository\RecordNotFoundException;
|
use Pterodactyl\Exceptions\Repository\RecordNotFoundException;
|
||||||
use Pterodactyl\Models\User;
|
use Pterodactyl\Models\User;
|
||||||
|
use Pterodactyl\Repositories\Eloquent\Attributes\SearchableRepository;
|
||||||
|
|
||||||
class UserRepository extends EloquentRepository implements UserRepositoryInterface
|
class UserRepository extends SearchableRepository implements UserRepositoryInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var \Illuminate\Contracts\Config\Repository
|
* @var \Illuminate\Contracts\Config\Repository
|
||||||
*/
|
*/
|
||||||
protected $config;
|
protected $config;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var bool|array
|
|
||||||
*/
|
|
||||||
protected $searchTerm = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UserRepository constructor.
|
* UserRepository constructor.
|
||||||
*
|
*
|
||||||
|
@ -64,21 +60,6 @@ class UserRepository extends EloquentRepository implements UserRepositoryInterfa
|
||||||
return User::class;
|
return User::class;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function search($term)
|
|
||||||
{
|
|
||||||
if (empty($term)) {
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
$clone = clone $this;
|
|
||||||
$clone->searchTerm = $term;
|
|
||||||
|
|
||||||
return $clone;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -170,115 +170,4 @@ class DatabaseRepository
|
||||||
$database->delete();
|
$database->delete();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes a database host from the system if it has no associated databases.
|
|
||||||
*
|
|
||||||
* @param int $id
|
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @throws \Pterodactyl\Exceptions\DisplayException
|
|
||||||
*/
|
|
||||||
public function delete($id)
|
|
||||||
{
|
|
||||||
$host = DatabaseHost::withCount('databases')->findOrFail($id);
|
|
||||||
|
|
||||||
if ($host->databases_count > 0) {
|
|
||||||
throw new DisplayException('You cannot delete a database host that has active databases attached to it.');
|
|
||||||
}
|
|
||||||
|
|
||||||
$host->delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a new Database Host to the system.
|
|
||||||
*
|
|
||||||
* @param array $data
|
|
||||||
* @return \Pterodactyl\Models\DatabaseHost
|
|
||||||
*
|
|
||||||
* @throws \Pterodactyl\Exceptions\DisplayValidationException
|
|
||||||
*/
|
|
||||||
public function add(array $data)
|
|
||||||
{
|
|
||||||
if (isset($data['host'])) {
|
|
||||||
$data['host'] = gethostbyname($data['host']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$validator = Validator::make($data, [
|
|
||||||
'name' => 'required|string|max:255',
|
|
||||||
'host' => 'required|ip|unique:database_hosts,host',
|
|
||||||
'port' => 'required|numeric|between:1,65535',
|
|
||||||
'username' => 'required|string|max:32',
|
|
||||||
'password' => 'required|string',
|
|
||||||
'node_id' => 'sometimes|required|exists:nodes,id',
|
|
||||||
]);
|
|
||||||
|
|
||||||
if ($validator->fails()) {
|
|
||||||
throw new DisplayValidationException(json_encode($validator->errors()));
|
|
||||||
}
|
|
||||||
|
|
||||||
return DB::transaction(function () use ($data) {
|
|
||||||
$host = new DatabaseHost;
|
|
||||||
$host->password = Crypt::encrypt($data['password']);
|
|
||||||
|
|
||||||
$host->fill([
|
|
||||||
'name' => $data['name'],
|
|
||||||
'host' => $data['host'],
|
|
||||||
'port' => $data['port'],
|
|
||||||
'username' => $data['username'],
|
|
||||||
'max_databases' => null,
|
|
||||||
'node_id' => (isset($data['node_id'])) ? $data['node_id'] : null,
|
|
||||||
])->save();
|
|
||||||
|
|
||||||
// Allows us to check that we can connect to things.
|
|
||||||
$host->setDynamicConnection();
|
|
||||||
DB::connection('dynamic')->select('SELECT 1 FROM dual');
|
|
||||||
|
|
||||||
return $host;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates a Database Host on the system.
|
|
||||||
*
|
|
||||||
* @param int $id
|
|
||||||
* @param array $data
|
|
||||||
* @return \Pterodactyl\Models\DatabaseHost
|
|
||||||
*
|
|
||||||
* @throws \Pterodactyl\Exceptions\DisplayValidationException
|
|
||||||
*/
|
|
||||||
public function update($id, array $data)
|
|
||||||
{
|
|
||||||
$host = DatabaseHost::findOrFail($id);
|
|
||||||
|
|
||||||
if (isset($data['host'])) {
|
|
||||||
$data['host'] = gethostbyname($data['host']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$validator = Validator::make($data, [
|
|
||||||
'name' => 'sometimes|required|string|max:255',
|
|
||||||
'host' => 'sometimes|required|ip|unique:database_hosts,host,' . $host->id,
|
|
||||||
'port' => 'sometimes|required|numeric|between:1,65535',
|
|
||||||
'username' => 'sometimes|required|string|max:32',
|
|
||||||
'password' => 'sometimes|required|string',
|
|
||||||
'node_id' => 'sometimes|required|exists:nodes,id',
|
|
||||||
]);
|
|
||||||
|
|
||||||
if ($validator->fails()) {
|
|
||||||
throw new DisplayValidationException(json_encode($validator->errors()));
|
|
||||||
}
|
|
||||||
|
|
||||||
return DB::transaction(function () use ($data, $host) {
|
|
||||||
if (isset($data['password'])) {
|
|
||||||
$host->password = Crypt::encrypt($data['password']);
|
|
||||||
}
|
|
||||||
$host->fill($data)->save();
|
|
||||||
|
|
||||||
// Check that we can still connect with these details.
|
|
||||||
$host->setDynamicConnection();
|
|
||||||
DB::connection('dynamic')->select('SELECT 1 FROM dual');
|
|
||||||
|
|
||||||
return $host;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
188
app/Services/Database/CreationService.php
Normal file
188
app/Services/Database/CreationService.php
Normal file
|
@ -0,0 +1,188 @@
|
||||||
|
<?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\Database;
|
||||||
|
|
||||||
|
use Illuminate\Database\ConnectionResolver;
|
||||||
|
use Illuminate\Database\ConnectionInterface;
|
||||||
|
use Illuminate\Contracts\Encryption\Encrypter;
|
||||||
|
use Pterodactyl\Extensions\DynamicDatabaseConnection;
|
||||||
|
use Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface;
|
||||||
|
|
||||||
|
class CreationService
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var \Illuminate\Database\ConnectionResolver
|
||||||
|
*/
|
||||||
|
protected $connection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Illuminate\Database\ConnectionInterface
|
||||||
|
*/
|
||||||
|
protected $database;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Extensions\DynamicDatabaseConnection
|
||||||
|
*/
|
||||||
|
protected $dynamic;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Illuminate\Contracts\Encryption\Encrypter
|
||||||
|
*/
|
||||||
|
protected $encrypter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface
|
||||||
|
*/
|
||||||
|
protected $repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CreationService constructor.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Database\ConnectionInterface $database
|
||||||
|
* @param \Illuminate\Database\ConnectionResolver $connection
|
||||||
|
* @param \Pterodactyl\Extensions\DynamicDatabaseConnection $dynamic
|
||||||
|
* @param \Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface $repository
|
||||||
|
* @param \Illuminate\Contracts\Encryption\Encrypter $encrypter
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
ConnectionInterface $database,
|
||||||
|
ConnectionResolver $connection,
|
||||||
|
DynamicDatabaseConnection $dynamic,
|
||||||
|
DatabaseRepositoryInterface $repository,
|
||||||
|
Encrypter $encrypter
|
||||||
|
) {
|
||||||
|
$this->connection = $connection;
|
||||||
|
$this->database = $database;
|
||||||
|
$this->dynamic = $dynamic;
|
||||||
|
$this->encrypter = $encrypter;
|
||||||
|
$this->repository = $repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new database that is linked to a specific host.
|
||||||
|
*
|
||||||
|
* @param array $data
|
||||||
|
* @return \Illuminate\Database\Eloquent\Model
|
||||||
|
*
|
||||||
|
* @throws \Exception
|
||||||
|
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||||
|
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||||
|
*/
|
||||||
|
public function create(array $data)
|
||||||
|
{
|
||||||
|
$data['database'] = sprintf('d%d_%s', $data['server_id'], $data['database']);
|
||||||
|
$data['username'] = sprintf('u%d_%s', $data['server_id'], str_random(10));
|
||||||
|
$data['password'] = $this->encrypter->encrypt(str_random(16));
|
||||||
|
|
||||||
|
$this->database->beginTransaction();
|
||||||
|
try {
|
||||||
|
$database = $this->repository->createIfNotExists($data);
|
||||||
|
$this->dynamic->set('dynamic', $data['database_host_id']);
|
||||||
|
|
||||||
|
$this->repository->createDatabase($database->database, 'dynamic');
|
||||||
|
$this->repository->createUser(
|
||||||
|
$database->username, $database->remote, $this->encrypter->decrypt($database->password), 'dynamic'
|
||||||
|
);
|
||||||
|
$this->repository->assignUserToDatabase(
|
||||||
|
$database->database, $database->username, $database->remote, 'dynamic'
|
||||||
|
);
|
||||||
|
$this->repository->flush('dynamic');
|
||||||
|
|
||||||
|
$this->database->commit();
|
||||||
|
} catch (\Exception $ex) {
|
||||||
|
try {
|
||||||
|
if (isset($database)) {
|
||||||
|
$this->repository->dropDatabase($database->database, 'dynamic');
|
||||||
|
$this->repository->dropUser($database->username, $database->remote, 'dynamic');
|
||||||
|
$this->repository->flush('dynamic');
|
||||||
|
}
|
||||||
|
} catch (\Exception $ex) {
|
||||||
|
// ignore an exception
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->database->rollBack();
|
||||||
|
throw $ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $database;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the password for a specific user and database combination.
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @param string $password
|
||||||
|
* @return bool
|
||||||
|
*
|
||||||
|
* @throws \Exception
|
||||||
|
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||||
|
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||||
|
*/
|
||||||
|
public function changePassword($id, $password)
|
||||||
|
{
|
||||||
|
$database = $this->repository->find($id);
|
||||||
|
$this->dynamic->set('dynamic', $database->database_host_id);
|
||||||
|
|
||||||
|
$this->database->beginTransaction();
|
||||||
|
|
||||||
|
try {
|
||||||
|
$updated = $this->repository->withoutFresh()->update($id, [
|
||||||
|
'password' => $this->encrypter->encrypt($password),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->repository->dropUser($database->username, $database->remote, 'dynamic');
|
||||||
|
$this->repository->createUser($database->username, $database->remote, $password);
|
||||||
|
$this->repository->assignUserToDatabase(
|
||||||
|
$database->database, $database->username, $database->remote, 'dynamic'
|
||||||
|
);
|
||||||
|
$this->repository->flush();
|
||||||
|
|
||||||
|
$this->database->commit();
|
||||||
|
} catch (\Exception $ex) {
|
||||||
|
$this->database->rollBack();
|
||||||
|
throw $ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $updated;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a database from the given host server.
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return bool|null
|
||||||
|
*/
|
||||||
|
public function delete($id)
|
||||||
|
{
|
||||||
|
$database = $this->repository->find($id);
|
||||||
|
$this->dynamic->set('dynamic', $database->database_host_id);
|
||||||
|
|
||||||
|
$this->repository->dropDatabase($database->database, 'dynamic');
|
||||||
|
$this->repository->dropUser($database->username, $database->remote, 'dynamic');
|
||||||
|
$this->repository->flush('dynamic');
|
||||||
|
|
||||||
|
return $this->repository->delete($id);
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,7 +27,7 @@ namespace Pterodactyl\Services\Database;
|
||||||
use Illuminate\Database\DatabaseManager;
|
use Illuminate\Database\DatabaseManager;
|
||||||
use Illuminate\Contracts\Encryption\Encrypter;
|
use Illuminate\Contracts\Encryption\Encrypter;
|
||||||
use Pterodactyl\Extensions\DynamicDatabaseConnection;
|
use Pterodactyl\Extensions\DynamicDatabaseConnection;
|
||||||
use Pterodactyl\Contracts\Repository\DatabaseHostInterface;
|
use Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface;
|
||||||
|
|
||||||
class DatabaseHostService
|
class DatabaseHostService
|
||||||
{
|
{
|
||||||
|
@ -47,20 +47,20 @@ class DatabaseHostService
|
||||||
protected $encrypter;
|
protected $encrypter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Pterodactyl\Contracts\Repository\DatabaseHostInterface
|
* @var \Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface
|
||||||
*/
|
*/
|
||||||
protected $repository;
|
protected $repository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DatabaseHostService constructor.
|
* DatabaseHostService constructor.
|
||||||
*
|
*
|
||||||
* @param \Pterodactyl\Contracts\Repository\DatabaseHostInterface $repository
|
* @param \Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface $repository
|
||||||
* @param \Illuminate\Database\DatabaseManager $database
|
* @param \Illuminate\Database\DatabaseManager $database
|
||||||
* @param \Pterodactyl\Extensions\DynamicDatabaseConnection $dynamic
|
* @param \Pterodactyl\Extensions\DynamicDatabaseConnection $dynamic
|
||||||
* @param \Illuminate\Contracts\Encryption\Encrypter $encrypter
|
* @param \Illuminate\Contracts\Encryption\Encrypter $encrypter
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
DatabaseHostInterface $repository,
|
DatabaseHostRepositoryInterface $repository,
|
||||||
DatabaseManager $database,
|
DatabaseManager $database,
|
||||||
DynamicDatabaseConnection $dynamic,
|
DynamicDatabaseConnection $dynamic,
|
||||||
Encrypter $encrypter
|
Encrypter $encrypter
|
||||||
|
|
|
@ -40,6 +40,7 @@ return [
|
||||||
'servers' => env('APP_PAGINATE_FRONT_SERVERS', 15),
|
'servers' => env('APP_PAGINATE_FRONT_SERVERS', 15),
|
||||||
],
|
],
|
||||||
'admin' => [
|
'admin' => [
|
||||||
|
'servers' => env('APP_PAGINATE_ADMIN_SERVERS', 25),
|
||||||
'users' => env('APP_PAGINATE_ADMIN_USERS', 25),
|
'users' => env('APP_PAGINATE_ADMIN_USERS', 25),
|
||||||
],
|
],
|
||||||
'api' => [
|
'api' => [
|
||||||
|
|
|
@ -29,7 +29,7 @@ use Tests\TestCase;
|
||||||
use Illuminate\Database\DatabaseManager;
|
use Illuminate\Database\DatabaseManager;
|
||||||
use Illuminate\Contracts\Encryption\Encrypter;
|
use Illuminate\Contracts\Encryption\Encrypter;
|
||||||
use Pterodactyl\Extensions\DynamicDatabaseConnection;
|
use Pterodactyl\Extensions\DynamicDatabaseConnection;
|
||||||
use Pterodactyl\Contracts\Repository\DatabaseHostInterface;
|
use Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface;
|
||||||
use Pterodactyl\Services\Database\DatabaseHostService;
|
use Pterodactyl\Services\Database\DatabaseHostService;
|
||||||
|
|
||||||
class DatabaseHostServiceTest extends TestCase
|
class DatabaseHostServiceTest extends TestCase
|
||||||
|
@ -50,7 +50,7 @@ class DatabaseHostServiceTest extends TestCase
|
||||||
protected $encrypter;
|
protected $encrypter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Pterodactyl\Contracts\Repository\DatabaseHostInterface
|
* @var \Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface
|
||||||
*/
|
*/
|
||||||
protected $repository;
|
protected $repository;
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ class DatabaseHostServiceTest extends TestCase
|
||||||
$this->database = m::mock(DatabaseManager::class);
|
$this->database = m::mock(DatabaseManager::class);
|
||||||
$this->dynamic = m::mock(DynamicDatabaseConnection::class);
|
$this->dynamic = m::mock(DynamicDatabaseConnection::class);
|
||||||
$this->encrypter = m::mock(Encrypter::class);
|
$this->encrypter = m::mock(Encrypter::class);
|
||||||
$this->repository = m::mock(DatabaseHostInterface::class);
|
$this->repository = m::mock(DatabaseHostRepositoryInterface::class);
|
||||||
|
|
||||||
$this->service = new DatabaseHostService(
|
$this->service = new DatabaseHostService(
|
||||||
$this->repository,
|
$this->repository,
|
||||||
|
|
Loading…
Reference in a new issue