Merge branch 'develop' into matthewpi/security-keys-backport

This commit is contained in:
Matthew Penner 2023-01-17 15:33:53 -07:00
commit f631ac1946
No known key found for this signature in database
1153 changed files with 25099 additions and 37002 deletions

View file

@ -40,14 +40,14 @@ class AllocationRepository extends EloquentRepository implements AllocationRepos
*/
protected function getDiscardableDedicatedAllocations(array $nodes = []): array
{
$query = Allocation::query()->selectRaw('CONCAT_WS("-", node_id, ip) as result');
$query = Allocation::query()->selectRaw('CONCAT_WS(\'-\', node_id, ip) as result');
if (!empty($nodes)) {
$query->whereIn('node_id', $nodes);
}
return $query->whereNotNull('server_id')
->groupByRaw('CONCAT(node_id, ip)')
->groupByRaw('result')
->get()
->pluck('result')
->toArray();
@ -89,7 +89,7 @@ class AllocationRepository extends EloquentRepository implements AllocationRepos
if (!empty($discard)) {
$query->whereNotIn(
$this->getBuilder()->raw('CONCAT_WS("-", node_id, ip)'),
$this->getBuilder()->raw('CONCAT_WS(\'-\', node_id, ip)'),
$discard
);
}

View file

@ -5,6 +5,7 @@ namespace Pterodactyl\Repositories\Eloquent;
use Illuminate\Http\Request;
use Webmozart\Assert\Assert;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Database\Eloquent\Model;
use Pterodactyl\Repositories\Repository;
use Illuminate\Database\Eloquent\Builder;
@ -75,6 +76,7 @@ abstract class EloquentRepository extends Repository implements RepositoryInterf
*/
public function create(array $fields, bool $validate = true, bool $force = false): Model|bool
{
/** @var \Pterodactyl\Models\Model $instance */
$instance = $this->getBuilder()->newModelInstance();
($force) ? $instance->forceFill($fields) : $instance->fill($fields);
@ -160,6 +162,7 @@ abstract class EloquentRepository extends Repository implements RepositoryInterf
public function update(int $id, array $fields, bool $validate = true, bool $force = false): Model|bool
{
try {
/** @var \Pterodactyl\Models\Model $instance */
$instance = $this->getBuilder()->where('id', $id)->firstOrFail();
} catch (ModelNotFoundException) {
throw new RecordNotFoundException();
@ -271,7 +274,17 @@ abstract class EloquentRepository extends Repository implements RepositoryInterf
return sprintf('(%s)', $grammar->parameterize($record));
})->implode(', ');
$statement = "insert ignore into $table ($columns) values $parameters";
$driver = DB::getPdo()->getAttribute(\PDO::ATTR_DRIVER_NAME);
switch ($driver) {
case 'mysql':
$statement = "insert ignore into $table ($columns) values $parameters";
break;
case 'pgsql':
$statement = "insert into $table ($columns) values $parameters on conflict do nothing";
break;
default:
throw new \RuntimeException("Unsupported database driver \"$driver\" for insert ignore.");
}
return $this->getBuilder()->getConnection()->statement($statement, $bindings);
}

View file

@ -21,11 +21,7 @@ class NodeRepository extends EloquentRepository implements NodeRepositoryInterfa
*/
public function getUsageStats(Node $node): array
{
$stats = $this->getBuilder()
->selectRaw('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', '=', $node->id)
->first();
$stats = $node->loadServerSums();
return Collection::make(['disk' => $stats->sum_disk, 'memory' => $stats->sum_memory])
->mapWithKeys(function ($value, $key) use ($node) {
@ -53,9 +49,7 @@ class NodeRepository extends EloquentRepository implements NodeRepositoryInterfa
*/
public function getUsageStatsRaw(Node $node): array
{
$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', $node->id)->first();
$stats = $node->loadServerSums();
return collect(['disk' => $stats->sum_disk, 'memory' => $stats->sum_memory])->mapWithKeys(function ($value, $key) use ($node) {
$maxUsage = $node->{$key};
@ -84,9 +78,7 @@ class NodeRepository extends EloquentRepository implements NodeRepositoryInterfa
// 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);
$node->loadCount('servers');
}
return $node;
@ -135,18 +127,4 @@ class NodeRepository extends EloquentRepository implements NodeRepositoryInterfa
];
})->values();
}
/**
* Returns a node with the given id with the Node's resource usage.
*/
public function getNodeWithResourceUsage(int $node_id): Node
{
$instance = $this->getBuilder()
->select(['nodes.id', 'nodes.fqdn', 'nodes.scheme', 'nodes.daemon_token', 'nodes.daemonListen', 'nodes.memory', 'nodes.disk', 'nodes.memory_overallocate', 'nodes.disk_overallocate'])
->selectRaw('IFNULL(SUM(servers.memory), 0) as sum_memory, IFNULL(SUM(servers.disk), 0) as sum_disk')
->leftJoin('servers', 'servers.node_id', '=', 'nodes.id')
->where('nodes.id', $node_id);
return $instance->first();
}
}

View file

@ -2,7 +2,6 @@
namespace Pterodactyl\Repositories\Eloquent;
use Exception;
use Pterodactyl\Contracts\Repository\PermissionRepositoryInterface;
class PermissionRepository extends EloquentRepository implements PermissionRepositoryInterface
@ -14,6 +13,6 @@ class PermissionRepository extends EloquentRepository implements PermissionRepos
*/
public function model(): string
{
throw new Exception('This functionality is not implemented.');
throw new \Exception('This functionality is not implemented.');
}
}

