diff --git a/app/Console/Commands/User/DeleteUserCommand.php b/app/Console/Commands/User/DeleteUserCommand.php index ce79a493d..c9a69bee8 100644 --- a/app/Console/Commands/User/DeleteUserCommand.php +++ b/app/Console/Commands/User/DeleteUserCommand.php @@ -61,7 +61,7 @@ class DeleteUserCommand extends Command $search = $this->option('user') ?? $this->ask(trans('command/messages.user.search_users')); Assert::notEmpty($search, 'Search term must be a non-null value, received %s.'); - $results = $this->repository->search($search)->all(); + $results = $this->repository->setSearchTerm($search)->all(); if (count($results) < 1) { $this->error(trans('command/messages.user.no_users_found')); if ($this->input->isInteractive()) { diff --git a/app/Console/Commands/User/DisableTwoFactorCommand.php b/app/Console/Commands/User/DisableTwoFactorCommand.php index 568a5a95e..7df23b41e 100644 --- a/app/Console/Commands/User/DisableTwoFactorCommand.php +++ b/app/Console/Commands/User/DisableTwoFactorCommand.php @@ -54,7 +54,7 @@ class DisableTwoFactorCommand extends Command } $email = $this->option('email') ?? $this->ask(trans('command/messages.user.ask_email')); - $user = $this->repository->withColumns(['id', 'email'])->findFirstWhere([['email', '=', $email]]); + $user = $this->repository->setColumns(['id', 'email'])->findFirstWhere([['email', '=', $email]]); $this->repository->withoutFresh()->update($user->id, [ 'use_totp' => false, diff --git a/app/Contracts/Repository/AllocationRepositoryInterface.php b/app/Contracts/Repository/AllocationRepositoryInterface.php index 90b75fced..fa854e24a 100644 --- a/app/Contracts/Repository/AllocationRepositoryInterface.php +++ b/app/Contracts/Repository/AllocationRepositoryInterface.php @@ -1,14 +1,9 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Contracts\Repository; +use Illuminate\Support\Collection; + interface AllocationRepositoryInterface extends RepositoryInterface { /** @@ -18,13 +13,13 @@ interface AllocationRepositoryInterface extends RepositoryInterface * @param array $ids * @return int */ - public function assignAllocationsToServer($server, array $ids); + public function assignAllocationsToServer(int $server = null, array $ids): int; /** * Return all of the allocations for a specific node. * * @param int $node - * @return \Illuminate\Database\Eloquent\Collection + * @return \Illuminate\Support\Collection */ - public function getAllocationsForNode($node); + public function getAllocationsForNode(int $node): Collection; } diff --git a/app/Contracts/Repository/Attributes/SearchableInterface.php b/app/Contracts/Repository/Attributes/SearchableInterface.php index 30b2a202a..f1ab6e804 100644 --- a/app/Contracts/Repository/Attributes/SearchableInterface.php +++ b/app/Contracts/Repository/Attributes/SearchableInterface.php @@ -1,21 +1,38 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Contracts\Repository\Attributes; interface SearchableInterface { /** - * Filter results by search term. + * Set the search term. * - * @param string $term + * @param string|null $term * @return $this + * @deprecated */ public function search($term); + + /** + * Set the search term to use when requesting all records from + * the model. + * + * @param string|null $term + * @return $this + */ + public function setSearchTerm(string $term = null); + + /** + * Determine if a valid search term is set on this repository. + * + * @return bool + */ + public function hasSearchTerm(): bool; + + /** + * Return the search term. + * + * @return string|null + */ + public function getSearchTerm(); } diff --git a/app/Contracts/Repository/DaemonKeyRepositoryInterface.php b/app/Contracts/Repository/DaemonKeyRepositoryInterface.php index 4f2156ad5..7979980c0 100644 --- a/app/Contracts/Repository/DaemonKeyRepositoryInterface.php +++ b/app/Contracts/Repository/DaemonKeyRepositoryInterface.php @@ -1,26 +1,4 @@ . - * - * 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; @@ -44,14 +22,6 @@ interface DaemonKeyRepositoryInterface extends RepositoryInterface */ public function loadServerAndUserRelations(DaemonKey $key, bool $refresh = false): DaemonKey; - /** - * Gets the daemon keys associated with a specific server. - * - * @param int $server - * @return \Illuminate\Support\Collection - */ - public function getServerKeys($server); - /** * Return a daemon key with the associated server relation attached. * @@ -60,7 +30,7 @@ interface DaemonKeyRepositoryInterface extends RepositoryInterface * * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ - public function getKeyWithServer($key); + public function getKeyWithServer(string $key): DaemonKey; /** * Get all of the keys for a specific user including the information needed diff --git a/app/Contracts/Repository/DatabaseHostRepositoryInterface.php b/app/Contracts/Repository/DatabaseHostRepositoryInterface.php index 955e1f7f3..dfd29e9ab 100644 --- a/app/Contracts/Repository/DatabaseHostRepositoryInterface.php +++ b/app/Contracts/Repository/DatabaseHostRepositoryInterface.php @@ -1,30 +1,28 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Contracts\Repository; +use Illuminate\Support\Collection; +use Pterodactyl\Models\DatabaseHost; + interface DatabaseHostRepositoryInterface extends RepositoryInterface { /** - * Return database hosts with a count of databases and the node information for which it is attached. + * Return database hosts with a count of databases and the node + * information for which it is attached. * * @return \Illuminate\Support\Collection */ - public function getWithViewDetails(); + public function getWithViewDetails(): Collection; /** - * Return a database host with the databases and associated servers that are attached to said databases. + * Return a database host with the databases and associated servers + * that are attached to said databases. * * @param int $id - * @return mixed + * @return \Pterodactyl\Models\DatabaseHost * * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ - public function getWithServers($id); + public function getWithServers(int $id): DatabaseHost; } diff --git a/app/Contracts/Repository/DatabaseRepositoryInterface.php b/app/Contracts/Repository/DatabaseRepositoryInterface.php index 1e90d0e04..7fc3bf045 100644 --- a/app/Contracts/Repository/DatabaseRepositoryInterface.php +++ b/app/Contracts/Repository/DatabaseRepositoryInterface.php @@ -9,6 +9,7 @@ namespace Pterodactyl\Contracts\Repository; +use Pterodactyl\Models\Database; use Illuminate\Support\Collection; interface DatabaseRepositoryInterface extends RepositoryInterface @@ -43,12 +44,12 @@ interface DatabaseRepositoryInterface extends RepositoryInterface * the provided details. * * @param array $data - * @return mixed + * @return \Pterodactyl\Models\Database * - * @throws \Pterodactyl\Exceptions\DisplayException * @throws \Pterodactyl\Exceptions\Model\DataValidationException + * @throws \Pterodactyl\Exceptions\Repository\DuplicateDatabaseNameException */ - public function createIfNotExists(array $data); + public function createIfNotExists(array $data): Database; /** * Create a new database on a given connection. @@ -56,7 +57,7 @@ interface DatabaseRepositoryInterface extends RepositoryInterface * @param string $database * @return bool */ - public function createDatabase($database); + public function createDatabase(string $database): bool; /** * Create a new database user on a given connection. @@ -66,7 +67,7 @@ interface DatabaseRepositoryInterface extends RepositoryInterface * @param string $password * @return bool */ - public function createUser($username, $remote, $password); + public function createUser(string $username, string $remote, string $password): bool; /** * Give a specific user access to a given database. @@ -76,14 +77,14 @@ interface DatabaseRepositoryInterface extends RepositoryInterface * @param string $remote * @return bool */ - public function assignUserToDatabase($database, $username, $remote); + public function assignUserToDatabase(string $database, string $username, string $remote): bool; /** * Flush the privileges for a given connection. * - * @return mixed + * @return bool */ - public function flush(); + public function flush(): bool; /** * Drop a given database on a specific connection. @@ -91,7 +92,7 @@ interface DatabaseRepositoryInterface extends RepositoryInterface * @param string $database * @return bool */ - public function dropDatabase($database); + public function dropDatabase(string $database): bool; /** * Drop a given user on a specific connection. @@ -100,5 +101,5 @@ interface DatabaseRepositoryInterface extends RepositoryInterface * @param string $remote * @return mixed */ - public function dropUser($username, $remote); + public function dropUser(string $username, string $remote): bool; } diff --git a/app/Contracts/Repository/LocationRepositoryInterface.php b/app/Contracts/Repository/LocationRepositoryInterface.php index ef68fdf28..e91da6c43 100644 --- a/app/Contracts/Repository/LocationRepositoryInterface.php +++ b/app/Contracts/Repository/LocationRepositoryInterface.php @@ -1,14 +1,9 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Contracts\Repository; +use Pterodactyl\Models\Location; +use Illuminate\Support\Collection; use Pterodactyl\Contracts\Repository\Attributes\SearchableInterface; interface LocationRepositoryInterface extends RepositoryInterface, SearchableInterface @@ -16,16 +11,16 @@ interface LocationRepositoryInterface extends RepositoryInterface, SearchableInt /** * Return locations with a count of nodes and servers attached to it. * - * @return mixed + * @return \Illuminate\Support\Collection */ - public function getAllWithDetails(); + public function getAllWithDetails(): Collection; /** * Return all of the available locations with the nodes as a relationship. * * @return \Illuminate\Support\Collection */ - public function getAllWithNodes(); + public function getAllWithNodes(): Collection; /** * Return all of the nodes and their respective count of servers for a location. @@ -35,7 +30,7 @@ interface LocationRepositoryInterface extends RepositoryInterface, SearchableInt * * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ - public function getWithNodes($id); + public function getWithNodes(int $id): Location; /** * Return a location and the count of nodes in that location. @@ -45,5 +40,5 @@ interface LocationRepositoryInterface extends RepositoryInterface, SearchableInt * * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ - public function getWithNodeCount($id); + public function getWithNodeCount(int $id): Location; } diff --git a/app/Contracts/Repository/NodeRepositoryInterface.php b/app/Contracts/Repository/NodeRepositoryInterface.php index 078a274db..49db33be8 100644 --- a/app/Contracts/Repository/NodeRepositoryInterface.php +++ b/app/Contracts/Repository/NodeRepositoryInterface.php @@ -1,68 +1,65 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Contracts\Repository; +use Pterodactyl\Models\Node; +use Illuminate\Support\Collection; +use Illuminate\Contracts\Pagination\LengthAwarePaginator; use Pterodactyl\Contracts\Repository\Attributes\SearchableInterface; interface NodeRepositoryInterface extends RepositoryInterface, SearchableInterface { + const THRESHOLD_PERCENTAGE_LOW = 75; + const THRESHOLD_PERCENTAGE_MEDIUM = 90; + /** * Return the usage stats for a single node. * - * @param int $id + * @param \Pterodactyl\Models\Node $node * @return array */ - public function getUsageStats($id); + public function getUsageStats(Node $node): array; /** * Return all available nodes with a searchable interface. * - * @param int $count * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator */ - public function getNodeListingData($count = 25); + public function getNodeListingData(): LengthAwarePaginator; /** * Return a single node with location and server information. * - * @param int $id - * @return mixed - * - * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException + * @param \Pterodactyl\Models\Node $node + * @param bool $refresh + * @return \Pterodactyl\Models\Node */ - public function getSingleNode($id); + public function loadLocationAndServerCount(Node $node, bool $refresh = false): Node; /** - * Return a node with all of the associated allocations and servers that are attached to said allocations. + * Attach a paginated set of allocations to a node mode including + * any servers that are also attached to those allocations. * - * @param int $id - * @return mixed - * - * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException + * @param \Pterodactyl\Models\Node $node + * @param bool $refresh + * @return \Pterodactyl\Models\Node */ - public function getNodeAllocations($id); + public function loadNodeAllocations(Node $node, bool $refresh = false): Node; /** * Return a node with all of the servers attached to that node. * * @param int $id - * @return mixed + * @return \Pterodactyl\Models\Node * * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ - public function getNodeServers($id); + public function getNodeServers(int $id): Node; /** * Return a collection of nodes for all locations to use in server creation UI. * - * @return mixed + * @return \Illuminate\Support\Collection */ - public function getNodesForServerCreation(); + public function getNodesForServerCreation(): Collection; } diff --git a/app/Contracts/Repository/PackRepositoryInterface.php b/app/Contracts/Repository/PackRepositoryInterface.php index d6ad80785..6ef7cef7f 100644 --- a/app/Contracts/Repository/PackRepositoryInterface.php +++ b/app/Contracts/Repository/PackRepositoryInterface.php @@ -1,44 +1,26 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Contracts\Repository; +use Pterodactyl\Models\Pack; +use Illuminate\Contracts\Pagination\LengthAwarePaginator; use Pterodactyl\Contracts\Repository\Attributes\SearchableInterface; interface PackRepositoryInterface extends RepositoryInterface, SearchableInterface { - /** - * Return a paginated listing of packs with their associated egg and server count. - * - * @param int $paginate - * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator - */ - public function paginateWithEggAndServerCount($paginate = 50); - /** * Return a pack with the associated server models attached to it. * - * @param int $id - * @return \Illuminate\Database\Eloquent\Collection - * - * @throws \Illuminate\Database\Eloquent\ModelNotFoundException + * @param \Pterodactyl\Models\Pack $pack + * @param bool $refresh + * @return \Pterodactyl\Models\Pack */ - public function getWithServers($id); + public function loadServerData(Pack $pack, bool $refresh = false): Pack; /** - * Return all of the file archives for a given pack. + * Return a paginated listing of packs with their associated egg and server count. * - * @param int $id - * @param bool $collection - * @return object|\Illuminate\Support\Collection - * - * @throws \Illuminate\Database\Eloquent\ModelNotFoundException + * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator */ - public function getFileArchives($id, $collection = false); + public function paginateWithEggAndServerCount(): LengthAwarePaginator; } diff --git a/app/Contracts/Repository/RepositoryInterface.php b/app/Contracts/Repository/RepositoryInterface.php index f31e852d8..028058af4 100644 --- a/app/Contracts/Repository/RepositoryInterface.php +++ b/app/Contracts/Repository/RepositoryInterface.php @@ -1,14 +1,9 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Contracts\Repository; +use Illuminate\Support\Collection; + interface RepositoryInterface { /** @@ -42,17 +37,34 @@ interface RepositoryInterface /** * An array of columns to filter the response by. * - * @param array $columns + * @param array|string $columns * @return $this */ - public function withColumns($columns = ['*']); + public function setColumns($columns = ['*']); /** - * Disable returning a fresh model when data is inserted or updated. + * Stop repository update functions from returning a fresh + * model when changes are committed. * * @return $this */ - public function withoutFresh(); + public function withoutFreshModel(); + + /** + * Return a fresh model with a repository updates a model. + * + * @return $this + */ + public function withFreshModel(); + + /** + * Set wether or not the repository should return a fresh model + * when changes are committed. + * + * @param bool $fresh + * @return $this + */ + public function setFreshModel(bool $fresh = true); /** * Create a new model instance and persist it to the database. @@ -64,23 +76,7 @@ interface RepositoryInterface * * @throws \Pterodactyl\Exceptions\Model\DataValidationException */ - public function create(array $fields, $validate = true, $force = false); - - /** - * Delete a given record from the database. - * - * @param int $id - * @return int - */ - public function delete($id); - - /** - * Delete records matching the given attributes. - * - * @param array $attributes - * @return int - */ - public function deleteWhere(array $attributes); + public function create(array $fields, bool $validate = true, bool $force = false); /** * Find a model that has the specific ID passed. @@ -90,15 +86,15 @@ interface RepositoryInterface * * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ - public function find($id); + public function find(int $id); /** * Find a model matching an array of where clauses. * * @param array $fields - * @return mixed + * @return \Illuminate\Support\Collection */ - public function findWhere(array $fields); + public function findWhere(array $fields): Collection; /** * Find and return the first matching instance for the given fields. @@ -116,7 +112,23 @@ interface RepositoryInterface * @param array $fields * @return int */ - public function findCountWhere(array $fields); + public function findCountWhere(array $fields): int; + + /** + * Delete a given record from the database. + * + * @param int $id + * @return int + */ + public function delete(int $id): int; + + /** + * Delete records matching the given attributes. + * + * @param array $attributes + * @return int + */ + public function deleteWhere(array $attributes): int; /** * Update a given ID with the passed array of fields. @@ -130,7 +142,7 @@ interface RepositoryInterface * @throws \Pterodactyl\Exceptions\Model\DataValidationException * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ - public function update($id, array $fields, $validate = true, $force = false); + public function update($id, array $fields, bool $validate = true, bool $force = false); /** * Perform a mass update where matching records are updated using whereIn. @@ -141,7 +153,7 @@ interface RepositoryInterface * @param array $fields * @return int */ - public function updateWhereIn($column, array $values, array $fields); + public function updateWhereIn(string $column, array $values, array $fields): int; /** * Update a record if it exists in the database, otherwise create it. @@ -154,23 +166,14 @@ interface RepositoryInterface * * @throws \Pterodactyl\Exceptions\Model\DataValidationException */ - public function updateOrCreate(array $where, array $fields, $validate = true, $force = false); + public function updateOrCreate(array $where, array $fields, bool $validate = true, bool $force = false); /** - * Update multiple records matching the passed clauses. + * Return all records associated with the given model. * - * @param array $where - * @param array $fields - * @return mixed + * @return Collection */ - public function massUpdate(array $where, array $fields); - - /** - * Return all records from the model. - * - * @return mixed - */ - public function all(); + public function all(): Collection; /** * Insert a single or multiple records into the database at once skipping @@ -179,7 +182,7 @@ interface RepositoryInterface * @param array $data * @return bool */ - public function insert(array $data); + public function insert(array $data): bool; /** * Insert multiple records into the database and ignore duplicates. @@ -187,5 +190,5 @@ interface RepositoryInterface * @param array $values * @return bool */ - public function insertIgnore(array $values); + public function insertIgnore(array $values): bool; } diff --git a/app/Contracts/Repository/ScheduleRepositoryInterface.php b/app/Contracts/Repository/ScheduleRepositoryInterface.php index 7e28b016f..32650bdcf 100644 --- a/app/Contracts/Repository/ScheduleRepositoryInterface.php +++ b/app/Contracts/Repository/ScheduleRepositoryInterface.php @@ -1,11 +1,4 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Contracts\Repository; @@ -38,5 +31,5 @@ interface ScheduleRepositoryInterface extends RepositoryInterface * @param string $timestamp * @return \Illuminate\Support\Collection */ - public function getSchedulesToProcess($timestamp); + public function getSchedulesToProcess(string $timestamp): Collection; } diff --git a/app/Contracts/Repository/ServerRepositoryInterface.php b/app/Contracts/Repository/ServerRepositoryInterface.php index 2fb8349e3..6d1c14e78 100644 --- a/app/Contracts/Repository/ServerRepositoryInterface.php +++ b/app/Contracts/Repository/ServerRepositoryInterface.php @@ -1,15 +1,11 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Contracts\Repository; +use Pterodactyl\Models\User; use Pterodactyl\Models\Server; +use Illuminate\Support\Collection; +use Illuminate\Contracts\Pagination\LengthAwarePaginator; use Pterodactyl\Contracts\Repository\Attributes\SearchableInterface; interface ServerRepositoryInterface extends RepositoryInterface, SearchableInterface @@ -17,19 +13,10 @@ interface ServerRepositoryInterface extends RepositoryInterface, SearchableInter /** * Returns a listing of all servers that exist including relationships. * - * @param int|null $paginate - * @return mixed + * @param int $paginate + * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator */ - public function getAllServers($paginate); - - /** - * Return a collection of servers with their associated data for rebuild operations. - * - * @param int|null $server - * @param int|null $node - * @return \Illuminate\Database\Eloquent\Collection - */ - public function getDataForRebuild($server = null, $node = null); + public function getAllServers(int $paginate): LengthAwarePaginator; /** * Load the egg relations onto the server model. @@ -40,15 +27,35 @@ interface ServerRepositoryInterface extends RepositoryInterface, SearchableInter */ public function loadEggRelations(Server $server, bool $refresh = false): Server; + /** + * Return a collection of servers with their associated data for rebuild operations. + * + * @param int|null $server + * @param int|null $node + * @return \Illuminate\Support\Collection + */ + public function getDataForRebuild(int $server = null, int $node = null): Collection; + /** * Return a server model and all variables associated with the server. * * @param int $id - * @return mixed + * @return \Pterodactyl\Models\Server * * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ - public function findWithVariables($id); + public function findWithVariables(int $id): Server; + + /** + * Get the primary allocation for a given server. If a model is passed into + * the function, load the allocation relationship onto it. Otherwise, find and + * return the server from the database. + * + * @param \Pterodactyl\Models\Server $server + * @param bool $refresh + * @return \Pterodactyl\Models\Server + */ + public function getPrimaryAllocation(Server $server, bool $refresh = false): Server; /** * Return all of the server variables possible and default to the variable @@ -60,20 +67,7 @@ interface ServerRepositoryInterface extends RepositoryInterface, SearchableInter * * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ - public function getVariablesWithValues($id, $returnAsObject = false); - - /** - * Get the primary allocation for a given server. If a model is passed into - * the function, load the allocation relationship onto it. Otherwise, find and - * return the server from the database. - * - * @param int|\Pterodactyl\Models\Server $server - * @param bool $refresh - * @return \Pterodactyl\Models\Server - * - * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException - */ - public function getPrimaryAllocation($server, bool $refresh = false): Server; + public function getVariablesWithValues(int $id, bool $returnAsObject = false); /** * Return enough data to be used for the creation of a server via the daemon. @@ -85,14 +79,13 @@ interface ServerRepositoryInterface extends RepositoryInterface, SearchableInter public function getDataForCreation(Server $server, bool $refresh = false): Server; /** - * Return a server as well as associated databases and their hosts. + * Load associated databases onto the server model. * - * @param int $id - * @return mixed - * - * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException + * @param \Pterodactyl\Models\Server $server + * @param bool $refresh + * @return \Pterodactyl\Models\Server */ - public function getWithDatabases($id); + public function loadDatabaseRelations(Server $server, bool $refresh = false): Server; /** * Get data for use when updating a server on the Daemon. Returns an array of @@ -105,24 +98,14 @@ interface ServerRepositoryInterface extends RepositoryInterface, SearchableInter */ public function getDaemonServiceData(Server $server, bool $refresh = false): array; - /** - * Return an array of server IDs that a given user can access based on owner and subuser permissions. - * - * @param int $user - * @return array - */ - public function getUserAccessServers($user); - /** * Return a paginated list of servers that a user can access at a given level. * - * @param int $user - * @param string $level - * @param bool $admin - * @param array $relations + * @param \Pterodactyl\Models\User $user + * @param int $level * @return \Illuminate\Pagination\LengthAwarePaginator */ - public function filterUserAccessServers($user, $admin = false, $level = 'all', array $relations = []); + public function filterUserAccessServers(User $user, int $level): LengthAwarePaginator; /** * Return a server by UUID. @@ -132,5 +115,5 @@ interface ServerRepositoryInterface extends RepositoryInterface, SearchableInter * * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ - public function getByUuid($uuid); + public function getByUuid(string $uuid): Server; } diff --git a/app/Contracts/Repository/ServerVariableRepositoryInterface.php b/app/Contracts/Repository/ServerVariableRepositoryInterface.php index a04f30e01..dc3e241a9 100644 --- a/app/Contracts/Repository/ServerVariableRepositoryInterface.php +++ b/app/Contracts/Repository/ServerVariableRepositoryInterface.php @@ -1,11 +1,4 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Contracts\Repository; diff --git a/app/Contracts/Repository/SessionRepositoryInterface.php b/app/Contracts/Repository/SessionRepositoryInterface.php index b95bad44e..1f2dd73e8 100644 --- a/app/Contracts/Repository/SessionRepositoryInterface.php +++ b/app/Contracts/Repository/SessionRepositoryInterface.php @@ -1,16 +1,19 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Contracts\Repository; +use Illuminate\Support\Collection; + interface SessionRepositoryInterface extends RepositoryInterface { + /** + * Return all of the active sessions for a user. + * + * @param int $user + * @return \Illuminate\Support\Collection + */ + public function getUserSessions(int $user): Collection; + /** * Delete a session for a given user. * @@ -18,13 +21,5 @@ interface SessionRepositoryInterface extends RepositoryInterface * @param int $session * @return null|int */ - public function deleteUserSession($user, $session); - - /** - * Return all of the active sessions for a user. - * - * @param int $user - * @return \Illuminate\Support\Collection - */ - public function getUserSessions($user); + public function deleteUserSession(int $user, int $session); } diff --git a/app/Contracts/Repository/SettingsRepositoryInterface.php b/app/Contracts/Repository/SettingsRepositoryInterface.php index dbf87f744..9128e7f78 100644 --- a/app/Contracts/Repository/SettingsRepositoryInterface.php +++ b/app/Contracts/Repository/SettingsRepositoryInterface.php @@ -9,7 +9,9 @@ interface SettingsRepositoryInterface extends RepositoryInterface * * @param string $key * @param string $value - * @return mixed + * + * @throws \Pterodactyl\Exceptions\Model\DataValidationException + * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ public function set(string $key, string $value); @@ -26,7 +28,6 @@ interface SettingsRepositoryInterface extends RepositoryInterface * Remove a key from the database cache. * * @param string $key - * @return mixed */ public function forget(string $key); } diff --git a/app/Contracts/Repository/SubuserRepositoryInterface.php b/app/Contracts/Repository/SubuserRepositoryInterface.php index 06a9efc38..2d722119a 100644 --- a/app/Contracts/Repository/SubuserRepositoryInterface.php +++ b/app/Contracts/Repository/SubuserRepositoryInterface.php @@ -34,25 +34,4 @@ interface SubuserRepositoryInterface extends RepositoryInterface * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ public function getWithPermissionsUsingUserAndServer(int $user, int $server): Subuser; - - /** - * Find a subuser and return with server and permissions relationships. - * - * @param int $id - * @return \Illuminate\Database\Eloquent\Collection - * - * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException - */ - public function getWithServerAndPermissions($id); - - /** - * Return a subuser and their associated connection key for a server. - * - * @param int $user - * @param int $server - * @return \Pterodactyl\Models\Subuser - * - * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException - */ - public function getWithKey($user, $server); } diff --git a/app/Contracts/Repository/TaskRepositoryInterface.php b/app/Contracts/Repository/TaskRepositoryInterface.php index 4f400adee..80ca277bb 100644 --- a/app/Contracts/Repository/TaskRepositoryInterface.php +++ b/app/Contracts/Repository/TaskRepositoryInterface.php @@ -1,14 +1,9 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Contracts\Repository; +use Pterodactyl\Models\Task; + interface TaskRepositoryInterface extends RepositoryInterface { /** @@ -19,14 +14,14 @@ interface TaskRepositoryInterface extends RepositoryInterface * * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ - public function getTaskWithServer($id); + public function getTaskWithServer(int $id): Task; /** * Returns the next task in a schedule. * - * @param int $schedule the ID of the schedule to select the next task from - * @param int $index the index of the current task + * @param int $schedule + * @param int $index * @return null|\Pterodactyl\Models\Task */ - public function getNextTask($schedule, $index); + public function getNextTask(int $schedule, int $index); } diff --git a/app/Contracts/Repository/UserRepositoryInterface.php b/app/Contracts/Repository/UserRepositoryInterface.php index fac353ed4..b5003e0b2 100644 --- a/app/Contracts/Repository/UserRepositoryInterface.php +++ b/app/Contracts/Repository/UserRepositoryInterface.php @@ -1,14 +1,9 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Contracts\Repository; +use Illuminate\Support\Collection; +use Illuminate\Contracts\Pagination\LengthAwarePaginator; use Pterodactyl\Contracts\Repository\Attributes\SearchableInterface; interface UserRepositoryInterface extends RepositoryInterface, SearchableInterface @@ -18,13 +13,13 @@ interface UserRepositoryInterface extends RepositoryInterface, SearchableInterfa * * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator */ - public function getAllUsersWithCounts(); + public function getAllUsersWithCounts(): LengthAwarePaginator; /** * Return all matching models for a user in a format that can be used for dropdowns. * * @param string $query - * @return \Illuminate\Database\Eloquent\Collection + * @return \Illuminate\Support\Collection */ - public function filterUsersByQuery($query); + public function filterUsersByQuery(string $query): Collection; } diff --git a/app/Http/Controllers/Admin/DatabaseController.php b/app/Http/Controllers/Admin/DatabaseController.php index 02271d699..dbf2766a1 100644 --- a/app/Http/Controllers/Admin/DatabaseController.php +++ b/app/Http/Controllers/Admin/DatabaseController.php @@ -139,7 +139,6 @@ class DatabaseController extends Controller * @param int $host * @return \Illuminate\Http\RedirectResponse * - * @throws \Pterodactyl\Exceptions\DisplayException * @throws \Pterodactyl\Exceptions\Model\DataValidationException * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ diff --git a/app/Http/Controllers/Admin/NodesController.php b/app/Http/Controllers/Admin/NodesController.php index d68a47556..a2b80b4f9 100644 --- a/app/Http/Controllers/Admin/NodesController.php +++ b/app/Http/Controllers/Admin/NodesController.php @@ -126,7 +126,7 @@ class NodesController extends Controller public function index(Request $request) { return view('admin.nodes.index', [ - 'nodes' => $this->repository->search($request->input('query'))->getNodeListingData(), + 'nodes' => $this->repository->setSearchTerm($request->input('query'))->getNodeListingData(), ]); } @@ -166,15 +166,15 @@ class NodesController extends Controller /** * Shows the index overview page for a specific node. * - * @param int $node + * @param \Pterodactyl\Models\Node $node * @return \Illuminate\View\View * * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ - public function viewIndex($node) + public function viewIndex(Node $node) { return view('admin.nodes.view.index', [ - 'node' => $this->repository->getSingleNode($node), + 'node' => $this->repository->loadLocationAndServerCount($node), 'stats' => $this->repository->getUsageStats($node), 'version' => $this->versionService, ]); @@ -208,14 +208,14 @@ class NodesController extends Controller /** * Shows the allocation page for a specific node. * - * @param int $node + * @param \Pterodactyl\Models\Node $node * @return \Illuminate\View\View * * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ - public function viewAllocation($node) + public function viewAllocation(Node $node) { - $node = $this->repository->getNodeAllocations($node); + $this->repository->loadNodeAllocations($node); Javascript::put(['node' => collect($node)->only(['id'])]); return view('admin.nodes.view.allocation', ['node' => $node]); diff --git a/app/Http/Controllers/Admin/PackController.php b/app/Http/Controllers/Admin/PackController.php index fed86f3a0..1dd7c881c 100644 --- a/app/Http/Controllers/Admin/PackController.php +++ b/app/Http/Controllers/Admin/PackController.php @@ -114,9 +114,7 @@ class PackController extends Controller public function index(Request $request) { return view('admin.packs.index', [ - 'packs' => $this->repository->search($request->input('query'))->paginateWithEggAndServerCount( - $this->config->get('pterodactyl.paginate.admin.packs') - ), + 'packs' => $this->repository->setSearchTerm($request->input('query'))->paginateWithEggAndServerCount(), ]); } @@ -177,14 +175,14 @@ class PackController extends Controller /** * Display pack view template to user. * - * @param int $pack + * @param \Pterodactyl\Models\Pack $pack * @return \Illuminate\View\View * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ - public function view($pack) + public function view(Pack $pack) { return view('admin.packs.view', [ - 'pack' => $this->repository->getWithServers($pack), + 'pack' => $this->repository->loadServerData($pack), 'nests' => $this->serviceRepository->getWithEggs(), ]); } diff --git a/app/Http/Controllers/Admin/ServersController.php b/app/Http/Controllers/Admin/ServersController.php index 427bb7d20..fb393e65c 100644 --- a/app/Http/Controllers/Admin/ServersController.php +++ b/app/Http/Controllers/Admin/ServersController.php @@ -352,14 +352,12 @@ class ServersController extends Controller /** * Display the database management page for a specific server. * - * @param int $server + * @param \Pterodactyl\Models\Server $server * @return \Illuminate\View\View - * - * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ - public function viewDatabase($server) + public function viewDatabase(Server $server) { - $server = $this->repository->getWithDatabases($server); + $this->repository->loadDatabaseRelations($server); return view('admin.servers.view.database', [ 'hosts' => $this->databaseHostRepository->all(), diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php index faa535b6a..5656ae124 100644 --- a/app/Http/Controllers/Admin/UserController.php +++ b/app/Http/Controllers/Admin/UserController.php @@ -83,7 +83,7 @@ class UserController extends Controller */ public function index(Request $request) { - $users = $this->repository->search($request->input('query'))->getAllUsersWithCounts(); + $users = $this->repository->setSearchTerm($request->input('query'))->getAllUsersWithCounts(); return view('admin.users.index', ['users' => $users]); } diff --git a/app/Http/Controllers/Base/IndexController.php b/app/Http/Controllers/Base/IndexController.php index 8e16f8605..7c2cc2f1c 100644 --- a/app/Http/Controllers/Base/IndexController.php +++ b/app/Http/Controllers/Base/IndexController.php @@ -1,31 +1,9 @@ - * Some Modifications (c) 2015 Dylan Seidt . - * - * 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\Controllers\Base; use Illuminate\Http\Request; +use Pterodactyl\Models\User; use GuzzleHttp\Exception\RequestException; use Pterodactyl\Http\Controllers\Controller; use Symfony\Component\HttpKernel\Exception\HttpException; @@ -75,8 +53,8 @@ class IndexController extends Controller */ public function getIndex(Request $request) { - $servers = $this->repository->search($request->input('query'))->filterUserAccessServers( - $request->user()->id, $request->user()->root_admin, 'all', ['user'] + $servers = $this->repository->setSearchTerm($request->input('query'))->filterUserAccessServers( + $request->user(), User::FILTER_LEVEL_ALL ); return view('base.index', ['servers' => $servers]); diff --git a/app/Http/Middleware/DaemonAuthenticate.php b/app/Http/Middleware/DaemonAuthenticate.php index 6bd2908cf..b8e83bf8c 100644 --- a/app/Http/Middleware/DaemonAuthenticate.php +++ b/app/Http/Middleware/DaemonAuthenticate.php @@ -34,6 +34,7 @@ class DaemonAuthenticate * Create a new filter instance. * * @param \Pterodactyl\Contracts\Repository\NodeRepositoryInterface $repository + * @deprecated */ public function __construct(NodeRepositoryInterface $repository) { @@ -47,6 +48,7 @@ class DaemonAuthenticate * @param \Closure $next * @return mixed * + * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException */ public function handle(Request $request, Closure $next) @@ -59,7 +61,7 @@ class DaemonAuthenticate throw new AccessDeniedHttpException; } - $node = $this->repository->findWhere(['daemonSecret' => $request->header('X-Access-Node')]); + $node = $this->repository->findFirstWhere(['daemonSecret' => $request->header('X-Access-Node')]); $request->attributes->set('node', $node); return $next($request); diff --git a/app/Models/User.php b/app/Models/User.php index 4452f0c33..af574b597 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -28,6 +28,11 @@ class User extends Model implements const USER_LEVEL_USER = 0; const USER_LEVEL_ADMIN = 1; + const FILTER_LEVEL_ALL = 0; + const FILTER_LEVEL_OWNER = 1; + const FILTER_LEVEL_ADMIN = 2; + const FILTER_LEVEL_SUBUSER = 3; + /** * Level of servers to display when using access() on a user. * diff --git a/app/Policies/APIKeyPolicy.php b/app/Policies/APIKeyPolicy.php index 69ce45c04..e8556ca9c 100644 --- a/app/Policies/APIKeyPolicy.php +++ b/app/Policies/APIKeyPolicy.php @@ -39,7 +39,7 @@ class APIKeyPolicy })->values(); }); - return $permissions->search($permission, true) !== false; + return $permissions->setSearchTerm($permission, true) !== false; } /** diff --git a/app/Policies/ServerPolicy.php b/app/Policies/ServerPolicy.php index 9b4db6f05..8891fa87f 100644 --- a/app/Policies/ServerPolicy.php +++ b/app/Policies/ServerPolicy.php @@ -32,7 +32,7 @@ class ServerPolicy })->values(); }); - return $permissions->search($permission, true) !== false; + return $permissions->setSearchTerm($permission, true) !== false; } /** diff --git a/app/Repositories/Concerns/Searchable.php b/app/Repositories/Concerns/Searchable.php index 0d396cdc4..26ed6544a 100644 --- a/app/Repositories/Concerns/Searchable.php +++ b/app/Repositories/Concerns/Searchable.php @@ -1,30 +1,36 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Repositories\Concerns; trait Searchable { /** - * The term to search. + * The search term to use when filtering results. * - * @var bool|string + * @var null|string */ - protected $searchTerm = false; + protected $searchTerm; /** - * Perform a search of the model using the given term. + * Set the search term. * - * @param string $term + * @param string|null $term * @return $this + * @deprecated */ public function search($term) + { + return $this->setSearchTerm($term); + } + + /** + * Set the search term to use when requesting all records from + * the model. + * + * @param string|null $term + * @return $this + */ + public function setSearchTerm(string $term = null) { if (empty($term)) { return $this; @@ -35,4 +41,24 @@ trait Searchable return $clone; } + + /** + * Determine if a valid search term is set on this repository. + * + * @return bool + */ + public function hasSearchTerm(): bool + { + return ! empty($this->searchTerm); + } + + /** + * Return the search term. + * + * @return string|null + */ + public function getSearchTerm() + { + return $this->searchTerm; + } } diff --git a/app/Repositories/Daemon/ServerRepository.php b/app/Repositories/Daemon/ServerRepository.php index f21ec197a..d46749e5d 100644 --- a/app/Repositories/Daemon/ServerRepository.php +++ b/app/Repositories/Daemon/ServerRepository.php @@ -1,11 +1,4 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Repositories\Daemon; diff --git a/app/Repositories/Eloquent/AllocationRepository.php b/app/Repositories/Eloquent/AllocationRepository.php index f613f734f..674d8b8fd 100644 --- a/app/Repositories/Eloquent/AllocationRepository.php +++ b/app/Repositories/Eloquent/AllocationRepository.php @@ -1,21 +1,17 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Repositories\Eloquent; +use Illuminate\Support\Collection; use Pterodactyl\Models\Allocation; use Pterodactyl\Contracts\Repository\AllocationRepositoryInterface; class AllocationRepository extends EloquentRepository implements AllocationRepositoryInterface { /** - * {@inheritdoc} + * Return the model backing this repository. + * + * @return string */ public function model() { @@ -23,18 +19,25 @@ class AllocationRepository extends EloquentRepository implements AllocationRepos } /** - * {@inheritdoc} + * Set an array of allocation IDs to be assigned to a specific server. + * + * @param int|null $server + * @param array $ids + * @return int */ - public function assignAllocationsToServer($server, array $ids) + public function assignAllocationsToServer(int $server = null, array $ids): int { return $this->getBuilder()->whereIn('id', $ids)->update(['server_id' => $server]); } /** - * {@inheritdoc} + * Return all of the allocations for a specific node. + * + * @param int $node + * @return \Illuminate\Support\Collection */ - public function getAllocationsForNode($node) + public function getAllocationsForNode(int $node): Collection { - return $this->getBuilder()->where('node_id', $node)->get(); + return $this->getBuilder()->where('node_id', $node)->get($this->getColumns()); } } diff --git a/app/Repositories/Eloquent/ApiKeyRepository.php b/app/Repositories/Eloquent/ApiKeyRepository.php index 107e0b6c9..f6169c939 100644 --- a/app/Repositories/Eloquent/ApiKeyRepository.php +++ b/app/Repositories/Eloquent/ApiKeyRepository.php @@ -1,11 +1,4 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Repositories\Eloquent; @@ -15,7 +8,9 @@ use Pterodactyl\Contracts\Repository\ApiKeyRepositoryInterface; class ApiKeyRepository extends EloquentRepository implements ApiKeyRepositoryInterface { /** - * {@inheritdoc} + * Return the model backing this repository. + * + * @return string */ public function model() { diff --git a/app/Repositories/Eloquent/ApiPermissionRepository.php b/app/Repositories/Eloquent/ApiPermissionRepository.php index b88fdfd1c..d94771327 100644 --- a/app/Repositories/Eloquent/ApiPermissionRepository.php +++ b/app/Repositories/Eloquent/ApiPermissionRepository.php @@ -1,11 +1,4 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Repositories\Eloquent; @@ -15,7 +8,9 @@ use Pterodactyl\Contracts\Repository\ApiPermissionRepositoryInterface; class ApiPermissionRepository extends EloquentRepository implements ApiPermissionRepositoryInterface { /** - * {@inheritdoc} + * Return the model backing this repository. + * + * @return string */ public function model() { diff --git a/app/Repositories/Eloquent/DaemonKeyRepository.php b/app/Repositories/Eloquent/DaemonKeyRepository.php index 97fe0c2bb..ba246f458 100644 --- a/app/Repositories/Eloquent/DaemonKeyRepository.php +++ b/app/Repositories/Eloquent/DaemonKeyRepository.php @@ -1,26 +1,4 @@ . - * - * 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; @@ -28,13 +6,16 @@ use Pterodactyl\Models\User; use Webmozart\Assert\Assert; use Pterodactyl\Models\DaemonKey; use Illuminate\Support\Collection; +use Illuminate\Database\Eloquent\ModelNotFoundException; use Pterodactyl\Exceptions\Repository\RecordNotFoundException; use Pterodactyl\Contracts\Repository\DaemonKeyRepositoryInterface; class DaemonKeyRepository extends EloquentRepository implements DaemonKeyRepositoryInterface { /** - * {@inheritdoc} + * Return the model backing this repository. + * + * @return string */ public function model() { @@ -62,28 +43,22 @@ class DaemonKeyRepository extends EloquentRepository implements DaemonKeyReposit } /** - * {@inheritdoc} + * Return a daemon key with the associated server relation attached. + * + * @param string $key + * @return \Pterodactyl\Models\DaemonKey + * + * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ - public function getServerKeys($server) + public function getKeyWithServer(string $key): DaemonKey { - Assert::integerish($server, 'First argument passed to getServerKeys must be integer, received %s.'); + Assert::notEmpty($key, 'Expected non-empty string as first argument passed to ' . __METHOD__); - return $this->getBuilder()->where('server_id', $server)->get($this->getColumns()); - } - - /** - * {@inheritdoc} - */ - public function getKeyWithServer($key) - { - Assert::stringNotEmpty($key, 'First argument passed to getServerByKey must be string, received %s.'); - - $instance = $this->getBuilder()->with('server')->where('secret', '=', $key)->first(); - if (is_null($instance)) { + try { + return $this->getBuilder()->with('server')->where('secret', '=', $key)->firstOrFail($this->getColumns()); + } catch (ModelNotFoundException $exception) { throw new RecordNotFoundException; } - - return $instance; } /** diff --git a/app/Repositories/Eloquent/DatabaseHostRepository.php b/app/Repositories/Eloquent/DatabaseHostRepository.php index 1bfe8d75b..6bfb94d70 100644 --- a/app/Repositories/Eloquent/DatabaseHostRepository.php +++ b/app/Repositories/Eloquent/DatabaseHostRepository.php @@ -1,23 +1,19 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Repositories\Eloquent; -use Webmozart\Assert\Assert; +use Illuminate\Support\Collection; use Pterodactyl\Models\DatabaseHost; +use Illuminate\Database\Eloquent\ModelNotFoundException; use Pterodactyl\Exceptions\Repository\RecordNotFoundException; use Pterodactyl\Contracts\Repository\DatabaseHostRepositoryInterface; class DatabaseHostRepository extends EloquentRepository implements DatabaseHostRepositoryInterface { /** - * {@inheritdoc} + * Return the model backing this repository. + * + * @return string */ public function model() { @@ -25,25 +21,31 @@ class DatabaseHostRepository extends EloquentRepository implements DatabaseHostR } /** - * {@inheritdoc} + * Return database hosts with a count of databases and the node + * information for which it is attached. + * + * @return \Illuminate\Support\Collection */ - public function getWithViewDetails() + public function getWithViewDetails(): Collection { return $this->getBuilder()->withCount('databases')->with('node')->get(); } /** - * {@inheritdoc} + * Return a database host with the databases and associated servers + * that are attached to said databases. + * + * @param int $id + * @return \Pterodactyl\Models\DatabaseHost + * + * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ - public function getWithServers($id) + public function getWithServers(int $id): DatabaseHost { - Assert::numeric($id, 'First argument passed to getWithServers must be numeric, recieved %s.'); - - $instance = $this->getBuilder()->with('databases.server')->find($id, $this->getColumns()); - if (! $instance) { - throw new RecordNotFoundException(); + try { + return $this->getBuilder()->with('databases.server')->findOrFail($id, $this->getColumns()); + } catch (ModelNotFoundException $exception) { + throw new RecordNotFoundException; } - - return $instance; } } diff --git a/app/Repositories/Eloquent/DatabaseRepository.php b/app/Repositories/Eloquent/DatabaseRepository.php index f030812b5..d24dd177e 100644 --- a/app/Repositories/Eloquent/DatabaseRepository.php +++ b/app/Repositories/Eloquent/DatabaseRepository.php @@ -1,11 +1,4 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Repositories\Eloquent; @@ -34,17 +27,17 @@ class DatabaseRepository extends EloquentRepository implements DatabaseRepositor * @param \Illuminate\Foundation\Application $application * @param \Illuminate\Database\DatabaseManager $database */ - public function __construct( - Application $application, - DatabaseManager $database - ) { + public function __construct(Application $application, DatabaseManager $database) + { parent::__construct($application); $this->database = $database; } /** - * {@inheritdoc} + * Return the model backing this repository. + * + * @return string */ public function model() { @@ -86,18 +79,24 @@ class DatabaseRepository extends EloquentRepository implements DatabaseRepositor } /** - * {@inheritdoc} - * @return bool|\Illuminate\Database\Eloquent\Model + * Create a new database if it does not already exist on the host with + * the provided details. + * + * @param array $data + * @return \Pterodactyl\Models\Database + * + * @throws \Pterodactyl\Exceptions\Model\DataValidationException + * @throws \Pterodactyl\Exceptions\Repository\DuplicateDatabaseNameException */ - public function createIfNotExists(array $data) + public function createIfNotExists(array $data): Database { - $instance = $this->getBuilder()->where([ + $count = $this->getBuilder()->where([ ['server_id', '=', array_get($data, 'server_id')], ['database_host_id', '=', array_get($data, 'database_host_id')], ['database', '=', array_get($data, 'database')], ])->count(); - if ($instance > 0) { + if ($count > 0) { throw new DuplicateDatabaseNameException('A database with those details already exists for the specified server.'); } @@ -105,27 +104,40 @@ class DatabaseRepository extends EloquentRepository implements DatabaseRepositor } /** - * {@inheritdoc} + * Create a new database on a given connection. + * + * @param string $database + * @return bool */ - public function createDatabase($database) + public function createDatabase(string $database): bool { - return $this->runStatement(sprintf('CREATE DATABASE IF NOT EXISTS `%s`', $database)); + return $this->run(sprintf('CREATE DATABASE IF NOT EXISTS `%s`', $database)); } /** - * {@inheritdoc} + * Create a new database user on a given connection. + * + * @param string $username + * @param string $remote + * @param string $password + * @return bool */ - public function createUser($username, $remote, $password) + public function createUser(string $username, string $remote, string $password): bool { - return $this->runStatement(sprintf('CREATE USER `%s`@`%s` IDENTIFIED BY \'%s\'', $username, $remote, $password)); + return $this->run(sprintf('CREATE USER `%s`@`%s` IDENTIFIED BY \'%s\'', $username, $remote, $password)); } /** - * {@inheritdoc} + * Give a specific user access to a given database. + * + * @param string $database + * @param string $username + * @param string $remote + * @return bool */ - public function assignUserToDatabase($database, $username, $remote) + public function assignUserToDatabase(string $database, string $username, string $remote): bool { - return $this->runStatement(sprintf( + return $this->run(sprintf( 'GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, INDEX, EXECUTE ON `%s`.* TO `%s`@`%s`', $database, $username, @@ -134,27 +146,36 @@ class DatabaseRepository extends EloquentRepository implements DatabaseRepositor } /** - * {@inheritdoc} + * Flush the privileges for a given connection. + * + * @return bool */ - public function flush() + public function flush(): bool { - return $this->runStatement('FLUSH PRIVILEGES'); + return $this->run('FLUSH PRIVILEGES'); } /** - * {@inheritdoc} + * Drop a given database on a specific connection. + * + * @param string $database + * @return bool */ - public function dropDatabase($database) + public function dropDatabase(string $database): bool { - return $this->runStatement(sprintf('DROP DATABASE IF EXISTS `%s`', $database)); + return $this->run(sprintf('DROP DATABASE IF EXISTS `%s`', $database)); } /** - * {@inheritdoc} + * Drop a given user on a specific connection. + * + * @param string $username + * @param string $remote + * @return mixed */ - public function dropUser($username, $remote) + public function dropUser(string $username, string $remote): bool { - return $this->runStatement(sprintf('DROP USER IF EXISTS `%s`@`%s`', $username, $remote)); + return $this->run(sprintf('DROP USER IF EXISTS `%s`@`%s`', $username, $remote)); } /** @@ -163,7 +184,7 @@ class DatabaseRepository extends EloquentRepository implements DatabaseRepositor * @param string $statement * @return bool */ - protected function runStatement($statement) + private function run(string $statement): bool { return $this->database->connection($this->getConnection())->statement($statement); } diff --git a/app/Repositories/Eloquent/EggRepository.php b/app/Repositories/Eloquent/EggRepository.php index c1fcc583f..bfb6738d9 100644 --- a/app/Repositories/Eloquent/EggRepository.php +++ b/app/Repositories/Eloquent/EggRepository.php @@ -1,24 +1,20 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Repositories\Eloquent; use Pterodactyl\Models\Egg; use Webmozart\Assert\Assert; use Illuminate\Database\Eloquent\Collection; +use Illuminate\Database\Eloquent\ModelNotFoundException; use Pterodactyl\Contracts\Repository\EggRepositoryInterface; use Pterodactyl\Exceptions\Repository\RecordNotFoundException; class EggRepository extends EloquentRepository implements EggRepositoryInterface { /** - * {@inheritdoc} + * Return the model backing this repository. + * + * @return string */ public function model() { @@ -35,13 +31,11 @@ class EggRepository extends EloquentRepository implements EggRepositoryInterface */ public function getWithVariables(int $id): Egg { - /** @var \Pterodactyl\Models\Egg $instance */ - $instance = $this->getBuilder()->with('variables')->find($id, $this->getColumns()); - if (! $instance) { + try { + return $this->getBuilder()->with('variables')->firstOrFail($id, $this->getColumns()); + } catch (ModelNotFoundException $exception) { throw new RecordNotFoundException; } - - return $instance; } /** @@ -67,13 +61,11 @@ class EggRepository extends EloquentRepository implements EggRepositoryInterface { Assert::true((is_digit($value) || is_string($value)), 'First argument passed to getWithCopyAttributes must be an integer or string, received %s.'); - /** @var \Pterodactyl\Models\Egg $instance */ - $instance = $this->getBuilder()->with('scriptFrom', 'configFrom')->where($column, '=', $value)->first($this->getColumns()); - if (! $instance) { + try { + return $this->getBuilder()->with('scriptFrom', 'configFrom')->where($column, '=', $value)->firstOrFail($this->getColumns()); + } catch (ModelNotFoundException $exception) { throw new RecordNotFoundException; } - - return $instance; } /** @@ -86,13 +78,11 @@ class EggRepository extends EloquentRepository implements EggRepositoryInterface */ public function getWithExportAttributes(int $id): Egg { - /** @var \Pterodactyl\Models\Egg $instance */ - $instance = $this->getBuilder()->with('scriptFrom', 'configFrom', 'variables')->find($id, $this->getColumns()); - if (! $instance) { + try { + return $this->getBuilder()->with('scriptFrom', 'configFrom', 'variables')->find($id, $this->getColumns()); + } catch (ModelNotFoundException $exception) { throw new RecordNotFoundException; } - - return $instance; } /** diff --git a/app/Repositories/Eloquent/EggVariableRepository.php b/app/Repositories/Eloquent/EggVariableRepository.php index 2c34c7527..9d84b9db1 100644 --- a/app/Repositories/Eloquent/EggVariableRepository.php +++ b/app/Repositories/Eloquent/EggVariableRepository.php @@ -1,11 +1,4 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Repositories\Eloquent; @@ -16,7 +9,9 @@ use Pterodactyl\Contracts\Repository\EggVariableRepositoryInterface; class EggVariableRepository extends EloquentRepository implements EggVariableRepositoryInterface { /** - * {@inheritdoc} + * Return the model backing this repository. + * + * @return string */ public function model() { diff --git a/app/Repositories/Eloquent/EloquentRepository.php b/app/Repositories/Eloquent/EloquentRepository.php index d94cd5cac..417b547ce 100644 --- a/app/Repositories/Eloquent/EloquentRepository.php +++ b/app/Repositories/Eloquent/EloquentRepository.php @@ -1,17 +1,12 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Repositories\Eloquent; use Webmozart\Assert\Assert; +use Illuminate\Support\Collection; use Pterodactyl\Repositories\Repository; use Illuminate\Database\Query\Expression; +use Illuminate\Database\Eloquent\ModelNotFoundException; use Pterodactyl\Contracts\Repository\RepositoryInterface; use Pterodactyl\Exceptions\Model\DataValidationException; use Pterodactyl\Exceptions\Repository\RecordNotFoundException; @@ -20,7 +15,19 @@ use Pterodactyl\Contracts\Repository\Attributes\SearchableInterface; abstract class EloquentRepository extends Repository implements RepositoryInterface { /** - * {@inheritdoc} + * Return an instance of the eloquent model bound to this + * repository instance. + * + * @return \Illuminate\Database\Eloquent\Model + */ + public function getModel() + { + return $this->model; + } + + /** + * Return an instance of the builder to use for this repository. + * * @return \Illuminate\Database\Eloquent\Builder */ public function getBuilder() @@ -29,22 +36,19 @@ abstract class EloquentRepository extends Repository implements RepositoryInterf } /** - * {@inheritdoc} - * @param bool $force + * Create a new record in the database and return the associated model. + * + * @param array $fields + * @param bool $validate + * @param bool $force * @return \Illuminate\Database\Eloquent\Model|bool + * + * @throws \Pterodactyl\Exceptions\Model\DataValidationException */ - public function create(array $fields, $validate = true, $force = false) + public function create(array $fields, bool $validate = true, bool $force = false) { - Assert::boolean($validate, 'Second argument passed to create must be boolean, recieved %s.'); - Assert::boolean($force, 'Third argument passed to create must be boolean, received %s.'); - $instance = $this->getBuilder()->newModelInstance(); - - if ($force) { - $instance->forceFill($fields); - } else { - $instance->fill($fields); - } + ($force) ? $instance->forceFill($fields) : $instance->fill($fields); if (! $validate) { $saved = $instance->skipValidation()->save(); @@ -58,99 +62,108 @@ abstract class EloquentRepository extends Repository implements RepositoryInterf } /** - * {@inheritdoc} - * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model + * Find a model that has the specific ID passed. + * + * @param int $id + * @return \Illuminate\Database\Eloquent\Model + * + * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ - public function find($id) + public function find(int $id) { - Assert::numeric($id, 'First argument passed to find must be numeric, received %s.'); - - $instance = $this->getBuilder()->find($id, $this->getColumns()); - - if (! $instance) { - throw new RecordNotFoundException(); + try { + return $this->getBuilder()->findOrFail($id, $this->getColumns()); + } catch (ModelNotFoundException $exception) { + throw new RecordNotFoundException; } - - return $instance; } /** - * {@inheritdoc} - * @return \Illuminate\Database\Eloquent\Collection + * Find a model matching an array of where clauses. + * + * @param array $fields + * @return \Illuminate\Support\Collection */ - public function findWhere(array $fields) + public function findWhere(array $fields): Collection { return $this->getBuilder()->where($fields)->get($this->getColumns()); } /** - * {@inheritdoc} + * Find and return the first matching instance for the given fields. + * + * @param array $fields * @return \Illuminate\Database\Eloquent\Model + * + * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ public function findFirstWhere(array $fields) { - $instance = $this->getBuilder()->where($fields)->first($this->getColumns()); - - if (! $instance) { + try { + return $this->getBuilder()->where($fields)->firstOrFail($this->getColumns()); + } catch (ModelNotFoundException $exception) { throw new RecordNotFoundException; } - - return $instance; } /** - * {@inheritdoc}. + * Return a count of records matching the passed arguments. + * + * @param array $fields + * @return int */ - public function findCountWhere(array $fields) + public function findCountWhere(array $fields): int { return $this->getBuilder()->where($fields)->count($this->getColumns()); } /** - * {@inheritdoc} + * Delete a given record from the database. + * + * @param int $id + * @param bool $destroy + * @return int */ - public function delete($id, $destroy = false) + public function delete(int $id, bool $destroy = false): int { - Assert::numeric($id, 'First argument passed to delete must be numeric, received %s.'); - Assert::boolean($destroy, 'Second argument passed to delete must be boolean, received %s.'); - - $instance = $this->getBuilder()->where($this->getModel()->getKeyName(), $id); - - return ($destroy) ? $instance->forceDelete() : $instance->delete(); + return $this->deleteWhere(['id' => $id], $destroy); } /** - * {@inheritdoc} + * Delete records matching the given attributes. + * + * @param array $attributes + * @param bool $force + * @return int */ - public function deleteWhere(array $attributes, $force = false) + public function deleteWhere(array $attributes, bool $force = false): int { - Assert::boolean($force, 'Second argument passed to deleteWhere must be boolean, received %s.'); - $instance = $this->getBuilder()->where($attributes); return ($force) ? $instance->forceDelete() : $instance->delete(); } /** - * {@inheritdoc} + * Update a given ID with the passed array of fields. + * + * @param int $id + * @param array $fields + * @param bool $validate + * @param bool $force + * @return \Illuminate\Database\Eloquent\Model|bool + * + * @throws \Pterodactyl\Exceptions\Model\DataValidationException + * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ - public function update($id, array $fields, $validate = true, $force = false) + public function update($id, array $fields, bool $validate = true, bool $force = false) { - Assert::numeric($id, 'First argument passed to update must be numeric, received %s.'); - Assert::boolean($validate, 'Third argument passed to update must be boolean, received %s.'); - Assert::boolean($force, 'Fourth argument passed to update must be boolean, received %s.'); - - $instance = $this->getBuilder()->where('id', $id)->first(); - - if (! $instance) { - throw new RecordNotFoundException(); + try { + $instance = $this->getBuilder()->where('id', $id)->firstOrFail(); + } catch (ModelNotFoundException $exception) { + throw new RecordNotFoundException; } - if ($force) { - $instance->forceFill($fields); - } else { - $instance->fill($fields); - } + ($force) ? $instance->forceFill($fields) : $instance->fill($fields); if (! $validate) { $saved = $instance->skipValidation()->save(); @@ -164,40 +177,71 @@ abstract class EloquentRepository extends Repository implements RepositoryInterf } /** - * {@inheritdoc} + * Perform a mass update where matching records are updated using whereIn. + * This does not perform any model data validation. + * + * @param string $column + * @param array $values + * @param array $fields + * @return int */ - public function updateWhereIn($column, array $values, array $fields) + public function updateWhereIn(string $column, array $values, array $fields): int { - Assert::stringNotEmpty($column, 'First argument passed to updateWhereIn must be a non-empty string, received %s.'); + Assert::notEmpty($column, 'First argument passed to updateWhereIn must be a non-empty string.'); return $this->getBuilder()->whereIn($column, $values)->update($fields); } /** - * {@inheritdoc} + * Update a record if it exists in the database, otherwise create it. + * + * @param array $where + * @param array $fields + * @param bool $validate + * @param bool $force + * @return \Illuminate\Database\Eloquent\Model + * + * @throws \Pterodactyl\Exceptions\Model\DataValidationException + * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ - public function massUpdate(array $where, array $fields) + public function updateOrCreate(array $where, array $fields, bool $validate = true, bool $force = false) { - // TODO: Implement massUpdate() method. + foreach ($where as $item) { + Assert::true(is_scalar($item) || is_null($item), 'First argument passed to updateOrCreate should be an array of scalar or null values, received an array value of %s.'); + } + + try { + $instance = $this->setColumns('id')->findFirstWhere($where); + } catch (RecordNotFoundException $exception) { + return $this->create(array_merge($where, $fields), $validate, $force); + } + + return $this->update($instance->id, $fields, $validate, $force); } /** - * {@inheritdoc} + * Return all records associated with the given model. + * + * @return \Illuminate\Support\Collection */ - public function all() + public function all(): Collection { $instance = $this->getBuilder(); - if (is_subclass_of(get_called_class(), SearchableInterface::class)) { - $instance = $instance->search($this->searchTerm); + if (is_subclass_of(get_called_class(), SearchableInterface::class) && $this->hasSearchTerm()) { + $instance = $instance->setSearchTerm($this->getSearchTerm()); } return $instance->get($this->getColumns()); } /** - * {@inheritdoc} + * Insert a single or multiple records into the database at once skipping + * validation and mass assignment checking. + * + * @param array $data + * @return bool */ - public function insert(array $data) + public function insert(array $data): bool { return $this->getBuilder()->insert($data); } @@ -208,19 +252,15 @@ abstract class EloquentRepository extends Repository implements RepositoryInterf * @param array $values * @return bool */ - public function insertIgnore(array $values) + public function insertIgnore(array $values): bool { if (empty($values)) { return true; } - if (! is_array(reset($values))) { - $values = [$values]; - } else { - foreach ($values as $key => $value) { - ksort($value); - $values[$key] = $value; - } + foreach ($values as $key => $value) { + ksort($value); + $values[$key] = $value; } $bindings = array_values(array_filter(array_flatten($values, 1), function ($binding) { @@ -239,26 +279,4 @@ abstract class EloquentRepository extends Repository implements RepositoryInterf return $this->getBuilder()->getConnection()->statement($statement, $bindings); } - - /** - * {@inheritdoc} - * @return bool|\Illuminate\Database\Eloquent\Model - */ - public function updateOrCreate(array $where, array $fields, $validate = true, $force = false) - { - Assert::boolean($validate, 'Third argument passed to updateOrCreate must be boolean, received %s.'); - Assert::boolean($force, 'Fourth argument passed to updateOrCreate must be boolean, received %s.'); - - foreach ($where as $item) { - Assert::true(is_scalar($item) || is_null($item), 'First argument passed to updateOrCreate should be an array of scalar or null values, received an array value of %s.'); - } - - $instance = $this->withColumns('id')->findWhere($where)->first(); - - if (! $instance) { - return $this->create(array_merge($where, $fields), $validate, $force); - } - - return $this->update($instance->id, $fields, $validate, $force); - } } diff --git a/app/Repositories/Eloquent/LocationRepository.php b/app/Repositories/Eloquent/LocationRepository.php index b893a0588..47d5e321a 100644 --- a/app/Repositories/Eloquent/LocationRepository.php +++ b/app/Repositories/Eloquent/LocationRepository.php @@ -1,16 +1,11 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Repositories\Eloquent; use Pterodactyl\Models\Location; +use Illuminate\Support\Collection; use Pterodactyl\Repositories\Concerns\Searchable; +use Illuminate\Database\Eloquent\ModelNotFoundException; use Pterodactyl\Exceptions\Repository\RecordNotFoundException; use Pterodactyl\Contracts\Repository\LocationRepositoryInterface; @@ -19,7 +14,9 @@ class LocationRepository extends EloquentRepository implements LocationRepositor use Searchable; /** - * {@inheritdoc} + * Return the model backing this repository. + * + * @return string */ public function model() { @@ -27,44 +24,56 @@ class LocationRepository extends EloquentRepository implements LocationRepositor } /** - * {@inheritdoc} + * Return locations with a count of nodes and servers attached to it. + * + * @return \Illuminate\Support\Collection */ - public function getAllWithDetails() + public function getAllWithDetails(): Collection { return $this->getBuilder()->withCount('nodes', 'servers')->get($this->getColumns()); } /** - * {@inheritdoc} + * Return all of the available locations with the nodes as a relationship. + * + * @return \Illuminate\Support\Collection */ - public function getAllWithNodes() + public function getAllWithNodes(): Collection { return $this->getBuilder()->with('nodes')->get($this->getColumns()); } /** - * {@inheritdoc} + * Return all of the nodes and their respective count of servers for a location. + * + * @param int $id + * @return mixed + * + * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ - public function getWithNodes($id) + public function getWithNodes(int $id): Location { - $instance = $this->getBuilder()->with('nodes.servers')->find($id, $this->getColumns()); - if (! $instance) { + try { + return $this->getBuilder()->with('nodes.servers')->findOrFail($id, $this->getColumns()); + } catch (ModelNotFoundException $exception) { throw new RecordNotFoundException; } - - return $instance; } /** - * {@inheritdoc} + * Return a location and the count of nodes in that location. + * + * @param int $id + * @return mixed + * + * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ - public function getWithNodeCount($id) + public function getWithNodeCount(int $id): Location { - $instance = $this->getBuilder()->withCount('nodes')->find($id, $this->getColumns()); - if (! $instance) { + try { + return $this->getBuilder()->withCount('nodes')->findOrFail($id, $this->getColumns()); + } catch (ModelNotFoundException $exception) { throw new RecordNotFoundException; } - - return $instance; } } diff --git a/app/Repositories/Eloquent/NestRepository.php b/app/Repositories/Eloquent/NestRepository.php index 923186c26..9c0fcf73c 100644 --- a/app/Repositories/Eloquent/NestRepository.php +++ b/app/Repositories/Eloquent/NestRepository.php @@ -16,7 +16,9 @@ use Pterodactyl\Exceptions\Repository\RecordNotFoundException; class NestRepository extends EloquentRepository implements NestRepositoryInterface { /** - * {@inheritdoc} + * Return the model backing this repository. + * + * @return string */ public function model() { diff --git a/app/Repositories/Eloquent/NodeRepository.php b/app/Repositories/Eloquent/NodeRepository.php index c1dd68a8a..f943441d1 100644 --- a/app/Repositories/Eloquent/NodeRepository.php +++ b/app/Repositories/Eloquent/NodeRepository.php @@ -1,16 +1,12 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Repositories\Eloquent; use Pterodactyl\Models\Node; +use Illuminate\Support\Collection; use Pterodactyl\Repositories\Concerns\Searchable; +use Illuminate\Database\Eloquent\ModelNotFoundException; +use Illuminate\Contracts\Pagination\LengthAwarePaginator; use Pterodactyl\Contracts\Repository\NodeRepositoryInterface; use Pterodactyl\Exceptions\Repository\RecordNotFoundException; @@ -18,11 +14,10 @@ class NodeRepository extends EloquentRepository implements NodeRepositoryInterfa { use Searchable; - const THRESHOLD_PERCENTAGE_LOW = 75; - const THRESHOLD_PERCENTAGE_MEDIUM = 90; - /** - * {@inheritdoc} + * Return the model backing this repository. + * + * @return string */ public function model() { @@ -30,113 +25,121 @@ class NodeRepository extends EloquentRepository implements NodeRepositoryInterfa } /** - * {@inheritdoc} + * Return the usage stats for a single node. + * + * @param \Pterodactyl\Models\Node $node + * @return array */ - public function getUsageStats($id) + public function getUsageStats(Node $node): array { - $node = $this->getBuilder()->select([ - 'nodes.disk_overallocate', - 'nodes.memory_overallocate', - 'nodes.disk', - 'nodes.memory', - ])->where('id', $id)->first(); - $stats = $this->getBuilder()->select( $this->getBuilder()->raw('IFNULL(SUM(servers.memory), 0) as sum_memory, IFNULL(SUM(servers.disk), 0) as sum_disk') - )->join('servers', 'servers.node_id', '=', 'nodes.id')->where('node_id', $id)->first(); + )->join('servers', 'servers.node_id', '=', 'nodes.id')->where('node_id', $node->id)->first(); - return collect(['disk' => $stats->sum_disk, 'memory' => $stats->sum_memory]) - ->mapWithKeys(function ($value, $key) use ($node) { - $maxUsage = $node->{$key}; - if ($node->{$key . '_overallocate'} > 0) { - $maxUsage = $node->{$key} * (1 + ($node->{$key . '_overallocate'} / 100)); - } + return collect(['disk' => $stats->sum_disk, 'memory' => $stats->sum_memory])->mapWithKeys(function ($value, $key) use ($node) { + $maxUsage = $node->{$key}; + if ($node->{$key . '_overallocate'} > 0) { + $maxUsage = $node->{$key} * (1 + ($node->{$key . '_overallocate'} / 100)); + } - $percent = ($value / $maxUsage) * 100; + $percent = ($value / $maxUsage) * 100; - return [ - $key => [ - 'value' => number_format($value), - 'max' => number_format($maxUsage), - 'percent' => $percent, - 'css' => ($percent <= self::THRESHOLD_PERCENTAGE_LOW) ? 'green' : (($percent > self::THRESHOLD_PERCENTAGE_MEDIUM) ? 'red' : 'yellow'), - ], - ]; - }) - ->toArray(); + return [ + $key => [ + 'value' => number_format($value), + 'max' => number_format($maxUsage), + 'percent' => $percent, + 'css' => ($percent <= self::THRESHOLD_PERCENTAGE_LOW) ? 'green' : (($percent > self::THRESHOLD_PERCENTAGE_MEDIUM) ? 'red' : 'yellow'), + ], + ]; + })->toArray(); } /** - * {@inheritdoc} + * Return all available nodes with a searchable interface. + * + * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator */ - public function getNodeListingData($count = 25) + public function getNodeListingData(): LengthAwarePaginator { $instance = $this->getBuilder()->with('location')->withCount('servers'); - if ($this->searchTerm) { - $instance->search($this->searchTerm); + if ($this->hasSearchTerm()) { + $instance->setSearchTerm($this->getSearchTerm()); } - return $instance->paginate($count, $this->getColumns()); + return $instance->paginate(25, $this->getColumns()); } /** - * {@inheritdoc} + * Return a single node with location and server information. + * + * @param \Pterodactyl\Models\Node $node + * @param bool $refresh + * @return \Pterodactyl\Models\Node */ - public function getSingleNode($id) + public function loadLocationAndServerCount(Node $node, bool $refresh = false): Node { - $instance = $this->getBuilder()->with('location')->withCount('servers')->find($id, $this->getColumns()); - - if (! $instance) { - throw new RecordNotFoundException(); + if (! $node->relationLoaded('location') || $refresh) { + $node->load('location'); } - return $instance; + // This is quite ugly and can probably be improved down the road. + // And by probably, I mean it should. + if (is_null($node->servers_count) || $refresh) { + $node->load('servers'); + $node->setRelation('servers_count', count($node->getRelation('servers'))); + unset($node->servers); + } + + return $node; } /** - * {@inheritdoc} + * Attach a paginated set of allocations to a node mode including + * any servers that are also attached to those allocations. + * + * @param \Pterodactyl\Models\Node $node + * @param bool $refresh + * @return \Pterodactyl\Models\Node */ - public function getNodeAllocations($id) + public function loadNodeAllocations(Node $node, bool $refresh = false): Node { - $instance = $this->getBuilder()->find($id, $this->getColumns()); - - if (! $instance) { - throw new RecordNotFoundException(); - } - - $instance->setRelation( - 'allocations', - $instance->allocations()->orderBy('ip', 'asc')->orderBy('port', 'asc')->with('server')->paginate(50) + $node->setRelation('allocations', + $node->allocations()->orderBy('ip', 'asc')->orderBy('port', 'asc')->with('server')->paginate(50) ); - return $instance; + return $node; } /** - * {@inheritdoc} + * Return a node with all of the servers attached to that node. + * + * @param int $id + * @return \Pterodactyl\Models\Node + * + * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ - public function getNodeServers($id) + public function getNodeServers(int $id): Node { - $instance = $this->getBuilder()->with('servers.user', 'servers.nest', 'servers.egg') - ->find($id, $this->getColumns()); - - if (! $instance) { - throw new RecordNotFoundException(); + try { + return $this->getBuilder()->with([ + 'servers.user', 'servers.nest', 'servers.egg', + ])->findOrFail($id, $this->getColumns()); + } catch (ModelNotFoundException $exception) { + throw new RecordNotFoundException; } - - return $instance; } /** - * {@inheritdoc} + * Return a collection of nodes for all locations to use in server creation UI. + * + * @return \Illuminate\Support\Collection */ - public function getNodesForServerCreation() + public function getNodesForServerCreation(): Collection { - $instance = $this->getBuilder()->with('allocations')->get(); - - return $instance->map(function ($item) { - $filtered = $item->allocations->where('server_id', null)->map(function ($map) { + return $this->getBuilder()->with('allocations')->get()->map(function (Node $item) { + $filtered = $item->getRelation('allocations')->where('server_id', null)->map(function ($map) { return collect($map)->only(['id', 'ip', 'port']); }); diff --git a/app/Repositories/Eloquent/PackRepository.php b/app/Repositories/Eloquent/PackRepository.php index b2c555512..a199e5500 100644 --- a/app/Repositories/Eloquent/PackRepository.php +++ b/app/Repositories/Eloquent/PackRepository.php @@ -1,27 +1,20 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Repositories\Eloquent; use Pterodactyl\Models\Pack; -use Webmozart\Assert\Assert; use Pterodactyl\Repositories\Concerns\Searchable; -use Illuminate\Database\Eloquent\ModelNotFoundException; +use Illuminate\Contracts\Pagination\LengthAwarePaginator; use Pterodactyl\Contracts\Repository\PackRepositoryInterface; -use Illuminate\Contracts\Filesystem\Factory as FilesystemFactory; class PackRepository extends EloquentRepository implements PackRepositoryInterface { use Searchable; /** - * {@inheritdoc} + * Return the model backing this repository. + * + * @return string */ public function model() { @@ -29,58 +22,32 @@ class PackRepository extends EloquentRepository implements PackRepositoryInterfa } /** - * {@inheritdoc} + * Return a pack with the associated server models attached to it. + * + * @param \Pterodactyl\Models\Pack $pack + * @param bool $refresh + * @return \Pterodactyl\Models\Pack */ - public function getFileArchives($id, $collection = false) + public function loadServerData(Pack $pack, bool $refresh = false): Pack { - Assert::numeric($id, 'First argument passed to getFileArchives must be numeric, received %s.'); - Assert::boolean($collection, 'Second argument passed to getFileArchives must be boolean, received %s.'); - - $pack = $this->getBuilder()->find($id, ['id', 'uuid']); - if (! $pack) { - throw new ModelNotFoundException; + if ($refresh) { + $pack->load(['servers.node', 'servers.user']); } - $storage = $this->app->make(FilesystemFactory::class); - $files = collect($storage->disk('default')->files('packs/' . $pack->uuid)); + $pack->loadMissing(['servers.node', 'servers.user']); - $files = $files->map(function ($file) { - $path = storage_path('app/' . $file); - - return (object) [ - 'name' => basename($file), - 'hash' => sha1_file($path), - 'size' => human_readable($path), - ]; - }); - - return ($collection) ? $files : (object) $files->all(); + return $pack; } /** - * {@inheritdoc} + * Return a paginated listing of packs with their associated egg and server count. + * + * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator */ - public function getWithServers($id) + public function paginateWithEggAndServerCount(): LengthAwarePaginator { - Assert::numeric($id, 'First argument passed to getWithServers must be numeric, received %s.'); - - $instance = $this->getBuilder()->with('servers.node', 'servers.user')->find($id, $this->getColumns()); - if (! $instance) { - throw new ModelNotFoundException; - } - - return $instance; - } - - /** - * {@inheritdoc} - */ - public function paginateWithEggAndServerCount($paginate = 50) - { - Assert::integer($paginate, 'First argument passed to paginateWithOptionAndServerCount must be integer, received %s.'); - return $this->getBuilder()->with('egg')->withCount('servers') - ->search($this->searchTerm) - ->paginate($paginate, $this->getColumns()); + ->setSearchTerm($this->getSearchTerm()) + ->paginate(50, $this->getColumns()); } } diff --git a/app/Repositories/Eloquent/PermissionRepository.php b/app/Repositories/Eloquent/PermissionRepository.php index ca67b3975..ad2fa6386 100644 --- a/app/Repositories/Eloquent/PermissionRepository.php +++ b/app/Repositories/Eloquent/PermissionRepository.php @@ -1,11 +1,4 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Repositories\Eloquent; @@ -15,7 +8,9 @@ use Pterodactyl\Contracts\Repository\PermissionRepositoryInterface; class PermissionRepository extends EloquentRepository implements PermissionRepositoryInterface { /** - * {@inheritdoc} + * Return the model backing this repository. + * + * @return string */ public function model() { diff --git a/app/Repositories/Eloquent/ScheduleRepository.php b/app/Repositories/Eloquent/ScheduleRepository.php index 4c0f5b0f0..02be96439 100644 --- a/app/Repositories/Eloquent/ScheduleRepository.php +++ b/app/Repositories/Eloquent/ScheduleRepository.php @@ -1,23 +1,19 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Repositories\Eloquent; use Pterodactyl\Models\Schedule; use Illuminate\Support\Collection; +use Illuminate\Database\Eloquent\ModelNotFoundException; use Pterodactyl\Exceptions\Repository\RecordNotFoundException; use Pterodactyl\Contracts\Repository\ScheduleRepositoryInterface; class ScheduleRepository extends EloquentRepository implements ScheduleRepositoryInterface { /** - * {@inheritdoc} + * Return the model backing this repository. + * + * @return string */ public function model() { @@ -45,19 +41,20 @@ class ScheduleRepository extends EloquentRepository implements ScheduleRepositor */ public function getScheduleWithTasks(int $schedule): Schedule { - /** @var \Pterodactyl\Models\Schedule $instance */ - $instance = $this->getBuilder()->with('tasks')->find($schedule, $this->getColumns()); - if (! $instance) { + try { + return $this->getBuilder()->with('tasks')->findOrFail($schedule, $this->getColumns()); + } catch (ModelNotFoundException $exception) { throw new RecordNotFoundException; } - - return $instance; } /** - * {@inheritdoc} + * Return all of the schedules that should be processed. + * + * @param string $timestamp + * @return \Illuminate\Support\Collection */ - public function getSchedulesToProcess($timestamp) + public function getSchedulesToProcess(string $timestamp): Collection { return $this->getBuilder()->with('tasks') ->where('is_active', true) diff --git a/app/Repositories/Eloquent/ServerRepository.php b/app/Repositories/Eloquent/ServerRepository.php index b8f5cc6fc..49fa53c41 100644 --- a/app/Repositories/Eloquent/ServerRepository.php +++ b/app/Repositories/Eloquent/ServerRepository.php @@ -1,17 +1,14 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Repositories\Eloquent; +use Pterodactyl\Models\User; use Webmozart\Assert\Assert; use Pterodactyl\Models\Server; +use Illuminate\Support\Collection; use Pterodactyl\Repositories\Concerns\Searchable; +use Illuminate\Database\Eloquent\ModelNotFoundException; +use Illuminate\Contracts\Pagination\LengthAwarePaginator; use Pterodactyl\Exceptions\Repository\RecordNotFoundException; use Pterodactyl\Contracts\Repository\ServerRepositoryInterface; @@ -20,7 +17,9 @@ class ServerRepository extends EloquentRepository implements ServerRepositoryInt use Searchable; /** - * {@inheritdoc} + * Return the model backing this repository. + * + * @return string */ public function model() { @@ -28,15 +27,16 @@ class ServerRepository extends EloquentRepository implements ServerRepositoryInt } /** - * {@inheritdoc} + * Returns a listing of all servers that exist including relationships. + * + * @param int $paginate + * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator */ - public function getAllServers($paginate = 25) + public function getAllServers(int $paginate): LengthAwarePaginator { - Assert::nullOrIntegerish($paginate, 'First argument passed to getAllServers must be integer or null, received %s.'); + $instance = $this->getBuilder()->with('node', 'user', 'allocation')->setSearchTerm($this->getSearchTerm()); - $instance = $this->getBuilder()->with('node', 'user', 'allocation')->search($this->searchTerm); - - return is_null($paginate) ? $instance->get($this->getColumns()) : $instance->paginate($paginate, $this->getColumns()); + return $instance->paginate($paginate, $this->getColumns()); } /** @@ -56,14 +56,15 @@ class ServerRepository extends EloquentRepository implements ServerRepositoryInt } /** - * {@inheritdoc} + * Return a collection of servers with their associated data for rebuild operations. + * + * @param int|null $server + * @param int|null $node + * @return \Illuminate\Support\Collection */ - public function getDataForRebuild($server = null, $node = null) + public function getDataForRebuild(int $server = null, int $node = null): Collection { - Assert::nullOrIntegerish($server, 'First argument passed to getDataForRebuild must be null or integer, received %s.'); - Assert::nullOrIntegerish($node, 'Second argument passed to getDataForRebuild must be null or integer, received %s.'); - - $instance = $this->getBuilder()->with('allocation', 'allocations', 'pack', 'egg', 'node'); + $instance = $this->getBuilder()->with(['allocation', 'allocations', 'pack', 'egg', 'node']); if (! is_null($server) && is_null($node)) { $instance = $instance->where('id', '=', $server); @@ -75,22 +76,22 @@ class ServerRepository extends EloquentRepository implements ServerRepositoryInt } /** - * {@inheritdoc} - * @return \Illuminate\Database\Eloquent\Model + * Return a server model and all variables associated with the server. + * + * @param int $id + * @return \Pterodactyl\Models\Server + * + * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ - public function findWithVariables($id) + public function findWithVariables(int $id): Server { - Assert::integerish($id, 'First argument passed to findWithVariables must be integer, received %s.'); - - $instance = $this->getBuilder()->with('egg.variables', 'variables') - ->where($this->getModel()->getKeyName(), '=', $id) - ->first($this->getColumns()); - - if (is_null($instance)) { - throw new RecordNotFoundException(); + try { + return $this->getBuilder()->with('egg.variables', 'variables') + ->where($this->getModel()->getKeyName(), '=', $id) + ->firstOrFail($this->getColumns()); + } catch (ModelNotFoundException $exception) { + throw new RecordNotFoundException; } - - return $instance; } /** @@ -98,51 +99,45 @@ class ServerRepository extends EloquentRepository implements ServerRepositoryInt * the function, load the allocation relationship onto it. Otherwise, find and * return the server from the database. * - * @param int|\Pterodactyl\Models\Server $server - * @param bool $refresh + * @param \Pterodactyl\Models\Server $server + * @param bool $refresh * @return \Pterodactyl\Models\Server - * - * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ - public function getPrimaryAllocation($server, bool $refresh = false): Server + public function getPrimaryAllocation(Server $server, bool $refresh = false): Server { - $instance = $server; - if (! $instance instanceof Server) { - Assert::integerish($server, 'First argument passed to getPrimaryAllocation must be instance of \Pterodactyl\Models\Server or integer, received %s.'); - $instance = $this->getBuilder()->find($server, $this->getColumns()); + if (! $server->relationLoaded('allocation') || $refresh) { + $server->load('allocation'); } - if (! $instance) { - throw new RecordNotFoundException; - } - - if (! $instance->relationLoaded('allocation') || $refresh) { - $instance->load('allocation'); - } - - return $instance; + return $server; } /** - * {@inheritdoc} + * Return all of the server variables possible and default to the variable + * default if there is no value defined for the specific server requested. + * + * @param int $id + * @param bool $returnAsObject + * @return array|object + * + * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ - public function getVariablesWithValues($id, $returnWithObject = false) + public function getVariablesWithValues(int $id, bool $returnAsObject = false) { - $instance = $this->getBuilder()->with('variables', 'egg.variables') - ->find($id, $this->getColumns()); - - if (! $instance) { - throw new RecordNotFoundException(); + try { + $instance = $this->getBuilder()->with('variables', 'egg.variables')->find($id, $this->getColumns()); + } catch (ModelNotFoundException $exception) { + throw new RecordNotFoundException; } $data = []; - $instance->egg->variables->each(function ($item) use (&$data, $instance) { - $display = $instance->variables->where('variable_id', $item->id)->pluck('variable_value')->first(); + $instance->getRelation('egg')->getRelation('variables')->each(function ($item) use (&$data, $instance) { + $display = $instance->getRelation('variables')->where('variable_id', $item->id)->pluck('variable_value')->first(); $data[$item->env_variable] = $display ?? $item->default_value; }); - if ($returnWithObject) { + if ($returnAsObject) { return (object) [ 'data' => $data, 'server' => $instance, @@ -171,19 +166,19 @@ class ServerRepository extends EloquentRepository implements ServerRepositoryInt } /** - * {@inheritdoc} + * Load associated databases onto the server model. + * + * @param \Pterodactyl\Models\Server $server + * @param bool $refresh + * @return \Pterodactyl\Models\Server */ - public function getWithDatabases($id) + public function loadDatabaseRelations(Server $server, bool $refresh = false): Server { - $instance = $this->getBuilder()->with('databases.host') - ->where('installed', 1) - ->find($id, $this->getColumns()); - - if (! $instance) { - throw new RecordNotFoundException(); + if (! $server->relationLoaded('databases') || $refresh) { + $server->load('databases.host'); } - return $instance; + return $server; } /** @@ -212,71 +207,70 @@ class ServerRepository extends EloquentRepository implements ServerRepositoryInt } /** - * {@inheritdoc} + * Return a paginated list of servers that a user can access at a given level. + * + * @param \Pterodactyl\Models\User $user + * @param int $level + * @return \Illuminate\Pagination\LengthAwarePaginator */ - public function getUserAccessServers($user) + public function filterUserAccessServers(User $user, int $level): LengthAwarePaginator { - Assert::numeric($user, 'First argument passed to getUserAccessServers must be numeric, received %s.'); - - $subuser = $this->app->make(SubuserRepository::class); - - return $this->getBuilder()->select('id')->where('owner_id', $user)->union( - $subuser->getBuilder()->select('server_id')->where('user_id', $user) - )->pluck('id')->all(); - } - - /** - * {@inheritdoc} - */ - public function filterUserAccessServers($user, $admin = false, $level = 'all', array $relations = []) - { - Assert::numeric($user, 'First argument passed to filterUserAccessServers must be numeric, received %s.'); - Assert::boolean($admin, 'Second argument passed to filterUserAccessServers must be boolean, received %s.'); - Assert::stringNotEmpty($level, 'Third argument passed to filterUserAccessServers must be a non-empty string, received %s.'); - - $instance = $this->getBuilder()->with($relations); + $instance = $this->getBuilder()->with(['user']); // If access level is set to owner, only display servers // that the user owns. - if ($level === 'owner') { - $instance->where('owner_id', $user); + if ($level === User::FILTER_LEVEL_OWNER) { + $instance->where('owner_id', $user->id); } // If set to all, display all servers they can access, including - // those they access as an admin. - // - // If set to subuser, only return the servers they can access because + // those they access as an admin. If set to subuser, only return the servers they can access because // they are owner, or marked as a subuser of the server. - if (($level === 'all' && ! $admin) || $level === 'subuser') { - $instance->whereIn('id', $this->getUserAccessServers($user)); + elseif (($level === User::FILTER_LEVEL_ALL && ! $user->root_admin) || $level === User::FILTER_LEVEL_SUBUSER) { + $instance->whereIn('id', $this->getUserAccessServers($user->id)); } // If set to admin, only display the servers a user can access // as an administrator (leaves out owned and subuser of). - if ($level === 'admin' && $admin) { - $instance->whereIn('id', $this->getUserAccessServers($user)); + elseif ($level === User::FILTER_LEVEL_ADMIN && $user->root_admin) { + $instance->whereNotIn('id', $this->getUserAccessServers($user->id)); } - return $instance->search($this->searchTerm)->paginate( - $this->app->make('config')->get('pterodactyl.paginate.frontend.servers') - ); + return $instance->setSearchTerm($this->getSearchTerm())->paginate(25); } /** - * {@inheritdoc} + * Return a server by UUID. + * + * @param string $uuid + * @return \Pterodactyl\Models\Server + * + * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ - public function getByUuid($uuid) + public function getByUuid(string $uuid): Server { - Assert::stringNotEmpty($uuid, 'First argument passed to getByUuid must be a non-empty string, received %s.'); + Assert::notEmpty($uuid, 'Expected non-empty string as first argument passed to ' . __METHOD__); - $instance = $this->getBuilder()->with('nest', 'node')->where(function ($query) use ($uuid) { - $query->where('uuidShort', $uuid)->orWhere('uuid', $uuid); - })->first($this->getColumns()); - - if (! $instance) { + try { + return $this->getBuilder()->with('nest', 'node')->where(function ($query) use ($uuid) { + $query->where('uuidShort', $uuid)->orWhere('uuid', $uuid); + })->firstOrFail($this->getColumns()); + } catch (ModelNotFoundException $exception) { throw new RecordNotFoundException; } + } - return $instance; + /** + * Return an array of server IDs that a given user can access based + * on owner and subuser permissions. + * + * @param int $user + * @return int[] + */ + private function getUserAccessServers(int $user): array + { + return $this->getBuilder()->select('id')->where('owner_id', $user)->union( + $this->app->make(SubuserRepository::class)->getBuilder()->select('server_id')->where('user_id', $user) + )->pluck('id')->all(); } } diff --git a/app/Repositories/Eloquent/ServerVariableRepository.php b/app/Repositories/Eloquent/ServerVariableRepository.php index 49a81430a..d0d5e4dba 100644 --- a/app/Repositories/Eloquent/ServerVariableRepository.php +++ b/app/Repositories/Eloquent/ServerVariableRepository.php @@ -1,11 +1,4 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Repositories\Eloquent; @@ -15,7 +8,9 @@ use Pterodactyl\Contracts\Repository\ServerVariableRepositoryInterface; class ServerVariableRepository extends EloquentRepository implements ServerVariableRepositoryInterface { /** - * {@inheritdoc} + * Return the model backing this repository. + * + * @return string */ public function model() { diff --git a/app/Repositories/Eloquent/SessionRepository.php b/app/Repositories/Eloquent/SessionRepository.php index 8ba826696..47d955077 100644 --- a/app/Repositories/Eloquent/SessionRepository.php +++ b/app/Repositories/Eloquent/SessionRepository.php @@ -1,21 +1,17 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Repositories\Eloquent; use Pterodactyl\Models\Session; +use Illuminate\Support\Collection; use Pterodactyl\Contracts\Repository\SessionRepositoryInterface; class SessionRepository extends EloquentRepository implements SessionRepositoryInterface { /** - * {@inheritdoc} + * Return the model backing this repository. + * + * @return string */ public function model() { @@ -23,17 +19,24 @@ class SessionRepository extends EloquentRepository implements SessionRepositoryI } /** - * {@inheritdoc} + * Return all of the active sessions for a user. + * + * @param int $user + * @return \Illuminate\Support\Collection */ - public function getUserSessions($user) + public function getUserSessions(int $user): Collection { return $this->getBuilder()->where('user_id', $user)->get($this->getColumns()); } /** - * {@inheritdoc} + * Delete a session for a given user. + * + * @param int $user + * @param int $session + * @return null|int */ - public function deleteUserSession($user, $session) + public function deleteUserSession(int $user, int $session) { return $this->getBuilder()->where('user_id', $user)->where('id', $session)->delete(); } diff --git a/app/Repositories/Eloquent/SettingsRepository.php b/app/Repositories/Eloquent/SettingsRepository.php index b6937bf31..dd516d68e 100644 --- a/app/Repositories/Eloquent/SettingsRepository.php +++ b/app/Repositories/Eloquent/SettingsRepository.php @@ -10,16 +10,15 @@ class SettingsRepository extends EloquentRepository implements SettingsRepositor /** * @var array */ - private $cache = []; + private static $cache = []; /** * @var array */ - private $databaseMiss = []; + private static $databaseMiss = []; /** - * Return an instance of the model that acts as the base for - * this repository. + * Return the model backing this repository. * * @return string */ @@ -33,12 +32,17 @@ class SettingsRepository extends EloquentRepository implements SettingsRepositor * * @param string $key * @param string $value + * + * @throws \Pterodactyl\Exceptions\Model\DataValidationException + * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ public function set(string $key, string $value) { // Clear item from the cache. $this->clearCache($key); - $this->withoutFresh()->updateOrCreate(['key' => $key], ['value' => $value]); + $this->withoutFreshModel()->updateOrCreate(['key' => $key], ['value' => $value]); + + self::$cache[$key] = $value; } /** @@ -51,32 +55,27 @@ class SettingsRepository extends EloquentRepository implements SettingsRepositor public function get(string $key, $default = null) { // If item has already been requested return it from the cache. If - // we already know it is missing, immediately return the default - // value. - if (array_key_exists($key, $this->cache)) { - return $this->cache[$key]; - } elseif (array_key_exists($key, $this->databaseMiss)) { - return $default; + // we already know it is missing, immediately return the default value. + if (array_key_exists($key, self::$cache)) { + return self::$cache[$key]; + } elseif (array_key_exists($key, self::$databaseMiss)) { + return value($default); } $instance = $this->getBuilder()->where('key', $key)->first(); - if (is_null($instance)) { - $this->databaseMiss[$key] = true; + self::$databaseMiss[$key] = true; - return $default; + return value($default); } - $this->cache[$key] = $instance->value; - - return $this->cache[$key]; + return self::$cache[$key] = $instance->value; } /** * Remove a key from the database cache. * * @param string $key - * @return mixed */ public function forget(string $key) { @@ -89,8 +88,8 @@ class SettingsRepository extends EloquentRepository implements SettingsRepositor * * @param string $key */ - protected function clearCache(string $key) + private function clearCache(string $key) { - unset($this->cache[$key], $this->databaseMiss[$key]); + unset(self::$cache[$key], self::$databaseMiss[$key]); } } diff --git a/app/Repositories/Eloquent/SubuserRepository.php b/app/Repositories/Eloquent/SubuserRepository.php index e1387b530..0296e0dbd 100644 --- a/app/Repositories/Eloquent/SubuserRepository.php +++ b/app/Repositories/Eloquent/SubuserRepository.php @@ -1,15 +1,7 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Repositories\Eloquent; -use Webmozart\Assert\Assert; use Pterodactyl\Models\Subuser; use Pterodactyl\Exceptions\Repository\RecordNotFoundException; use Pterodactyl\Contracts\Repository\SubuserRepositoryInterface; @@ -17,7 +9,9 @@ use Pterodactyl\Contracts\Repository\SubuserRepositoryInterface; class SubuserRepository extends EloquentRepository implements SubuserRepositoryInterface { /** - * {@inheritdoc} + * Return the model backing this repository. + * + * @return string */ public function model() { @@ -86,39 +80,4 @@ class SubuserRepository extends EloquentRepository implements SubuserRepositoryI return $instance; } - - /** - * {@inheritdoc} - */ - public function getWithServerAndPermissions($id) - { - Assert::numeric($id, 'First argument passed to getWithServerAndPermissions must be numeric, received %s.'); - - $instance = $this->getBuilder()->with('server', 'permission', 'user')->find($id, $this->getColumns()); - if (! $instance) { - throw new RecordNotFoundException; - } - - return $instance; - } - - /** - * {@inheritdoc} - */ - public function getWithKey($user, $server) - { - Assert::integerish($user, 'First argument passed to getWithKey must be integer, received %s.'); - Assert::integerish($server, 'Second argument passed to getWithKey must be integer, received %s.'); - - $instance = $this->getBuilder()->with('key')->where([ - ['user_id', '=', $user], - ['server_id', '=', $server], - ])->first(); - - if (is_null($instance)) { - throw new RecordNotFoundException; - } - - return $instance; - } } diff --git a/app/Repositories/Eloquent/TaskRepository.php b/app/Repositories/Eloquent/TaskRepository.php index c44aa2fc6..ef4a92a0b 100644 --- a/app/Repositories/Eloquent/TaskRepository.php +++ b/app/Repositories/Eloquent/TaskRepository.php @@ -1,23 +1,18 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Repositories\Eloquent; use Pterodactyl\Models\Task; -use Webmozart\Assert\Assert; +use Illuminate\Database\Eloquent\ModelNotFoundException; use Pterodactyl\Contracts\Repository\TaskRepositoryInterface; use Pterodactyl\Exceptions\Repository\RecordNotFoundException; class TaskRepository extends EloquentRepository implements TaskRepositoryInterface { /** - * {@inheritdoc} + * Return the model backing this repository. + * + * @return string */ public function model() { @@ -25,28 +20,31 @@ class TaskRepository extends EloquentRepository implements TaskRepositoryInterfa } /** - * {@inheritdoc} + * Get a task and the server relationship for that task. + * + * @param int $id + * @return \Pterodactyl\Models\Task + * + * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException */ - public function getTaskWithServer($id) + public function getTaskWithServer(int $id): Task { - Assert::integerish($id, 'First argument passed to getTaskWithServer must be numeric, received %s.'); - - $instance = $this->getBuilder()->with('server.user')->find($id, $this->getColumns()); - if (! $instance) { + try { + return $this->getBuilder()->with('server.user')->findOrFail($id, $this->getColumns()); + } catch (ModelNotFoundException $exception) { throw new RecordNotFoundException; } - - return $instance; } /** - * {@inheritdoc} + * Returns the next task in a schedule. + * + * @param int $schedule + * @param int $index + * @return null|\Pterodactyl\Models\Task */ - public function getNextTask($schedule, $index) + public function getNextTask(int $schedule, int $index) { - Assert::integerish($schedule, 'First argument passed to getNextTask must be integer, received %s.'); - Assert::integerish($index, 'Second argument passed to getNextTask must be integer, received %s.'); - return $this->getBuilder()->where('schedule_id', '=', $schedule) ->where('sequence_id', '=', $index + 1) ->first($this->getColumns()); diff --git a/app/Repositories/Eloquent/UserRepository.php b/app/Repositories/Eloquent/UserRepository.php index 6dbb5d8c3..4b033dc14 100644 --- a/app/Repositories/Eloquent/UserRepository.php +++ b/app/Repositories/Eloquent/UserRepository.php @@ -1,44 +1,21 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Repositories\Eloquent; use Pterodactyl\Models\User; -use Illuminate\Foundation\Application; +use Illuminate\Support\Collection; use Pterodactyl\Repositories\Concerns\Searchable; +use Illuminate\Contracts\Pagination\LengthAwarePaginator; use Pterodactyl\Contracts\Repository\UserRepositoryInterface; -use Illuminate\Contracts\Config\Repository as ConfigRepository; class UserRepository extends EloquentRepository implements UserRepositoryInterface { use Searchable; /** - * @var \Illuminate\Contracts\Config\Repository - */ - protected $config; - - /** - * UserRepository constructor. + * Return the model backing this repository. * - * @param \Illuminate\Foundation\Application $application - * @param \Illuminate\Contracts\Config\Repository $config - */ - public function __construct(Application $application, ConfigRepository $config) - { - parent::__construct($application); - - $this->config = $config; - } - - /** - * {@inheritdoc} + * @return string */ public function model() { @@ -46,32 +23,30 @@ class UserRepository extends EloquentRepository implements UserRepositoryInterfa } /** - * {@inheritdoc} + * Return all users with counts of servers and subusers of servers. + * + * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator */ - public function getAllUsersWithCounts() + public function getAllUsersWithCounts(): LengthAwarePaginator { - $users = $this->getBuilder()->withCount('servers', 'subuserOf'); - - if ($this->searchTerm) { - $users->search($this->searchTerm); - } - - return $users->paginate( - $this->config->get('pterodactyl.paginate.admin.users'), - $this->getColumns() - ); + return $this->getBuilder()->withCount('servers', 'subuserOf') + ->setSearchTerm($this->getSearchTerm()) + ->paginate(50, $this->getColumns()); } /** - * {@inheritdoc} + * Return all matching models for a user in a format that can be used for dropdowns. + * + * @param string $query + * @return \Illuminate\Support\Collection */ - public function filterUsersByQuery($query) + public function filterUsersByQuery(string $query): Collection { - $this->withColumns([ + $this->setColumns([ 'id', 'email', 'username', 'name_first', 'name_last', ]); - $instance = $this->getBuilder()->search($query)->get($this->getColumns()); + $instance = $this->getBuilder()->setSearchTerm($query)->get($this->getColumns()); return $instance->transform(function ($item) { $item->md5 = md5(strtolower($item->email)); diff --git a/app/Repositories/Repository.php b/app/Repositories/Repository.php index f9164d284..c3014a31a 100644 --- a/app/Repositories/Repository.php +++ b/app/Repositories/Repository.php @@ -1,14 +1,8 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Pterodactyl\Repositories; +use InvalidArgumentException; use Illuminate\Foundation\Application; use Pterodactyl\Contracts\Repository\RepositoryInterface; @@ -43,35 +37,13 @@ abstract class Repository implements RepositoryInterface { $this->app = $application; - $this->setModel($this->model()); + $this->initalizeModel($this->model()); } /** - * Take the provided model and make it accessible to the rest of the repository. + * Return the model backing this repository. * - * @param string|array $model - * @return mixed - */ - protected function setModel($model) - { - if (is_array($model)) { - if (count($model) !== 2) { - throw new \InvalidArgumentException( - printf('setModel expected exactly 2 parameters, %d received.', count($model)) - ); - } - - return $this->model = call_user_func( - $model[1], - $this->app->make($model[0]) - ); - } - - return $this->model = $this->app->make($model); - } - - /** - * @return mixed + * @return string|\Closure|object */ abstract public function model(); @@ -88,10 +60,10 @@ abstract class Repository implements RepositoryInterface /** * Setup column selection functionality. * - * @param array $columns + * @param array|string $columns * @return $this */ - public function withColumns($columns = ['*']) + public function setColumns($columns = ['*']) { $clone = clone $this; $clone->columns = is_array($columns) ? $columns : func_get_args(); @@ -110,15 +82,56 @@ abstract class Repository implements RepositoryInterface } /** - * Set repository to not return a fresh record from the DB when completed. + * Stop repository update functions from returning a fresh + * model when changes are committed. * * @return $this */ - public function withoutFresh() + public function withoutFreshModel() + { + return $this->setFreshModel(false); + } + + /** + * Return a fresh model with a repository updates a model. + * + * @return $this + */ + public function withFreshModel() + { + return $this->setFreshModel(true); + } + + /** + * Set wether or not the repository should return a fresh model + * when changes are committed. + * + * @param bool $fresh + * @return $this + */ + public function setFreshModel(bool $fresh = true) { $clone = clone $this; - $clone->withFresh = false; + $clone->withFresh = $fresh; return $clone; } + + /** + * Take the provided model and make it accessible to the rest of the repository. + * + * @param array $model + * @return mixed + */ + protected function initalizeModel(...$model) + { + switch (count($model)) { + case 1: + return $this->model = $this->app->make($model[0]); + case 2: + return $this->model = call_user_func([$this->app->make($model[0]), $model[1]]); + default: + throw new InvalidArgumentException('Model must be a FQCN or an array with a count of two.'); + } + } } diff --git a/app/Services/Eggs/Sharing/EggUpdateImporterService.php b/app/Services/Eggs/Sharing/EggUpdateImporterService.php index f0df63ad7..3cb275ff7 100644 --- a/app/Services/Eggs/Sharing/EggUpdateImporterService.php +++ b/app/Services/Eggs/Sharing/EggUpdateImporterService.php @@ -96,7 +96,7 @@ class EggUpdateImporterService }); $imported = collect($parsed->variables)->pluck('env_variable')->toArray(); - $existing = $this->variableRepository->withColumns(['id', 'env_variable'])->findWhere([['egg_id', '=', $egg]]); + $existing = $this->variableRepository->setColumns(['id', 'env_variable'])->findWhere([['egg_id', '=', $egg]]); // Delete variables not present in the import. collect($existing)->each(function ($variable) use ($egg, $imported) { diff --git a/app/Services/Eggs/Variables/VariableUpdateService.php b/app/Services/Eggs/Variables/VariableUpdateService.php index 0249e4fba..91694b166 100644 --- a/app/Services/Eggs/Variables/VariableUpdateService.php +++ b/app/Services/Eggs/Variables/VariableUpdateService.php @@ -49,7 +49,7 @@ class VariableUpdateService ])); } - $search = $this->repository->withColumns('id')->findCountWhere([ + $search = $this->repository->setColumns('id')->findCountWhere([ ['env_variable', '=', array_get($data, 'env_variable')], ['egg_id', '=', $variable->egg_id], ['id', '!=', $variable->id], diff --git a/app/Services/Nodes/NodeDeletionService.php b/app/Services/Nodes/NodeDeletionService.php index 9df62be6a..e4d2ed999 100644 --- a/app/Services/Nodes/NodeDeletionService.php +++ b/app/Services/Nodes/NodeDeletionService.php @@ -63,7 +63,7 @@ class NodeDeletionService $node = $node->id; } - $servers = $this->serverRepository->withColumns('id')->findCountWhere([['node_id', '=', $node]]); + $servers = $this->serverRepository->setColumns('id')->findCountWhere([['node_id', '=', $node]]); if ($servers > 0) { throw new HasActiveServersException($this->translator->trans('exceptions.node.servers_attached')); } diff --git a/app/Services/Packs/PackDeletionService.php b/app/Services/Packs/PackDeletionService.php index 5118990ad..9d4743310 100644 --- a/app/Services/Packs/PackDeletionService.php +++ b/app/Services/Packs/PackDeletionService.php @@ -69,7 +69,7 @@ class PackDeletionService public function handle($pack) { if (! $pack instanceof Pack) { - $pack = $this->repository->withColumns(['id', 'uuid'])->find($pack); + $pack = $this->repository->setColumns(['id', 'uuid'])->find($pack); } $count = $this->serverRepository->findCountWhere([['pack_id', '=', $pack->id]]); diff --git a/app/Services/Packs/PackUpdateService.php b/app/Services/Packs/PackUpdateService.php index bb84f7b98..3354a66f5 100644 --- a/app/Services/Packs/PackUpdateService.php +++ b/app/Services/Packs/PackUpdateService.php @@ -54,7 +54,7 @@ class PackUpdateService public function handle($pack, array $data) { if (! $pack instanceof Pack) { - $pack = $this->repository->withColumns(['id', 'egg_id'])->find($pack); + $pack = $this->repository->setColumns(['id', 'egg_id'])->find($pack); } if ((int) array_get($data, 'egg_id', $pack->egg_id) !== $pack->egg_id) { diff --git a/app/Services/Servers/ServerDeletionService.php b/app/Services/Servers/ServerDeletionService.php index 1129a187c..4ae5c645d 100644 --- a/app/Services/Servers/ServerDeletionService.php +++ b/app/Services/Servers/ServerDeletionService.php @@ -106,7 +106,7 @@ class ServerDeletionService public function handle($server) { if (! $server instanceof Server) { - $server = $this->repository->withColumns(['id', 'node_id', 'uuid'])->find($server); + $server = $this->repository->setColumns(['id', 'node_id', 'uuid'])->find($server); } try { @@ -128,7 +128,7 @@ class ServerDeletionService } $this->connection->beginTransaction(); - $this->databaseRepository->withColumns('id')->findWhere([['server_id', '=', $server->id]])->each(function ($item) { + $this->databaseRepository->setColumns('id')->findWhere([['server_id', '=', $server->id]])->each(function ($item) { $this->databaseManagementService->delete($item->id); }); diff --git a/app/Services/Sftp/AuthenticateUsingPasswordService.php b/app/Services/Sftp/AuthenticateUsingPasswordService.php index 16ac56b67..1cf64bd8e 100644 --- a/app/Services/Sftp/AuthenticateUsingPasswordService.php +++ b/app/Services/Sftp/AuthenticateUsingPasswordService.php @@ -68,7 +68,7 @@ class AuthenticateUsingPasswordService } try { - $user = $this->userRepository->withColumns(['id', 'root_admin', 'password'])->findFirstWhere([['username', '=', $username]]); + $user = $this->userRepository->setColumns(['id', 'root_admin', 'password'])->findFirstWhere([['username', '=', $username]]); if (! password_verify($password, $user->password)) { throw new AuthenticationException; @@ -77,7 +77,7 @@ class AuthenticateUsingPasswordService throw new AuthenticationException; } - $server = $this->repository->withColumns(['id', 'node_id', 'owner_id', 'uuid'])->getByUuid($server); + $server = $this->repository->setColumns(['id', 'node_id', 'owner_id', 'uuid'])->getByUuid($server); if ($server->node_id !== $node || (! $user->root_admin && $server->owner_id !== $user->id)) { throw new RecordNotFoundException; } diff --git a/app/Services/Users/UserDeletionService.php b/app/Services/Users/UserDeletionService.php index 6b335be4b..942e76faf 100644 --- a/app/Services/Users/UserDeletionService.php +++ b/app/Services/Users/UserDeletionService.php @@ -63,7 +63,7 @@ class UserDeletionService $user = $user->id; } - $servers = $this->serverRepository->withColumns('id')->findCountWhere([['owner_id', '=', $user]]); + $servers = $this->serverRepository->setColumns('id')->findCountWhere([['owner_id', '=', $user]]); if ($servers > 0) { throw new DisplayException($this->translator->trans('admin/user.exceptions.user_has_servers')); } diff --git a/database/factories/ModelFactory.php b/database/factories/ModelFactory.php index c5501d119..6e585d4d6 100644 --- a/database/factories/ModelFactory.php +++ b/database/factories/ModelFactory.php @@ -186,6 +186,7 @@ $factory->define(Pterodactyl\Models\Database::class, function (Faker $faker) { 'database_host_id' => $faker->randomNumber(), 'database' => str_random(10), 'username' => str_random(10), + 'remote' => '%', 'password' => $password ?: bcrypt('test123'), 'created_at' => \Carbon\Carbon::now()->toDateTimeString(), 'updated_at' => \Carbon\Carbon::now()->toDateTimeString(), diff --git a/database/seeds/EggSeeder.php b/database/seeds/EggSeeder.php index 4f5915a2d..245d74ac3 100644 --- a/database/seeds/EggSeeder.php +++ b/database/seeds/EggSeeder.php @@ -122,7 +122,7 @@ class EggSeeder extends Seeder $file = new UploadedFile($file->getPathname(), $file->getFilename(), 'application/json', $file->getSize()); try { - $egg = $this->repository->withColumns('id')->findFirstWhere([ + $egg = $this->repository->setColumns('id')->findFirstWhere([ ['author', '=', $decoded->author], ['name', '=', $decoded->name], ['nest_id', '=', $nest->id], diff --git a/tests/Traits/Http/RequestMockHelpers.php b/tests/Traits/Http/RequestMockHelpers.php index 8611e710f..f33ff71e9 100644 --- a/tests/Traits/Http/RequestMockHelpers.php +++ b/tests/Traits/Http/RequestMockHelpers.php @@ -45,11 +45,12 @@ trait RequestMockHelpers /** * Generates a new request user model and also returns the generated model. * + * @param array $args * @return \Pterodactyl\Models\User */ - public function generateRequestUserModel(): User + public function generateRequestUserModel(array $args = []): User { - $user = factory(User::class)->make(); + $user = factory(User::class)->make($args); $this->setRequestUserModel($user); return $user; diff --git a/tests/Unit/Commands/User/DeleteUserCommandTest.php b/tests/Unit/Commands/User/DeleteUserCommandTest.php index 1800c70da..fa5b5199d 100644 --- a/tests/Unit/Commands/User/DeleteUserCommandTest.php +++ b/tests/Unit/Commands/User/DeleteUserCommandTest.php @@ -1,11 +1,4 @@ . - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ namespace Tests\Unit\Commands\User; @@ -60,7 +53,7 @@ class DeleteUserCommandTest extends CommandTestCase $user2 = factory(User::class)->make(), ]); - $this->repository->shouldReceive('search')->with($user1->username)->once()->andReturnSelf() + $this->repository->shouldReceive('setSearchTerm')->with($user1->username)->once()->andReturnSelf() ->shouldReceive('all')->withNoArgs()->once()->andReturn($users); $this->deletionService->shouldReceive('handle')->with($user1->id)->once()->andReturnNull(); @@ -82,9 +75,9 @@ class DeleteUserCommandTest extends CommandTestCase $user1 = factory(User::class)->make(), ]); - $this->repository->shouldReceive('search')->with('noResults')->once()->andReturnSelf() - ->shouldReceive('all')->withNoArgs()->once()->andReturn([]); - $this->repository->shouldReceive('search')->with($user1->username)->once()->andReturnSelf() + $this->repository->shouldReceive('setSearchTerm')->with('noResults')->once()->andReturnSelf() + ->shouldReceive('all')->withNoArgs()->once()->andReturn(collect()); + $this->repository->shouldReceive('setSearchTerm')->with($user1->username)->once()->andReturnSelf() ->shouldReceive('all')->withNoArgs()->once()->andReturn($users); $this->deletionService->shouldReceive('handle')->with($user1->id)->once()->andReturnNull(); @@ -107,7 +100,7 @@ class DeleteUserCommandTest extends CommandTestCase $user1 = factory(User::class)->make(), ]); - $this->repository->shouldReceive('search')->with($user1->username)->twice()->andReturnSelf() + $this->repository->shouldReceive('setSearchTerm')->with($user1->username)->twice()->andReturnSelf() ->shouldReceive('all')->withNoArgs()->twice()->andReturn($users); $this->deletionService->shouldReceive('handle')->with($user1->id)->once()->andReturnNull(); @@ -130,7 +123,7 @@ class DeleteUserCommandTest extends CommandTestCase $user1 = factory(User::class)->make(), ]); - $this->repository->shouldReceive('search')->with($user1->username)->once()->andReturnSelf() + $this->repository->shouldReceive('setSearchTerm')->with($user1->username)->once()->andReturnSelf() ->shouldReceive('all')->withNoArgs()->once()->andReturn($users); $this->deletionService->shouldNotReceive('handle'); @@ -149,7 +142,7 @@ class DeleteUserCommandTest extends CommandTestCase $user1 = factory(User::class)->make(), ]); - $this->repository->shouldReceive('search')->with($user1->username)->once()->andReturnSelf() + $this->repository->shouldReceive('setSearchTerm')->with($user1->username)->once()->andReturnSelf() ->shouldReceive('all')->withNoArgs()->once()->andReturn($users); $this->deletionService->shouldReceive('handle')->with($user1)->once()->andReturnNull(); @@ -169,7 +162,7 @@ class DeleteUserCommandTest extends CommandTestCase $user2 = factory(User::class)->make(), ]); - $this->repository->shouldReceive('search')->with($user1->username)->once()->andReturnSelf() + $this->repository->shouldReceive('setSearchTerm')->with($user1->username)->once()->andReturnSelf() ->shouldReceive('all')->withNoArgs()->once()->andReturn($users); $this->deletionService->shouldNotReceive('handle'); @@ -184,8 +177,8 @@ class DeleteUserCommandTest extends CommandTestCase */ public function testNoInteractionWithNoResults() { - $this->repository->shouldReceive('search')->with(123456)->once()->andReturnSelf() - ->shouldReceive('all')->withNoArgs()->once()->andReturn([]); + $this->repository->shouldReceive('setSearchTerm')->with(123456)->once()->andReturnSelf() + ->shouldReceive('all')->withNoArgs()->once()->andReturn(collect()); $display = $this->withoutInteraction()->runCommand($this->command, ['--user' => 123456]); diff --git a/tests/Unit/Commands/User/DisableTwoFactorCommandTest.php b/tests/Unit/Commands/User/DisableTwoFactorCommandTest.php index 577dd0275..d741e8be4 100644 --- a/tests/Unit/Commands/User/DisableTwoFactorCommandTest.php +++ b/tests/Unit/Commands/User/DisableTwoFactorCommandTest.php @@ -47,7 +47,7 @@ class DisableTwoFactorCommandTest extends CommandTestCase { $user = factory(User::class)->make(); - $this->repository->shouldReceive('withColumns')->with(['id', 'email'])->once()->andReturnSelf() + $this->repository->shouldReceive('setColumns')->with(['id', 'email'])->once()->andReturnSelf() ->shouldReceive('findFirstWhere')->with([['email', '=', $user->email]])->once()->andReturn($user); $this->repository->shouldReceive('withoutFresh')->withNoArgs()->once()->andReturnSelf() ->shouldReceive('update')->with($user->id, [ @@ -68,7 +68,7 @@ class DisableTwoFactorCommandTest extends CommandTestCase { $user = factory(User::class)->make(); - $this->repository->shouldReceive('withColumns')->with(['id', 'email'])->once()->andReturnSelf() + $this->repository->shouldReceive('setColumns')->with(['id', 'email'])->once()->andReturnSelf() ->shouldReceive('findFirstWhere')->with([['email', '=', $user->email]])->once()->andReturn($user); $this->repository->shouldReceive('withoutFresh')->withNoArgs()->once()->andReturnSelf() ->shouldReceive('update')->with($user->id, [ diff --git a/tests/Unit/Http/Controllers/Admin/DatabaseControllerTest.php b/tests/Unit/Http/Controllers/Admin/DatabaseControllerTest.php index 62b66d0bb..108198bde 100644 --- a/tests/Unit/Http/Controllers/Admin/DatabaseControllerTest.php +++ b/tests/Unit/Http/Controllers/Admin/DatabaseControllerTest.php @@ -11,6 +11,7 @@ namespace Tests\Unit\Http\Controllers\Admin; use Mockery as m; use Tests\TestCase; +use Pterodactyl\Models\DatabaseHost; use Prologue\Alerts\AlertsMessageBag; use Tests\Assertions\ControllerAssertionsTrait; use Pterodactyl\Http\Controllers\Admin\DatabaseController; @@ -74,8 +75,8 @@ class DatabaseControllerTest extends TestCase */ public function testIndexController() { - $this->locationRepository->shouldReceive('getAllWithNodes')->withNoArgs()->once()->andReturn('getAllWithNodes'); - $this->repository->shouldReceive('getWithViewDetails')->withNoArgs()->once()->andReturn('getWithViewDetails'); + $this->locationRepository->shouldReceive('getAllWithNodes')->withNoArgs()->once()->andReturn(collect(['getAllWithNodes'])); + $this->repository->shouldReceive('getWithViewDetails')->withNoArgs()->once()->andReturn(collect(['getWithViewDetails'])); $response = $this->getController()->index(); @@ -83,8 +84,8 @@ class DatabaseControllerTest extends TestCase $this->assertViewNameEquals('admin.databases.index', $response); $this->assertViewHasKey('locations', $response); $this->assertViewHasKey('hosts', $response); - $this->assertViewKeyEquals('locations', 'getAllWithNodes', $response); - $this->assertViewKeyEquals('hosts', 'getWithViewDetails', $response); + $this->assertViewKeyEquals('locations', collect(['getAllWithNodes']), $response); + $this->assertViewKeyEquals('hosts', collect(['getWithViewDetails']), $response); } /** @@ -92,8 +93,10 @@ class DatabaseControllerTest extends TestCase */ public function testViewController() { - $this->locationRepository->shouldReceive('getAllWithNodes')->withNoArgs()->once()->andReturn('getAllWithNodes'); - $this->repository->shouldReceive('getWithServers')->with(1)->once()->andReturn('getWithServers'); + $model = factory(DatabaseHost::class)->make(); + + $this->locationRepository->shouldReceive('getAllWithNodes')->withNoArgs()->once()->andReturn(collect(['getAllWithNodes'])); + $this->repository->shouldReceive('getWithServers')->with(1)->once()->andReturn($model); $response = $this->getController()->view(1); @@ -101,8 +104,8 @@ class DatabaseControllerTest extends TestCase $this->assertViewNameEquals('admin.databases.view', $response); $this->assertViewHasKey('locations', $response); $this->assertViewHasKey('host', $response); - $this->assertViewKeyEquals('locations', 'getAllWithNodes', $response); - $this->assertViewKeyEquals('host', 'getWithServers', $response); + $this->assertViewKeyEquals('locations', collect(['getAllWithNodes']), $response); + $this->assertViewKeyEquals('host', $model, $response); } /** diff --git a/tests/Unit/Http/Controllers/Base/APIControllerTest.php b/tests/Unit/Http/Controllers/Base/APIControllerTest.php index 579fb43bb..e356c3910 100644 --- a/tests/Unit/Http/Controllers/Base/APIControllerTest.php +++ b/tests/Unit/Http/Controllers/Base/APIControllerTest.php @@ -46,15 +46,15 @@ class APIControllerTest extends ControllerTestCase */ public function testIndexController() { - $model = $this->setRequestUser(); + $model = $this->generateRequestUserModel(); - $this->repository->shouldReceive('findWhere')->with([['user_id', '=', $model->id]])->once()->andReturn(['testkeys']); + $this->repository->shouldReceive('findWhere')->with([['user_id', '=', $model->id]])->once()->andReturn(collect(['testkeys'])); $response = $this->getController()->index($this->request); $this->assertIsViewResponse($response); $this->assertViewNameEquals('base.api.index', $response); $this->assertViewHasKey('keys', $response); - $this->assertViewKeyEquals('keys', ['testkeys'], $response); + $this->assertViewKeyEquals('keys', collect(['testkeys']), $response); } /** @@ -64,7 +64,7 @@ class APIControllerTest extends ControllerTestCase */ public function testCreateController($admin) { - $this->setRequestUser(factory(User::class)->make(['root_admin' => $admin])); + $this->generateRequestUserModel(['root_admin' => $admin]); $response = $this->getController()->create($this->request); $this->assertIsViewResponse($response); @@ -87,7 +87,7 @@ class APIControllerTest extends ControllerTestCase public function testStoreController($admin) { $this->setRequestMockClass(ApiKeyFormRequest::class); - $model = $this->setRequestUser(factory(User::class)->make(['root_admin' => $admin])); + $model = $this->generateRequestUserModel(['root_admin' => $admin]); $keyModel = factory(APIKey::class)->make(); if ($admin) { @@ -118,12 +118,12 @@ class APIControllerTest extends ControllerTestCase */ public function testRevokeController() { - $model = $this->setRequestUser(); + $model = $this->generateRequestUserModel(); $this->repository->shouldReceive('deleteWhere')->with([ ['user_id', '=', $model->id], ['token', '=', 'testKey123'], - ])->once()->andReturnNull(); + ])->once()->andReturn(1); $response = $this->getController()->revoke($this->request, 'testKey123'); $this->assertIsResponse($response); diff --git a/tests/Unit/Http/Controllers/Base/IndexControllerTest.php b/tests/Unit/Http/Controllers/Base/IndexControllerTest.php index 7245e9662..8dab9007a 100644 --- a/tests/Unit/Http/Controllers/Base/IndexControllerTest.php +++ b/tests/Unit/Http/Controllers/Base/IndexControllerTest.php @@ -15,6 +15,7 @@ use Pterodactyl\Models\Server; use Tests\Assertions\ControllerAssertionsTrait; use Tests\Unit\Http\Controllers\ControllerTestCase; use Pterodactyl\Http\Controllers\Base\IndexController; +use Illuminate\Contracts\Pagination\LengthAwarePaginator; use Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService; use Pterodactyl\Contracts\Repository\ServerRepositoryInterface; use Pterodactyl\Contracts\Repository\Daemon\ServerRepositoryInterface as DaemonServerRepositoryInterface; @@ -62,19 +63,19 @@ class IndexControllerTest extends ControllerTestCase */ public function testIndexController() { - $model = $this->setRequestUser(); + $paginator = m::mock(LengthAwarePaginator::class); + $model = $this->generateRequestUserModel(); $this->request->shouldReceive('input')->with('query')->once()->andReturn('searchTerm'); - $this->repository->shouldReceive('search')->with('searchTerm')->once()->andReturnSelf() - ->shouldReceive('filterUserAccessServers')->with( - $model->id, $model->root_admin, 'all', ['user'] - )->once()->andReturn(['test']); + $this->repository->shouldReceive('setSearchTerm')->with('searchTerm')->once()->andReturnSelf() + ->shouldReceive('filterUserAccessServers')->with($model, User::FILTER_LEVEL_ALL) + ->once()->andReturn($paginator); $response = $this->controller->getIndex($this->request); $this->assertIsViewResponse($response); $this->assertViewNameEquals('base.index', $response); $this->assertViewHasKey('servers', $response); - $this->assertViewKeyEquals('servers', ['test'], $response); + $this->assertViewKeyEquals('servers', $paginator, $response); } /** @@ -82,7 +83,7 @@ class IndexControllerTest extends ControllerTestCase */ public function testStatusController() { - $user = $this->setRequestUser(); + $user = $this->generateRequestUserModel(); $server = factory(Server::class)->make(['suspended' => 0, 'installed' => 1]); $this->repository->shouldReceive('findFirstWhere')->with([['uuidShort', '=', $server->uuidShort]])->once()->andReturn($server); @@ -105,7 +106,7 @@ class IndexControllerTest extends ControllerTestCase */ public function testStatusControllerWhenServerNotInstalled() { - $user = $this->setRequestUser(); + $user = $this->generateRequestUserModel(); $server = factory(Server::class)->make(['suspended' => 0, 'installed' => 0]); $this->repository->shouldReceive('findFirstWhere')->with([['uuidShort', '=', $server->uuidShort]])->once()->andReturn($server); diff --git a/tests/Unit/Http/Controllers/Base/SecurityControllerTest.php b/tests/Unit/Http/Controllers/Base/SecurityControllerTest.php index 7c698a597..72435791b 100644 --- a/tests/Unit/Http/Controllers/Base/SecurityControllerTest.php +++ b/tests/Unit/Http/Controllers/Base/SecurityControllerTest.php @@ -61,13 +61,13 @@ class SecurityControllerTest extends ControllerTestCase $model = $this->generateRequestUserModel(); $this->config->shouldReceive('get')->with('session.driver')->once()->andReturn('database'); - $this->repository->shouldReceive('getUserSessions')->with($model->id)->once()->andReturn(['sessions']); + $this->repository->shouldReceive('getUserSessions')->with($model->id)->once()->andReturn(collect(['sessions'])); $response = $this->getController()->index($this->request); $this->assertIsViewResponse($response); $this->assertViewNameEquals('base.security', $response); $this->assertViewHasKey('sessions', $response); - $this->assertViewKeyEquals('sessions', ['sessions'], $response); + $this->assertViewKeyEquals('sessions', collect(['sessions']), $response); } /** diff --git a/tests/Unit/Http/Controllers/Server/Files/FileActionsControllerTest.php b/tests/Unit/Http/Controllers/Server/Files/FileActionsControllerTest.php index 077cf02d9..f6d8cac0c 100644 --- a/tests/Unit/Http/Controllers/Server/Files/FileActionsControllerTest.php +++ b/tests/Unit/Http/Controllers/Server/Files/FileActionsControllerTest.php @@ -103,7 +103,7 @@ class FileActionsControllerTest extends ControllerTestCase ->shouldReceive('setAccessToken')->with('abc123')->once()->andReturnSelf() ->shouldReceive('getContent')->with($file)->once()->andReturn('file contents'); - $response = $controller->update($this->request, '1234', $file); + $response = $controller->view($this->request, '1234', $file); $this->assertIsViewResponse($response); $this->assertViewNameEquals('server.files.edit', $response); $this->assertViewHasKey('file', $response); @@ -134,7 +134,7 @@ class FileActionsControllerTest extends ControllerTestCase $this->repository->shouldReceive('setNode')->with($server->node_id)->once()->andThrow($this->getExceptionMock()); try { - $controller->update($this->request, '1234', 'file.txt'); + $controller->view($this->request, '1234', 'file.txt'); } catch (PterodactylException $exception) { $this->assertInstanceOf(DaemonConnectionException::class, $exception); $this->assertInstanceOf(RequestException::class, $exception->getPrevious()); diff --git a/tests/Unit/Http/Controllers/Server/SubuserControllerTest.php b/tests/Unit/Http/Controllers/Server/SubuserControllerTest.php index 6bf6111b6..f9b550cfc 100644 --- a/tests/Unit/Http/Controllers/Server/SubuserControllerTest.php +++ b/tests/Unit/Http/Controllers/Server/SubuserControllerTest.php @@ -76,7 +76,7 @@ class SubuserControllerTest extends ControllerTestCase $this->mockInjectJavascript(); $controller->shouldReceive('authorize')->with('list-subusers', $server)->once()->andReturnNull(); - $this->repository->shouldReceive('findWhere')->with([['server_id', '=', $server->id]])->once()->andReturn([]); + $this->repository->shouldReceive('findWhere')->with([['server_id', '=', $server->id]])->once()->andReturn(collect()); $response = $controller->index($this->request); $this->assertIsViewResponse($response); diff --git a/tests/Unit/Http/Middleware/DaemonAuthenticateTest.php b/tests/Unit/Http/Middleware/DaemonAuthenticateTest.php index f6531bfbc..861e2724c 100644 --- a/tests/Unit/Http/Middleware/DaemonAuthenticateTest.php +++ b/tests/Unit/Http/Middleware/DaemonAuthenticateTest.php @@ -34,7 +34,7 @@ class DaemonAuthenticateTest extends MiddlewareTestCase $this->request->shouldReceive('route->getName')->withNoArgs()->once()->andReturn('random.name'); $this->request->shouldReceive('header')->with('X-Access-Node')->twice()->andReturn($node->uuid); - $this->repository->shouldReceive('findWhere')->with(['daemonSecret' => $node->uuid])->once()->andReturn($node); + $this->repository->shouldReceive('findFirstWhere')->with(['daemonSecret' => $node->uuid])->once()->andReturn($node); $this->getMiddleware()->handle($this->request, $this->getClosureAssertions()); $this->assertRequestHasAttribute('node'); diff --git a/tests/Unit/Repositories/Eloquent/AllocationRepositoryTest.php b/tests/Unit/Repositories/Eloquent/AllocationRepositoryTest.php deleted file mode 100644 index a316fc61c..000000000 --- a/tests/Unit/Repositories/Eloquent/AllocationRepositoryTest.php +++ /dev/null @@ -1,72 +0,0 @@ -. - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ - -namespace Tests\Unit\Repositories\Eloquent; - -use Mockery as m; -use Tests\TestCase; -use Pterodactyl\Models\Allocation; -use Illuminate\Database\Eloquent\Builder; -use Pterodactyl\Repositories\Eloquent\AllocationRepository; - -class AllocationRepositoryTest extends TestCase -{ - /** - * @var \Illuminate\Database\Eloquent\Builder - */ - protected $builder; - - /** - * @var \Pterodactyl\Repositories\Eloquent\AllocationRepository - */ - protected $repository; - - /** - * Setup tests. - */ - public function setUp() - { - parent::setUp(); - - $this->builder = m::mock(Builder::class); - $this->repository = m::mock(AllocationRepository::class)->makePartial(); - - $this->repository->shouldReceive('getBuilder')->withNoArgs()->andReturn($this->builder); - } - - /** - * Test that we are returning the correct model. - */ - public function testCorrectModelIsAssigned() - { - $this->assertEquals(Allocation::class, $this->repository->model()); - } - - /** - * Test that allocations can be assigned to a server correctly. - */ - public function testAllocationsAreAssignedToAServer() - { - $this->builder->shouldReceive('whereIn')->with('id', [1, 2])->once()->andReturnSelf() - ->shouldReceive('update')->with(['server_id' => 10])->once()->andReturn(true); - - $this->assertTrue($this->repository->assignAllocationsToServer(10, [1, 2])); - } - - /** - * Test that allocations with a node relationship are returned. - */ - public function testAllocationsForANodeAreReturned() - { - $this->builder->shouldReceive('where')->with('node_id', 1)->once()->andReturnSelf() - ->shouldReceive('get')->once()->andReturn(factory(Allocation::class)->make()); - - $this->assertInstanceOf(Allocation::class, $this->repository->getAllocationsForNode(1)); - } -} diff --git a/tests/Unit/Repositories/Eloquent/ApiKeyRepositoryTest.php b/tests/Unit/Repositories/Eloquent/ApiKeyRepositoryTest.php deleted file mode 100644 index e304041ca..000000000 --- a/tests/Unit/Repositories/Eloquent/ApiKeyRepositoryTest.php +++ /dev/null @@ -1,50 +0,0 @@ -. - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ - -namespace Tests\Unit\Repositories\Eloquent; - -use Mockery as m; -use Tests\TestCase; -use Pterodactyl\Models\APIKey; -use Illuminate\Database\Eloquent\Builder; -use Pterodactyl\Repositories\Eloquent\ApiKeyRepository; - -class ApiKeyRepositoryTest extends TestCase -{ - /** - * @var \Illuminate\Database\Eloquent\Builder - */ - protected $builder; - - /** - * @var \Pterodactyl\Repositories\Eloquent\ApiKeyRepository - */ - protected $repository; - - /** - * Setup tests. - */ - public function setUp() - { - parent::setUp(); - - $this->builder = m::mock(Builder::class); - $this->repository = m::mock(ApiKeyRepository::class)->makePartial(); - - $this->repository->shouldReceive('getBuilder')->withNoArgs()->andReturn($this->builder); - } - - /** - * Test that we are returning the correct model. - */ - public function testCorrectModelIsAssigned() - { - $this->assertEquals(APIKey::class, $this->repository->model()); - } -} diff --git a/tests/Unit/Repositories/Eloquent/ApiPermissionRepositoryTest.php b/tests/Unit/Repositories/Eloquent/ApiPermissionRepositoryTest.php deleted file mode 100644 index d1641f04f..000000000 --- a/tests/Unit/Repositories/Eloquent/ApiPermissionRepositoryTest.php +++ /dev/null @@ -1,50 +0,0 @@ -. - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ - -namespace Tests\Unit\Repositories\Eloquent; - -use Mockery as m; -use Tests\TestCase; -use Pterodactyl\Models\APIPermission; -use Illuminate\Database\Eloquent\Builder; -use Pterodactyl\Repositories\Eloquent\ApiPermissionRepository; - -class ApiPermissionRepositoryTest extends TestCase -{ - /** - * @var \Illuminate\Database\Eloquent\Builder - */ - protected $builder; - - /** - * @var \Pterodactyl\Repositories\Eloquent\ApiPermissionRepository - */ - protected $repository; - - /** - * Setup tests. - */ - public function setUp() - { - parent::setUp(); - - $this->builder = m::mock(Builder::class); - $this->repository = m::mock(ApiPermissionRepository::class)->makePartial(); - - $this->repository->shouldReceive('getBuilder')->withNoArgs()->andReturn($this->builder); - } - - /** - * Test that we are returning the correct model. - */ - public function testCorrectModelIsAssigned() - { - $this->assertEquals(APIPermission::class, $this->repository->model()); - } -} diff --git a/tests/Unit/Repositories/Eloquent/DatabaseHostRepositoryTest.php b/tests/Unit/Repositories/Eloquent/DatabaseHostRepositoryTest.php deleted file mode 100644 index 94c9486b4..000000000 --- a/tests/Unit/Repositories/Eloquent/DatabaseHostRepositoryTest.php +++ /dev/null @@ -1,88 +0,0 @@ -. - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ - -namespace Tests\Unit\Repositories\Eloquent; - -use Mockery as m; -use Tests\TestCase; -use Pterodactyl\Models\DatabaseHost; -use Illuminate\Database\Eloquent\Builder; -use Pterodactyl\Repositories\Eloquent\DatabaseHostRepository; - -class DatabaseHostRepositoryTest extends TestCase -{ - /** - * @var \Illuminate\Database\Eloquent\Builder - */ - protected $builder; - - /** - * @var \Pterodactyl\Repositories\Eloquent\DatabaseHostRepository - */ - protected $repository; - - /** - * Setup tests. - */ - public function setUp() - { - parent::setUp(); - - $this->builder = m::mock(Builder::class); - $this->repository = m::mock(DatabaseHostRepository::class)->makePartial(); - - $this->repository->shouldReceive('getBuilder')->withNoArgs()->andReturn($this->builder); - } - - /** - * Test that we are returning the correct model. - */ - public function testCorrectModelIsAssigned() - { - $this->assertEquals(DatabaseHost::class, $this->repository->model()); - } - - /** - * Test query to reutrn all of the default view data. - */ - public function testHostWithDefaultViewDataIsReturned() - { - $this->builder->shouldReceive('withCount')->with('databases')->once()->andReturnSelf() - ->shouldReceive('with')->with('node')->once()->andReturnSelf() - ->shouldReceive('get')->withNoArgs()->once()->andReturnNull(); - - $this->assertNull($this->repository->getWithViewDetails()); - } - - /** - * Test query to return host and servers. - */ - public function testHostIsReturnedWithServers() - { - $model = factory(DatabaseHost::class)->make(); - - $this->builder->shouldReceive('with')->with('databases.server')->once()->andReturnSelf() - ->shouldReceive('find')->with(1, ['*'])->once()->andReturn($model); - - $this->assertEquals($model, $this->repository->getWithServers(1)); - } - - /** - * Test exception is found if no host is found when querying for servers. - * - * @expectedException \Pterodactyl\Exceptions\Repository\RecordNotFoundException - */ - public function testExceptionIsThrownIfNoRecordIsFoundWithServers() - { - $this->builder->shouldReceive('with')->with('databases.server')->once()->andReturnSelf() - ->shouldReceive('find')->with(1, ['*'])->once()->andReturnNull(); - - $this->repository->getWithServers(1); - } -} diff --git a/tests/Unit/Repositories/Eloquent/DatabaseRepositoryTest.php b/tests/Unit/Repositories/Eloquent/DatabaseRepositoryTest.php deleted file mode 100644 index 4a7f0ccc3..000000000 --- a/tests/Unit/Repositories/Eloquent/DatabaseRepositoryTest.php +++ /dev/null @@ -1,157 +0,0 @@ -. - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ - -namespace Tests\Unit\Repositories\Eloquent; - -use Mockery as m; -use Tests\TestCase; -use Pterodactyl\Models\Database; -use Illuminate\Database\Eloquent\Builder; -use Pterodactyl\Exceptions\DisplayException; -use Pterodactyl\Repositories\Eloquent\DatabaseRepository; -use Pterodactyl\Exceptions\Repository\DuplicateDatabaseNameException; - -class DatabaseRepositoryTest extends TestCase -{ - /** - * @var \Illuminate\Database\Eloquent\Builder - */ - protected $builder; - - /** - * @var \Pterodactyl\Repositories\Eloquent\DatabaseRepository - */ - protected $repository; - - /** - * Setup tests. - */ - public function setUp() - { - parent::setUp(); - - $this->builder = m::mock(Builder::class); - $this->repository = m::mock(DatabaseRepository::class)->makePartial()->shouldAllowMockingProtectedMethods(); - - $this->repository->shouldReceive('getBuilder')->withNoArgs()->andReturn($this->builder); - $this->repository->shouldNotReceive('runStatement'); - } - - /** - * Test that we are returning the correct model. - */ - public function testCorrectModelIsAssigned() - { - $this->assertEquals(Database::class, $this->repository->model()); - } - - /** - * Test that a database can be created if it does not already exist. - */ - public function testDatabaseIsCreatedIfNotExists() - { - $data = [ - 'server_id' => 1, - 'database_host_id' => 100, - 'database' => 'somename', - ]; - - $this->builder->shouldReceive('where')->with([ - ['server_id', '=', array_get($data, 'server_id')], - ['database_host_id', '=', array_get($data, 'database_host_id')], - ['database', '=', array_get($data, 'database')], - ])->once()->andReturnSelf() - ->shouldReceive('count')->withNoArgs()->once()->andReturn(0); - - $this->repository->shouldReceive('create')->with($data)->once()->andReturn(true); - - $this->assertTrue($this->repository->createIfNotExists($data)); - } - - /** - * Test that an exception is thrown if a database already exists with the given name. - */ - public function testExceptionIsThrownIfDatabaseAlreadyExists() - { - $this->builder->shouldReceive('where->count')->once()->andReturn(1); - $this->repository->shouldNotReceive('create'); - - try { - $this->repository->createIfNotExists([]); - } catch (DisplayException $exception) { - $this->assertInstanceOf(DuplicateDatabaseNameException::class, $exception); - $this->assertEquals('A database with those details already exists for the specified server.', $exception->getMessage()); - } - } - - /** - * Test SQL used to create a database. - */ - public function testCreateDatabaseStatement() - { - $query = sprintf('CREATE DATABASE IF NOT EXISTS `%s`', 'test_database'); - $this->repository->shouldReceive('runStatement')->with($query)->once()->andReturn(true); - - $this->assertTrue($this->repository->createDatabase('test_database', 'test')); - } - - /** - * Test SQL used to create a user. - */ - public function testCreateUserStatement() - { - $query = sprintf('CREATE USER `%s`@`%s` IDENTIFIED BY \'%s\'', 'test', '%', 'password'); - $this->repository->shouldReceive('runStatement')->with($query)->once()->andReturn(true); - - $this->assertTrue($this->repository->createUser('test', '%', 'password', 'test')); - } - - /** - * Test that a user is assigned the correct permissions on a database. - */ - public function testUserAssignmentToDatabaseStatement() - { - $query = sprintf('GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, INDEX, EXECUTE ON `%s`.* TO `%s`@`%s`', 'test_database', 'test', '%'); - $this->repository->shouldReceive('runStatement')->with($query)->once()->andReturn(true); - - $this->assertTrue($this->repository->assignUserToDatabase('test_database', 'test', '%', 'test')); - } - - /** - * Test SQL for flushing privileges. - */ - public function testFlushStatement() - { - $this->repository->shouldReceive('runStatement')->with('FLUSH PRIVILEGES')->once()->andReturn(true); - - $this->assertTrue($this->repository->flush('test')); - } - - /** - * Test SQL to drop a database. - */ - public function testDropDatabaseStatement() - { - $query = sprintf('DROP DATABASE IF EXISTS `%s`', 'test_database'); - $this->repository->shouldReceive('runStatement')->with($query)->once()->andReturn(true); - - $this->assertTrue($this->repository->dropDatabase('test_database', 'test')); - } - - /** - * Test SQL to drop a user. - */ - public function testDropUserStatement() - { - $query = sprintf('DROP USER IF EXISTS `%s`@`%s`', 'test', '%'); - $this->repository->shouldReceive('runStatement')->with($query)->once()->andReturn(true); - - $this->assertTrue($this->repository->dropUser('test', '%', 'test')); - } -} diff --git a/tests/Unit/Repositories/Eloquent/LocationRepositoryTest.php b/tests/Unit/Repositories/Eloquent/LocationRepositoryTest.php deleted file mode 100644 index a245e2a9e..000000000 --- a/tests/Unit/Repositories/Eloquent/LocationRepositoryTest.php +++ /dev/null @@ -1,100 +0,0 @@ -. - * - * This software is licensed under the terms of the MIT license. - * https://opensource.org/licenses/MIT - */ - -namespace Tests\Unit\Repositories\Eloquent; - -use Mockery as m; -use Tests\TestCase; -use Pterodactyl\Models\Location; -use Illuminate\Database\Eloquent\Builder; -use Pterodactyl\Repositories\Eloquent\LocationRepository; - -class LocationRepositoryTest extends TestCase -{ - /** - * @var \Illuminate\Database\Eloquent\Builder - */ - protected $builder; - - /** - * @var \Pterodactyl\Repositories\Eloquent\LocationRepository - */ - protected $repository; - - /** - * Setup tests. - */ - public function setUp() - { - parent::setUp(); - - $this->builder = m::mock(Builder::class); - $this->repository = m::mock(LocationRepository::class)->makePartial(); - - $this->repository->shouldReceive('getBuilder')->withNoArgs()->andReturn($this->builder); - } - - /** - * Test that we are returning the correct model. - */ - public function testCorrectModelIsAssigned() - { - $this->assertEquals(Location::class, $this->repository->model()); - } - - /** - * Test that all locations with associated node and server counts are returned. - */ - public function testAllLocationsWithDetailsAreReturned() - { - $this->builder->shouldReceive('withCount')->with('nodes', 'servers')->once()->andReturnSelf() - ->shouldReceive('get')->with(['*'])->once()->andReturnNull(); - - $this->assertNull($this->repository->getAllWithDetails()); - } - - /** - * Test that all locations with associated node are returned. - */ - public function testAllLocationsWithNodes() - { - $this->builder->shouldReceive('with')->with('nodes')->once()->andReturnSelf() - ->shouldReceive('get')->with(['*'])->once()->andReturnNull(); - - $this->assertNull($this->repository->getAllWithNodes()); - } - - /** - * Test that a single location with associated node is returned. - */ - public function testLocationWithNodeIsReturned() - { - $model = factory(Location::class)->make(); - - $this->builder->shouldReceive('with')->with('nodes.servers')->once()->andReturnSelf() - ->shouldReceive('find')->with(1, ['*'])->once()->andReturn($model); - - $response = $this->repository->getWithNodes(1); - $this->assertInstanceOf(Location::class, $response); - $this->assertEquals($model, $response); - } - - /** - * Test that an exception is thrown when getting location with nodes if no location is found. - * - * @expectedException \Pterodactyl\Exceptions\Repository\RecordNotFoundException - */ - public function testExceptionIsThrownIfNoLocationIsFoundWithNodes() - { - $this->builder->shouldReceive('with')->with('nodes.servers')->once()->andReturnSelf() - ->shouldReceive('find')->with(1, ['*'])->once()->andReturnNull(); - - $this->repository->getWithNodes(1); - } -} diff --git a/tests/Unit/Services/Allocations/AssignmentServiceTest.php b/tests/Unit/Services/Allocations/AssignmentServiceTest.php index 7f91955d5..805b789a3 100644 --- a/tests/Unit/Services/Allocations/AssignmentServiceTest.php +++ b/tests/Unit/Services/Allocations/AssignmentServiceTest.php @@ -84,7 +84,7 @@ class AssignmentServiceTest extends TestCase 'ip_alias' => null, 'server_id' => null, ], - ])->once()->andReturnNull(); + ])->once()->andReturn(true); $this->connection->shouldReceive('commit')->withNoArgs()->once()->andReturnNull(); $this->service->handle($this->node->id, $data); @@ -123,7 +123,7 @@ class AssignmentServiceTest extends TestCase 'ip_alias' => null, 'server_id' => null, ], - ])->once()->andReturnNull(); + ])->once()->andReturn(true); $this->connection->shouldReceive('commit')->withNoArgs()->once()->andReturnNull(); $this->service->handle($this->node->id, $data); @@ -149,7 +149,7 @@ class AssignmentServiceTest extends TestCase 'ip_alias' => 'my.alias.net', 'server_id' => null, ], - ])->once()->andReturnNull(); + ])->once()->andReturn(true); $this->connection->shouldReceive('commit')->withNoArgs()->once()->andReturnNull(); $this->service->handle($this->node->id, $data); @@ -177,7 +177,7 @@ class AssignmentServiceTest extends TestCase 'ip_alias' => null, 'server_id' => null, ], - ])->once()->andReturnNull(); + ])->once()->andReturn(true); $this->connection->shouldReceive('commit')->withNoArgs()->once()->andReturnNull(); $this->service->handle($this->node->id, $data); @@ -202,7 +202,7 @@ class AssignmentServiceTest extends TestCase 'ip_alias' => null, 'server_id' => null, ], - ])->once()->andReturnNull(); + ])->once()->andReturn(true); $this->repository->shouldReceive('insertIgnore')->with([ [ @@ -212,7 +212,7 @@ class AssignmentServiceTest extends TestCase 'ip_alias' => null, 'server_id' => null, ], - ])->once()->andReturnNull(); + ])->once()->andReturn(true); $this->connection->shouldReceive('commit')->withNoArgs()->once()->andReturnNull(); $this->service->handle($this->node->id, $data); @@ -303,7 +303,7 @@ class AssignmentServiceTest extends TestCase 'ip_alias' => null, 'server_id' => null, ], - ])->once()->andReturnNull(); + ])->once()->andReturn(true); $this->connection->shouldReceive('commit')->withNoArgs()->once()->andReturnNull(); $this->service->handle($this->node, $data); diff --git a/tests/Unit/Services/DaemonKeys/DaemonKeyDeletionServiceTest.php b/tests/Unit/Services/DaemonKeys/DaemonKeyDeletionServiceTest.php index 85067bf9e..558c1eb45 100644 --- a/tests/Unit/Services/DaemonKeys/DaemonKeyDeletionServiceTest.php +++ b/tests/Unit/Services/DaemonKeys/DaemonKeyDeletionServiceTest.php @@ -97,7 +97,7 @@ class DaemonKeyDeletionServiceTest extends TestCase ['server_id', '=', $server->id], ])->once()->andReturn($key); - $this->repository->shouldReceive('delete')->with($key->id)->once()->andReturnNull(); + $this->repository->shouldReceive('delete')->with($key->id)->once()->andReturn(1); $this->daemonRepository->shouldReceive('setNode')->with($server->node_id)->once()->andReturnSelf() ->shouldReceive('revokeAccessKey')->with($key->secret)->once()->andReturnNull(); $this->connection->shouldReceive('commit')->withNoArgs()->once()->andReturnNull(); @@ -121,7 +121,7 @@ class DaemonKeyDeletionServiceTest extends TestCase ['server_id', '=', $server->id], ])->once()->andReturn($key); - $this->repository->shouldReceive('delete')->with($key->id)->once()->andReturnNull(); + $this->repository->shouldReceive('delete')->with($key->id)->once()->andReturn(1); $this->daemonRepository->shouldReceive('setNode')->with($server->node_id)->once()->andReturnSelf() ->shouldReceive('revokeAccessKey')->with($key->secret)->once()->andReturnNull(); $this->connection->shouldReceive('commit')->withNoArgs()->once()->andReturnNull(); @@ -144,7 +144,7 @@ class DaemonKeyDeletionServiceTest extends TestCase ['server_id', '=', $server->id], ])->once()->andReturn($key); - $this->repository->shouldReceive('delete')->with($key->id)->once()->andReturnNull(); + $this->repository->shouldReceive('delete')->with($key->id)->once()->andReturn(1); $this->daemonRepository->shouldReceive('setNode')->with($server->node_id)->once()->andThrow($this->exception); $this->exception->shouldReceive('getResponse')->withNoArgs()->once()->andReturnNull(); $this->connection->shouldReceive('rollBack')->withNoArgs()->once()->andReturnNull(); diff --git a/tests/Unit/Services/Databases/DatabasePasswordServiceTest.php b/tests/Unit/Services/Databases/DatabasePasswordServiceTest.php index 54d46b950..2388e2d34 100644 --- a/tests/Unit/Services/Databases/DatabasePasswordServiceTest.php +++ b/tests/Unit/Services/Databases/DatabasePasswordServiceTest.php @@ -66,11 +66,11 @@ class DatabasePasswordServiceTest extends TestCase $this->repository->shouldReceive('withoutFresh')->withNoArgs()->once()->andReturnSelf(); $this->repository->shouldReceive('update')->with($model->id, ['password' => 'enc123'])->once()->andReturn(true); - $this->repository->shouldReceive('dropUser')->with($model->username, $model->remote)->once()->andReturnNull(); - $this->repository->shouldReceive('createUser')->with($model->username, $model->remote, 'test123')->once()->andReturnNull(); - $this->repository->shouldReceive('assignUserToDatabase')->with($model->database, $model->username, $model->remote)->once()->andReturnNull(); - $this->repository->shouldReceive('flush')->withNoArgs()->once()->andReturnNull(); - $this->connection->shouldReceive('commit')->withNoArgs()->once()->andReturnNull(); + $this->repository->shouldReceive('dropUser')->with($model->username, $model->remote)->once()->andReturn(true); + $this->repository->shouldReceive('createUser')->with($model->username, $model->remote, 'test123')->once()->andReturn(true); + $this->repository->shouldReceive('assignUserToDatabase')->with($model->database, $model->username, $model->remote)->once()->andReturn(true); + $this->repository->shouldReceive('flush')->withNoArgs()->once()->andReturn(true); + $this->connection->shouldReceive('commit')->withNoArgs()->once()->andReturn(true); $response = $this->getService()->handle($useModel ? $model : 1234, 'test123'); $this->assertNotEmpty($response); diff --git a/tests/Unit/Services/Eggs/EggUpdateServiceTest.php b/tests/Unit/Services/Eggs/EggUpdateServiceTest.php index 89f02c49c..db548b962 100644 --- a/tests/Unit/Services/Eggs/EggUpdateServiceTest.php +++ b/tests/Unit/Services/Eggs/EggUpdateServiceTest.php @@ -9,7 +9,6 @@ namespace Tests\Unit\Services\Services\Options; -use Exception; use Mockery as m; use Tests\TestCase; use Pterodactyl\Models\Egg; diff --git a/tests/Unit/Services/Eggs/Sharing/EggUpdateImporterServiceTest.php b/tests/Unit/Services/Eggs/Sharing/EggUpdateImporterServiceTest.php index 28bbdc4a8..df95ee214 100644 --- a/tests/Unit/Services/Eggs/Sharing/EggUpdateImporterServiceTest.php +++ b/tests/Unit/Services/Eggs/Sharing/EggUpdateImporterServiceTest.php @@ -86,8 +86,8 @@ class EggUpdateImporterServiceTest extends TestCase 'env_variable' => $variable->env_variable, ], collect($variable)->except(['egg_id', 'env_variable'])->toArray())->once()->andReturnNull(); - $this->variableRepository->shouldReceive('withColumns')->with(['id', 'env_variable'])->once()->andReturnSelf() - ->shouldReceive('findWhere')->with([['egg_id', '=', $egg->id]])->once()->andReturn([$variable]); + $this->variableRepository->shouldReceive('setColumns')->with(['id', 'env_variable'])->once()->andReturnSelf() + ->shouldReceive('findWhere')->with([['egg_id', '=', $egg->id]])->once()->andReturn(collect([$variable])); $this->connection->shouldReceive('commit')->withNoArgs()->once()->andReturnNull(); @@ -126,13 +126,13 @@ class EggUpdateImporterServiceTest extends TestCase 'env_variable' => $variable1->env_variable, ], collect($variable1)->except(['egg_id', 'env_variable'])->toArray())->once()->andReturnNull(); - $this->variableRepository->shouldReceive('withColumns')->with(['id', 'env_variable'])->once()->andReturnSelf() - ->shouldReceive('findWhere')->with([['egg_id', '=', $egg->id]])->once()->andReturn([$variable1, $variable2]); + $this->variableRepository->shouldReceive('setColumns')->with(['id', 'env_variable'])->once()->andReturnSelf() + ->shouldReceive('findWhere')->with([['egg_id', '=', $egg->id]])->once()->andReturn(collect([$variable1, $variable2])); $this->variableRepository->shouldReceive('deleteWhere')->with([ ['egg_id', '=', $egg->id], ['env_variable', '=', $variable2->env_variable], - ])->once()->andReturnNull(); + ])->once()->andReturn(1); $this->connection->shouldReceive('commit')->withNoArgs()->once()->andReturnNull(); diff --git a/tests/Unit/Services/Eggs/Variables/VariableUpdateServiceTest.php b/tests/Unit/Services/Eggs/Variables/VariableUpdateServiceTest.php index bf1f209ae..84d082b33 100644 --- a/tests/Unit/Services/Eggs/Variables/VariableUpdateServiceTest.php +++ b/tests/Unit/Services/Eggs/Variables/VariableUpdateServiceTest.php @@ -76,7 +76,7 @@ class VariableUpdateServiceTest extends TestCase */ public function testVariableIsUpdatedWhenValidEnvironmentVariableIsPassed() { - $this->repository->shouldReceive('withColumns')->with('id')->once()->andReturnSelf() + $this->repository->shouldReceive('setColumns')->with('id')->once()->andReturnSelf() ->shouldReceive('findCountWhere')->with([ ['env_variable', '=', 'TEST_VAR_123'], ['egg_id', '=', $this->model->option_id], @@ -116,7 +116,7 @@ class VariableUpdateServiceTest extends TestCase */ public function testDataPassedIntoHandlerTakesLowerPriorityThanDataSet() { - $this->repository->shouldReceive('withColumns')->with('id')->once()->andReturnSelf() + $this->repository->shouldReceive('setColumns')->with('id')->once()->andReturnSelf() ->shouldReceive('findCountWhere')->with([ ['env_variable', '=', 'TEST_VAR_123'], ['egg_id', '=', $this->model->option_id], @@ -138,7 +138,7 @@ class VariableUpdateServiceTest extends TestCase */ public function testExceptionIsThrownIfEnvironmentVariableIsNotUnique() { - $this->repository->shouldReceive('withColumns')->with('id')->once()->andReturnSelf() + $this->repository->shouldReceive('setColumns')->with('id')->once()->andReturnSelf() ->shouldReceive('findCountWhere')->with([ ['env_variable', '=', 'TEST_VAR_123'], ['egg_id', '=', $this->model->option_id], diff --git a/tests/Unit/Services/Nodes/NodeDeletionServiceTest.php b/tests/Unit/Services/Nodes/NodeDeletionServiceTest.php index 5c0a44878..a7ae2df05 100644 --- a/tests/Unit/Services/Nodes/NodeDeletionServiceTest.php +++ b/tests/Unit/Services/Nodes/NodeDeletionServiceTest.php @@ -62,14 +62,11 @@ class NodeDeletionServiceTest extends TestCase */ public function testNodeIsDeletedIfNoServersAreAttached() { - $this->serverRepository->shouldReceive('withColumns')->with('id')->once()->andReturnSelf() + $this->serverRepository->shouldReceive('setColumns')->with('id')->once()->andReturnSelf() ->shouldReceive('findCountWhere')->with([['node_id', '=', 1]])->once()->andReturn(0); - $this->repository->shouldReceive('delete')->with(1)->once()->andReturn(true); + $this->repository->shouldReceive('delete')->with(1)->once()->andReturn(1); - $this->assertTrue( - $this->service->handle(1), - 'Assert that deletion returns a positive boolean value.' - ); + $this->assertEquals(1, $this->service->handle(1)); } /** @@ -79,7 +76,7 @@ class NodeDeletionServiceTest extends TestCase */ public function testExceptionIsThrownIfServersAreAttachedToNode() { - $this->serverRepository->shouldReceive('withColumns')->with('id')->once()->andReturnSelf() + $this->serverRepository->shouldReceive('setColumns')->with('id')->once()->andReturnSelf() ->shouldReceive('findCountWhere')->with([['node_id', '=', 1]])->once()->andReturn(1); $this->translator->shouldReceive('trans')->with('exceptions.node.servers_attached')->once()->andReturnNull(); $this->repository->shouldNotReceive('delete'); @@ -94,13 +91,10 @@ class NodeDeletionServiceTest extends TestCase { $node = factory(Node::class)->make(); - $this->serverRepository->shouldReceive('withColumns')->with('id')->once()->andReturnSelf() + $this->serverRepository->shouldReceive('setColumns')->with('id')->once()->andReturnSelf() ->shouldReceive('findCountWhere')->with([['node_id', '=', $node->id]])->once()->andReturn(0); - $this->repository->shouldReceive('delete')->with($node->id)->once()->andReturn(true); + $this->repository->shouldReceive('delete')->with($node->id)->once()->andReturn(1); - $this->assertTrue( - $this->service->handle($node), - 'Assert that deletion returns a positive boolean value.' - ); + $this->assertEquals(1, $this->service->handle($node)); } } diff --git a/tests/Unit/Services/Packs/PackDeletionServiceTest.php b/tests/Unit/Services/Packs/PackDeletionServiceTest.php index 5c169f3de..75e6684e1 100644 --- a/tests/Unit/Services/Packs/PackDeletionServiceTest.php +++ b/tests/Unit/Services/Packs/PackDeletionServiceTest.php @@ -76,7 +76,7 @@ class PackDeletionServiceTest extends TestCase $this->serverRepository->shouldReceive('findCountWhere')->with([['pack_id', '=', $model->id]])->once()->andReturn(0); $this->connection->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull(); - $this->repository->shouldReceive('delete')->with($model->id)->once()->andReturnNull(); + $this->repository->shouldReceive('delete')->with($model->id)->once()->andReturn(1); $this->storage->shouldReceive('disk')->withNoArgs()->once()->andReturnSelf() ->shouldReceive('deleteDirectory')->with('packs/' . $model->uuid)->once()->andReturnNull(); $this->connection->shouldReceive('commit')->withNoArgs()->once()->andReturnNull(); @@ -91,11 +91,11 @@ class PackDeletionServiceTest extends TestCase { $model = factory(Pack::class)->make(); - $this->repository->shouldReceive('withColumns')->with(['id', 'uuid'])->once()->andReturnSelf() + $this->repository->shouldReceive('setColumns')->with(['id', 'uuid'])->once()->andReturnSelf() ->shouldReceive('find')->with($model->id)->once()->andReturn($model); $this->serverRepository->shouldReceive('findCountWhere')->with([['pack_id', '=', $model->id]])->once()->andReturn(0); $this->connection->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull(); - $this->repository->shouldReceive('delete')->with($model->id)->once()->andReturnNull(); + $this->repository->shouldReceive('delete')->with($model->id)->once()->andReturn(1); $this->storage->shouldReceive('disk')->withNoArgs()->once()->andReturnSelf() ->shouldReceive('deleteDirectory')->with('packs/' . $model->uuid)->once()->andReturnNull(); $this->connection->shouldReceive('commit')->withNoArgs()->once()->andReturnNull(); diff --git a/tests/Unit/Services/Packs/PackUpdateServiceTest.php b/tests/Unit/Services/Packs/PackUpdateServiceTest.php index 8a09311f1..7078a003c 100644 --- a/tests/Unit/Services/Packs/PackUpdateServiceTest.php +++ b/tests/Unit/Services/Packs/PackUpdateServiceTest.php @@ -85,7 +85,7 @@ class PackUpdateServiceTest extends TestCase { $model = factory(Pack::class)->make(); - $this->repository->shouldReceive('withColumns')->with(['id', 'egg_id'])->once()->andReturnSelf() + $this->repository->shouldReceive('setColumns')->with(['id', 'egg_id'])->once()->andReturnSelf() ->shouldReceive('find')->with($model->id)->once()->andReturn($model); $this->repository->shouldReceive('withoutFresh->update')->with($model->id, [ 'locked' => false, diff --git a/tests/Unit/Services/Servers/ServerCreationServiceTest.php b/tests/Unit/Services/Servers/ServerCreationServiceTest.php index 4df486d5c..b50ad1d84 100644 --- a/tests/Unit/Services/Servers/ServerCreationServiceTest.php +++ b/tests/Unit/Services/Servers/ServerCreationServiceTest.php @@ -116,7 +116,7 @@ class ServerCreationServiceTest extends TestCase 'egg_id' => $model->egg_id, ]))->once()->andReturn($model); - $this->allocationRepository->shouldReceive('assignAllocationsToServer')->with($model->id, [$model->allocation_id])->once()->andReturnNull(); + $this->allocationRepository->shouldReceive('assignAllocationsToServer')->with($model->id, [$model->allocation_id])->once()->andReturn(1); $this->validatorService->shouldReceive('setUserLevel')->with(User::USER_LEVEL_ADMIN)->once()->andReturnNull(); $this->validatorService->shouldReceive('handle')->with($model->egg_id, [])->once()->andReturn( @@ -129,7 +129,7 @@ class ServerCreationServiceTest extends TestCase 'variable_id' => 123, 'variable_value' => 'var1-value', ], - ])->once()->andReturnNull(); + ])->once()->andReturn(true); $this->configurationStructureService->shouldReceive('handle')->with($model)->once()->andReturn(['test' => 'struct']); $this->daemonServerRepository->shouldReceive('setNode')->with($model->node_id)->once()->andReturnSelf(); @@ -154,7 +154,7 @@ class ServerCreationServiceTest extends TestCase $this->connection->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull(); $this->repository->shouldReceive('create')->once()->andReturn($model); - $this->allocationRepository->shouldReceive('assignAllocationsToServer')->once()->andReturnNull(); + $this->allocationRepository->shouldReceive('assignAllocationsToServer')->once()->andReturn(1); $this->validatorService->shouldReceive('setUserLevel')->once()->andReturnNull(); $this->validatorService->shouldReceive('handle')->once()->andReturn(collect([])); $this->configurationStructureService->shouldReceive('handle')->once()->andReturn([]); diff --git a/tests/Unit/Services/Servers/ServerDeletionServiceTest.php b/tests/Unit/Services/Servers/ServerDeletionServiceTest.php index 93fa478f2..26d7fa103 100644 --- a/tests/Unit/Services/Servers/ServerDeletionServiceTest.php +++ b/tests/Unit/Services/Servers/ServerDeletionServiceTest.php @@ -116,13 +116,13 @@ class ServerDeletionServiceTest extends TestCase ->shouldReceive('delete')->withNoArgs()->once()->andReturnNull(); $this->connection->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull(); - $this->databaseRepository->shouldReceive('withColumns')->with('id')->once()->andReturnSelf() + $this->databaseRepository->shouldReceive('setColumns')->with('id')->once()->andReturnSelf() ->shouldReceive('findWhere')->with([ ['server_id', '=', $this->model->id], ])->once()->andReturn(collect([(object) ['id' => 50]])); $this->databaseManagementService->shouldReceive('delete')->with(50)->once()->andReturnNull(); - $this->repository->shouldReceive('delete')->with($this->model->id)->once()->andReturnNull(); + $this->repository->shouldReceive('delete')->with($this->model->id)->once()->andReturn(1); $this->connection->shouldReceive('commit')->withNoArgs()->once()->andReturnNull(); $this->service->handle($this->model); @@ -140,13 +140,13 @@ class ServerDeletionServiceTest extends TestCase $this->exception->shouldReceive('getResponse')->withNoArgs()->once()->andReturnNull(); $this->writer->shouldReceive('warning')->with($this->exception)->once()->andReturnNull(); $this->connection->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull(); - $this->databaseRepository->shouldReceive('withColumns')->with('id')->once()->andReturnSelf() + $this->databaseRepository->shouldReceive('setColumns')->with('id')->once()->andReturnSelf() ->shouldReceive('findWhere')->with([ ['server_id', '=', $this->model->id], ])->once()->andReturn(collect([(object) ['id' => 50]])); $this->databaseManagementService->shouldReceive('delete')->with(50)->once()->andReturnNull(); - $this->repository->shouldReceive('delete')->with($this->model->id)->once()->andReturnNull(); + $this->repository->shouldReceive('delete')->with($this->model->id)->once()->andReturn(1); $this->connection->shouldReceive('commit')->withNoArgs()->once()->andReturnNull(); $this->service->withForce()->handle($this->model); @@ -176,21 +176,21 @@ class ServerDeletionServiceTest extends TestCase */ public function testIntegerCanBePassedInPlaceOfServerModel() { - $this->repository->shouldReceive('withColumns')->with(['id', 'node_id', 'uuid'])->once()->andReturnSelf() + $this->repository->shouldReceive('setColumns')->with(['id', 'node_id', 'uuid'])->once()->andReturnSelf() ->shouldReceive('find')->with($this->model->id)->once()->andReturn($this->model); $this->daemonServerRepository->shouldReceive('setNode')->with($this->model->node_id)->once()->andReturnSelf() ->shouldReceive('setAccessServer')->with($this->model->uuid)->once()->andReturnSelf() - ->shouldReceive('delete')->withNoArgs()->once()->andReturnNull(); + ->shouldReceive('delete')->withNoArgs()->once()->andReturn(1); $this->connection->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull(); - $this->databaseRepository->shouldReceive('withColumns')->with('id')->once()->andReturnSelf() + $this->databaseRepository->shouldReceive('setColumns')->with('id')->once()->andReturnSelf() ->shouldReceive('findWhere')->with([ ['server_id', '=', $this->model->id], ])->once()->andReturn(collect([(object) ['id' => 50]])); $this->databaseManagementService->shouldReceive('delete')->with(50)->once()->andReturnNull(); - $this->repository->shouldReceive('delete')->with($this->model->id)->once()->andReturnNull(); + $this->repository->shouldReceive('delete')->with($this->model->id)->once()->andReturn(1); $this->connection->shouldReceive('commit')->withNoArgs()->once()->andReturnNull(); $this->service->handle($this->model->id); diff --git a/tests/Unit/Services/Sftp/AuthenticateUsingPasswordServiceTest.php b/tests/Unit/Services/Sftp/AuthenticateUsingPasswordServiceTest.php index 904f10a0a..26584522f 100644 --- a/tests/Unit/Services/Sftp/AuthenticateUsingPasswordServiceTest.php +++ b/tests/Unit/Services/Sftp/AuthenticateUsingPasswordServiceTest.php @@ -49,10 +49,10 @@ class AuthenticateUsingPasswordServiceTest extends TestCase $user = factory(User::class)->make(['root_admin' => 0]); $server = factory(Server::class)->make(['node_id' => 1, 'owner_id' => $user->id]); - $this->userRepository->shouldReceive('withColumns')->with(['id', 'root_admin', 'password'])->once()->andReturnSelf(); + $this->userRepository->shouldReceive('setColumns')->with(['id', 'root_admin', 'password'])->once()->andReturnSelf(); $this->userRepository->shouldReceive('findFirstWhere')->with([['username', '=', $user->username]])->once()->andReturn($user); - $this->repository->shouldReceive('withColumns')->with(['id', 'node_id', 'owner_id', 'uuid'])->once()->andReturnSelf(); + $this->repository->shouldReceive('setColumns')->with(['id', 'node_id', 'owner_id', 'uuid'])->once()->andReturnSelf(); $this->repository->shouldReceive('getByUuid')->with($server->uuidShort)->once()->andReturn($server); $this->keyProviderService->shouldReceive('handle')->with($server, $user)->once()->andReturn('server_token'); @@ -74,10 +74,10 @@ class AuthenticateUsingPasswordServiceTest extends TestCase $user = factory(User::class)->make(['root_admin' => 1]); $server = factory(Server::class)->make(['node_id' => 1, 'owner_id' => $user->id + 1]); - $this->userRepository->shouldReceive('withColumns')->with(['id', 'root_admin', 'password'])->once()->andReturnSelf(); + $this->userRepository->shouldReceive('setColumns')->with(['id', 'root_admin', 'password'])->once()->andReturnSelf(); $this->userRepository->shouldReceive('findFirstWhere')->with([['username', '=', $user->username]])->once()->andReturn($user); - $this->repository->shouldReceive('withColumns')->with(['id', 'node_id', 'owner_id', 'uuid'])->once()->andReturnSelf(); + $this->repository->shouldReceive('setColumns')->with(['id', 'node_id', 'owner_id', 'uuid'])->once()->andReturnSelf(); $this->repository->shouldReceive('getByUuid')->with($server->uuidShort)->once()->andReturn($server); $this->keyProviderService->shouldReceive('handle')->with($server, $user)->once()->andReturn('server_token'); @@ -110,7 +110,7 @@ class AuthenticateUsingPasswordServiceTest extends TestCase { $user = factory(User::class)->make(); - $this->userRepository->shouldReceive('withColumns')->with(['id', 'root_admin', 'password'])->once()->andReturnSelf(); + $this->userRepository->shouldReceive('setColumns')->with(['id', 'root_admin', 'password'])->once()->andReturnSelf(); $this->userRepository->shouldReceive('findFirstWhere')->with([['username', '=', $user->username]])->once()->andReturn($user); $this->getService()->handle($user->username, 'wrongpassword', 1, '1234'); @@ -123,7 +123,7 @@ class AuthenticateUsingPasswordServiceTest extends TestCase */ public function testExceptionIsThrownIfNoUserAccountIsFound() { - $this->userRepository->shouldReceive('withColumns')->with(['id', 'root_admin', 'password'])->once()->andReturnSelf(); + $this->userRepository->shouldReceive('setColumns')->with(['id', 'root_admin', 'password'])->once()->andReturnSelf(); $this->userRepository->shouldReceive('findFirstWhere')->with([['username', '=', 'something']])->once()->andThrow(new RecordNotFoundException); $this->getService()->handle('something', 'password', 1, '1234'); @@ -140,10 +140,10 @@ class AuthenticateUsingPasswordServiceTest extends TestCase $user = factory(User::class)->make(['root_admin' => 0]); $server = factory(Server::class)->make(['node_id' => 1, 'owner_id' => $user->id + 1]); - $this->userRepository->shouldReceive('withColumns')->with(['id', 'root_admin', 'password'])->once()->andReturnSelf(); + $this->userRepository->shouldReceive('setColumns')->with(['id', 'root_admin', 'password'])->once()->andReturnSelf(); $this->userRepository->shouldReceive('findFirstWhere')->with([['username', '=', $user->username]])->once()->andReturn($user); - $this->repository->shouldReceive('withColumns')->with(['id', 'node_id', 'owner_id', 'uuid'])->once()->andReturnSelf(); + $this->repository->shouldReceive('setColumns')->with(['id', 'node_id', 'owner_id', 'uuid'])->once()->andReturnSelf(); $this->repository->shouldReceive('getByUuid')->with($server->uuidShort)->once()->andReturn($server); $this->getService()->handle($user->username, 'password', 1, $server->uuidShort); @@ -160,10 +160,10 @@ class AuthenticateUsingPasswordServiceTest extends TestCase $user = factory(User::class)->make(['root_admin' => 0]); $server = factory(Server::class)->make(['node_id' => 2, 'owner_id' => $user->id]); - $this->userRepository->shouldReceive('withColumns')->with(['id', 'root_admin', 'password'])->once()->andReturnSelf(); + $this->userRepository->shouldReceive('setColumns')->with(['id', 'root_admin', 'password'])->once()->andReturnSelf(); $this->userRepository->shouldReceive('findFirstWhere')->with([['username', '=', $user->username]])->once()->andReturn($user); - $this->repository->shouldReceive('withColumns')->with(['id', 'node_id', 'owner_id', 'uuid'])->once()->andReturnSelf(); + $this->repository->shouldReceive('setColumns')->with(['id', 'node_id', 'owner_id', 'uuid'])->once()->andReturnSelf(); $this->repository->shouldReceive('getByUuid')->with($server->uuidShort)->once()->andReturn($server); $this->getService()->handle($user->username, 'password', 1, $server->uuidShort); diff --git a/tests/Unit/Services/Subusers/PermissionCreationServiceTest.php b/tests/Unit/Services/Subusers/PermissionCreationServiceTest.php index 477cd6c6c..ddfd8c551 100644 --- a/tests/Unit/Services/Subusers/PermissionCreationServiceTest.php +++ b/tests/Unit/Services/Subusers/PermissionCreationServiceTest.php @@ -48,7 +48,7 @@ class PermissionCreationServiceTest extends TestCase ->shouldReceive('insert')->with([ ['subuser_id' => 1, 'permission' => 'reset-sftp'], ['subuser_id' => 1, 'permission' => 'view-sftp'], - ])->once()->andReturnNull(); + ])->once()->andReturn(true); $this->service->handle(1, $permissions); $this->assertTrue(true); diff --git a/tests/Unit/Services/Subusers/SubuserDeletionServiceTest.php b/tests/Unit/Services/Subusers/SubuserDeletionServiceTest.php index ed8c5fab1..b32b272ed 100644 --- a/tests/Unit/Services/Subusers/SubuserDeletionServiceTest.php +++ b/tests/Unit/Services/Subusers/SubuserDeletionServiceTest.php @@ -55,7 +55,7 @@ class SubuserDeletionServiceTest extends TestCase $this->connection->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull(); $this->keyDeletionService->shouldReceive('handle')->with($subuser->server_id, $subuser->user_id)->once()->andReturnNull(); - $this->repository->shouldReceive('delete')->with($subuser->id)->once()->andReturnNull(); + $this->repository->shouldReceive('delete')->with($subuser->id)->once()->andReturn(1); $this->connection->shouldReceive('commit')->withNoArgs()->once()->andReturnNull(); $this->getService()->handle($subuser); diff --git a/tests/Unit/Services/Subusers/SubuserUpdateServiceTest.php b/tests/Unit/Services/Subusers/SubuserUpdateServiceTest.php index 6b9f8ab32..550411337 100644 --- a/tests/Unit/Services/Subusers/SubuserUpdateServiceTest.php +++ b/tests/Unit/Services/Subusers/SubuserUpdateServiceTest.php @@ -86,7 +86,7 @@ class SubuserUpdateServiceTest extends TestCase $this->repository->shouldReceive('loadServerAndUserRelations')->with($subuser)->once()->andReturn($subuser); $this->connection->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull(); - $this->permissionRepository->shouldReceive('deleteWhere')->with([['subuser_id', '=', $subuser->id]])->once()->andReturnNull(); + $this->permissionRepository->shouldReceive('deleteWhere')->with([['subuser_id', '=', $subuser->id]])->once()->andReturn(1); $this->permissionService->shouldReceive('handle')->with($subuser->id, ['some-permission'])->once()->andReturnNull(); $this->keyProviderService->shouldReceive('handle')->with($subuser->server, $subuser->user, false)->once()->andReturn('test123'); @@ -112,7 +112,7 @@ class SubuserUpdateServiceTest extends TestCase $this->repository->shouldReceive('loadServerAndUserRelations')->with($subuser)->once()->andReturn($subuser); $this->connection->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull(); - $this->permissionRepository->shouldReceive('deleteWhere')->with([['subuser_id', '=', $subuser->id]])->once()->andReturnNull(); + $this->permissionRepository->shouldReceive('deleteWhere')->with([['subuser_id', '=', $subuser->id]])->once()->andReturn(1); $this->permissionService->shouldReceive('handle')->with($subuser->id, [])->once()->andReturnNull(); $this->keyProviderService->shouldReceive('handle')->with($subuser->server, $subuser->user, false)->once()->andReturn('test123'); diff --git a/tests/Unit/Services/Users/UserDeletionServiceTest.php b/tests/Unit/Services/Users/UserDeletionServiceTest.php index 1eed3358a..2876ce147 100644 --- a/tests/Unit/Services/Users/UserDeletionServiceTest.php +++ b/tests/Unit/Services/Users/UserDeletionServiceTest.php @@ -68,14 +68,11 @@ class UserDeletionServiceTest extends TestCase */ public function testUserIsDeletedIfNoServersAreAttachedToAccount() { - $this->serverRepository->shouldReceive('withColumns')->with('id')->once()->andReturnSelf() + $this->serverRepository->shouldReceive('setColumns')->with('id')->once()->andReturnSelf() ->shouldReceive('findCountWhere')->with([['owner_id', '=', $this->user->id]])->once()->andReturn(0); - $this->repository->shouldReceive('delete')->with($this->user->id)->once()->andReturn(true); + $this->repository->shouldReceive('delete')->with($this->user->id)->once()->andReturn(1); - $this->assertTrue( - $this->service->handle($this->user->id), - 'Assert that service responds true.' - ); + $this->assertEquals(1, $this->service->handle($this->user->id)); } /** @@ -85,7 +82,7 @@ class UserDeletionServiceTest extends TestCase */ public function testExceptionIsThrownIfServersAreAttachedToAccount() { - $this->serverRepository->shouldReceive('withColumns')->with('id')->once()->andReturnSelf() + $this->serverRepository->shouldReceive('setColumns')->with('id')->once()->andReturnSelf() ->shouldReceive('findCountWhere')->with([['owner_id', '=', $this->user->id]])->once()->andReturn(1); $this->translator->shouldReceive('trans')->with('admin/user.exceptions.user_has_servers')->once()->andReturnNull(); @@ -97,13 +94,10 @@ class UserDeletionServiceTest extends TestCase */ public function testModelCanBePassedInPlaceOfUserId() { - $this->serverRepository->shouldReceive('withColumns')->with('id')->once()->andReturnSelf() + $this->serverRepository->shouldReceive('setColumns')->with('id')->once()->andReturnSelf() ->shouldReceive('findCountWhere')->with([['owner_id', '=', $this->user->id]])->once()->andReturn(0); - $this->repository->shouldReceive('delete')->with($this->user->id)->once()->andReturn(true); + $this->repository->shouldReceive('delete')->with($this->user->id)->once()->andReturn(1); - $this->assertTrue( - $this->service->handle($this->user), - 'Assert that service responds true.' - ); + $this->assertEquals(1, $this->service->handle($this->user)); } }