diff --git a/app/Contracts/Repository/UserRepositoryInterface.php b/app/Contracts/Repository/UserRepositoryInterface.php index d6a02c925..0265d6f44 100644 --- a/app/Contracts/Repository/UserRepositoryInterface.php +++ b/app/Contracts/Repository/UserRepositoryInterface.php @@ -44,4 +44,12 @@ interface UserRepositoryInterface extends RepositoryInterface, SearchableInterfa * @throws \Pterodactyl\Exceptions\DisplayException */ public function deleteIfNoServers($id); + + /** + * Return all matching models for a user in a format that can be used for dropdowns. + * + * @param string $query + * @return \Illuminate\Database\Eloquent\Collection + */ + public function filterUsersByQuery($query); } diff --git a/app/Http/Controllers/Admin/ServersController.php b/app/Http/Controllers/Admin/ServersController.php index 7af2e22ac..725eff0b9 100644 --- a/app/Http/Controllers/Admin/ServersController.php +++ b/app/Http/Controllers/Admin/ServersController.php @@ -63,6 +63,11 @@ class ServersController extends Controller */ protected $databaseRepository; + /** + * @var \Pterodactyl\Services\Database\CreationService + */ + protected $databaseCreationService; + /** * @var \Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface */ @@ -97,6 +102,7 @@ class ServersController extends Controller AllocationRepositoryInterface $allocationRepository, ConfigRepository $config, CreationService $service, + \Pterodactyl\Services\Database\CreationService $databaseCreationService, DatabaseRepositoryInterface $databaseRepository, DatabaseHostRepository $databaseHostRepository, LocationRepositoryInterface $locationRepository, @@ -106,6 +112,7 @@ class ServersController extends Controller ) { $this->allocationRepository = $allocationRepository; $this->config = $config; + $this->databaseCreationService = $databaseCreationService; $this->databaseRepository = $databaseRepository; $this->databaseHostRepository = $databaseHostRepository; $this->locationRepository = $locationRepository; @@ -583,20 +590,25 @@ class ServersController extends Controller */ public function newDatabase(Request $request, $id) { - $repo = new DatabaseRepository; - - try { - $repo->create($id, $request->only(['host', 'database', 'connection'])); - - Alert::success('A new database was assigned to this server successfully.')->flash(); - } catch (DisplayValidationException $ex) { - return redirect()->route('admin.servers.view.database', $id)->withInput()->withErrors(json_decode($ex->getMessage()))->withInput(); - } catch (DisplayException $ex) { - Alert::danger($ex->getMessage())->flash(); - } catch (\Exception $ex) { - Log::error($ex); - Alert::danger('An exception occured while attempting to add a new database for this server. This error has been logged.')->flash(); - } + $this->databaseCreationService->create($id, [ + 'database' => $request->input('database'), + 'remote' => $request->input('remote'), + 'database_host_id' => $request->input('database_host_id'), + ]); +// $repo = new DatabaseRepository; +// +// try { +// $repo->create($id, $request->only(['host', 'database', 'connection'])); +// +// Alert::success('A new database was assigned to this server successfully.')->flash(); +// } catch (DisplayValidationException $ex) { +// return redirect()->route('admin.servers.view.database', $id)->withInput()->withErrors(json_decode($ex->getMessage()))->withInput(); +// } catch (DisplayException $ex) { +// Alert::danger($ex->getMessage())->flash(); +// } catch (\Exception $ex) { +// Log::error($ex); +// Alert::danger('An exception occured while attempting to add a new database for this server. This error has been logged.')->flash(); +// } return redirect()->route('admin.servers.view.database', $id)->withInput(); } diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php index 151d9774c..42da3f57f 100644 --- a/app/Http/Controllers/Admin/UserController.php +++ b/app/Http/Controllers/Admin/UserController.php @@ -28,7 +28,7 @@ use Illuminate\Http\Request; use Pterodactyl\Contracts\Repository\UserRepositoryInterface; use Pterodactyl\Models\User; use Prologue\Alerts\AlertsMessageBag; -use Pterodactyl\Services\Administrative\UserService; +use Pterodactyl\Services\UserService; use Pterodactyl\Exceptions\DisplayException; use Pterodactyl\Http\Controllers\Controller; use Pterodactyl\Http\Requests\Admin\UserFormRequest; @@ -41,7 +41,7 @@ class UserController extends Controller protected $alert; /** - * @var \Pterodactyl\Services\Administrative\UserService + * @var \Pterodactyl\Services\UserService */ protected $service; @@ -59,7 +59,7 @@ class UserController extends Controller * UserController constructor. * * @param \Prologue\Alerts\AlertsMessageBag $alert - * @param \Pterodactyl\Services\Administrative\UserService $service + * @param \Pterodactyl\Services\UserService $service * @param \Pterodactyl\Contracts\Repository\UserRepositoryInterface $repository * @param \Pterodactyl\Models\User $model */ @@ -178,17 +178,11 @@ class UserController extends Controller /** * Get a JSON response of users on the system. * - * @param \Illuminate\Http\Request $request - * @return \Pterodactyl\Models\User + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Database\Eloquent\Collection */ public function json(Request $request) { - return $this->model->search($request->input('q'))->all([ - 'id', 'email', 'username', 'name_first', 'name_last', - ])->transform(function ($item) { - $item->md5 = md5(strtolower($item->email)); - - return $item; - }); + return $this->repository->filterUsersByQuery($request->input('q')); } } diff --git a/app/Http/Requests/Admin/DatabaseHostFormRequest.php b/app/Http/Requests/Admin/DatabaseHostFormRequest.php index 42052f5bd..66c95703f 100644 --- a/app/Http/Requests/Admin/DatabaseHostFormRequest.php +++ b/app/Http/Requests/Admin/DatabaseHostFormRequest.php @@ -33,17 +33,10 @@ class DatabaseHostFormRequest extends AdminFormRequest */ 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; + if ($this->method() !== 'POST') { + return DatabaseHost::getUpdateRulesForId($this->route()->parameter('host')->id); } - return $rules; + return DatabaseHost::getCreateRules(); } } diff --git a/app/Models/Database.php b/app/Models/Database.php index a7ee970e2..ee8be0c51 100644 --- a/app/Models/Database.php +++ b/app/Models/Database.php @@ -24,11 +24,12 @@ namespace Pterodactyl\Models; -use Illuminate\Database\Eloquent\Model; use Sofa\Eloquence\Eloquence; use Sofa\Eloquence\Validable; +use Illuminate\Database\Eloquent\Model; +use Sofa\Eloquence\Contracts\Validable as ValidableContract; -class Database extends Model +class Database extends Model implements ValidableContract { use Eloquence, Validable; @@ -52,7 +53,7 @@ class Database extends Model * @var array */ protected $fillable = [ - 'server_id', 'database_host_id', 'database', 'username', 'remote', + 'server_id', 'database_host_id', 'database', 'username', 'password', 'remote', ]; /** diff --git a/app/Models/DatabaseHost.php b/app/Models/DatabaseHost.php index 54a16d3ec..d9eb48ff1 100644 --- a/app/Models/DatabaseHost.php +++ b/app/Models/DatabaseHost.php @@ -27,8 +27,9 @@ namespace Pterodactyl\Models; use Sofa\Eloquence\Eloquence; use Sofa\Eloquence\Validable; use Illuminate\Database\Eloquent\Model; +use Sofa\Eloquence\Contracts\Validable as ValidableContract; -class DatabaseHost extends Model +class DatabaseHost extends Model implements ValidableContract { use Eloquence, Validable; @@ -52,7 +53,7 @@ class DatabaseHost extends Model * @var array */ protected $fillable = [ - 'name', 'host', 'port', 'username', 'max_databases', 'node_id', + 'name', 'host', 'port', 'username', 'password', 'max_databases', 'node_id', ]; /** @@ -79,11 +80,12 @@ class DatabaseHost extends Model 'node_id' => 'sometimes|required', ]; - /** - * Validation rules to assign to this model. - * - * @var array - */ +/** + * Validation rules to assign to this model. + * + * @var array + */ + // @todo the node_id field doesn't validate correctly if no node is provided in request protected static $dataIntegrityRules = [ 'name' => 'string|max:255', 'host' => 'ip|unique:database_hosts,host', diff --git a/app/Repositories/Eloquent/DatabaseRepository.php b/app/Repositories/Eloquent/DatabaseRepository.php index 3a2a589c2..0e2bd6c1f 100644 --- a/app/Repositories/Eloquent/DatabaseRepository.php +++ b/app/Repositories/Eloquent/DatabaseRepository.php @@ -24,32 +24,32 @@ namespace Pterodactyl\Repositories\Eloquent; +use Illuminate\Database\DatabaseManager; 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 + * @var \Illuminate\Database\DatabaseManager */ - protected $connection; + protected $database; /** * DatabaseRepository constructor. * - * @param \Illuminate\Foundation\Application $application - * @param \Illuminate\Database\ConnectionResolver $connection + * @param \Illuminate\Foundation\Application $application + * @param \Illuminate\Database\DatabaseManager $database */ public function __construct( Application $application, - ConnectionResolver $connection + DatabaseManager $database ) { parent::__construct($application); - $this->connection = $connection; + $this->database = $database; } /** @@ -150,6 +150,6 @@ class DatabaseRepository extends EloquentRepository implements DatabaseRepositor */ protected function runStatement($statement, $connection = null) { - return $this->connection->connection($connection)->statement($statement); + return $this->database->connection($connection)->statement($statement); } } diff --git a/app/Repositories/Eloquent/UserRepository.php b/app/Repositories/Eloquent/UserRepository.php index 4ad33419e..8915b33a7 100644 --- a/app/Repositories/Eloquent/UserRepository.php +++ b/app/Repositories/Eloquent/UserRepository.php @@ -93,4 +93,22 @@ class UserRepository extends SearchableRepository implements UserRepositoryInter return $user->delete(); } + + /** + * {@inheritdoc} + */ + public function filterUsersByQuery($query) + { + $this->withColumns([ + 'id', 'email', 'username', 'name_first', 'name_last', + ]); + + $instance = $this->getBuilder()->search($query)->get($this->getColumns()); + + return $instance->transform(function ($item) { + $item->md5 = md5(strtolower($item->email)); + + return $item; + }); + } } diff --git a/app/Services/Database/CreationService.php b/app/Services/Database/CreationService.php index b1f480af0..339a0b8f0 100644 --- a/app/Services/Database/CreationService.php +++ b/app/Services/Database/CreationService.php @@ -24,8 +24,7 @@ namespace Pterodactyl\Services\Database; -use Illuminate\Database\ConnectionResolver; -use Illuminate\Database\ConnectionInterface; +use Illuminate\Database\DatabaseManager; use Illuminate\Contracts\Encryption\Encrypter; use Pterodactyl\Extensions\DynamicDatabaseConnection; use Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface; @@ -33,12 +32,7 @@ use Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface; class CreationService { /** - * @var \Illuminate\Database\ConnectionResolver - */ - protected $connection; - - /** - * @var \Illuminate\Database\ConnectionInterface + * @var \Illuminate\Database\DatabaseManager */ protected $database; @@ -60,20 +54,17 @@ class CreationService /** * CreationService constructor. * - * @param \Illuminate\Database\ConnectionInterface $database - * @param \Illuminate\Database\ConnectionResolver $connection + * @param \Illuminate\Database\DatabaseManager $database * @param \Pterodactyl\Extensions\DynamicDatabaseConnection $dynamic * @param \Pterodactyl\Contracts\Repository\DatabaseRepositoryInterface $repository * @param \Illuminate\Contracts\Encryption\Encrypter $encrypter */ public function __construct( - ConnectionInterface $database, - ConnectionResolver $connection, + DatabaseManager $database, DynamicDatabaseConnection $dynamic, DatabaseRepositoryInterface $repository, Encrypter $encrypter ) { - $this->connection = $connection; $this->database = $database; $this->dynamic = $dynamic; $this->encrypter = $encrypter; @@ -83,6 +74,7 @@ class CreationService /** * Create a new database that is linked to a specific host. * + * @param int $server * @param array $data * @return \Illuminate\Database\Eloquent\Model * @@ -90,10 +82,11 @@ class CreationService * @throws \Pterodactyl\Exceptions\DisplayException * @throws \Pterodactyl\Exceptions\Model\DataValidationException */ - public function create(array $data) + public function create($server, 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['server_id'] = $server; + $data['database'] = sprintf('d%d_%s', $server, $data['database']); + $data['username'] = sprintf('u%d_%s', $server, str_random(10)); $data['password'] = $this->encrypter->encrypt(str_random(16)); $this->database->beginTransaction(); diff --git a/app/Services/Database/DatabaseHostService.php b/app/Services/Database/DatabaseHostService.php index ad54a1cdb..94170d83a 100644 --- a/app/Services/Database/DatabaseHostService.php +++ b/app/Services/Database/DatabaseHostService.php @@ -24,8 +24,8 @@ namespace Pterodactyl\Services\Database; -use Illuminate\Database\DatabaseManager; use Illuminate\Contracts\Encryption\Encrypter; +use Illuminate\Database\DatabaseManager; use Pterodactyl\Extensions\DynamicDatabaseConnection; use Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface; @@ -54,14 +54,14 @@ class DatabaseHostService /** * DatabaseHostService constructor. * - * @param \Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface $repository * @param \Illuminate\Database\DatabaseManager $database + * @param \Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface $repository * @param \Pterodactyl\Extensions\DynamicDatabaseConnection $dynamic * @param \Illuminate\Contracts\Encryption\Encrypter $encrypter */ public function __construct( - DatabaseHostRepositoryInterface $repository, DatabaseManager $database, + DatabaseHostRepositoryInterface $repository, DynamicDatabaseConnection $dynamic, Encrypter $encrypter ) { @@ -74,7 +74,7 @@ class DatabaseHostService /** * Create a new database host and persist it to the database. * - * @param array $data + * @param array $data * @return \Pterodactyl\Models\DatabaseHost * * @throws \Throwable @@ -106,11 +106,11 @@ class DatabaseHostService /** * Update a database host and persist to the database. * - * @param int $id - * @param array $data + * @param int $id + * @param array $data * @return mixed * - * @throws \PDOException + * @throws \Pterodactyl\Exceptions\Model\DataValidationException */ public function update($id, array $data) { @@ -135,7 +135,7 @@ class DatabaseHostService /** * Delete a database host if it has no active databases attached to it. * - * @param int $id + * @param int $id * @return bool|null * * @throws \Pterodactyl\Exceptions\DisplayException diff --git a/resources/themes/pterodactyl/admin/databases/index.blade.php b/resources/themes/pterodactyl/admin/databases/index.blade.php index e8e0c21ca..be805d608 100644 --- a/resources/themes/pterodactyl/admin/databases/index.blade.php +++ b/resources/themes/pterodactyl/admin/databases/index.blade.php @@ -117,7 +117,7 @@