View file

@ -46,6 +46,7 @@ class SettingsRepository extends EloquentRepository implements SettingsRepositor
return value($default);
}
/** @var Setting $instance */
$instance = $this->getBuilder()->where('key', $key)->first();
if (is_null($instance)) {
self::$databaseMiss[$key] = true;

View file

@ -2,7 +2,6 @@
namespace Pterodactyl\Repositories;
use InvalidArgumentException;
use Illuminate\Foundation\Application;
use Illuminate\Database\Eloquent\Model;
use Pterodactyl\Contracts\Repository\RepositoryInterface;
@ -97,7 +96,7 @@ abstract class Repository implements RepositoryInterface
case 2:
return $this->model = call_user_func([$this->app->make($model[0]), $model[1]]);
default:
throw new InvalidArgumentException('Model must be a FQDN or an array with a count of two.');
throw new \InvalidArgumentException('Model must be a FQDN or an array with a count of two.');
}
}
}

View file

@ -14,10 +14,10 @@ class DaemonConfigurationRepository extends DaemonRepository
*
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
*/
public function getSystemInformation(): array
public function getSystemInformation(?int $version = null): array
{
try {
$response = $this->getHttpClient()->get('/api/system');
$response = $this->getHttpClient()->get('/api/system' . (!is_null($version) ? '?v=' . $version : ''));
} catch (TransferException $exception) {
throw new DaemonConnectionException($exception);
}

View file

@ -2,9 +2,11 @@
namespace Pterodactyl\Repositories\Wings;
use Illuminate\Support\Arr;
use Webmozart\Assert\Assert;
use Pterodactyl\Models\Server;
use Psr\Http\Message\ResponseInterface;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\TransferException;
use Pterodactyl\Exceptions\Http\Server\FileSizeTooLargeException;
use Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException;
@ -31,12 +33,11 @@ class DaemonFileRepository extends DaemonRepository
'query' => ['file' => $path],
]
);
} catch (TransferException $exception) {
} catch (ClientException|TransferException $exception) {
throw new DaemonConnectionException($exception);
}
$length = (int) $response->getHeader('Content-Length')[0] ?? 0;
$length = (int) Arr::get($response->getHeader('Content-Length'), 0, 0);
if ($notLargerThan && $length > $notLargerThan) {
throw new FileSizeTooLargeException();
}
@ -231,6 +232,9 @@ class DaemonFileRepository extends DaemonRepository
'root' => $root ?? '/',
'file' => $file,
],
// Wait for up to 15 minutes for the decompress to be completed when calling this endpoint
// since it will likely take quite awhile for large directories.
'timeout' => 60 * 15,
]
);
} catch (TransferException $exception) {

View file

@ -2,8 +2,8 @@
namespace Pterodactyl\Repositories\Wings;
use Pterodactyl\Models\Node;
use Lcobucci\JWT\Token\Plain;
use Pterodactyl\Models\Server;
use GuzzleHttp\Exception\GuzzleException;
use Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException;
@ -12,16 +12,16 @@ class DaemonTransferRepository extends DaemonRepository
/**
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
*/
public function notify(Server $server, Plain $token): void
public function notify(Node $targetNode, Plain $token): void
{
try {
$this->getHttpClient()->post('/api/transfer', [
$this->getHttpClient()->post(sprintf('/api/servers/%s/transfer', $this->server->uuid), [
'json' => [
'server_id' => $server->uuid,
'url' => $server->node->getConnectionAddress() . sprintf('/api/servers/%s/archive', $server->uuid),
'server_id' => $this->server->uuid,
'url' => $targetNode->getConnectionAddress() . '/api/transfers',
'token' => 'Bearer ' . $token->toString(),
'server' => [
'uuid' => $server->uuid,
'uuid' => $this->server->uuid,
'start_on_completion' => false,
],
],